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                 /*
 469                  * If setgid is set but no group execute bit then this
 470                  * is a candidate for mandatory locking, not a setgid
 471                  * executable.
 472                  */
 473                 bprm->e_gid = ((i & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ?
 474                         bprm->inode->i_gid : current->egid;
 475         }
 476         if ((retval = permission(bprm->inode, MAY_EXEC)) != 0)
 477                 return retval;
 478         if (!(bprm->inode->i_mode & 0111) && fsuser())
 479                 return -EACCES;
 480         /* better not execute files which are being written to */
 481         if (bprm->inode->i_writecount > 0)
 482                 return -ETXTBSY;
 483 
 484         memset(bprm->buf,0,sizeof(bprm->buf));
 485         return read_exec(bprm->inode,0,bprm->buf,128,1);
 486 }
 487 
 488 void remove_arg_zero(struct linux_binprm *bprm)
     /* [previous][next][first][last][top][bottom][index][help] */
 489 {
 490         if (bprm->argc) {
 491                 unsigned long offset;
 492                 char * page;
 493                 offset = bprm->p % PAGE_SIZE;
 494                 page = (char*)bprm->page[bprm->p/PAGE_SIZE];
 495                 while(bprm->p++,*(page+offset++))
 496                         if(offset==PAGE_SIZE){
 497                                 offset=0;
 498                                 page = (char*)bprm->page[bprm->p/PAGE_SIZE];
 499                         }
 500                 bprm->argc--;
 501         }
 502 }
 503 
 504 /*
 505  * cycle the list of binary formats handler, until one recognizes the image
 506  */
 507 int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 508 {
 509         int try,retval=0;
 510         struct linux_binfmt *fmt;
 511 #ifdef __alpha__
 512         /* handle /sbin/loader.. */
 513         {
 514             struct exec * eh = (struct exec *) bprm->buf;
 515 
 516             if (!bprm->loader && eh->fh.f_magic == 0x183 &&
 517                 (eh->fh.f_flags & 0x3000) == 0x3000)
 518             {
 519                 char * dynloader[] = { "/sbin/loader" };
 520                 iput(bprm->inode);
 521                 bprm->dont_iput = 1;
 522                 remove_arg_zero(bprm);
 523                 bprm->p = copy_strings(1, dynloader, bprm->page, bprm->p, 2);
 524                 bprm->argc++;
 525                 bprm->loader = bprm->p;
 526                 retval = open_namei(dynloader[0], 0, 0, &bprm->inode, NULL);
 527                 if (retval)
 528                         return retval;
 529                 bprm->dont_iput = 0;
 530                 retval = prepare_binprm(bprm);
 531                 if (retval<0)
 532                         return retval;
 533                 /* should call search_binary_handler recursively here,
 534                    but it does not matter */
 535             }
 536         }
 537 #endif
 538         for (try=0; try<2; try++) {
 539                 for (fmt = formats ; fmt ; fmt = fmt->next) {
 540                         int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
 541                         if (!fn)
 542                                 continue;
 543                         retval = fn(bprm, regs);
 544                         if (retval >= 0) {
 545                                 if(!bprm->dont_iput)
 546                                         iput(bprm->inode);
 547                                 bprm->dont_iput=1;
 548                                 current->did_exec = 1;
 549                                 return retval;
 550                         }
 551                         if (retval != -ENOEXEC)
 552                                 break;
 553                         if (bprm->dont_iput) /* We don't have the inode anymore*/
 554                                 return retval;
 555                 }
 556                 if (retval != -ENOEXEC) {
 557                         break;
 558 #ifdef CONFIG_KERNELD
 559                 }else{
 560 #define printable(c) (((c)=='\t') || ((c)=='\n') || (0x20<=(c) && (c)<=0x7e))
 561                         char modname[20];
 562                         if (printable(bprm->buf[0]) &&
 563                             printable(bprm->buf[1]) &&
 564                             printable(bprm->buf[2]) &&
 565                             printable(bprm->buf[3]))
 566                                 break; /* -ENOEXEC */
 567                         sprintf(modname, "binfmt-%hd", *(short*)(&bprm->buf));
 568                         request_module(modname);
 569 #endif
 570                 }
 571         }
 572         return retval;
 573 }
 574 
 575 
 576 /*
 577  * sys_execve() executes a new program.
 578  */
 579 int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 580 {
 581         struct linux_binprm bprm;
 582         int retval;
 583         int i;
 584 
 585         bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
 586         for (i=0 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */
 587                 bprm.page[i] = 0;
 588         retval = open_namei(filename, 0, 0, &bprm.inode, NULL);
 589         if (retval)
 590                 return retval;
 591         bprm.filename = filename;
 592         bprm.sh_bang = 0;
 593         bprm.loader = 0;
 594         bprm.exec = 0;
 595         bprm.dont_iput = 0;
 596         if ((bprm.argc = count(argv)) < 0)
 597                 return bprm.argc;
 598         if ((bprm.envc = count(envp)) < 0)
 599                 return bprm.envc;
 600 
 601         retval = prepare_binprm(&bprm);
 602         
 603         if(retval>=0) {
 604                 bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p, 2);
 605                 bprm.exec = bprm.p;
 606                 bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p,0);
 607                 bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p,0);
 608                 if (!bprm.p)
 609                         retval = -E2BIG;
 610         }
 611 
 612         if(retval>=0)
 613                 retval = search_binary_handler(&bprm,regs);
 614         if(retval>=0)
 615                 /* execve success */
 616                 return retval;
 617 
 618         /* Something went wrong, return the inode and free the argument pages*/
 619         if(!bprm.dont_iput)
 620                 iput(bprm.inode);
 621         for (i=0 ; i<MAX_ARG_PAGES ; i++)
 622                 free_page(bprm.page[i]);
 623         return(retval);
 624 }

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