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. count
  7. copy_strings
  8. setup_arg_pages
  9. read_exec
  10. exec_mmap
  11. flush_old_exec
  12. prepare_binprm
  13. remove_arg_zero
  14. search_binary_handler
  15. 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         /* This cannot be configured out of the kernel */
  74         init_script_binfmt();
  75 }
  76 
  77 int register_binfmt(struct linux_binfmt * fmt)
     /* [previous][next][first][last][top][bottom][index][help] */
  78 {
  79         struct linux_binfmt ** tmp = &formats;
  80 
  81         if (!fmt)
  82                 return -EINVAL;
  83         if (fmt->next)
  84                 return -EBUSY;
  85         while (*tmp) {
  86                 if (fmt == *tmp)
  87                         return -EBUSY;
  88                 tmp = &(*tmp)->next;
  89         }
  90         fmt->next = formats;
  91         formats = fmt;
  92         return 0;       
  93 }
  94 
  95 #ifdef CONFIG_MODULES
  96 int unregister_binfmt(struct linux_binfmt * fmt)
     /* [previous][next][first][last][top][bottom][index][help] */
  97 {
  98         struct linux_binfmt ** tmp = &formats;
  99 
 100         while (*tmp) {
 101                 if (fmt == *tmp) {
 102                         *tmp = fmt->next;
 103                         return 0;
 104                 }
 105                 tmp = &(*tmp)->next;
 106         }
 107         return -EINVAL;
 108 }
 109 #endif  /* CONFIG_MODULES */
 110 
 111 int open_inode(struct inode * inode, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 112 {
 113         int error, fd;
 114         struct file *f, **fpp;
 115 
 116         if (!inode->i_op || !inode->i_op->default_file_ops)
 117                 return -EINVAL;
 118         f = get_empty_filp();
 119         if (!f)
 120                 return -ENFILE;
 121         fd = 0;
 122         fpp = current->files->fd;
 123         for (;;) {
 124                 if (!*fpp)
 125                         break;
 126                 if (++fd >= NR_OPEN) {
 127                         f->f_count--;
 128                         return -EMFILE;
 129                 }
 130                 fpp++;
 131         }
 132         *fpp = f;
 133         f->f_flags = mode;
 134         f->f_mode = (mode+1) & O_ACCMODE;
 135         f->f_inode = inode;
 136         f->f_pos = 0;
 137         f->f_reada = 0;
 138         f->f_op = inode->i_op->default_file_ops;
 139         if (f->f_op->open) {
 140                 error = f->f_op->open(inode,f);
 141                 if (error) {
 142                         *fpp = NULL;
 143                         f->f_count--;
 144                         return error;
 145                 }
 146         }
 147         inode->i_count++;
 148         return fd;
 149 }
 150 
 151 /*
 152  * Note that a shared library must be both readable and executable due to
 153  * security reasons.
 154  *
 155  * Also note that we take the address to load from from the file itself.
 156  */
 157 asmlinkage int sys_uselib(const char * library)
     /* [previous][next][first][last][top][bottom][index][help] */
 158 {
 159         int fd, retval;
 160         struct file * file;
 161         struct linux_binfmt * fmt;
 162 
 163         fd = sys_open(library, 0, 0);
 164         if (fd < 0)
 165                 return fd;
 166         file = current->files->fd[fd];
 167         retval = -ENOEXEC;
 168         if (file && file->f_inode && file->f_op && file->f_op->read) {
 169                 for (fmt = formats ; fmt ; fmt = fmt->next) {
 170                         int (*fn)(int) = fmt->load_shlib;
 171                         if (!fn)
 172                                 continue;
 173                         retval = fn(fd);
 174                         if (retval != -ENOEXEC)
 175                                 break;
 176                 }
 177         }
 178         sys_close(fd);
 179         return retval;
 180 }
 181 
 182 /*
 183  * count() counts the number of arguments/envelopes
 184  *
 185  * We also do some limited EFAULT checking: this isn't complete, but
 186  * it does cover most cases. I'll have to do this correctly some day..
 187  */
 188 static int count(char ** argv)
     /* [previous][next][first][last][top][bottom][index][help] */
 189 {
 190         int error, i = 0;
 191         char ** tmp, *p;
 192 
 193         if ((tmp = argv) != NULL) {
 194                 error = verify_area(VERIFY_READ, tmp, sizeof(char *));
 195                 if (error)
 196                         return error;
 197                 while ((p = get_user(tmp++)) != NULL) {
 198                         i++;
 199                         error = verify_area(VERIFY_READ, p, 1);
 200                         if (error)
 201                                 return error;
 202                 }
 203         }
 204         return i;
 205 }
 206 
 207 /*
 208  * 'copy_string()' copies argument/envelope strings from user
 209  * memory to free pages in kernel mem. These are in a format ready
 210  * to be put directly into the top of new user memory.
 211  *
 212  * Modified by TYT, 11/24/91 to add the from_kmem argument, which specifies
 213  * whether the string and the string array are from user or kernel segments:
 214  * 
 215  * from_kmem     argv *        argv **
 216  *    0          user space    user space
 217  *    1          kernel space  user space
 218  *    2          kernel space  kernel space
 219  * 
 220  * We do this by playing games with the fs segment register.  Since it
 221  * is expensive to load a segment register, we try to avoid calling
 222  * set_fs() unless we absolutely have to.
 223  */
 224 unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
     /* [previous][next][first][last][top][bottom][index][help] */
 225                 unsigned long p, int from_kmem)
 226 {
 227         char *tmp, *tmp1, *pag = NULL;
 228         int len, offset = 0;
 229         unsigned long old_fs, new_fs;
 230 
 231         if (!p)
 232                 return 0;       /* bullet-proofing */
 233         new_fs = get_ds();
 234         old_fs = get_fs();
 235         if (from_kmem==2)
 236                 set_fs(new_fs);
 237         while (argc-- > 0) {
 238                 if (from_kmem == 1)
 239                         set_fs(new_fs);
 240                 if (!(tmp1 = tmp = get_user(argv+argc)))
 241                         panic("VFS: argc is wrong");
 242                 if (from_kmem == 1)
 243                         set_fs(old_fs);
 244                 while (get_user(tmp++));
 245                 len = tmp - tmp1;
 246                 if (p < len) {  /* this shouldn't happen - 128kB */
 247                         set_fs(old_fs);
 248                         return 0;
 249                 }
 250                 while (len) {
 251                         --p; --tmp; --len;
 252                         if (--offset < 0) {
 253                                 offset = p % PAGE_SIZE;
 254                                 if (from_kmem==2)
 255                                         set_fs(old_fs);
 256                                 if (!(pag = (char *) page[p/PAGE_SIZE]) &&
 257                                     !(pag = (char *) page[p/PAGE_SIZE] =
 258                                       (unsigned long *) get_free_page(GFP_USER))) 
 259                                         return 0;
 260                                 if (from_kmem==2)
 261                                         set_fs(new_fs);
 262 
 263                         }
 264                         if (len == 0 || offset == 0)
 265                           *(pag + offset) = get_user(tmp);
 266                         else {
 267                           int bytes_to_copy = (len > offset) ? offset : len;
 268                           tmp -= bytes_to_copy;
 269                           p -= bytes_to_copy;
 270                           offset -= bytes_to_copy;
 271                           len -= bytes_to_copy;
 272                           memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
 273                         }
 274                 }
 275         }
 276         if (from_kmem==2)
 277                 set_fs(old_fs);
 278         return p;
 279 }
 280 
 281 unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm)
     /* [previous][next][first][last][top][bottom][index][help] */
 282 {
 283         unsigned long stack_base;
 284         struct vm_area_struct *mpnt;
 285         int i;
 286 
 287         stack_base = STACK_TOP - MAX_ARG_PAGES*PAGE_SIZE;
 288 
 289         p += stack_base;
 290         if (bprm->loader)
 291                 bprm->loader += stack_base;
 292         bprm->exec += stack_base;
 293 
 294         mpnt = (struct vm_area_struct *)kmalloc(sizeof(*mpnt), GFP_KERNEL);
 295         if (mpnt) {
 296                 mpnt->vm_mm = current->mm;
 297                 mpnt->vm_start = PAGE_MASK & (unsigned long) p;
 298                 mpnt->vm_end = STACK_TOP;
 299                 mpnt->vm_page_prot = PAGE_COPY;
 300                 mpnt->vm_flags = VM_STACK_FLAGS;
 301                 mpnt->vm_ops = NULL;
 302                 mpnt->vm_offset = 0;
 303                 mpnt->vm_inode = NULL;
 304                 mpnt->vm_pte = 0;
 305                 insert_vm_struct(current, mpnt);
 306                 current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
 307         }
 308 
 309         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
 310                 if (bprm->page[i]) {
 311                         current->mm->rss++;
 312                         put_dirty_page(current,bprm->page[i],stack_base);
 313                 }
 314                 stack_base += PAGE_SIZE;
 315         }
 316         return p;
 317 }
 318 
 319 /*
 320  * Read in the complete executable. This is used for "-N" files
 321  * that aren't on a block boundary, and for files on filesystems
 322  * without bmap support.
 323  */
 324 int read_exec(struct inode *inode, unsigned long offset,
     /* [previous][next][first][last][top][bottom][index][help] */
 325         char * addr, unsigned long count, int to_kmem)
 326 {
 327         struct file file;
 328         int result = -ENOEXEC;
 329 
 330         if (!inode->i_op || !inode->i_op->default_file_ops)
 331                 goto end_readexec;
 332         file.f_mode = 1;
 333         file.f_flags = 0;
 334         file.f_count = 1;
 335         file.f_inode = inode;
 336         file.f_pos = 0;
 337         file.f_reada = 0;
 338         file.f_op = inode->i_op->default_file_ops;
 339         if (file.f_op->open)
 340                 if (file.f_op->open(inode,&file))
 341                         goto end_readexec;
 342         if (!file.f_op || !file.f_op->read)
 343                 goto close_readexec;
 344         if (file.f_op->lseek) {
 345                 if (file.f_op->lseek(inode,&file,offset,0) != offset)
 346                         goto close_readexec;
 347         } else
 348                 file.f_pos = offset;
 349         if (to_kmem) {
 350                 unsigned long old_fs = get_fs();
 351                 set_fs(get_ds());
 352                 result = file.f_op->read(inode, &file, addr, count);
 353                 set_fs(old_fs);
 354         } else {
 355                 result = verify_area(VERIFY_WRITE, addr, count);
 356                 if (result)
 357                         goto close_readexec;
 358                 result = file.f_op->read(inode, &file, addr, count);
 359         }
 360 close_readexec:
 361         if (file.f_op->release)
 362                 file.f_op->release(inode,&file);
 363 end_readexec:
 364         return result;
 365 }
 366 
 367 static void exec_mmap(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 368 {
 369         /*
 370          * The clear_page_tables done later on exec does the right thing
 371          * to the page directory when shared, except for graceful abort
 372          * (the oom is wrong there, too, IMHO)
 373          */
 374         if (current->mm->count > 1) {
 375                 struct mm_struct *mm = kmalloc(sizeof(*mm), GFP_KERNEL);
 376                 if (!mm) {
 377                         /* this is wrong, I think. */
 378                         oom(current);
 379                         return;
 380                 }
 381                 *mm = *current->mm;
 382                 mm->def_flags = 0;      /* should future lockings be kept? */
 383                 mm->count = 1;
 384                 mm->mmap = NULL;
 385                 mm->mmap_avl = NULL;
 386                 mm->total_vm = 0;
 387                 mm->rss = 0;
 388                 current->mm->count--;
 389                 current->mm = mm;
 390                 new_page_tables(current);
 391                 return;
 392         }
 393         exit_mmap(current->mm);
 394         clear_page_tables(current);
 395 }
 396 
 397 /*
 398  * This function flushes out all traces of the currently running executable so
 399  * that a new one can be started
 400  */
 401 
 402 void flush_old_exec(struct linux_binprm * bprm)
     /* [previous][next][first][last][top][bottom][index][help] */
 403 {
 404         int i;
 405         int ch;
 406         char * name;
 407 
 408         if (current->euid == current->uid && current->egid == current->gid)
 409                 current->dumpable = 1;
 410         name = bprm->filename;
 411         for (i=0; (ch = *(name++)) != '\0';) {
 412                 if (ch == '/')
 413                         i = 0;
 414                 else
 415                         if (i < 15)
 416                                 current->comm[i++] = ch;
 417         }
 418         current->comm[i] = '\0';
 419 
 420         /* Release all of the old mmap stuff. */
 421         exec_mmap();
 422 
 423         flush_thread();
 424 
 425         if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || 
 426             permission(bprm->inode,MAY_READ))
 427                 current->dumpable = 0;
 428         current->signal = 0;
 429         for (i=0 ; i<32 ; i++) {
 430                 current->sig->action[i].sa_mask = 0;
 431                 current->sig->action[i].sa_flags = 0;
 432                 if (current->sig->action[i].sa_handler != SIG_IGN)
 433                         current->sig->action[i].sa_handler = NULL;
 434         }
 435         for (i=0 ; i<NR_OPEN ; i++)
 436                 if (FD_ISSET(i,&current->files->close_on_exec))
 437                         sys_close(i);
 438         FD_ZERO(&current->files->close_on_exec);
 439 }
 440 
 441 /* 
 442  * Fill the binprm structure from the inode. 
 443  * Check permissions, then read the first 512 bytes
 444  */
 445 int prepare_binprm(struct linux_binprm *bprm)
     /* [previous][next][first][last][top][bottom][index][help] */
 446 {
 447         int mode;
 448         int retval,id_change;
 449 
 450         mode = bprm->inode->i_mode;
 451         if (!S_ISREG(mode))                     /* must be regular file */
 452                 return -EACCES;
 453         if (!(mode & 0111))                     /* with at least _one_ execute bit set */
 454                 return -EACCES;
 455         if (IS_NOEXEC(bprm->inode))             /* FS mustn't be mounted noexec */
 456                 return -EACCES;
 457         if (!bprm->inode->i_sb)
 458                 return -EACCES;
 459         if ((retval = permission(bprm->inode, MAY_EXEC)) != 0)
 460                 return retval;
 461         /* better not execute files which are being written to */
 462         if (bprm->inode->i_writecount > 0)
 463                 return -ETXTBSY;
 464 
 465         bprm->e_uid = current->euid;
 466         bprm->e_gid = current->egid;
 467         id_change = 0;
 468 
 469         /* Set-uid? */
 470         if (mode & S_ISUID) {
 471                 bprm->e_uid = bprm->inode->i_uid;
 472                 if (bprm->e_uid != current->euid)
 473                         id_change = 1;
 474         }
 475 
 476         /* Set-gid? */
 477         /*
 478          * If setgid is set but no group execute bit then this
 479          * is a candidate for mandatory locking, not a setgid
 480          * executable.
 481          */
 482         if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
 483                 bprm->e_gid = bprm->inode->i_gid;
 484                 if (!in_group_p(bprm->e_gid))
 485                         id_change = 1;
 486         }
 487 
 488         if (id_change) {
 489                 /* We can't suid-execute if we're sharing parts of the executable */
 490                 /* or if we're being traced (or if suid execs are not allowed)    */
 491                 /* (current->mm->count > 1 is ok, as we'll get a new mm anyway)   */
 492                 if (IS_NOSUID(bprm->inode)
 493                     || (current->flags & PF_PTRACED)
 494                     || (current->fs->count > 1)
 495                     || (current->sig->count > 1)
 496                     || (current->files->count > 1)) {
 497                         if (!suser())
 498                                 return -EPERM;
 499                 }
 500         }
 501 
 502         memset(bprm->buf,0,sizeof(bprm->buf));
 503         return read_exec(bprm->inode,0,bprm->buf,128,1);
 504 }
 505 
 506 void remove_arg_zero(struct linux_binprm *bprm)
     /* [previous][next][first][last][top][bottom][index][help] */
 507 {
 508         if (bprm->argc) {
 509                 unsigned long offset;
 510                 char * page;
 511                 offset = bprm->p % PAGE_SIZE;
 512                 page = (char*)bprm->page[bprm->p/PAGE_SIZE];
 513                 while(bprm->p++,*(page+offset++))
 514                         if(offset==PAGE_SIZE){
 515                                 offset=0;
 516                                 page = (char*)bprm->page[bprm->p/PAGE_SIZE];
 517                         }
 518                 bprm->argc--;
 519         }
 520 }
 521 
 522 /*
 523  * cycle the list of binary formats handler, until one recognizes the image
 524  */
 525 int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 526 {
 527         int try,retval=0;
 528         struct linux_binfmt *fmt;
 529 #ifdef __alpha__
 530         /* handle /sbin/loader.. */
 531         {
 532             struct exec * eh = (struct exec *) bprm->buf;
 533 
 534             if (!bprm->loader && eh->fh.f_magic == 0x183 &&
 535                 (eh->fh.f_flags & 0x3000) == 0x3000)
 536             {
 537                 char * dynloader[] = { "/sbin/loader" };
 538                 iput(bprm->inode);
 539                 bprm->dont_iput = 1;
 540                 remove_arg_zero(bprm);
 541                 bprm->p = copy_strings(1, dynloader, bprm->page, bprm->p, 2);
 542                 bprm->argc++;
 543                 bprm->loader = bprm->p;
 544                 retval = open_namei(dynloader[0], 0, 0, &bprm->inode, NULL);
 545                 if (retval)
 546                         return retval;
 547                 bprm->dont_iput = 0;
 548                 retval = prepare_binprm(bprm);
 549                 if (retval<0)
 550                         return retval;
 551                 /* should call search_binary_handler recursively here,
 552                    but it does not matter */
 553             }
 554         }
 555 #endif
 556         for (try=0; try<2; try++) {
 557                 for (fmt = formats ; fmt ; fmt = fmt->next) {
 558                         int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
 559                         if (!fn)
 560                                 continue;
 561                         retval = fn(bprm, regs);
 562                         if (retval >= 0) {
 563                                 if(!bprm->dont_iput)
 564                                         iput(bprm->inode);
 565                                 bprm->dont_iput=1;
 566                                 current->did_exec = 1;
 567                                 return retval;
 568                         }
 569                         if (retval != -ENOEXEC)
 570                                 break;
 571                         if (bprm->dont_iput) /* We don't have the inode anymore*/
 572                                 return retval;
 573                 }
 574                 if (retval != -ENOEXEC) {
 575                         break;
 576 #ifdef CONFIG_KERNELD
 577                 }else{
 578 #define printable(c) (((c)=='\t') || ((c)=='\n') || (0x20<=(c) && (c)<=0x7e))
 579                         char modname[20];
 580                         if (printable(bprm->buf[0]) &&
 581                             printable(bprm->buf[1]) &&
 582                             printable(bprm->buf[2]) &&
 583                             printable(bprm->buf[3]))
 584                                 break; /* -ENOEXEC */
 585                         sprintf(modname, "binfmt-%hd", *(short*)(&bprm->buf));
 586                         request_module(modname);
 587 #endif
 588                 }
 589         }
 590         return retval;
 591 }
 592 
 593 
 594 /*
 595  * sys_execve() executes a new program.
 596  */
 597 int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 598 {
 599         struct linux_binprm bprm;
 600         int retval;
 601         int i;
 602 
 603         bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
 604         for (i=0 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */
 605                 bprm.page[i] = 0;
 606         retval = open_namei(filename, 0, 0, &bprm.inode, NULL);
 607         if (retval)
 608                 return retval;
 609         bprm.filename = filename;
 610         bprm.sh_bang = 0;
 611         bprm.loader = 0;
 612         bprm.exec = 0;
 613         bprm.dont_iput = 0;
 614         if ((bprm.argc = count(argv)) < 0)
 615                 return bprm.argc;
 616         if ((bprm.envc = count(envp)) < 0)
 617                 return bprm.envc;
 618 
 619         retval = prepare_binprm(&bprm);
 620         
 621         if(retval>=0) {
 622                 bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p, 2);
 623                 bprm.exec = bprm.p;
 624                 bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p,0);
 625                 bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p,0);
 626                 if (!bprm.p)
 627                         retval = -E2BIG;
 628         }
 629 
 630         if(retval>=0)
 631                 retval = search_binary_handler(&bprm,regs);
 632         if(retval>=0)
 633                 /* execve success */
 634                 return retval;
 635 
 636         /* Something went wrong, return the inode and free the argument pages*/
 637         if(!bprm.dont_iput)
 638                 iput(bprm.inode);
 639         for (i=0 ; i<MAX_ARG_PAGES ; i++)
 640                 free_page(bprm.page[i]);
 641         return(retval);
 642 }

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