add swifi to the build/install.
[minix.git] / servers / vfs / exec.c
blobf854e002ddf2c87ac41b2bb0022ae9ccc95aea3a
1 /* This file handles the EXEC system call. It performs the work as follows:
2 * - see if the permissions allow the file to be executed
3 * - read the header and extract the sizes
4 * - fetch the initial args and environment from the user space
5 * - allocate the memory for the new process
6 * - copy the initial stack from PM to the process
7 * - read in the text and data segments and copy to the process
8 * - take care of setuid and setgid bits
9 * - fix up 'mproc' table
10 * - tell kernel about EXEC
11 * - save offset to initial argc (for ps)
13 * The entry points into this file are:
14 * pm_exec: perform the EXEC system call
17 #include "fs.h"
18 #include <sys/stat.h>
19 #include <minix/callnr.h>
20 #include <minix/endpoint.h>
21 #include <minix/com.h>
22 #include <minix/u64.h>
23 #include <a.out.h>
24 #include <signal.h>
25 #include <string.h>
26 #include <dirent.h>
27 #include "fproc.h"
28 #include "param.h"
29 #include "vnode.h"
30 #include "vmnt.h"
31 #include <minix/vfsif.h>
33 FORWARD _PROTOTYPE( int exec_newmem, (int proc_e, vir_bytes text_bytes,
34 vir_bytes data_bytes, vir_bytes bss_bytes, vir_bytes tot_bytes,
35 vir_bytes frame_len, int sep_id,
36 Dev_t st_dev, ino_t st_ino, time_t st_ctime, char *progname,
37 int new_uid, int new_gid,
38 vir_bytes *stack_topp, int *load_textp, int *allow_setuidp) );
39 FORWARD _PROTOTYPE( int read_header, (struct vnode *vp, int *sep_id,
40 vir_bytes *text_bytes, vir_bytes *data_bytes,
41 vir_bytes *bss_bytes, phys_bytes *tot_bytes, vir_bytes *pc,
42 int *hdrlenp) );
43 FORWARD _PROTOTYPE( int patch_stack, (struct vnode *vp,
44 char stack[ARG_MAX], vir_bytes *stk_bytes) );
45 FORWARD _PROTOTYPE( int insert_arg, (char stack[ARG_MAX],
46 vir_bytes *stk_bytes, char *arg, int replace) );
47 FORWARD _PROTOTYPE( void patch_ptr, (char stack[ARG_MAX],
48 vir_bytes base) );
49 FORWARD _PROTOTYPE( int read_seg, (struct vnode *vp, off_t off,
50 int proc_e, int seg, phys_bytes seg_bytes) );
51 FORWARD _PROTOTYPE( void clo_exec, (struct fproc *rfp) );
53 #define ESCRIPT (-2000) /* Returned by read_header for a #! script. */
54 #define PTRSIZE sizeof(char *) /* Size of pointers in argv[] and envp[]. */
56 /*===========================================================================*
57 * pm_exec *
58 *===========================================================================*/
59 PUBLIC int pm_exec(proc_e, path, path_len, frame, frame_len)
60 int proc_e;
61 char *path;
62 vir_bytes path_len;
63 char *frame;
64 vir_bytes frame_len;
66 /* Perform the execve(name, argv, envp) call. The user library builds a
67 * complete stack image, including pointers, args, environ, etc. The stack
68 * is copied to a buffer inside FS, and then to the new core image.
70 int r, r1, sep_id, round, proc_s, hdrlen, load_text, allow_setuid;
71 vir_bytes text_bytes, data_bytes, bss_bytes, pc;
72 phys_bytes tot_bytes; /* total space for program, including gap */
73 vir_bytes stack_top, vsp;
74 off_t off;
75 uid_t new_uid;
76 gid_t new_gid;
77 struct fproc *rfp;
78 struct vnode *vp;
79 time_t v_ctime;
80 char *cp;
81 struct stat sb;
82 char progname[PROC_NAME_LEN];
83 static char mbuf[ARG_MAX]; /* buffer for stack and zeroes */
85 okendpt(proc_e, &proc_s);
86 rfp = fp = &fproc[proc_s];
87 who_e = proc_e;
88 who_p = proc_s;
89 super_user = (fp->fp_effuid == SU_UID ? TRUE : FALSE); /* su? */
91 /* Get the exec file name. */
92 if ((r = fetch_name(path, path_len, 0)) != OK) return(r);
94 /* Fetch the stack from the user before destroying the old core image. */
95 if (frame_len > ARG_MAX) return(ENOMEM); /* stack too big */
96 r = sys_datacopy(proc_e, (vir_bytes) frame, SELF, (vir_bytes) mbuf,
97 (phys_bytes) frame_len);
98 if (r != OK) { /* can't fetch stack (e.g. bad virtual addr) */
99 printf("pm_exec: sys_datacopy failed\n");
100 return(r);
103 /* The default is to keep the original user and group IDs */
104 new_uid = rfp->fp_effuid;
105 new_gid = rfp->fp_effgid;
107 for (round= 0; round < 2; round++) {
108 /* round = 0 (first attempt), or 1 (interpreted script) */
110 /* Save the name of the program */
111 (cp= strrchr(user_fullpath, '/')) ? cp++ : (cp= user_fullpath);
113 strncpy(progname, cp, PROC_NAME_LEN-1);
114 progname[PROC_NAME_LEN-1] = '\0';
116 /* Open executable */
117 if ((vp = eat_path(PATH_NOFLAGS)) == NIL_VNODE) return(err_code);
119 if ((vp->v_mode & I_TYPE) != I_REGULAR)
120 r = ENOEXEC;
121 else if ((r1 = forbidden(vp, X_BIT)) != OK)
122 r = r1;
123 else
124 r = req_stat(vp->v_fs_e, vp->v_inode_nr, FS_PROC_NR,
125 (char *) &sb, 0);
126 if (r != OK) {
127 put_vnode(vp);
128 return(r);
131 v_ctime = sb.st_ctime;
132 if (round == 0) {
133 /* Deal with setuid/setgid executables */
134 if (vp->v_mode & I_SET_UID_BIT) new_uid = vp->v_uid;
135 if (vp->v_mode & I_SET_GID_BIT) new_gid = vp->v_gid;
138 /* Read the file header and extract the segment sizes. */
139 r = read_header(vp, &sep_id, &text_bytes, &data_bytes, &bss_bytes,
140 &tot_bytes, &pc, &hdrlen);
141 if (r != ESCRIPT || round != 0)
142 break;
144 /* Get fresh copy of the file name. */
145 if ((r = fetch_name(path, path_len, 0)) != OK)
146 printf("VFS pm_exec: 2nd fetch_name failed\n");
147 else if ((r = patch_stack(vp, mbuf, &frame_len)) != OK)
148 printf("VFS pm_exec: patch_stack failed\n");
149 put_vnode(vp);
150 if (r != OK) return(r);
153 if (r != OK) {
154 put_vnode(vp);
155 return(ENOEXEC);
158 r = exec_newmem(proc_e, text_bytes, data_bytes, bss_bytes, tot_bytes,
159 frame_len, sep_id, vp->v_dev, vp->v_inode_nr, v_ctime,
160 progname, new_uid, new_gid, &stack_top, &load_text,
161 &allow_setuid);
162 if (r != OK) {
163 printf("VFS: pm_exec: exec_newmem failed: %d\n", r);
164 put_vnode(vp);
165 return(r);
168 /* Patch up stack and copy it from FS to new core image. */
169 vsp = stack_top;
170 vsp -= frame_len;
171 patch_ptr(mbuf, vsp);
172 if ((r = sys_datacopy(SELF, (vir_bytes) mbuf, proc_e, (vir_bytes) vsp,
173 (phys_bytes)frame_len)) != OK) {
174 printf("VFS: datacopy failed (%d) trying to copy to %p\n", r, vsp);
175 return(r);
178 off = hdrlen;
180 /* Read in text and data segments. */
181 if (load_text) r = read_seg(vp, off, proc_e, T, text_bytes);
182 off += text_bytes;
183 if (r == OK) r = read_seg(vp, off, proc_e, D, data_bytes);
184 put_vnode(vp);
185 if (r != OK) return(r);
186 clo_exec(rfp);
188 if (allow_setuid) {
189 rfp->fp_effuid = new_uid;
190 rfp->fp_effgid = new_gid;
193 /* This child has now exec()ced. */
194 rfp->fp_execced = 1;
196 /* Check if this is a driver that can now be useful. */
197 dmap_endpt_up(rfp->fp_endpoint);
199 return(OK);
203 /*===========================================================================*
204 * exec_newmem *
205 *===========================================================================*/
206 PRIVATE int exec_newmem(proc_e, text_bytes, data_bytes, bss_bytes, tot_bytes,
207 frame_len, sep_id, st_dev, st_ino, st_ctime, progname,
208 new_uid, new_gid, stack_topp, load_textp, allow_setuidp)
209 int proc_e;
210 vir_bytes text_bytes;
211 vir_bytes data_bytes;
212 vir_bytes bss_bytes;
213 vir_bytes tot_bytes;
214 vir_bytes frame_len;
215 int sep_id;
216 dev_t st_dev;
217 ino_t st_ino;
218 time_t st_ctime;
219 int new_uid;
220 int new_gid;
221 char *progname;
222 vir_bytes *stack_topp;
223 int *load_textp;
224 int *allow_setuidp;
226 int r;
227 struct exec_newmem e;
228 message m;
230 e.text_bytes = text_bytes;
231 e.data_bytes = data_bytes;
232 e.bss_bytes = bss_bytes;
233 e.tot_bytes = tot_bytes;
234 e.args_bytes = frame_len;
235 e.sep_id = sep_id;
236 e.st_dev = st_dev;
237 e.st_ino = st_ino;
238 e.st_ctime = st_ctime;
239 e.new_uid = new_uid;
240 e.new_gid = new_gid;
241 strncpy(e.progname, progname, sizeof(e.progname)-1);
242 e.progname[sizeof(e.progname)-1] = '\0';
244 m.m_type = EXEC_NEWMEM;
245 m.EXC_NM_PROC = proc_e;
246 m.EXC_NM_PTR = (char *)&e;
247 if ((r = sendrec(PM_PROC_NR, &m)) != OK) return(r);
249 *stack_topp = m.m1_i1;
250 *load_textp = !!(m.m1_i2 & EXC_NM_RF_LOAD_TEXT);
251 *allow_setuidp = !!(m.m1_i2 & EXC_NM_RF_ALLOW_SETUID);
253 return(m.m_type);
257 /*===========================================================================*
258 * read_header *
259 *===========================================================================*/
260 PRIVATE int read_header(vp, sep_id, text_bytes, data_bytes, bss_bytes,
261 tot_bytes, pc, hdrlenp)
262 struct vnode *vp; /* inode for reading exec file */
263 int *sep_id; /* true iff sep I&D */
264 vir_bytes *text_bytes; /* place to return text size */
265 vir_bytes *data_bytes; /* place to return initialized data size */
266 vir_bytes *bss_bytes; /* place to return bss size */
267 phys_bytes *tot_bytes; /* place to return total size */
268 vir_bytes *pc; /* program entry point (initial PC) */
269 int *hdrlenp;
271 /* Read the header and extract the text, data, bss and total sizes from it. */
272 off_t pos;
273 int r;
274 u64_t new_pos;
275 unsigned int cum_io;
276 struct exec hdr; /* a.out header is read in here */
278 /* Read the header and check the magic number. The standard MINIX header
279 * is defined in <a.out.h>. It consists of 8 chars followed by 6 longs.
280 * Then come 4 more longs that are not used here.
281 * Byte 0: magic number 0x01
282 * Byte 1: magic number 0x03
283 * Byte 2: normal = 0x10 (not checked, 0 is OK), separate I/D = 0x20
284 * Byte 3: CPU type, Intel 16 bit = 0x04, Intel 32 bit = 0x10,
285 * Motorola = 0x0B, Sun SPARC = 0x17
286 * Byte 4: Header length = 0x20
287 * Bytes 5-7 are not used.
289 * Now come the 6 longs
290 * Bytes 8-11: size of text segments in bytes
291 * Bytes 12-15: size of initialized data segment in bytes
292 * Bytes 16-19: size of bss in bytes
293 * Bytes 20-23: program entry point
294 * Bytes 24-27: total memory allocated to program (text, data + stack)
295 * Bytes 28-31: size of symbol table in bytes
296 * The longs are represented in a machine dependent order,
297 * little-endian on the 8088, big-endian on the 68000.
298 * The header is followed directly by the text and data segments, and the
299 * symbol table (if any). The sizes are given in the header. Only the
300 * text and data segments are copied into memory by exec. The header is
301 * used here only. The symbol table is for the benefit of a debugger and
302 * is ignored here.
305 pos= 0; /* Read from the start of the file */
307 /* Issue request */
308 r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, cvul64(pos), READING,
309 FS_PROC_NR, (char*)&hdr, sizeof(hdr), &new_pos, &cum_io);
310 if (r != OK) return r;
312 /* Interpreted script? */
313 if (((char*)&hdr)[0] == '#' && ((char*)&hdr)[1] == '!' && vp->v_size >= 2)
314 return(ESCRIPT);
316 if (vp->v_size < A_MINHDR) return(ENOEXEC);
318 /* Check magic number, cpu type, and flags. */
319 if (BADMAG(hdr)) return(ENOEXEC);
320 #if (CHIP == INTEL && _WORD_SIZE == 2)
321 if (hdr.a_cpu != A_I8086) return(ENOEXEC);
322 #endif
323 #if (CHIP == INTEL && _WORD_SIZE == 4)
324 if (hdr.a_cpu != A_I80386) return(ENOEXEC);
325 #endif
326 if ((hdr.a_flags & ~(A_NSYM | A_EXEC | A_SEP)) != 0) return(ENOEXEC);
328 *sep_id = !!(hdr.a_flags & A_SEP); /* separate I & D or not */
330 /* Get text and data sizes. */
331 *text_bytes = (vir_bytes) hdr.a_text; /* text size in bytes */
332 *data_bytes = (vir_bytes) hdr.a_data; /* data size in bytes */
333 *bss_bytes = (vir_bytes) hdr.a_bss; /* bss size in bytes */
334 *tot_bytes = hdr.a_total; /* total bytes to allocate for prog */
335 if (*tot_bytes == 0) return(ENOEXEC);
337 if (!*sep_id) {
338 /* If I & D space is not separated, it is all considered data. Text=0*/
339 *data_bytes += *text_bytes;
340 *text_bytes = 0;
342 *pc = hdr.a_entry; /* initial address to start execution */
343 *hdrlenp = hdr.a_hdrlen & BYTE; /* header length */
345 return(OK);
349 /*===========================================================================*
350 * patch_stack *
351 *===========================================================================*/
352 PRIVATE int patch_stack(vp, stack, stk_bytes)
353 struct vnode *vp; /* pointer for open script file */
354 char stack[ARG_MAX]; /* pointer to stack image within FS */
355 vir_bytes *stk_bytes; /* size of initial stack */
357 /* Patch the argument vector to include the path name of the script to be
358 * interpreted, and all strings on the #! line. Returns the path name of
359 * the interpreter.
361 enum { INSERT=FALSE, REPLACE=TRUE };
362 int n, r;
363 off_t pos;
364 char *sp, *interp = NULL;
365 u64_t new_pos;
366 unsigned int cum_io;
367 char buf[_MAX_BLOCK_SIZE];
369 /* Make user_fullpath the new argv[0]. */
370 if (!insert_arg(stack, stk_bytes, user_fullpath, REPLACE)) return(ENOMEM);
372 pos = 0; /* Read from the start of the file */
374 /* Issue request */
375 r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, cvul64(pos), READING,
376 FS_PROC_NR, buf, _MAX_BLOCK_SIZE, &new_pos, &cum_io);
377 if (r != OK) return(r);
379 n = vp->v_size;
380 if (n > _MAX_BLOCK_SIZE)
381 n = _MAX_BLOCK_SIZE;
382 if (n < 2) return ENOEXEC;
384 sp = &(buf[2]); /* just behind the #! */
385 n -= 2;
386 if (n > PATH_MAX) n = PATH_MAX;
388 /* Use the user_fullpath variable for temporary storage */
389 memcpy(user_fullpath, sp, n);
391 if ((sp = memchr(user_fullpath, '\n', n)) == NULL) /* must be a proper line */
392 return(ENOEXEC);
394 /* Move sp backwards through script[], prepending each string to stack. */
395 for (;;) {
396 /* skip spaces behind argument. */
397 while (sp > user_fullpath && (*--sp == ' ' || *sp == '\t')) {}
398 if (sp == user_fullpath) break;
400 sp[1] = 0;
401 /* Move to the start of the argument. */
402 while (sp > user_fullpath && sp[-1] != ' ' && sp[-1] != '\t') --sp;
404 interp = sp;
405 if (!insert_arg(stack, stk_bytes, sp, INSERT)) return(ENOMEM);
408 /* Round *stk_bytes up to the size of a pointer for alignment contraints. */
409 *stk_bytes= ((*stk_bytes + PTRSIZE - 1) / PTRSIZE) * PTRSIZE;
411 if (interp != user_fullpath)
412 memmove(user_fullpath, interp, strlen(interp)+1);
413 return(OK);
416 /*===========================================================================*
417 * insert_arg *
418 *===========================================================================*/
419 PRIVATE int insert_arg(stack, stk_bytes, arg, replace)
420 char stack[ARG_MAX]; /* pointer to stack image within PM */
421 vir_bytes *stk_bytes; /* size of initial stack */
422 char *arg; /* argument to prepend/replace as new argv[0] */
423 int replace;
425 /* Patch the stack so that arg will become argv[0]. Be careful, the stack may
426 * be filled with garbage, although it normally looks like this:
427 * nargs argv[0] ... argv[nargs-1] NULL envp[0] ... NULL
428 * followed by the strings "pointed" to by the argv[i] and the envp[i]. The
429 * pointers are really offsets from the start of stack.
430 * Return true iff the operation succeeded.
432 int offset, a0, a1, old_bytes = *stk_bytes;
434 /* Prepending arg adds at least one string and a zero byte. */
435 offset = strlen(arg) + 1;
437 a0 = (int) ((char **) stack)[1]; /* argv[0] */
438 if (a0 < 4 * PTRSIZE || a0 >= old_bytes) return(FALSE);
440 a1 = a0; /* a1 will point to the strings to be moved */
441 if (replace) {
442 /* Move a1 to the end of argv[0][] (argv[1] if nargs > 1). */
443 do {
444 if (a1 == old_bytes) return(FALSE);
445 --offset;
446 } while (stack[a1++] != 0);
447 } else {
448 offset += PTRSIZE; /* new argv[0] needs new pointer in argv[] */
449 a0 += PTRSIZE; /* location of new argv[0][]. */
452 /* stack will grow by offset bytes (or shrink by -offset bytes) */
453 if ((*stk_bytes += offset) > ARG_MAX) return(FALSE);
455 /* Reposition the strings by offset bytes */
456 memmove(stack + a1 + offset, stack + a1, old_bytes - a1);
458 strcpy(stack + a0, arg); /* Put arg in the new space. */
460 if (!replace) {
461 /* Make space for a new argv[0]. */
462 memmove(stack + 2 * PTRSIZE, stack + 1 * PTRSIZE, a0 - 2 * PTRSIZE);
464 ((char **) stack)[0]++; /* nargs++; */
466 /* Now patch up argv[] and envp[] by offset. */
467 patch_ptr(stack, (vir_bytes) offset);
468 ((char **) stack)[1] = (char *) a0; /* set argv[0] correctly */
469 return(TRUE);
473 /*===========================================================================*
474 * patch_ptr *
475 *===========================================================================*/
476 PRIVATE void patch_ptr(stack, base)
477 char stack[ARG_MAX]; /* pointer to stack image within PM */
478 vir_bytes base; /* virtual address of stack base inside user */
480 /* When doing an exec(name, argv, envp) call, the user builds up a stack
481 * image with arg and env pointers relative to the start of the stack. Now
482 * these pointers must be relocated, since the stack is not positioned at
483 * address 0 in the user's address space.
486 char **ap, flag;
487 vir_bytes v;
489 flag = 0; /* counts number of 0-pointers seen */
490 ap = (char **) stack; /* points initially to 'nargs' */
491 ap++; /* now points to argv[0] */
492 while (flag < 2) {
493 if (ap >= (char **) &stack[ARG_MAX]) return; /* too bad */
494 if (*ap != NULL) {
495 v = (vir_bytes) *ap; /* v is relative pointer */
496 v += base; /* relocate it */
497 *ap = (char *) v; /* put it back */
498 } else {
499 flag++;
501 ap++;
506 /*===========================================================================*
507 * read_seg *
508 *===========================================================================*/
509 PRIVATE int read_seg(vp, off, proc_e, seg, seg_bytes)
510 struct vnode *vp; /* inode descriptor to read from */
511 off_t off; /* offset in file */
512 int proc_e; /* process number (endpoint) */
513 int seg; /* T, D, or S */
514 phys_bytes seg_bytes; /* how much is to be transferred? */
517 * The byte count on read is usually smaller than the segment count, because
518 * a segment is padded out to a click multiple, and the data segment is only
519 * partially initialized.
521 int r;
522 unsigned n, o;
523 u64_t new_pos;
524 unsigned int cum_io;
525 char buf[1024];
527 /* Make sure that the file is big enough */
528 if (vp->v_size < off+seg_bytes) return(EIO);
530 if (seg != D) {
531 /* We have to use a copy loop until safecopies support segments */
532 o = 0;
533 while (o < seg_bytes) {
534 n = seg_bytes - o;
535 if (n > sizeof(buf))
536 n = sizeof(buf);
538 if ((r = req_readwrite(vp->v_fs_e,vp->v_inode_nr,cvul64(off+o), READING, FS_PROC_NR, buf,
539 n, &new_pos, &cum_io)) != OK) {
540 printf("VFS: read_seg: req_readwrite failed (text)\n");
541 return(r);
544 if (cum_io != n) {
545 printf(
546 "VFSread_seg segment has not been read properly by exec() \n");
547 return(EIO);
550 if ((r = sys_vircopy(FS_PROC_NR, D, (vir_bytes)buf, proc_e,
551 seg, o, n)) != OK) {
552 printf("VFS: read_seg: copy failed (text)\n");
553 return(r);
556 o += n;
558 return(OK);
561 if ((r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, cvul64(off), READING,
562 proc_e, 0, seg_bytes, &new_pos, &cum_io)) != OK) {
563 printf("VFS: read_seg: req_readwrite failed (data)\n");
564 return(r);
567 if (r == OK && cum_io != seg_bytes)
568 printf("VFSread_seg segment has not been read properly by exec()\n");
570 return(r);
574 /*===========================================================================*
575 * clo_exec *
576 *===========================================================================*/
577 PRIVATE void clo_exec(rfp)
578 struct fproc *rfp;
580 /* Files can be marked with the FD_CLOEXEC bit (in fp->fp_cloexec).
582 int i;
584 /* Check the file desriptors one by one for presence of FD_CLOEXEC. */
585 for (i = 0; i < OPEN_MAX; i++)
586 if ( FD_ISSET(i, &rfp->fp_cloexec_set))
587 (void) close_fd(rfp, i);