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         if (last_task_used_math == current)
 440                 last_task_used_math = NULL;
 441         current->used_math = 0;
 442 }
 443 
 444 /* 
 445  * Fill the binprm structure from the inode. 
 446  * Check permissions, then read the first 512 bytes
 447  */
 448 int prepare_binprm(struct linux_binprm *bprm)
     /* [previous][next][first][last][top][bottom][index][help] */
 449 {
 450         int retval,i;
 451         if (!S_ISREG(bprm->inode->i_mode))  /* must be regular file */
 452                 return -EACCES;
 453         if (IS_NOEXEC(bprm->inode))         /* FS mustn't be mounted noexec */
 454                 return -EACCES;
 455         if (!bprm->inode->i_sb)
 456                 return -EACCES;
 457         i = bprm->inode->i_mode;
 458         if (IS_NOSUID(bprm->inode) && 
 459                 (((i & S_ISUID) && bprm->inode->i_uid != current->euid) 
 460                         || ((i & S_ISGID) && !in_group_p(bprm->inode->i_gid))) && !suser())
 461                 return -EPERM;
 462         /* make sure we don't let suid, sgid files be ptraced. */
 463         if (current->flags & PF_PTRACED) {
 464                 bprm->e_uid = current->euid;
 465                 bprm->e_gid = current->egid;
 466         } else {
 467                 bprm->e_uid = (i & S_ISUID) ? bprm->inode->i_uid : current->euid;
 468                 bprm->e_gid = (i & S_ISGID) ? bprm->inode->i_gid : current->egid;
 469         }
 470         if ((retval = permission(bprm->inode, MAY_EXEC)) != 0)
 471                 return retval;
 472         if (!(bprm->inode->i_mode & 0111) && fsuser())
 473                 return -EACCES;
 474         /* better not execute files which are being written to */
 475         if (bprm->inode->i_writecount > 0)
 476                 return -ETXTBSY;
 477 
 478         memset(bprm->buf,0,sizeof(bprm->buf));
 479         return read_exec(bprm->inode,0,bprm->buf,128,1);
 480 }
 481 
 482 void remove_arg_zero(struct linux_binprm *bprm)
     /* [previous][next][first][last][top][bottom][index][help] */
 483 {
 484         if (bprm->argc) {
 485                 unsigned long offset;
 486                 char * page;
 487                 offset = bprm->p % PAGE_SIZE;
 488                 page = (char*)bprm->page[bprm->p/PAGE_SIZE];
 489                 while(bprm->p++,*(page+offset++))
 490                         if(offset==PAGE_SIZE){
 491                                 offset=0;
 492                                 page = (char*)bprm->page[bprm->p/PAGE_SIZE];
 493                         }
 494                 bprm->argc--;
 495         }
 496 }
 497 
 498 /*
 499  * cycle the list of binary formats handler, until one recognizes the image
 500  */
 501 int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 502 {
 503         int try,retval=0;
 504         struct linux_binfmt *fmt;
 505 #ifdef __alpha__
 506         /* handle /sbin/loader.. */
 507         {
 508             struct exec * eh = (struct exec *) bprm->buf;
 509 
 510             if (!bprm->loader && eh->fh.f_magic == 0x183 &&
 511                 (eh->fh.f_flags & 0x3000) == 0x3000)
 512             {
 513                 char * dynloader[] = { "/sbin/loader" };
 514                 iput(bprm->inode);
 515                 bprm->dont_iput = 1;
 516                 remove_arg_zero(bprm);
 517                 bprm->p = copy_strings(1, dynloader, bprm->page, bprm->p, 2);
 518                 bprm->argc++;
 519                 bprm->loader = bprm->p;
 520                 retval = open_namei(dynloader[0], 0, 0, &bprm->inode, NULL);
 521                 if (retval)
 522                         return retval;
 523                 bprm->dont_iput = 0;
 524                 retval = prepare_binprm(bprm);
 525                 if (retval<0)
 526                         return retval;
 527                 /* should call search_binary_handler recursively here,
 528                    but it does not matter */
 529             }
 530         }
 531 #endif
 532         for (try=0; try<2; try++) {
 533                 for (fmt = formats ; fmt ; fmt = fmt->next) {
 534                         int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
 535                         if (!fn)
 536                                 continue;
 537                         retval = fn(bprm, regs);
 538                         if (retval >= 0) {
 539                                 if(!bprm->dont_iput)
 540                                         iput(bprm->inode);
 541                                 bprm->dont_iput=1;
 542                                 current->did_exec = 1;
 543                                 return retval;
 544                         }
 545                         if (retval != -ENOEXEC)
 546                                 break;
 547                         if (bprm->dont_iput) /* We don't have the inode anymore*/
 548                                 return retval;
 549                 }
 550                 if (retval != -ENOEXEC) {
 551                         break;
 552 #ifdef CONFIG_KERNELD
 553                 }else{
 554 #define printable(c) (((c)=='\t') || ((c)=='\n') || (0x20<=(c) && (c)<=0x7e))
 555                         char modname[20];
 556                         if (printable(bprm->buf[0]) &&
 557                             printable(bprm->buf[1]) &&
 558                             printable(bprm->buf[2]) &&
 559                             printable(bprm->buf[3]))
 560                                 break; /* -ENOEXEC */
 561                         sprintf(modname, "binfmt-%hd", *(short*)(&bprm->buf));
 562                         request_module(modname);
 563 #endif
 564                 }
 565         }
 566         return retval;
 567 }
 568 
 569 
 570 /*
 571  * sys_execve() executes a new program.
 572  */
 573 int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 574 {
 575         struct linux_binprm bprm;
 576         int retval;
 577         int i;
 578 
 579         bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
 580         for (i=0 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */
 581                 bprm.page[i] = 0;
 582         retval = open_namei(filename, 0, 0, &bprm.inode, NULL);
 583         if (retval)
 584                 return retval;
 585         bprm.filename = filename;
 586         bprm.sh_bang = 0;
 587         bprm.loader = 0;
 588         bprm.exec = 0;
 589         bprm.dont_iput = 0;
 590         if ((bprm.argc = count(argv)) < 0)
 591                 return bprm.argc;
 592         if ((bprm.envc = count(envp)) < 0)
 593                 return bprm.envc;
 594 
 595         retval = prepare_binprm(&bprm);
 596         
 597         if(retval>=0) {
 598                 bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p, 2);
 599                 bprm.exec = bprm.p;
 600                 bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p,0);
 601                 bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p,0);
 602                 if (!bprm.p)
 603                         retval = -E2BIG;
 604         }
 605 
 606         if(retval>=0)
 607                 retval = search_binary_handler(&bprm,regs);
 608         if(retval>=0)
 609                 /* execve success */
 610                 return retval;
 611 
 612         /* Something went wrong, return the inode and free the argument pages*/
 613         if(!bprm.dont_iput)
 614                 iput(bprm.inode);
 615         for (i=0 ; i<MAX_ARG_PAGES ; i++)
 616                 free_page(bprm.page[i]);
 617         return(retval);
 618 }

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