root/fs/exec.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. open_inode
  2. core_dump
  3. sys_uselib
  4. create_tables
  5. count
  6. copy_strings
  7. change_ldt
  8. read_exec
  9. flush_old_exec
  10. do_execve
  11. sys_execve
  12. load_aout_binary
  13. load_aout_library

   1 /*
   2  *  linux/fs/exec.c
   3  *
   4  *  Copyright (C) 1991, 1992  Linus Torvalds
   5  */
   6 
   7 /*
   8  * #!-checking implemented by tytso.
   9  */
  10 
  11 /*
  12  * Demand-loading implemented 01.12.91 - no need to read anything but
  13  * the header into memory. The inode of the executable is put into
  14  * "current->executable", and page faults do the actual loading. Clean.
  15  *
  16  * Once more I can proudly say that linux stood up to being changed: it
  17  * was less than 2 hours work to get demand-loading completely implemented.
  18  *
  19  * Demand loading changed July 1993 by Eric Youngdale.   Use mmap instead,
  20  * current->executable is only used by the procfs.  This allows a dispatch
  21  * table to check for several different types  of binary formats.  We keep
  22  * trying until we recognize the file or we run out of supported binary
  23  * formats. 
  24  */
  25 
  26 #include <linux/fs.h>
  27 #include <linux/sched.h>
  28 #include <linux/kernel.h>
  29 #include <linux/mm.h>
  30 #include <linux/mman.h>
  31 #include <linux/a.out.h>
  32 #include <linux/errno.h>
  33 #include <linux/signal.h>
  34 #include <linux/string.h>
  35 #include <linux/stat.h>
  36 #include <linux/fcntl.h>
  37 #include <linux/ptrace.h>
  38 #include <linux/user.h>
  39 #include <linux/segment.h>
  40 #include <asm/system.h>
  41 
  42 #include <linux/binfmts.h>
  43 
  44 #include <asm/segment.h>
  45 #include <asm/system.h>
  46 
  47 asmlinkage int sys_exit(int exit_code);
  48 asmlinkage int sys_close(unsigned fd);
  49 asmlinkage int sys_open(const char *, int, int);
  50 
  51 extern void shm_exit (void);
  52 
  53 int open_inode(struct inode * inode, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
  54 {
  55         int error, fd;
  56         struct file *f, **fpp;
  57 
  58         if (!inode->i_op || !inode->i_op->default_file_ops)
  59                 return -EINVAL;
  60         f = get_empty_filp();
  61         if (!f)
  62                 return -EMFILE;
  63         fd = 0;
  64         fpp = current->filp;
  65         for (;;) {
  66                 if (!*fpp)
  67                         break;
  68                 if (++fd > NR_OPEN)
  69                         return -ENFILE;
  70                 fpp++;
  71         }
  72         *fpp = f;
  73         f->f_flags = mode;
  74         f->f_mode = (mode+1) & O_ACCMODE;
  75         f->f_inode = inode;
  76         f->f_pos = 0;
  77         f->f_reada = 0;
  78         f->f_op = inode->i_op->default_file_ops;
  79         if (f->f_op->open) {
  80                 error = f->f_op->open(inode,f);
  81                 if (error) {
  82                         *fpp = NULL;
  83                         f->f_count--;
  84                         return error;
  85                 }
  86         }
  87         inode->i_count++;
  88         return fd;
  89 }
  90 
  91 /*
  92  * These are the only things you should do on a core-file: use only these
  93  * macros to write out all the necessary info.
  94  */
  95 #define DUMP_WRITE(addr,nr) \
  96 while (file.f_op->write(inode,&file,(char *)(addr),(nr)) != (nr)) goto close_coredump
  97 
  98 #define DUMP_SEEK(offset) \
  99 if (file.f_op->lseek) { \
 100         if (file.f_op->lseek(inode,&file,(offset),0) != (offset)) \
 101                 goto close_coredump; \
 102 } else file.f_pos = (offset)            
 103 
 104 /*
 105  * Routine writes a core dump image in the current directory.
 106  * Currently only a stub-function.
 107  *
 108  * Note that setuid/setgid files won't make a core-dump if the uid/gid
 109  * changed due to the set[u|g]id. It's enforced by the "current->dumpable"
 110  * field, which also makes sure the core-dumps won't be recursive if the
 111  * dumping of the process results in another error..
 112  */
 113 int core_dump(long signr, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 114 {
 115         struct inode * inode = NULL;
 116         struct file file;
 117         unsigned short fs;
 118         int has_dumped = 0;
 119         char corefile[6+sizeof(current->comm)];
 120         register int dump_start, dump_size;
 121         struct user dump;
 122 
 123         if (!current->dumpable)
 124                 return 0;
 125         current->dumpable = 0;
 126 
 127 /* See if we have enough room to write the upage.  */
 128         if (current->rlim[RLIMIT_CORE].rlim_cur < PAGE_SIZE)
 129                 return 0;
 130         fs = get_fs();
 131         set_fs(KERNEL_DS);
 132         memcpy(corefile,"core.",5);
 133         memcpy(corefile+5,current->comm,sizeof(current->comm));
 134         if (open_namei(corefile,O_CREAT | 2 | O_TRUNC,0600,&inode,NULL)) {
 135                 inode = NULL;
 136                 goto end_coredump;
 137         }
 138         if (!S_ISREG(inode->i_mode))
 139                 goto end_coredump;
 140         if (!inode->i_op || !inode->i_op->default_file_ops)
 141                 goto end_coredump;
 142         file.f_mode = 3;
 143         file.f_flags = 0;
 144         file.f_count = 1;
 145         file.f_inode = inode;
 146         file.f_pos = 0;
 147         file.f_reada = 0;
 148         file.f_op = inode->i_op->default_file_ops;
 149         if (file.f_op->open)
 150                 if (file.f_op->open(inode,&file))
 151                         goto end_coredump;
 152         if (!file.f_op->write)
 153                 goto close_coredump;
 154         has_dumped = 1;
 155 /* changed the size calculations - should hopefully work better. lbt */
 156         dump.magic = CMAGIC;
 157         dump.start_code = 0;
 158         dump.start_stack = regs->esp & ~(PAGE_SIZE - 1);
 159         dump.u_tsize = ((unsigned long) current->end_code) >> 12;
 160         dump.u_dsize = ((unsigned long) (current->brk + (PAGE_SIZE-1))) >> 12;
 161         dump.u_dsize -= dump.u_tsize;
 162         dump.u_ssize = 0;
 163         if (dump.start_stack < TASK_SIZE)
 164                 dump.u_ssize = ((unsigned long) (TASK_SIZE - dump.start_stack)) >> 12;
 165 /* If the size of the dump file exceeds the rlimit, then see what would happen
 166    if we wrote the stack, but not the data area.  */
 167         if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
 168             current->rlim[RLIMIT_CORE].rlim_cur)
 169                 dump.u_dsize = 0;
 170 /* Make sure we have enough room to write the stack and data areas. */
 171         if ((dump.u_ssize+1) * PAGE_SIZE >
 172             current->rlim[RLIMIT_CORE].rlim_cur)
 173                 dump.u_ssize = 0;
 174         dump.u_comm = 0;
 175         dump.u_ar0 = (struct pt_regs *)(((int)(&dump.regs)) -((int)(&dump)));
 176         dump.signal = signr;
 177         dump.regs = *regs;
 178 /* Flag indicating the math stuff is valid. We don't support this for the
 179    soft-float routines yet */
 180         if (hard_math) {
 181                 if ((dump.u_fpvalid = current->used_math) != 0) {
 182                         if (last_task_used_math == current)
 183                                 __asm__("clts ; fnsave %0": :"m" (dump.i387));
 184                         else
 185                                 memcpy(&dump.i387,&current->tss.i387.hard,sizeof(dump.i387));
 186                 }
 187         } else {
 188                 /* we should dump the emulator state here, but we need to
 189                    convert it into standard 387 format first.. */
 190                 dump.u_fpvalid = 0;
 191         }
 192         set_fs(KERNEL_DS);
 193 /* struct user */
 194         DUMP_WRITE(&dump,sizeof(dump));
 195 /* name of the executable */
 196         DUMP_WRITE(current->comm,16);
 197 /* Now dump all of the user data.  Include malloced stuff as well */
 198         DUMP_SEEK(PAGE_SIZE);
 199 /* now we start writing out the user space info */
 200         set_fs(USER_DS);
 201 /* Dump the data area */
 202         if (dump.u_dsize != 0) {
 203                 dump_start = dump.u_tsize << 12;
 204                 dump_size = dump.u_dsize << 12;
 205                 DUMP_WRITE(dump_start,dump_size);
 206         };
 207 /* Now prepare to dump the stack area */
 208         if (dump.u_ssize != 0) {
 209                 dump_start = dump.start_stack;
 210                 dump_size = dump.u_ssize << 12;
 211                 DUMP_WRITE(dump_start,dump_size);
 212         };
 213 /* Finally dump the task struct.  Not be used by gdb, but could be useful */
 214         set_fs(KERNEL_DS);
 215         DUMP_WRITE(current,sizeof(*current));
 216 close_coredump:
 217         if (file.f_op->release)
 218                 file.f_op->release(inode,&file);
 219 end_coredump:
 220         set_fs(fs);
 221         iput(inode);
 222         return has_dumped;
 223 }
 224 
 225 /*
 226  * Note that a shared library must be both readable and executable due to
 227  * security reasons.
 228  *
 229  * Also note that we take the address to load from from the file itself.
 230  */
 231 asmlinkage int sys_uselib(const char * library)
     /* [previous][next][first][last][top][bottom][index][help] */
 232 {
 233         int fd, retval;
 234         struct file * file;
 235         struct linux_binfmt * fmt;
 236 
 237         fd = sys_open(library, 0, 0);
 238         if (fd < 0)
 239                 return fd;
 240         file = current->filp[fd];
 241         retval = -ENOEXEC;
 242         if (file && file->f_inode && file->f_op && file->f_op->read) {
 243                 fmt = formats;
 244                 do {
 245                         int (*fn)(int) = fmt->load_shlib;
 246                         if (!fn)
 247                                 break;
 248                         retval = fn(fd);
 249                         fmt++;
 250                 } while (retval == -ENOEXEC);
 251         }
 252         sys_close(fd);
 253         return retval;
 254 }
 255 
 256 /*
 257  * create_tables() parses the env- and arg-strings in new user
 258  * memory and creates the pointer tables from them, and puts their
 259  * addresses on the "stack", returning the new stack pointer value.
 260  */
 261 unsigned long * create_tables(char * p,int argc,int envc)
     /* [previous][next][first][last][top][bottom][index][help] */
 262 {
 263         unsigned long *argv,*envp;
 264         unsigned long * sp;
 265 
 266         sp = (unsigned long *) (0xfffffffc & (unsigned long) p);
 267         sp -= envc+1;
 268         envp = sp;
 269         sp -= argc+1;
 270         argv = sp;
 271         put_fs_long((unsigned long)envp,--sp);
 272         put_fs_long((unsigned long)argv,--sp);
 273         put_fs_long((unsigned long)argc,--sp);
 274         current->arg_start = (unsigned long) p;
 275         while (argc-->0) {
 276                 put_fs_long((unsigned long) p,argv++);
 277                 while (get_fs_byte(p++)) /* nothing */ ;
 278         }
 279         put_fs_long(0,argv);
 280         current->arg_end = current->env_start = (unsigned long) p;
 281         while (envc-->0) {
 282                 put_fs_long((unsigned long) p,envp++);
 283                 while (get_fs_byte(p++)) /* nothing */ ;
 284         }
 285         put_fs_long(0,envp);
 286         current->env_end = (unsigned long) p;
 287         return sp;
 288 }
 289 
 290 /*
 291  * count() counts the number of arguments/envelopes
 292  */
 293 static int count(char ** argv)
     /* [previous][next][first][last][top][bottom][index][help] */
 294 {
 295         int i=0;
 296         char ** tmp;
 297 
 298         if ((tmp = argv) != 0)
 299                 while (get_fs_long((unsigned long *) (tmp++)))
 300                         i++;
 301 
 302         return i;
 303 }
 304 
 305 /*
 306  * 'copy_string()' copies argument/envelope strings from user
 307  * memory to free pages in kernel mem. These are in a format ready
 308  * to be put directly into the top of new user memory.
 309  *
 310  * Modified by TYT, 11/24/91 to add the from_kmem argument, which specifies
 311  * whether the string and the string array are from user or kernel segments:
 312  * 
 313  * from_kmem     argv *        argv **
 314  *    0          user space    user space
 315  *    1          kernel space  user space
 316  *    2          kernel space  kernel space
 317  * 
 318  * We do this by playing games with the fs segment register.  Since it
 319  * it is expensive to load a segment register, we try to avoid calling
 320  * set_fs() unless we absolutely have to.
 321  */
 322 unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
     /* [previous][next][first][last][top][bottom][index][help] */
 323                 unsigned long p, int from_kmem)
 324 {
 325         char *tmp, *pag = NULL;
 326         int len, offset = 0;
 327         unsigned long old_fs, new_fs;
 328 
 329         if (!p)
 330                 return 0;       /* bullet-proofing */
 331         new_fs = get_ds();
 332         old_fs = get_fs();
 333         if (from_kmem==2)
 334                 set_fs(new_fs);
 335         while (argc-- > 0) {
 336                 if (from_kmem == 1)
 337                         set_fs(new_fs);
 338                 if (!(tmp = (char *)get_fs_long(((unsigned long *)argv)+argc)))
 339                         panic("VFS: argc is wrong");
 340                 if (from_kmem == 1)
 341                         set_fs(old_fs);
 342                 len=0;          /* remember zero-padding */
 343                 do {
 344                         len++;
 345                 } while (get_fs_byte(tmp++));
 346                 if (p < len) {  /* this shouldn't happen - 128kB */
 347                         set_fs(old_fs);
 348                         return 0;
 349                 }
 350                 while (len) {
 351                         --p; --tmp; --len;
 352                         if (--offset < 0) {
 353                                 offset = p % PAGE_SIZE;
 354                                 if (from_kmem==2)
 355                                         set_fs(old_fs);
 356                                 if (!(pag = (char *) page[p/PAGE_SIZE]) &&
 357                                     !(pag = (char *) page[p/PAGE_SIZE] =
 358                                       (unsigned long *) get_free_page(GFP_USER))) 
 359                                         return 0;
 360                                 if (from_kmem==2)
 361                                         set_fs(new_fs);
 362 
 363                         }
 364                         *(pag + offset) = get_fs_byte(tmp);
 365                 }
 366         }
 367         if (from_kmem==2)
 368                 set_fs(old_fs);
 369         return p;
 370 }
 371 
 372 unsigned long change_ldt(unsigned long text_size,unsigned long * page)
     /* [previous][next][first][last][top][bottom][index][help] */
 373 {
 374         unsigned long code_limit,data_limit,code_base,data_base;
 375         int i;
 376 
 377         code_limit = TASK_SIZE;
 378         data_limit = TASK_SIZE;
 379         code_base = data_base = 0;
 380         current->start_code = code_base;
 381         data_base += data_limit;
 382         for (i=MAX_ARG_PAGES-1 ; i>=0 ; i--) {
 383                 data_base -= PAGE_SIZE;
 384                 if (page[i]) {
 385                         current->rss++;
 386                         put_dirty_page(current,page[i],data_base);
 387                 }
 388         }
 389         return data_limit;
 390 }
 391 
 392 /*
 393  * Read in the complete executable. This is used for "-N" files
 394  * that aren't on a block boundary, and for files on filesystems
 395  * without bmap support.
 396  */
 397 int read_exec(struct inode *inode, unsigned long offset,
     /* [previous][next][first][last][top][bottom][index][help] */
 398         char * addr, unsigned long count)
 399 {
 400         struct file file;
 401         int result = -ENOEXEC;
 402 
 403         if (!inode->i_op || !inode->i_op->default_file_ops)
 404                 goto end_readexec;
 405         file.f_mode = 1;
 406         file.f_flags = 0;
 407         file.f_count = 1;
 408         file.f_inode = inode;
 409         file.f_pos = 0;
 410         file.f_reada = 0;
 411         file.f_op = inode->i_op->default_file_ops;
 412         if (file.f_op->open)
 413                 if (file.f_op->open(inode,&file))
 414                         goto end_readexec;
 415         if (!file.f_op || !file.f_op->read)
 416                 goto close_readexec;
 417         if (file.f_op->lseek) {
 418                 if (file.f_op->lseek(inode,&file,offset,0) != offset)
 419                         goto close_readexec;
 420         } else
 421                 file.f_pos = offset;
 422         result = file.f_op->read(inode, &file, addr, count);
 423 close_readexec:
 424         if (file.f_op->release)
 425                 file.f_op->release(inode,&file);
 426 end_readexec:
 427         return result;
 428 }
 429 
 430 
 431 /*
 432  * This function flushes out all traces of the currently running executable so
 433  * that a new one can be started
 434  */
 435 
 436 void flush_old_exec(struct linux_binprm * bprm)
     /* [previous][next][first][last][top][bottom][index][help] */
 437 {
 438         int i;
 439         int ch;
 440         char * name;
 441         struct vm_area_struct * mpnt, *mpnt1;
 442 
 443         current->dumpable = 1;
 444         name = bprm->filename;
 445         for (i=0; (ch = *(name++)) != '\0';) {
 446                 if (ch == '/')
 447                         i = 0;
 448                 else
 449                         if (i < 15)
 450                                 current->comm[i++] = ch;
 451         }
 452         current->comm[i] = '\0';
 453         if (current->shm)
 454                 shm_exit();
 455         if (current->executable) {
 456                 iput(current->executable);
 457                 current->executable = NULL;
 458         }
 459         /* Release all of the old mmap stuff. */
 460 
 461         mpnt = current->mmap;
 462         current->mmap = NULL;
 463         while (mpnt) {
 464                 mpnt1 = mpnt->vm_next;
 465                 if (mpnt->vm_ops && mpnt->vm_ops->close)
 466                         mpnt->vm_ops->close(mpnt);
 467                 kfree(mpnt);
 468                 mpnt = mpnt1;
 469         }
 470 
 471         /* Flush the old ldt stuff... */
 472         if (current->ldt) {
 473                 free_page((unsigned long) current->ldt);
 474                 current->ldt = NULL;
 475                 for (i=1 ; i<NR_TASKS ; i++) {
 476                         if (task[i] == current)  {
 477                                 set_ldt_desc(gdt+(i<<1)+
 478                                              FIRST_LDT_ENTRY,&default_ldt, 1);
 479                                 load_ldt(i);
 480                         }
 481                 }       
 482         }
 483 
 484         if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || 
 485             !permission(bprm->inode,MAY_READ))
 486                 current->dumpable = 0;
 487         current->signal = 0;
 488         for (i=0 ; i<32 ; i++) {
 489                 current->sigaction[i].sa_mask = 0;
 490                 current->sigaction[i].sa_flags = 0;
 491                 if (current->sigaction[i].sa_handler != SIG_IGN)
 492                         current->sigaction[i].sa_handler = NULL;
 493         }
 494         for (i=0 ; i<NR_OPEN ; i++)
 495                 if (FD_ISSET(i,&current->close_on_exec))
 496                         sys_close(i);
 497         FD_ZERO(&current->close_on_exec);
 498         clear_page_tables(current);
 499         if (last_task_used_math == current)
 500                 last_task_used_math = NULL;
 501         current->used_math = 0;
 502         current->elf_executable = 0;
 503 }
 504 
 505 /*
 506  * sys_execve() executes a new program.
 507  */
 508 static int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 509 {
 510         struct linux_binprm bprm;
 511         struct linux_binfmt * fmt;
 512         unsigned long old_fs;
 513         int i;
 514         int retval;
 515         int sh_bang = 0;
 516 
 517         if (regs->cs != USER_CS)
 518                 return -EINVAL;
 519         bprm.p = PAGE_SIZE*MAX_ARG_PAGES-4;
 520         for (i=0 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */
 521                 bprm.page[i] = 0;
 522         retval = open_namei(filename, 0, 0, &bprm.inode, NULL);
 523         if (retval)
 524                 return retval;
 525         bprm.filename = filename;
 526         bprm.argc = count(argv);
 527         bprm.envc = count(envp);
 528         
 529 restart_interp:
 530         if (!S_ISREG(bprm.inode->i_mode)) {     /* must be regular file */
 531                 retval = -EACCES;
 532                 goto exec_error2;
 533         }
 534         if (IS_NOEXEC(bprm.inode)) {            /* FS mustn't be mounted noexec */
 535                 retval = -EPERM;
 536                 goto exec_error2;
 537         }
 538         if (!bprm.inode->i_sb) {
 539                 retval = -EACCES;
 540                 goto exec_error2;
 541         }
 542         i = bprm.inode->i_mode;
 543         if (IS_NOSUID(bprm.inode) && (((i & S_ISUID) && bprm.inode->i_uid != current->
 544             euid) || ((i & S_ISGID) && !in_group_p(bprm.inode->i_gid))) &&
 545             !suser()) {
 546                 retval = -EPERM;
 547                 goto exec_error2;
 548         }
 549         /* make sure we don't let suid, sgid files be ptraced. */
 550         if (current->flags & PF_PTRACED) {
 551                 bprm.e_uid = current->euid;
 552                 bprm.e_gid = current->egid;
 553         } else {
 554                 bprm.e_uid = (i & S_ISUID) ? bprm.inode->i_uid : current->euid;
 555                 bprm.e_gid = (i & S_ISGID) ? bprm.inode->i_gid : current->egid;
 556         }
 557         if (current->euid == bprm.inode->i_uid)
 558                 i >>= 6;
 559         else if (in_group_p(bprm.inode->i_gid))
 560                 i >>= 3;
 561         if (!(i & 1) &&
 562             !((bprm.inode->i_mode & 0111) && suser())) {
 563                 retval = -EACCES;
 564                 goto exec_error2;
 565         }
 566         memset(bprm.buf,0,sizeof(bprm.buf));
 567         old_fs = get_fs();
 568         set_fs(get_ds());
 569         retval = read_exec(bprm.inode,0,bprm.buf,128);
 570         set_fs(old_fs);
 571         if (retval < 0)
 572                 goto exec_error2;
 573         if ((bprm.buf[0] == '#') && (bprm.buf[1] == '!') && (!sh_bang)) {
 574                 /*
 575                  * This section does the #! interpretation.
 576                  * Sorta complicated, but hopefully it will work.  -TYT
 577                  */
 578 
 579                 char *cp, *interp, *i_name, *i_arg;
 580 
 581                 iput(bprm.inode);
 582                 bprm.buf[127] = '\0';
 583                 if ((cp = strchr(bprm.buf, '\n')) == NULL)
 584                         cp = bprm.buf+127;
 585                 *cp = '\0';
 586                 while (cp > bprm.buf) {
 587                         cp--;
 588                         if ((*cp == ' ') || (*cp == '\t'))
 589                                 *cp = '\0';
 590                         else
 591                                 break;
 592                 }
 593                 for (cp = bprm.buf+2; (*cp == ' ') || (*cp == '\t'); cp++);
 594                 if (!cp || *cp == '\0') {
 595                         retval = -ENOEXEC; /* No interpreter name found */
 596                         goto exec_error1;
 597                 }
 598                 interp = i_name = cp;
 599                 i_arg = 0;
 600                 for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) {
 601                         if (*cp == '/')
 602                                 i_name = cp+1;
 603                 }
 604                 while ((*cp == ' ') || (*cp == '\t'))
 605                         *cp++ = '\0';
 606                 if (*cp)
 607                         i_arg = cp;
 608                 /*
 609                  * OK, we've parsed out the interpreter name and
 610                  * (optional) argument.
 611                  */
 612                 if (sh_bang++ == 0) {
 613                         bprm.p = copy_strings(bprm.envc, envp, bprm.page, bprm.p, 0);
 614                         bprm.p = copy_strings(--bprm.argc, argv+1, bprm.page, bprm.p, 0);
 615                 }
 616                 /*
 617                  * Splice in (1) the interpreter's name for argv[0]
 618                  *           (2) (optional) argument to interpreter
 619                  *           (3) filename of shell script
 620                  *
 621                  * This is done in reverse order, because of how the
 622                  * user environment and arguments are stored.
 623                  */
 624                 bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p, 2);
 625                 bprm.argc++;
 626                 if (i_arg) {
 627                         bprm.p = copy_strings(1, &i_arg, bprm.page, bprm.p, 2);
 628                         bprm.argc++;
 629                 }
 630                 bprm.p = copy_strings(1, &i_name, bprm.page, bprm.p, 2);
 631                 bprm.argc++;
 632                 if (!bprm.p) {
 633                         retval = -E2BIG;
 634                         goto exec_error1;
 635                 }
 636                 /*
 637                  * OK, now restart the process with the interpreter's inode.
 638                  * Note that we use open_namei() as the name is now in kernel
 639                  * space, and we don't need to copy it.
 640                  */
 641                 retval = open_namei(interp, 0, 0, &bprm.inode, NULL);
 642                 if (retval)
 643                         goto exec_error1;
 644                 goto restart_interp;
 645         }
 646         if (!sh_bang) {
 647                 bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p,0);
 648                 bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p,0);
 649                 if (!bprm.p) {
 650                         retval = -E2BIG;
 651                         goto exec_error2;
 652                 }
 653         }
 654 
 655         bprm.sh_bang = sh_bang;
 656         fmt = formats;
 657         do {
 658                 int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
 659                 if (!fn)
 660                         break;
 661                 retval = fn(&bprm, regs);
 662                 if (retval == 0) {
 663                         iput(bprm.inode);
 664                         return 0;
 665                 }
 666                 fmt++;
 667         } while (retval == -ENOEXEC);
 668 exec_error2:
 669         iput(bprm.inode);
 670 exec_error1:
 671         for (i=0 ; i<MAX_ARG_PAGES ; i++)
 672                 free_page(bprm.page[i]);
 673         return(retval);
 674 }
 675 
 676 /*
 677  * sys_execve() executes a new program.
 678  */
 679 asmlinkage int sys_execve(struct pt_regs regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 680 {
 681         int error;
 682         char * filename;
 683 
 684         error = getname((char *) regs.ebx, &filename);
 685         if (error)
 686                 return error;
 687         error = do_execve(filename, (char **) regs.ecx, (char **) regs.edx, &regs);
 688         putname(filename);
 689         return error;
 690 }
 691 
 692 /*
 693  * These are  the prototypes for the  functions in the  dispatch table, as
 694  * well as the  dispatch  table itself.
 695  */
 696 
 697 extern int load_aout_binary(struct linux_binprm *,
 698                             struct pt_regs * regs);
 699 extern int load_aout_library(int fd);
 700 
 701 extern int load_elf_binary(struct linux_binprm *,
 702                             struct pt_regs * regs);
 703 extern int load_elf_library(int fd);
 704 
 705 /* Here are the actual binaries that will be accepted  */
 706 struct linux_binfmt formats[] = {
 707         {load_aout_binary, load_aout_library},
 708 #ifdef CONFIG_BINFMT_ELF
 709         {load_elf_binary, load_elf_library},
 710 #endif
 711         {NULL, NULL}
 712 };
 713 
 714 /*
 715  * These are the functions used to load a.out style executables and shared
 716  * libraries.  There is no binary dependent code anywhere else.
 717  */
 718 
 719 int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 720 {
 721         struct exec ex;
 722         struct file * file;
 723         int fd, error;
 724         unsigned long p = bprm->p;
 725 
 726         ex = *((struct exec *) bprm->buf);              /* exec-header */
 727         if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && 
 728              N_MAGIC(ex) != QMAGIC) ||
 729             ex.a_trsize || ex.a_drsize ||
 730             bprm->inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) {
 731                 return -ENOEXEC;
 732         }
 733 
 734         if (N_MAGIC(ex) == ZMAGIC &&
 735             (N_TXTOFF(ex) < bprm->inode->i_sb->s_blocksize)) {
 736                 printk("N_TXTOFF < BLOCK_SIZE. Please convert binary.");
 737                 return -ENOEXEC;
 738         }
 739 
 740         if (N_TXTOFF(ex) != BLOCK_SIZE && N_MAGIC(ex) == ZMAGIC) {
 741                 printk("N_TXTOFF != BLOCK_SIZE. See a.out.h.");
 742                 return -ENOEXEC;
 743         }
 744         
 745         /* OK, This is the point of no return */
 746         flush_old_exec(bprm);
 747         current->start_brk = current->brk = ex.a_bss +
 748                 (current->end_data = ex.a_data +
 749                  (current->end_code = N_TXTADDR(ex) + ex.a_text));
 750 
 751         current->start_code += N_TXTADDR(ex);
 752 
 753         current->rss = 0;
 754         current->suid = current->euid = bprm->e_uid;
 755         current->mmap = NULL;
 756         current->executable = NULL;  /* for OMAGIC files */
 757         current->sgid = current->egid = bprm->e_gid;
 758         if (N_MAGIC(ex) == OMAGIC) {
 759                 read_exec(bprm->inode, 32, (char *) 0, ex.a_text+ex.a_data);
 760         } else {
 761                 if (ex.a_text & 0xfff || ex.a_data & 0xfff)
 762                         printk("%s: executable not page aligned\n", current->comm);
 763                 
 764                 fd = open_inode(bprm->inode, O_RDONLY);
 765                 
 766                 if (fd < 0)
 767                         return fd;
 768                 file = current->filp[fd];
 769                 if (!file->f_op || !file->f_op->mmap) {
 770                         sys_close(fd);
 771                         read_exec(bprm->inode, N_TXTOFF(ex), 
 772                                   (char *) N_TXTADDR(ex), ex.a_text+ex.a_data);
 773                         goto beyond_if;
 774                 }
 775                 error = do_mmap(file, N_TXTADDR(ex), ex.a_text,
 776                                 PROT_READ | PROT_EXEC,
 777                                 MAP_FIXED | MAP_SHARED, N_TXTOFF(ex));
 778 
 779                 if (error != N_TXTADDR(ex)) {
 780                         sys_close(fd);
 781                         send_sig(SIGSEGV, current, 0);
 782                         return 0;
 783                 };
 784                 
 785                 error = do_mmap(file, N_TXTADDR(ex) + ex.a_text, ex.a_data,
 786                                 PROT_READ | PROT_WRITE | PROT_EXEC,
 787                                 MAP_FIXED | MAP_PRIVATE, N_TXTOFF(ex) + ex.a_text);
 788                 sys_close(fd);
 789                 if (error != N_TXTADDR(ex) + ex.a_text) {
 790                         send_sig(SIGSEGV, current, 0);
 791                         return 0;
 792                 };
 793                 current->executable = bprm->inode;
 794                 bprm->inode->i_count++;
 795         }
 796 beyond_if:
 797         zeromap_page_range((N_TXTADDR(ex) + ex.a_text + ex.a_data + 0xfff) & 0xfffff000,ex.a_bss, PAGE_COPY);
 798         p += change_ldt(ex.a_text,bprm->page);
 799         p -= MAX_ARG_PAGES*PAGE_SIZE;
 800         p = (unsigned long) create_tables((char *)p,bprm->argc,bprm->envc);
 801         current->start_stack = p;
 802         regs->eip = ex.a_entry;         /* eip, magic happens :-) */
 803         regs->esp = p;                  /* stack pointer */
 804         if (current->flags & PF_PTRACED)
 805                 send_sig(SIGTRAP, current, 0);
 806         return 0;
 807 }
 808 
 809 
 810 int load_aout_library(int fd)
     /* [previous][next][first][last][top][bottom][index][help] */
 811 {
 812         struct file * file;
 813         struct exec ex;
 814         struct  inode * inode;
 815         unsigned int len;
 816         unsigned int bss;
 817         unsigned int start_addr;
 818         int error;
 819         
 820         file = current->filp[fd];
 821         inode = file->f_inode;
 822         
 823         set_fs(KERNEL_DS);
 824         if (file->f_op->read(inode, file, (char *) &ex, sizeof(ex)) != sizeof(ex)) {
 825                 return -EACCES;
 826         }
 827         set_fs(USER_DS);
 828         
 829         /* We come in here for the regular a.out style of shared libraries */
 830         if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || ex.a_trsize ||
 831             ex.a_drsize || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) ||
 832             inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) {
 833                 return -ENOEXEC;
 834         }
 835         if (N_MAGIC(ex) == ZMAGIC && N_TXTOFF(ex) && 
 836             (N_TXTOFF(ex) < inode->i_sb->s_blocksize)) {
 837                 printk("N_TXTOFF < BLOCK_SIZE. Please convert library\n");
 838                 return -ENOEXEC;
 839         }
 840         
 841         if (N_FLAGS(ex)) return -ENOEXEC;
 842 
 843         /* For  QMAGIC, the starting address is 0x20 into the page.  We mask
 844            this off to get the starting address for the page */
 845 
 846         start_addr =  ex.a_entry & 0xfffff000;
 847 
 848         /* Now use mmap to map the library into memory. */
 849         error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
 850                         PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE,
 851                         N_TXTOFF(ex));
 852         if (error != start_addr)
 853                 return error;
 854         len = (ex.a_text + ex.a_data + 0xfff) & 0xfffff000;
 855         bss = ex.a_text + ex.a_data + ex.a_bss;
 856         if (bss > len)
 857                 zeromap_page_range(start_addr + len, bss-len, PAGE_COPY);
 858         return 0;
 859 }

/* [previous][next][first][last][top][bottom][index][help] */