root/fs/exec.c

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

DEFINITIONS

This source file includes following definitions.
  1. binfmt_setup
  2. register_binfmt
  3. unregister_binfmt
  4. open_inode
  5. sys_uselib
  6. create_tables
  7. count
  8. copy_strings
  9. setup_arg_pages
  10. read_exec
  11. exec_mmap
  12. flush_old_exec
  13. do_execve

   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  * Demand-loading implemented 01.12.91 - no need to read anything but
  12  * the header into memory. The inode of the executable is put into
  13  * "current->executable", and page faults do the actual loading. Clean.
  14  *
  15  * Once more I can proudly say that linux stood up to being changed: it
  16  * was less than 2 hours work to get demand-loading completely implemented.
  17  *
  18  * Demand loading changed July 1993 by Eric Youngdale.   Use mmap instead,
  19  * current->executable is only used by the procfs.  This allows a dispatch
  20  * table to check for several different types  of binary formats.  We keep
  21  * trying until we recognize the file or we run out of supported binary
  22  * formats. 
  23  */
  24 
  25 #include <linux/fs.h>
  26 #include <linux/sched.h>
  27 #include <linux/kernel.h>
  28 #include <linux/mm.h>
  29 #include <linux/mman.h>
  30 #include <linux/a.out.h>
  31 #include <linux/errno.h>
  32 #include <linux/signal.h>
  33 #include <linux/string.h>
  34 #include <linux/stat.h>
  35 #include <linux/fcntl.h>
  36 #include <linux/ptrace.h>
  37 #include <linux/user.h>
  38 #include <linux/malloc.h>
  39 #include <linux/binfmts.h>
  40 #include <linux/personality.h>
  41 
  42 #include <asm/system.h>
  43 #include <asm/segment.h>
  44 #include <asm/pgtable.h>
  45 
  46 #include <linux/config.h>
  47 #ifdef CONFIG_KERNELD
  48 #include <linux/kerneld.h>
  49 #endif
  50 
  51 asmlinkage int sys_exit(int exit_code);
  52 asmlinkage int sys_brk(unsigned long);
  53 
  54 /*
  55  * Here are the actual binaries that will be accepted:
  56  * add more with "register_binfmt()" if using modules...
  57  *
  58  * These are defined again for the 'real' modules if you are using a
  59  * module definition for these routines.
  60  */
  61 
  62 static struct linux_binfmt *formats = (struct linux_binfmt *) NULL;
  63 
  64 void binfmt_setup(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  65 {
  66 #ifdef CONFIG_BINFMT_ELF
  67         init_elf_binfmt();
  68 #endif
  69 
  70 #ifdef CONFIG_BINFMT_AOUT
  71         init_aout_binfmt();
  72 #endif
  73 }
  74 
  75 int register_binfmt(struct linux_binfmt * fmt)
     /* [previous][next][first][last][top][bottom][index][help] */
  76 {
  77         struct linux_binfmt ** tmp = &formats;
  78 
  79         if (!fmt)
  80                 return -EINVAL;
  81         if (fmt->next)
  82                 return -EBUSY;
  83         while (*tmp) {
  84                 if (fmt == *tmp)
  85                         return -EBUSY;
  86                 tmp = &(*tmp)->next;
  87         }
  88         fmt->next = formats;
  89         formats = fmt;
  90         return 0;       
  91 }
  92 
  93 #ifdef CONFIG_MODULES
  94 int unregister_binfmt(struct linux_binfmt * fmt)
     /* [previous][next][first][last][top][bottom][index][help] */
  95 {
  96         struct linux_binfmt ** tmp = &formats;
  97 
  98         while (*tmp) {
  99                 if (fmt == *tmp) {
 100                         *tmp = fmt->next;
 101                         return 0;
 102                 }
 103                 tmp = &(*tmp)->next;
 104         }
 105         return -EINVAL;
 106 }
 107 #endif  /* CONFIG_MODULES */
 108 
 109 int open_inode(struct inode * inode, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 110 {
 111         int error, fd;
 112         struct file *f, **fpp;
 113 
 114         if (!inode->i_op || !inode->i_op->default_file_ops)
 115                 return -EINVAL;
 116         f = get_empty_filp();
 117         if (!f)
 118                 return -ENFILE;
 119         fd = 0;
 120         fpp = current->files->fd;
 121         for (;;) {
 122                 if (!*fpp)
 123                         break;
 124                 if (++fd >= NR_OPEN) {
 125                         f->f_count--;
 126                         return -EMFILE;
 127                 }
 128                 fpp++;
 129         }
 130         *fpp = f;
 131         f->f_flags = mode;
 132         f->f_mode = (mode+1) & O_ACCMODE;
 133         f->f_inode = inode;
 134         f->f_pos = 0;
 135         f->f_reada = 0;
 136         f->f_op = inode->i_op->default_file_ops;
 137         if (f->f_op->open) {
 138                 error = f->f_op->open(inode,f);
 139                 if (error) {
 140                         *fpp = NULL;
 141                         f->f_count--;
 142                         return error;
 143                 }
 144         }
 145         inode->i_count++;
 146         return fd;
 147 }
 148 
 149 /*
 150  * Note that a shared library must be both readable and executable due to
 151  * security reasons.
 152  *
 153  * Also note that we take the address to load from from the file itself.
 154  */
 155 asmlinkage int sys_uselib(const char * library)
     /* [previous][next][first][last][top][bottom][index][help] */
 156 {
 157         int fd, retval;
 158         struct file * file;
 159         struct linux_binfmt * fmt;
 160 
 161         fd = sys_open(library, 0, 0);
 162         if (fd < 0)
 163                 return fd;
 164         file = current->files->fd[fd];
 165         retval = -ENOEXEC;
 166         if (file && file->f_inode && file->f_op && file->f_op->read) {
 167                 for (fmt = formats ; fmt ; fmt = fmt->next) {
 168                         int (*fn)(int) = fmt->load_shlib;
 169                         if (!fn)
 170                                 continue;
 171                         retval = fn(fd);
 172                         if (retval != -ENOEXEC)
 173                                 break;
 174                 }
 175         }
 176         sys_close(fd);
 177         return retval;
 178 }
 179 
 180 /*
 181  * create_tables() parses the env- and arg-strings in new user
 182  * memory and creates the pointer tables from them, and puts their
 183  * addresses on the "stack", returning the new stack pointer value.
 184  */
 185 unsigned long * create_tables(char * p, struct linux_binprm * bprm, int ibcs)
     /* [previous][next][first][last][top][bottom][index][help] */
 186 {
 187         unsigned long *argv,*envp;
 188         unsigned long * sp;
 189         struct vm_area_struct *mpnt;
 190         int argc = bprm->argc;
 191         int envc = bprm->envc;
 192 
 193         mpnt = (struct vm_area_struct *)kmalloc(sizeof(*mpnt), GFP_KERNEL);
 194         if (mpnt) {
 195                 mpnt->vm_mm = current->mm;
 196                 mpnt->vm_start = PAGE_MASK & (unsigned long) p;
 197                 mpnt->vm_end = STACK_TOP;
 198                 mpnt->vm_page_prot = PAGE_COPY;
 199                 mpnt->vm_flags = VM_STACK_FLAGS;
 200                 mpnt->vm_ops = NULL;
 201                 mpnt->vm_offset = 0;
 202                 mpnt->vm_inode = NULL;
 203                 mpnt->vm_pte = 0;
 204                 insert_vm_struct(current, mpnt);
 205                 current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
 206         }
 207         sp = (unsigned long *) ((-(unsigned long)sizeof(char *)) & (unsigned long) p);
 208 #ifdef __alpha__
 209 /* whee.. test-programs are so much fun. */
 210         put_user(0, --sp);
 211         put_user(0, --sp);
 212         if (bprm->loader) {
 213                 put_user(0, --sp);
 214                 put_user(0x3eb, --sp);
 215                 put_user(bprm->loader, --sp);
 216                 put_user(0x3ea, --sp);
 217         }
 218         put_user(bprm->exec, --sp);
 219         put_user(0x3e9, --sp);
 220 #endif
 221         sp -= envc+1;
 222         envp = sp;
 223         sp -= argc+1;
 224         argv = sp;
 225 #ifdef __i386__
 226         if (!ibcs) {
 227                 put_user(envp,--sp);
 228                 put_user(argv,--sp);
 229         }
 230 #endif
 231         put_user(argc,--sp);
 232         current->mm->arg_start = (unsigned long) p;
 233         while (argc-->0) {
 234                 put_user(p,argv++);
 235                 while (get_user(p++)) /* nothing */ ;
 236         }
 237         put_user(NULL,argv);
 238         current->mm->arg_end = current->mm->env_start = (unsigned long) p;
 239         while (envc-->0) {
 240                 put_user(p,envp++);
 241                 while (get_user(p++)) /* nothing */ ;
 242         }
 243         put_user(NULL,envp);
 244         current->mm->env_end = (unsigned long) p;
 245         return sp;
 246 }
 247 
 248 /*
 249  * count() counts the number of arguments/envelopes
 250  *
 251  * We also do some limited EFAULT checking: this isn't complete, but
 252  * it does cover most cases. I'll have to do this correctly some day..
 253  */
 254 static int count(char ** argv)
     /* [previous][next][first][last][top][bottom][index][help] */
 255 {
 256         int error, i = 0;
 257         char ** tmp, *p;
 258 
 259         if ((tmp = argv) != NULL) {
 260                 error = verify_area(VERIFY_READ, tmp, sizeof(char *));
 261                 if (error)
 262                         return error;
 263                 while ((p = get_user(tmp++)) != NULL) {
 264                         i++;
 265                         error = verify_area(VERIFY_READ, p, 1);
 266                         if (error)
 267                                 return error;
 268                 }
 269         }
 270         return i;
 271 }
 272 
 273 /*
 274  * 'copy_string()' copies argument/envelope strings from user
 275  * memory to free pages in kernel mem. These are in a format ready
 276  * to be put directly into the top of new user memory.
 277  *
 278  * Modified by TYT, 11/24/91 to add the from_kmem argument, which specifies
 279  * whether the string and the string array are from user or kernel segments:
 280  * 
 281  * from_kmem     argv *        argv **
 282  *    0          user space    user space
 283  *    1          kernel space  user space
 284  *    2          kernel space  kernel space
 285  * 
 286  * We do this by playing games with the fs segment register.  Since it
 287  * is expensive to load a segment register, we try to avoid calling
 288  * set_fs() unless we absolutely have to.
 289  */
 290 unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
     /* [previous][next][first][last][top][bottom][index][help] */
 291                 unsigned long p, int from_kmem)
 292 {
 293         char *tmp, *tmp1, *pag = NULL;
 294         int len, offset = 0;
 295         unsigned long old_fs, new_fs;
 296 
 297         if (!p)
 298                 return 0;       /* bullet-proofing */
 299         new_fs = get_ds();
 300         old_fs = get_fs();
 301         if (from_kmem==2)
 302                 set_fs(new_fs);
 303         while (argc-- > 0) {
 304                 if (from_kmem == 1)
 305                         set_fs(new_fs);
 306                 if (!(tmp1 = tmp = get_user(argv+argc)))
 307                         panic("VFS: argc is wrong");
 308                 if (from_kmem == 1)
 309                         set_fs(old_fs);
 310                 while (get_user(tmp++));
 311                 len = tmp - tmp1;
 312                 if (p < len) {  /* this shouldn't happen - 128kB */
 313                         set_fs(old_fs);
 314                         return 0;
 315                 }
 316                 while (len) {
 317                         --p; --tmp; --len;
 318                         if (--offset < 0) {
 319                                 offset = p % PAGE_SIZE;
 320                                 if (from_kmem==2)
 321                                         set_fs(old_fs);
 322                                 if (!(pag = (char *) page[p/PAGE_SIZE]) &&
 323                                     !(pag = (char *) page[p/PAGE_SIZE] =
 324                                       (unsigned long *) get_free_page(GFP_USER))) 
 325                                         return 0;
 326                                 if (from_kmem==2)
 327                                         set_fs(new_fs);
 328 
 329                         }
 330                         if (len == 0 || offset == 0)
 331                           *(pag + offset) = get_user(tmp);
 332                         else {
 333                           int bytes_to_copy = (len > offset) ? offset : len;
 334                           tmp -= bytes_to_copy;
 335                           p -= bytes_to_copy;
 336                           offset -= bytes_to_copy;
 337                           len -= bytes_to_copy;
 338                           memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
 339                         }
 340                 }
 341         }
 342         if (from_kmem==2)
 343                 set_fs(old_fs);
 344         return p;
 345 }
 346 
 347 unsigned long setup_arg_pages(unsigned long text_size, unsigned long * page)
     /* [previous][next][first][last][top][bottom][index][help] */
 348 {
 349         unsigned long data_base;
 350         int i;
 351 
 352         data_base = STACK_TOP;
 353         for (i=MAX_ARG_PAGES-1 ; i>=0 ; i--) {
 354                 data_base -= PAGE_SIZE;
 355                 if (page[i]) {
 356                         current->mm->rss++;
 357                         put_dirty_page(current,page[i],data_base);
 358                 }
 359         }
 360         return STACK_TOP;
 361 }
 362 
 363 /*
 364  * Read in the complete executable. This is used for "-N" files
 365  * that aren't on a block boundary, and for files on filesystems
 366  * without bmap support.
 367  */
 368 int read_exec(struct inode *inode, unsigned long offset,
     /* [previous][next][first][last][top][bottom][index][help] */
 369         char * addr, unsigned long count, int to_kmem)
 370 {
 371         struct file file;
 372         int result = -ENOEXEC;
 373 
 374         if (!inode->i_op || !inode->i_op->default_file_ops)
 375                 goto end_readexec;
 376         file.f_mode = 1;
 377         file.f_flags = 0;
 378         file.f_count = 1;
 379         file.f_inode = inode;
 380         file.f_pos = 0;
 381         file.f_reada = 0;
 382         file.f_op = inode->i_op->default_file_ops;
 383         if (file.f_op->open)
 384                 if (file.f_op->open(inode,&file))
 385                         goto end_readexec;
 386         if (!file.f_op || !file.f_op->read)
 387                 goto close_readexec;
 388         if (file.f_op->lseek) {
 389                 if (file.f_op->lseek(inode,&file,offset,0) != offset)
 390                         goto close_readexec;
 391         } else
 392                 file.f_pos = offset;
 393         if (to_kmem) {
 394                 unsigned long old_fs = get_fs();
 395                 set_fs(get_ds());
 396                 result = file.f_op->read(inode, &file, addr, count);
 397                 set_fs(old_fs);
 398         } else {
 399                 result = verify_area(VERIFY_WRITE, addr, count);
 400                 if (result)
 401                         goto close_readexec;
 402                 result = file.f_op->read(inode, &file, addr, count);
 403         }
 404 close_readexec:
 405         if (file.f_op->release)
 406                 file.f_op->release(inode,&file);
 407 end_readexec:
 408         return result;
 409 }
 410 
 411 static void exec_mmap(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 412 {
 413         /*
 414          * The clear_page_tables done later on exec does the right thing
 415          * to the page directory when shared, except for graceful abort
 416          * (the oom is wrong there, too, IMHO)
 417          */
 418         if (current->mm->count > 1) {
 419                 struct mm_struct *mm = kmalloc(sizeof(*mm), GFP_KERNEL);
 420                 if (!mm) {
 421                         /* this is wrong, I think. */
 422                         oom(current);
 423                         return;
 424                 }
 425                 *mm = *current->mm;
 426                 mm->def_flags = 0;      /* should future lockings be kept? */
 427                 mm->count = 1;
 428                 mm->mmap = NULL;
 429                 mm->mmap_avl = NULL;
 430                 mm->total_vm = 0;
 431                 mm->rss = 0;
 432                 current->mm->count--;
 433                 current->mm = mm;
 434                 new_page_tables(current);
 435                 return;
 436         }
 437         exit_mmap(current->mm);
 438         clear_page_tables(current);
 439 }
 440 
 441 /*
 442  * This function flushes out all traces of the currently running executable so
 443  * that a new one can be started
 444  */
 445 
 446 void flush_old_exec(struct linux_binprm * bprm)
     /* [previous][next][first][last][top][bottom][index][help] */
 447 {
 448         int i;
 449         int ch;
 450         char * name;
 451 
 452         if (current->euid == current->uid && current->egid == current->gid)
 453                 current->dumpable = 1;
 454         name = bprm->filename;
 455         for (i=0; (ch = *(name++)) != '\0';) {
 456                 if (ch == '/')
 457                         i = 0;
 458                 else
 459                         if (i < 15)
 460                                 current->comm[i++] = ch;
 461         }
 462         current->comm[i] = '\0';
 463 
 464         /* Release all of the old mmap stuff. */
 465         exec_mmap();
 466 
 467         flush_thread();
 468 
 469         if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || 
 470             permission(bprm->inode,MAY_READ))
 471                 current->dumpable = 0;
 472         current->signal = 0;
 473         for (i=0 ; i<32 ; i++) {
 474                 current->sig->action[i].sa_mask = 0;
 475                 current->sig->action[i].sa_flags = 0;
 476                 if (current->sig->action[i].sa_handler != SIG_IGN)
 477                         current->sig->action[i].sa_handler = NULL;
 478         }
 479         for (i=0 ; i<NR_OPEN ; i++)
 480                 if (FD_ISSET(i,&current->files->close_on_exec))
 481                         sys_close(i);
 482         FD_ZERO(&current->files->close_on_exec);
 483         if (last_task_used_math == current)
 484                 last_task_used_math = NULL;
 485         current->used_math = 0;
 486 }
 487 
 488 /*
 489  * sys_execve() executes a new program.
 490  */
 491 int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 492 {
 493         struct linux_binprm bprm;
 494         struct linux_binfmt * fmt;
 495         int i;
 496         int retval;
 497         int sh_bang = 0;
 498         int try;
 499 #ifdef __alpha__
 500         int loader = 0;
 501 #endif
 502 
 503         bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
 504         for (i=0 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */
 505                 bprm.page[i] = 0;
 506         retval = open_namei(filename, 0, 0, &bprm.inode, NULL);
 507         if (retval)
 508                 return retval;
 509         bprm.filename = filename;
 510         bprm.loader = 0;
 511         bprm.exec = 0;
 512         if ((bprm.argc = count(argv)) < 0)
 513                 return bprm.argc;
 514         if ((bprm.envc = count(envp)) < 0)
 515                 return bprm.envc;
 516         
 517 restart_interp:
 518         if (!S_ISREG(bprm.inode->i_mode)) {     /* must be regular file */
 519                 retval = -EACCES;
 520                 goto exec_error2;
 521         }
 522         if (IS_NOEXEC(bprm.inode)) {            /* FS mustn't be mounted noexec */
 523                 retval = -EPERM;
 524                 goto exec_error2;
 525         }
 526         if (!bprm.inode->i_sb) {
 527                 retval = -EACCES;
 528                 goto exec_error2;
 529         }
 530         i = bprm.inode->i_mode;
 531         if (IS_NOSUID(bprm.inode) && (((i & S_ISUID) && bprm.inode->i_uid != current->
 532             euid) || ((i & S_ISGID) && !in_group_p(bprm.inode->i_gid))) && !suser()) {
 533                 retval = -EPERM;
 534                 goto exec_error2;
 535         }
 536         /* make sure we don't let suid, sgid files be ptraced. */
 537         if (current->flags & PF_PTRACED) {
 538                 bprm.e_uid = current->euid;
 539                 bprm.e_gid = current->egid;
 540         } else {
 541                 bprm.e_uid = (i & S_ISUID) ? bprm.inode->i_uid : current->euid;
 542                 bprm.e_gid = (i & S_ISGID) ? bprm.inode->i_gid : current->egid;
 543         }
 544         if ((retval = permission(bprm.inode, MAY_EXEC)) != 0)
 545                 goto exec_error2;
 546         if (!(bprm.inode->i_mode & 0111) && fsuser()) {
 547                 retval = -EACCES;
 548                 goto exec_error2;
 549         }
 550         /* better not execute files which are being written to */
 551         if (bprm.inode->i_writecount > 0) {
 552                 retval = -ETXTBSY;
 553                 goto exec_error2;
 554         }
 555         memset(bprm.buf,0,sizeof(bprm.buf));
 556         retval = read_exec(bprm.inode,0,bprm.buf,128,1);
 557         if (retval < 0)
 558                 goto exec_error2;
 559         if ((bprm.buf[0] == '#') && (bprm.buf[1] == '!') && (!sh_bang)) {
 560                 /*
 561                  * This section does the #! interpretation.
 562                  * Sorta complicated, but hopefully it will work.  -TYT
 563                  */
 564 
 565                 char *cp, *interp, *i_name, *i_arg;
 566 
 567                 iput(bprm.inode);
 568                 bprm.buf[127] = '\0';
 569                 if ((cp = strchr(bprm.buf, '\n')) == NULL)
 570                         cp = bprm.buf+127;
 571                 *cp = '\0';
 572                 while (cp > bprm.buf) {
 573                         cp--;
 574                         if ((*cp == ' ') || (*cp == '\t'))
 575                                 *cp = '\0';
 576                         else
 577                                 break;
 578                 }
 579                 for (cp = bprm.buf+2; (*cp == ' ') || (*cp == '\t'); cp++);
 580                 if (!cp || *cp == '\0') {
 581                         retval = -ENOEXEC; /* No interpreter name found */
 582                         goto exec_error1;
 583                 }
 584                 interp = i_name = cp;
 585                 i_arg = 0;
 586                 for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) {
 587                         if (*cp == '/')
 588                                 i_name = cp+1;
 589                 }
 590                 while ((*cp == ' ') || (*cp == '\t'))
 591                         *cp++ = '\0';
 592                 if (*cp)
 593                         i_arg = cp;
 594                 /*
 595                  * OK, we've parsed out the interpreter name and
 596                  * (optional) argument.
 597                  */
 598                 if (sh_bang++ == 0) {
 599                         bprm.p = copy_strings(bprm.envc, envp, bprm.page, bprm.p, 0);
 600                         bprm.p = copy_strings(--bprm.argc, argv+1, bprm.page, bprm.p, 0);
 601                 }
 602                 /*
 603                  * Splice in (1) the interpreter's name for argv[0]
 604                  *           (2) (optional) argument to interpreter
 605                  *           (3) filename of shell script
 606                  *
 607                  * This is done in reverse order, because of how the
 608                  * user environment and arguments are stored.
 609                  */
 610                 bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p, 2);
 611                 bprm.argc++;
 612                 if (i_arg) {
 613                         bprm.p = copy_strings(1, &i_arg, bprm.page, bprm.p, 2);
 614                         bprm.argc++;
 615                 }
 616                 bprm.p = copy_strings(1, &i_name, bprm.page, bprm.p, 2);
 617                 bprm.argc++;
 618                 if (!bprm.p) {
 619                         retval = -E2BIG;
 620                         goto exec_error1;
 621                 }
 622                 /*
 623                  * OK, now restart the process with the interpreter's inode.
 624                  * Note that we use open_namei() as the name is now in kernel
 625                  * space, and we don't need to copy it.
 626                  */
 627                 retval = open_namei(interp, 0, 0, &bprm.inode, NULL);
 628                 if (retval)
 629                         goto exec_error1;
 630                 goto restart_interp;
 631         }
 632 #ifdef __alpha__
 633         /* handle /sbin/loader.. */
 634         {
 635             struct exec * eh = (struct exec *) bprm.buf;
 636 
 637             if (!loader && eh->fh.f_magic == 0x183 &&
 638                 (eh->fh.f_flags & 0x3000) == 0x3000)
 639             {
 640                 char * dynloader[] = { "/sbin/loader" };
 641                 iput(bprm.inode);
 642                 loader = 1;
 643                 bprm.p = copy_strings(1, dynloader, bprm.page, bprm.p, 2);
 644                 bprm.loader = bprm.p;
 645                 retval = open_namei(dynloader[0], 0, 0, &bprm.inode, NULL);
 646                 if (retval)
 647                         goto exec_error1;
 648                 goto restart_interp;
 649             }
 650         }
 651 #endif
 652         if (!sh_bang) {
 653                 bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p, 2);
 654                 bprm.exec = bprm.p;
 655                 bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p,0);
 656                 bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p,0);
 657                 if (!bprm.p) {
 658                         retval = -E2BIG;
 659                         goto exec_error2;
 660                 }
 661         }
 662 
 663         bprm.sh_bang = sh_bang;
 664         for (try=0; try<2; try++) {
 665                 for (fmt = formats ; fmt ; fmt = fmt->next) {
 666                         int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
 667                         if (!fn)
 668                                 continue;
 669                         retval = fn(&bprm, regs);
 670                         if (retval >= 0) {
 671                                 iput(bprm.inode);
 672                                 current->did_exec = 1;
 673                                 return retval;
 674                         }
 675                         if (retval != -ENOEXEC)
 676                                 break;
 677                 }
 678                 if (retval != -ENOEXEC) {
 679                         break;
 680 #ifdef CONFIG_KERNELD
 681                 }else{
 682 #define printable(c) (((c)=='\t') || ((c)=='\n') || (0x20<=(c) && (c)<=0x7e))
 683                         char modname[20];
 684                         if (printable(bprm.buf[0]) &&
 685                             printable(bprm.buf[1]) &&
 686                             printable(bprm.buf[2]) &&
 687                             printable(bprm.buf[3]))
 688                                 break; /* -ENOEXEC */
 689                         sprintf(modname, "binfmt-%hd", *(short*)(&bprm.buf));
 690                         request_module(modname);
 691 #endif
 692                 }
 693         }
 694 exec_error2:
 695         iput(bprm.inode);
 696 exec_error1:
 697         for (i=0 ; i<MAX_ARG_PAGES ; i++)
 698                 free_page(bprm.page[i]);
 699         return(retval);
 700 }

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