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                                 break;
 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, *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 (!(tmp = get_user(argv+argc)))
 307                         panic("VFS: argc is wrong");
 308                 if (from_kmem == 1)
 309                         set_fs(old_fs);
 310                 len=0;          /* remember zero-padding */
 311                 do {
 312                         len++;
 313                 } while (get_user(tmp++));
 314                 if (p < len) {  /* this shouldn't happen - 128kB */
 315                         set_fs(old_fs);
 316                         return 0;
 317                 }
 318                 while (len) {
 319                         --p; --tmp; --len;
 320                         if (--offset < 0) {
 321                                 offset = p % PAGE_SIZE;
 322                                 if (from_kmem==2)
 323                                         set_fs(old_fs);
 324                                 if (!(pag = (char *) page[p/PAGE_SIZE]) &&
 325                                     !(pag = (char *) page[p/PAGE_SIZE] =
 326                                       (unsigned long *) get_free_page(GFP_USER))) 
 327                                         return 0;
 328                                 if (from_kmem==2)
 329                                         set_fs(new_fs);
 330 
 331                         }
 332                         *(pag + offset) = get_user(tmp);
 333                 }
 334         }
 335         if (from_kmem==2)
 336                 set_fs(old_fs);
 337         return p;
 338 }
 339 
 340 unsigned long setup_arg_pages(unsigned long text_size, unsigned long * page)
     /* [previous][next][first][last][top][bottom][index][help] */
 341 {
 342         unsigned long data_base;
 343         int i;
 344 
 345         data_base = STACK_TOP;
 346         for (i=MAX_ARG_PAGES-1 ; i>=0 ; i--) {
 347                 data_base -= PAGE_SIZE;
 348                 if (page[i]) {
 349                         current->mm->rss++;
 350                         put_dirty_page(current,page[i],data_base);
 351                 }
 352         }
 353         return STACK_TOP;
 354 }
 355 
 356 /*
 357  * Read in the complete executable. This is used for "-N" files
 358  * that aren't on a block boundary, and for files on filesystems
 359  * without bmap support.
 360  */
 361 int read_exec(struct inode *inode, unsigned long offset,
     /* [previous][next][first][last][top][bottom][index][help] */
 362         char * addr, unsigned long count, int to_kmem)
 363 {
 364         struct file file;
 365         int result = -ENOEXEC;
 366 
 367         if (!inode->i_op || !inode->i_op->default_file_ops)
 368                 goto end_readexec;
 369         file.f_mode = 1;
 370         file.f_flags = 0;
 371         file.f_count = 1;
 372         file.f_inode = inode;
 373         file.f_pos = 0;
 374         file.f_reada = 0;
 375         file.f_op = inode->i_op->default_file_ops;
 376         if (file.f_op->open)
 377                 if (file.f_op->open(inode,&file))
 378                         goto end_readexec;
 379         if (!file.f_op || !file.f_op->read)
 380                 goto close_readexec;
 381         if (file.f_op->lseek) {
 382                 if (file.f_op->lseek(inode,&file,offset,0) != offset)
 383                         goto close_readexec;
 384         } else
 385                 file.f_pos = offset;
 386         if (to_kmem) {
 387                 unsigned long old_fs = get_fs();
 388                 set_fs(get_ds());
 389                 result = file.f_op->read(inode, &file, addr, count);
 390                 set_fs(old_fs);
 391         } else {
 392                 result = verify_area(VERIFY_WRITE, addr, count);
 393                 if (result)
 394                         goto close_readexec;
 395                 result = file.f_op->read(inode, &file, addr, count);
 396         }
 397 close_readexec:
 398         if (file.f_op->release)
 399                 file.f_op->release(inode,&file);
 400 end_readexec:
 401         return result;
 402 }
 403 
 404 static void exec_mmap(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 405 {
 406         /*
 407          * The clear_page_tables done later on exec does the right thing
 408          * to the page directory when shared, except for graceful abort
 409          * (the oom is wrong there, too, IMHO)
 410          */
 411         if (current->mm->count > 1) {
 412                 struct mm_struct *mm = kmalloc(sizeof(*mm), GFP_KERNEL);
 413                 if (!mm) {
 414                         /* this is wrong, I think. */
 415                         oom(current);
 416                         return;
 417                 }
 418                 *mm = *current->mm;
 419                 mm->def_flags = 0;      /* should future lockings be kept? */
 420                 mm->count = 1;
 421                 mm->mmap = NULL;
 422                 mm->mmap_avl = NULL;
 423                 mm->total_vm = 0;
 424                 mm->rss = 0;
 425                 current->mm->count--;
 426                 current->mm = mm;
 427                 new_page_tables(current);
 428                 return;
 429         }
 430         exit_mmap(current->mm);
 431         clear_page_tables(current);
 432 }
 433 
 434 /*
 435  * This function flushes out all traces of the currently running executable so
 436  * that a new one can be started
 437  */
 438 
 439 void flush_old_exec(struct linux_binprm * bprm)
     /* [previous][next][first][last][top][bottom][index][help] */
 440 {
 441         int i;
 442         int ch;
 443         char * name;
 444 
 445         if (current->euid == current->uid && current->egid == current->gid)
 446                 current->dumpable = 1;
 447         name = bprm->filename;
 448         for (i=0; (ch = *(name++)) != '\0';) {
 449                 if (ch == '/')
 450                         i = 0;
 451                 else
 452                         if (i < 15)
 453                                 current->comm[i++] = ch;
 454         }
 455         current->comm[i] = '\0';
 456 
 457         /* Release all of the old mmap stuff. */
 458         exec_mmap();
 459 
 460         flush_thread();
 461 
 462         if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || 
 463             permission(bprm->inode,MAY_READ))
 464                 current->dumpable = 0;
 465         current->signal = 0;
 466         for (i=0 ; i<32 ; i++) {
 467                 current->sig->action[i].sa_mask = 0;
 468                 current->sig->action[i].sa_flags = 0;
 469                 if (current->sig->action[i].sa_handler != SIG_IGN)
 470                         current->sig->action[i].sa_handler = NULL;
 471         }
 472         for (i=0 ; i<NR_OPEN ; i++)
 473                 if (FD_ISSET(i,&current->files->close_on_exec))
 474                         sys_close(i);
 475         FD_ZERO(&current->files->close_on_exec);
 476         if (last_task_used_math == current)
 477                 last_task_used_math = NULL;
 478         current->used_math = 0;
 479 }
 480 
 481 /*
 482  * sys_execve() executes a new program.
 483  */
 484 int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 485 {
 486         struct linux_binprm bprm;
 487         struct linux_binfmt * fmt;
 488         int i;
 489         int retval;
 490         int sh_bang = 0;
 491         int try;
 492 #ifdef __alpha__
 493         int loader = 0;
 494 #endif
 495 
 496         bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
 497         for (i=0 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */
 498                 bprm.page[i] = 0;
 499         retval = open_namei(filename, 0, 0, &bprm.inode, NULL);
 500         if (retval)
 501                 return retval;
 502         bprm.filename = filename;
 503         bprm.loader = 0;
 504         bprm.exec = 0;
 505         if ((bprm.argc = count(argv)) < 0)
 506                 return bprm.argc;
 507         if ((bprm.envc = count(envp)) < 0)
 508                 return bprm.envc;
 509         
 510 restart_interp:
 511         if (!S_ISREG(bprm.inode->i_mode)) {     /* must be regular file */
 512                 retval = -EACCES;
 513                 goto exec_error2;
 514         }
 515         if (IS_NOEXEC(bprm.inode)) {            /* FS mustn't be mounted noexec */
 516                 retval = -EPERM;
 517                 goto exec_error2;
 518         }
 519         if (!bprm.inode->i_sb) {
 520                 retval = -EACCES;
 521                 goto exec_error2;
 522         }
 523         i = bprm.inode->i_mode;
 524         if (IS_NOSUID(bprm.inode) && (((i & S_ISUID) && bprm.inode->i_uid != current->
 525             euid) || ((i & S_ISGID) && !in_group_p(bprm.inode->i_gid))) && !suser()) {
 526                 retval = -EPERM;
 527                 goto exec_error2;
 528         }
 529         /* make sure we don't let suid, sgid files be ptraced. */
 530         if (current->flags & PF_PTRACED) {
 531                 bprm.e_uid = current->euid;
 532                 bprm.e_gid = current->egid;
 533         } else {
 534                 bprm.e_uid = (i & S_ISUID) ? bprm.inode->i_uid : current->euid;
 535                 bprm.e_gid = (i & S_ISGID) ? bprm.inode->i_gid : current->egid;
 536         }
 537         if ((retval = permission(bprm.inode, MAY_EXEC)) != 0)
 538                 goto exec_error2;
 539         if (!(bprm.inode->i_mode & 0111) && fsuser()) {
 540                 retval = -EACCES;
 541                 goto exec_error2;
 542         }
 543         /* better not execute files which are being written to */
 544         if (bprm.inode->i_writecount > 0) {
 545                 retval = -ETXTBSY;
 546                 goto exec_error2;
 547         }
 548         memset(bprm.buf,0,sizeof(bprm.buf));
 549         retval = read_exec(bprm.inode,0,bprm.buf,128,1);
 550         if (retval < 0)
 551                 goto exec_error2;
 552         if ((bprm.buf[0] == '#') && (bprm.buf[1] == '!') && (!sh_bang)) {
 553                 /*
 554                  * This section does the #! interpretation.
 555                  * Sorta complicated, but hopefully it will work.  -TYT
 556                  */
 557 
 558                 char *cp, *interp, *i_name, *i_arg;
 559 
 560                 iput(bprm.inode);
 561                 bprm.buf[127] = '\0';
 562                 if ((cp = strchr(bprm.buf, '\n')) == NULL)
 563                         cp = bprm.buf+127;
 564                 *cp = '\0';
 565                 while (cp > bprm.buf) {
 566                         cp--;
 567                         if ((*cp == ' ') || (*cp == '\t'))
 568                                 *cp = '\0';
 569                         else
 570                                 break;
 571                 }
 572                 for (cp = bprm.buf+2; (*cp == ' ') || (*cp == '\t'); cp++);
 573                 if (!cp || *cp == '\0') {
 574                         retval = -ENOEXEC; /* No interpreter name found */
 575                         goto exec_error1;
 576                 }
 577                 interp = i_name = cp;
 578                 i_arg = 0;
 579                 for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) {
 580                         if (*cp == '/')
 581                                 i_name = cp+1;
 582                 }
 583                 while ((*cp == ' ') || (*cp == '\t'))
 584                         *cp++ = '\0';
 585                 if (*cp)
 586                         i_arg = cp;
 587                 /*
 588                  * OK, we've parsed out the interpreter name and
 589                  * (optional) argument.
 590                  */
 591                 if (sh_bang++ == 0) {
 592                         bprm.p = copy_strings(bprm.envc, envp, bprm.page, bprm.p, 0);
 593                         bprm.p = copy_strings(--bprm.argc, argv+1, bprm.page, bprm.p, 0);
 594                 }
 595                 /*
 596                  * Splice in (1) the interpreter's name for argv[0]
 597                  *           (2) (optional) argument to interpreter
 598                  *           (3) filename of shell script
 599                  *
 600                  * This is done in reverse order, because of how the
 601                  * user environment and arguments are stored.
 602                  */
 603                 bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p, 2);
 604                 bprm.argc++;
 605                 if (i_arg) {
 606                         bprm.p = copy_strings(1, &i_arg, bprm.page, bprm.p, 2);
 607                         bprm.argc++;
 608                 }
 609                 bprm.p = copy_strings(1, &i_name, bprm.page, bprm.p, 2);
 610                 bprm.argc++;
 611                 if (!bprm.p) {
 612                         retval = -E2BIG;
 613                         goto exec_error1;
 614                 }
 615                 /*
 616                  * OK, now restart the process with the interpreter's inode.
 617                  * Note that we use open_namei() as the name is now in kernel
 618                  * space, and we don't need to copy it.
 619                  */
 620                 retval = open_namei(interp, 0, 0, &bprm.inode, NULL);
 621                 if (retval)
 622                         goto exec_error1;
 623                 goto restart_interp;
 624         }
 625 #ifdef __alpha__
 626         /* handle /sbin/loader.. */
 627         {
 628             struct exec * eh = (struct exec *) bprm.buf;
 629 
 630             if (!loader && eh->fh.f_magic == 0x183 &&
 631                 (eh->fh.f_flags & 0x3000) == 0x3000)
 632             {
 633                 char * dynloader[] = { "/sbin/loader" };
 634                 iput(bprm.inode);
 635                 loader = 1;
 636                 bprm.p = copy_strings(1, dynloader, bprm.page, bprm.p, 2);
 637                 bprm.loader = bprm.p;
 638                 retval = open_namei(dynloader[0], 0, 0, &bprm.inode, NULL);
 639                 if (retval)
 640                         goto exec_error1;
 641                 goto restart_interp;
 642             }
 643         }
 644 #endif
 645         if (!sh_bang) {
 646                 bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p, 2);
 647                 bprm.exec = bprm.p;
 648                 bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p,0);
 649                 bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p,0);
 650                 if (!bprm.p) {
 651                         retval = -E2BIG;
 652                         goto exec_error2;
 653                 }
 654         }
 655 
 656         bprm.sh_bang = sh_bang;
 657         for (try=0; try<2; try++) {
 658                 for (fmt = formats ; fmt ; fmt = fmt->next) {
 659                         int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
 660                         if (!fn)
 661                                 break;
 662                         retval = fn(&bprm, regs);
 663                         if (retval >= 0) {
 664                                 iput(bprm.inode);
 665                                 current->did_exec = 1;
 666                                 return retval;
 667                         }
 668                         if (retval != -ENOEXEC)
 669                                 break;
 670                 }
 671                 if (retval != -ENOEXEC) {
 672                         break;
 673 #ifdef CONFIG_KERNELD
 674                 }else{
 675 #define printable(c) (((c)=='\t') || ((c)=='\n') || (0x20<=(c) && (c)<=0x7e))
 676                         char modname[20];
 677                         if (printable(bprm.buf[0]) &&
 678                             printable(bprm.buf[1]) &&
 679                             printable(bprm.buf[2]) &&
 680                             printable(bprm.buf[3]))
 681                                 break; /* -ENOEXEC */
 682                         sprintf(modname, "binfmt-%hd", *(short*)(&bprm.buf));
 683                         request_module(modname);
 684 #endif
 685                 }
 686         }
 687 exec_error2:
 688         iput(bprm.inode);
 689 exec_error1:
 690         for (i=0 ; i<MAX_ARG_PAGES ; i++)
 691                 free_page(bprm.page[i]);
 692         return(retval);
 693 }

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