this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Implement some more options for posix_spawn

POSIX_SPAWN_CLOEXEC_DEFAULT is set to close all fds inherited by the new process except for those explicitly marked as inheritable (or those newly created by posix_spawn actions). We can replicate this by adding O_CLOEXEC to all open fds in the child before performing our actions (except special fds like commpage).

Other than that, some new actions have also been implemented: chdir, fchdir, and inherit. chdir and fchdir change the cwd of the child to the given path or fd. inherit ensures the given fd is inherited by the child (i.e. that O_CLOEXEC is not set on it).

+139 -14
+110 -3
src/kernel/emulation/linux/process/posix_spawn.c
··· 24 24 #include <stddef.h> 25 25 #include <stdint.h> 26 26 #include <sys/spawn.h> 27 + #include "../unistd/chdir.h" 28 + #include "../unistd/fchdir.h" 29 + #include "../fcntl/fcntl.h" 30 + #include "../dirent/getdirentries.h" 31 + 32 + // for debugging only; remove before committing 33 + #include "../signal/kill.h" 34 + #include "../unistd/getpid.h" 27 35 28 36 #ifndef _POSIX_SPAWN_DISABLE_ASLR 29 37 #define _POSIX_SPAWN_DISABLE_ASLR 0x0100 30 38 #endif 31 39 32 40 #define LINUX_ADDR_NO_RANDOMIZE 0x40000 33 - 34 41 35 42 long sys_posix_spawn(int* pid, const char* path, const struct _posix_spawn_args_desc* desc, 36 43 char** argvp, char** envp) ··· 87 94 lkm_call(NR_stop_after_exec, NULL); 88 95 } 89 96 97 + if (desc->attrp->psa_flags & POSIX_SPAWN_CLOEXEC_DEFAULT) { 98 + // set O_CLOEXEC on everything 99 + int dir = sys_open("/proc/self/fd", BSD_O_RDONLY, 0); 100 + char buf[4096]; 101 + int len = 0; 102 + 103 + //__simple_kprintf("asked for cloexec default\n"); 104 + 105 + if (dir < 0) { 106 + ret = dir; 107 + goto fail; 108 + } 109 + 110 + while ((len = LINUX_SYSCALL(__NR_getdents64, dir, buf, sizeof(buf))) > 0) { 111 + struct linux_dirent64* dirent = (struct linux_dirent64*)&buf[0]; 112 + for (int i = 0; i < len; i += dirent->d_reclen, dirent = (struct linux_dirent64*)&buf[i]) { 113 + int fd = -1; 114 + 115 + //__simple_kprintf("dentry name: %s\n", dirent->d_name); 116 + if (dirent->d_name[0] == '.') { 117 + continue; 118 + } 119 + 120 + fd = __simple_atoi(dirent->d_name, NULL); 121 + 122 + // FIXME: pretty sure this should not be hardcoded 123 + if (fd == 1023) { 124 + // special commpage fd 125 + continue; 126 + } 127 + 128 + //__simple_kprintf("setting cloexec on %d\n", fd); 129 + 130 + ret = sys_fcntl(fd, F_GETFD, 0); 131 + if (ret < 0) { 132 + close_internal(dir); 133 + goto fail; 134 + } 135 + 136 + ret = sys_fcntl(fd, F_SETFD, ret | FD_CLOEXEC); 137 + if (ret < 0) { 138 + close_internal(dir); 139 + goto fail; 140 + } 141 + } 142 + } 143 + 144 + close_internal(dir); 145 + 146 + if (len < 0) { 147 + ret = len; 148 + goto fail; 149 + } 150 + } 151 + 90 152 // TODO: other attributes 91 153 } 92 154 if (desc && desc->factp) 93 155 { 94 156 int i; 95 157 158 + //__simple_kprintf("act count: %d\n", desc->factp->psfa_act_count); 159 + 160 + //sys_kill(sys_getpid(), SIGSTOP, 0); 161 + 96 162 for (i = 0; i < desc->factp->psfa_act_count; i++) 97 163 { 98 164 const struct _psfa_action* act; 99 165 100 166 act = &desc->factp->psfa_act_acts[i]; 101 167 102 - if (act->psfaa_filedes == pipe[1]) 168 + //__simple_kprintf("act count (on iter %d): %d\n", i, desc->factp->psfa_act_count); 169 + 170 + if (act->psfaa_filedes == pipe[1] || (act->psfaa_type == PSFA_DUP2 && act->psfaa_dup2args.psfad_newfiledes == pipe[1])) 103 171 { 104 172 ret = sys_dup(pipe[1]); 105 173 if (ret < 0) ··· 112 180 switch (act->psfaa_type) 113 181 { 114 182 case PSFA_CLOSE: 183 + //__simple_kprintf("closing %d\n", act->psfaa_filedes); 115 184 ret = close_internal(act->psfaa_filedes); 116 185 if (ret != 0) 117 186 goto fail; 118 187 break; 188 + 119 189 case PSFA_DUP2: 120 - ret = sys_dup2(act->psfaa_filedes, act->psfaa_openargs.psfao_oflag); 190 + //__simple_kprintf("duping %d to %d\n", act->psfaa_filedes, act->psfaa_dup2args.psfad_newfiledes); 191 + ret = sys_dup2(act->psfaa_filedes, act->psfaa_dup2args.psfad_newfiledes); 121 192 if (ret < 0) 122 193 goto fail; 123 194 break; 195 + 124 196 case PSFA_OPEN: 125 197 { 198 + //__simple_kprintf("opening %s to %d\n", act->psfaa_openargs.psfao_path, act->psfaa_filedes); 126 199 ret = sys_open(act->psfaa_openargs.psfao_path, 127 200 act->psfaa_openargs.psfao_oflag, act->psfaa_openargs.psfao_mode); 128 201 if (ret < 0) ··· 141 214 } 142 215 break; 143 216 } 217 + 218 + case PSFA_CHDIR: { 219 + //__simple_kprintf("chdiring to %s\n", act->psfaa_chdirargs.psfac_path); 220 + ret = sys_chdir(act->psfaa_chdirargs.psfac_path); 221 + if (ret < 0) { 222 + goto fail; 223 + } 224 + } break; 225 + 226 + case PSFA_FCHDIR: { 227 + //__simple_kprintf("fchdiring to %d\n", act->psfaa_filedes); 228 + ret = sys_fchdir(act->psfaa_filedes); 229 + if (ret < 0) { 230 + goto fail; 231 + } 232 + } break; 233 + 234 + // unset CLOEXEC on this fd 235 + case PSFA_INHERIT: { 236 + //__simple_kprintf("inheriting %d\n", act->psfaa_filedes); 237 + ret = sys_fcntl(act->psfaa_filedes, F_GETFD, 0); 238 + if (ret < 0) { 239 + goto fail; 240 + } 241 + ret = sys_fcntl(act->psfaa_filedes, F_SETFD, ret & ~FD_CLOEXEC); 242 + if (ret < 0) { 243 + goto fail; 244 + } 245 + } break; 246 + 144 247 default: 248 + //__simple_kprintf("unknown PSFA type %d\n", act->psfaa_type); 145 249 ; 146 250 } 147 251 } 252 + 253 + //__simple_kprintf("act count (on finish): %d\n", desc->factp->psfa_act_count); 148 254 } 149 255 150 256 char binprefs[64]; ··· 174 280 175 281 ret = sys_execve((char*) path, argvp, envp); 176 282 fail: 283 + //__simple_kprintf("posix_spawn is failing with %d\n", ret); 177 284 if (desc && desc->attrp && desc->attrp->psa_flags & POSIX_SPAWN_SETEXEC) 178 285 { 179 286 // no_fork case
+29 -11
src/kernel/emulation/linux/process/posix_spawn.h
··· 1 1 #ifndef LINUX_POSIX_SPAWN_H 2 2 #define LINUX_POSIX_SPAWN_H 3 + 4 + #include <sys/types.h> 5 + #include <limits.h> 6 + #include <mach/mach_port.h> 7 + 3 8 typedef enum { 4 - PSFA_OPEN = 0, 5 - PSFA_CLOSE = 1, 6 - PSFA_DUP2 = 2, 7 - PSFA_INHERIT = 3 9 + PSFA_OPEN = 0, 10 + PSFA_CLOSE = 1, 11 + PSFA_DUP2 = 2, 12 + PSFA_INHERIT = 3, 13 + PSFA_FILEPORT_DUP2 = 4, 14 + PSFA_CHDIR = 5, 15 + PSFA_FCHDIR = 6 8 16 } psfa_t; 9 17 10 18 struct _posix_spawnattr ··· 22 30 struct _psfa_action 23 31 { 24 32 psfa_t psfaa_type; 25 - int psfaa_filedes; 26 - struct _psfaa_open 27 - { 28 - int psfao_oflag; 29 - unsigned short psfao_mode; 30 - char psfao_path[1024]; 31 - } psfaa_openargs; 33 + union { 34 + int psfaa_filedes; 35 + mach_port_name_t psfaa_fileport; 36 + }; 37 + union { 38 + struct _psfaa_open { 39 + int psfao_oflag; 40 + mode_t psfao_mode; 41 + char psfao_path[PATH_MAX]; 42 + } psfaa_openargs; 43 + struct { 44 + int psfad_newfiledes; 45 + } psfaa_dup2args; 46 + struct { 47 + char psfac_path[PATH_MAX]; 48 + } psfaa_chdirargs; 49 + }; 32 50 }; 33 51 34 52 struct _posix_spawn_file_actions