root/fs/exec.c

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

DEFINITIONS

This source file includes following definitions.
  1. register_binfmt
  2. unregister_binfmt
  3. open_inode
  4. core_dump
  5. sys_uselib
  6. create_tables
  7. count
  8. copy_strings
  9. change_ldt
  10. read_exec
  11. flush_old_exec
  12. do_execve
  13. sys_execve
  14. no_lcall7
  15. set_brk
  16. load_aout_binary
  17. load_aout_library

   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 /*
  12  * Demand-loading implemented 01.12.91 - no need to read anything but
  13  * the header into memory. The inode of the executable is put into
  14  * "current->executable", and page faults do the actual loading. Clean.
  15  *
  16  * Once more I can proudly say that linux stood up to being changed: it
  17  * was less than 2 hours work to get demand-loading completely implemented.
  18  *
  19  * Demand loading changed July 1993 by Eric Youngdale.   Use mmap instead,
  20  * current->executable is only used by the procfs.  This allows a dispatch
  21  * table to check for several different types  of binary formats.  We keep
  22  * trying until we recognize the file or we run out of supported binary
  23  * formats. 
  24  */
  25 
  26 #include <linux/fs.h>
  27 #include <linux/sched.h>
  28 #include <linux/kernel.h>
  29 #include <linux/mm.h>
  30 #include <linux/mman.h>
  31 #include <linux/a.out.h>
  32 #include <linux/errno.h>
  33 #include <linux/signal.h>
  34 #include <linux/string.h>
  35 #include <linux/stat.h>
  36 #include <linux/fcntl.h>
  37 #include <linux/ptrace.h>
  38 #include <linux/user.h>
  39 #include <linux/segment.h>
  40 #include <linux/malloc.h>
  41 
  42 #include <asm/system.h>
  43 
  44 #include <linux/binfmts.h>
  45 
  46 #include <asm/segment.h>
  47 #include <asm/system.h>
  48 
  49 asmlinkage int sys_exit(int exit_code);
  50 asmlinkage int sys_close(unsigned fd);
  51 asmlinkage int sys_open(const char *, int, int);
  52 asmlinkage int sys_brk(unsigned long);
  53 
  54 extern void shm_exit (void);
  55 
  56 static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs);
  57 static int load_aout_library(int fd);
  58 
  59 /*
  60  * Here are the actual binaries that will be accepted:
  61  * add more with "register_binfmt()"..
  62  */
  63 static struct linux_binfmt aout_format = { NULL, load_aout_binary, load_aout_library };
  64 static struct linux_binfmt *formats = &aout_format;
  65 
  66 int register_binfmt(struct linux_binfmt * fmt)
     /* [previous][next][first][last][top][bottom][index][help] */
  67 {
  68         struct linux_binfmt ** tmp = &formats;
  69 
  70         if (!fmt)
  71                 return -EINVAL;
  72         if (fmt->next)
  73                 return -EBUSY;
  74         while (*tmp) {
  75                 if (fmt == *tmp)
  76                         return -EBUSY;
  77                 tmp = &(*tmp)->next;
  78         }
  79         *tmp = fmt;
  80         return 0;       
  81 }
  82 
  83 int unregister_binfmt(struct linux_binfmt * fmt)
     /* [previous][next][first][last][top][bottom][index][help] */
  84 {
  85         struct linux_binfmt ** tmp = &formats;
  86 
  87         while (*tmp) {
  88                 if (fmt == *tmp) {
  89                         *tmp = fmt->next;
  90                         return 0;
  91                 }
  92                 tmp = &(*tmp)->next;
  93         }
  94         return -EINVAL;
  95 }
  96 
  97 int open_inode(struct inode * inode, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
  98 {
  99         int error, fd;
 100         struct file *f, **fpp;
 101 
 102         if (!inode->i_op || !inode->i_op->default_file_ops)
 103                 return -EINVAL;
 104         f = get_empty_filp();
 105         if (!f)
 106                 return -EMFILE;
 107         fd = 0;
 108         fpp = current->files->fd;
 109         for (;;) {
 110                 if (!*fpp)
 111                         break;
 112                 if (++fd > NR_OPEN)
 113                         return -ENFILE;
 114                 fpp++;
 115         }
 116         *fpp = f;
 117         f->f_flags = mode;
 118         f->f_mode = (mode+1) & O_ACCMODE;
 119         f->f_inode = inode;
 120         f->f_pos = 0;
 121         f->f_reada = 0;
 122         f->f_op = inode->i_op->default_file_ops;
 123         if (f->f_op->open) {
 124                 error = f->f_op->open(inode,f);
 125                 if (error) {
 126                         *fpp = NULL;
 127                         f->f_count--;
 128                         return error;
 129                 }
 130         }
 131         inode->i_count++;
 132         return fd;
 133 }
 134 
 135 /*
 136  * These are the only things you should do on a core-file: use only these
 137  * macros to write out all the necessary info.
 138  */
 139 #define DUMP_WRITE(addr,nr) \
 140 while (file.f_op->write(inode,&file,(char *)(addr),(nr)) != (nr)) goto close_coredump
 141 
 142 #define DUMP_SEEK(offset) \
 143 if (file.f_op->lseek) { \
 144         if (file.f_op->lseek(inode,&file,(offset),0) != (offset)) \
 145                 goto close_coredump; \
 146 } else file.f_pos = (offset)            
 147 
 148 /*
 149  * Routine writes a core dump image in the current directory.
 150  * Currently only a stub-function.
 151  *
 152  * Note that setuid/setgid files won't make a core-dump if the uid/gid
 153  * changed due to the set[u|g]id. It's enforced by the "current->dumpable"
 154  * field, which also makes sure the core-dumps won't be recursive if the
 155  * dumping of the process results in another error..
 156  */
 157 int core_dump(long signr, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 158 {
 159         struct inode * inode = NULL;
 160         struct file file;
 161         unsigned short fs;
 162         int has_dumped = 0;
 163         char corefile[6+sizeof(current->comm)];
 164         int i;
 165         register int dump_start, dump_size;
 166         struct user dump;
 167 
 168         if (!current->dumpable)
 169                 return 0;
 170         current->dumpable = 0;
 171 
 172 /* See if we have enough room to write the upage.  */
 173         if (current->rlim[RLIMIT_CORE].rlim_cur < PAGE_SIZE)
 174                 return 0;
 175         fs = get_fs();
 176         set_fs(KERNEL_DS);
 177         memcpy(corefile,"core.",5);
 178 #if 0
 179         memcpy(corefile+5,current->comm,sizeof(current->comm));
 180 #else
 181         corefile[4] = '\0';
 182 #endif
 183         if (open_namei(corefile,O_CREAT | 2 | O_TRUNC,0600,&inode,NULL)) {
 184                 inode = NULL;
 185                 goto end_coredump;
 186         }
 187         if (!S_ISREG(inode->i_mode))
 188                 goto end_coredump;
 189         if (!inode->i_op || !inode->i_op->default_file_ops)
 190                 goto end_coredump;
 191         file.f_mode = 3;
 192         file.f_flags = 0;
 193         file.f_count = 1;
 194         file.f_inode = inode;
 195         file.f_pos = 0;
 196         file.f_reada = 0;
 197         file.f_op = inode->i_op->default_file_ops;
 198         if (file.f_op->open)
 199                 if (file.f_op->open(inode,&file))
 200                         goto end_coredump;
 201         if (!file.f_op->write)
 202                 goto close_coredump;
 203         has_dumped = 1;
 204 /* changed the size calculations - should hopefully work better. lbt */
 205         dump.magic = CMAGIC;
 206         dump.start_code = 0;
 207         dump.start_stack = regs->esp & ~(PAGE_SIZE - 1);
 208         dump.u_tsize = ((unsigned long) current->mm->end_code) >> 12;
 209         dump.u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> 12;
 210         dump.u_dsize -= dump.u_tsize;
 211         dump.u_ssize = 0;
 212         for(i=0; i<8; i++) dump.u_debugreg[i] = current->debugreg[i];  
 213         if (dump.start_stack < TASK_SIZE)
 214                 dump.u_ssize = ((unsigned long) (TASK_SIZE - dump.start_stack)) >> 12;
 215 /* If the size of the dump file exceeds the rlimit, then see what would happen
 216    if we wrote the stack, but not the data area.  */
 217         if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
 218             current->rlim[RLIMIT_CORE].rlim_cur)
 219                 dump.u_dsize = 0;
 220 /* Make sure we have enough room to write the stack and data areas. */
 221         if ((dump.u_ssize+1) * PAGE_SIZE >
 222             current->rlim[RLIMIT_CORE].rlim_cur)
 223                 dump.u_ssize = 0;
 224         strncpy(dump.u_comm, current->comm, sizeof(current->comm));
 225         dump.u_ar0 = (struct pt_regs *)(((int)(&dump.regs)) -((int)(&dump)));
 226         dump.signal = signr;
 227         dump.regs = *regs;
 228 /* Flag indicating the math stuff is valid. We don't support this for the
 229    soft-float routines yet */
 230         if (hard_math) {
 231                 if ((dump.u_fpvalid = current->used_math) != 0) {
 232                         if (last_task_used_math == current)
 233                                 __asm__("clts ; fnsave %0": :"m" (dump.i387));
 234                         else
 235                                 memcpy(&dump.i387,&current->tss.i387.hard,sizeof(dump.i387));
 236                 }
 237         } else {
 238                 /* we should dump the emulator state here, but we need to
 239                    convert it into standard 387 format first.. */
 240                 dump.u_fpvalid = 0;
 241         }
 242         set_fs(KERNEL_DS);
 243 /* struct user */
 244         DUMP_WRITE(&dump,sizeof(dump));
 245 /* Now dump all of the user data.  Include malloced stuff as well */
 246         DUMP_SEEK(PAGE_SIZE);
 247 /* now we start writing out the user space info */
 248         set_fs(USER_DS);
 249 /* Dump the data area */
 250         if (dump.u_dsize != 0) {
 251                 dump_start = dump.u_tsize << 12;
 252                 dump_size = dump.u_dsize << 12;
 253                 DUMP_WRITE(dump_start,dump_size);
 254         };
 255 /* Now prepare to dump the stack area */
 256         if (dump.u_ssize != 0) {
 257                 dump_start = dump.start_stack;
 258                 dump_size = dump.u_ssize << 12;
 259                 DUMP_WRITE(dump_start,dump_size);
 260         };
 261 /* Finally dump the task struct.  Not be used by gdb, but could be useful */
 262         set_fs(KERNEL_DS);
 263         DUMP_WRITE(current,sizeof(*current));
 264 close_coredump:
 265         if (file.f_op->release)
 266                 file.f_op->release(inode,&file);
 267 end_coredump:
 268         set_fs(fs);
 269         iput(inode);
 270         return has_dumped;
 271 }
 272 
 273 /*
 274  * Note that a shared library must be both readable and executable due to
 275  * security reasons.
 276  *
 277  * Also note that we take the address to load from from the file itself.
 278  */
 279 asmlinkage int sys_uselib(const char * library)
     /* [previous][next][first][last][top][bottom][index][help] */
 280 {
 281         int fd, retval;
 282         struct file * file;
 283         struct linux_binfmt * fmt;
 284 
 285         fd = sys_open(library, 0, 0);
 286         if (fd < 0)
 287                 return fd;
 288         file = current->files->fd[fd];
 289         retval = -ENOEXEC;
 290         if (file && file->f_inode && file->f_op && file->f_op->read) {
 291                 for (fmt = formats ; fmt ; fmt = fmt->next) {
 292                         int (*fn)(int) = fmt->load_shlib;
 293                         if (!fn)
 294                                 break;
 295                         retval = fn(fd);
 296                         if (retval != -ENOEXEC)
 297                                 break;
 298                 }
 299         }
 300         sys_close(fd);
 301         return retval;
 302 }
 303 
 304 /*
 305  * create_tables() parses the env- and arg-strings in new user
 306  * memory and creates the pointer tables from them, and puts their
 307  * addresses on the "stack", returning the new stack pointer value.
 308  */
 309 unsigned long * create_tables(char * p,int argc,int envc,int ibcs)
     /* [previous][next][first][last][top][bottom][index][help] */
 310 {
 311         unsigned long *argv,*envp;
 312         unsigned long * sp;
 313         struct vm_area_struct *mpnt;
 314 
 315         mpnt = (struct vm_area_struct *)kmalloc(sizeof(*mpnt), GFP_KERNEL);
 316         if (mpnt) {
 317                 mpnt->vm_task = current;
 318                 mpnt->vm_start = PAGE_MASK & (unsigned long) p;
 319                 mpnt->vm_end = TASK_SIZE;
 320                 mpnt->vm_page_prot = PAGE_PRIVATE|PAGE_DIRTY;
 321                 mpnt->vm_share = NULL;
 322                 mpnt->vm_inode = NULL;
 323                 mpnt->vm_offset = 0;
 324                 mpnt->vm_ops = NULL;
 325                 insert_vm_struct(current, mpnt);
 326                 current->mm->stk_vma = mpnt;
 327         }
 328         sp = (unsigned long *) (0xfffffffc & (unsigned long) p);
 329         sp -= envc+1;
 330         envp = sp;
 331         sp -= argc+1;
 332         argv = sp;
 333         if (!ibcs) {
 334                 put_fs_long((unsigned long)envp,--sp);
 335                 put_fs_long((unsigned long)argv,--sp);
 336         }
 337         put_fs_long((unsigned long)argc,--sp);
 338         current->mm->arg_start = (unsigned long) p;
 339         while (argc-->0) {
 340                 put_fs_long((unsigned long) p,argv++);
 341                 while (get_fs_byte(p++)) /* nothing */ ;
 342         }
 343         put_fs_long(0,argv);
 344         current->mm->arg_end = current->mm->env_start = (unsigned long) p;
 345         while (envc-->0) {
 346                 put_fs_long((unsigned long) p,envp++);
 347                 while (get_fs_byte(p++)) /* nothing */ ;
 348         }
 349         put_fs_long(0,envp);
 350         current->mm->env_end = (unsigned long) p;
 351         return sp;
 352 }
 353 
 354 /*
 355  * count() counts the number of arguments/envelopes
 356  */
 357 static int count(char ** argv)
     /* [previous][next][first][last][top][bottom][index][help] */
 358 {
 359         int i=0;
 360         char ** tmp;
 361 
 362         if ((tmp = argv) != 0)
 363                 while (get_fs_long((unsigned long *) (tmp++)))
 364                         i++;
 365 
 366         return i;
 367 }
 368 
 369 /*
 370  * 'copy_string()' copies argument/envelope strings from user
 371  * memory to free pages in kernel mem. These are in a format ready
 372  * to be put directly into the top of new user memory.
 373  *
 374  * Modified by TYT, 11/24/91 to add the from_kmem argument, which specifies
 375  * whether the string and the string array are from user or kernel segments:
 376  * 
 377  * from_kmem     argv *        argv **
 378  *    0          user space    user space
 379  *    1          kernel space  user space
 380  *    2          kernel space  kernel space
 381  * 
 382  * We do this by playing games with the fs segment register.  Since it
 383  * it is expensive to load a segment register, we try to avoid calling
 384  * set_fs() unless we absolutely have to.
 385  */
 386 unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
     /* [previous][next][first][last][top][bottom][index][help] */
 387                 unsigned long p, int from_kmem)
 388 {
 389         char *tmp, *pag = NULL;
 390         int len, offset = 0;
 391         unsigned long old_fs, new_fs;
 392 
 393         if (!p)
 394                 return 0;       /* bullet-proofing */
 395         new_fs = get_ds();
 396         old_fs = get_fs();
 397         if (from_kmem==2)
 398                 set_fs(new_fs);
 399         while (argc-- > 0) {
 400                 if (from_kmem == 1)
 401                         set_fs(new_fs);
 402                 if (!(tmp = (char *)get_fs_long(((unsigned long *)argv)+argc)))
 403                         panic("VFS: argc is wrong");
 404                 if (from_kmem == 1)
 405                         set_fs(old_fs);
 406                 len=0;          /* remember zero-padding */
 407                 do {
 408                         len++;
 409                 } while (get_fs_byte(tmp++));
 410                 if (p < len) {  /* this shouldn't happen - 128kB */
 411                         set_fs(old_fs);
 412                         return 0;
 413                 }
 414                 while (len) {
 415                         --p; --tmp; --len;
 416                         if (--offset < 0) {
 417                                 offset = p % PAGE_SIZE;
 418                                 if (from_kmem==2)
 419                                         set_fs(old_fs);
 420                                 if (!(pag = (char *) page[p/PAGE_SIZE]) &&
 421                                     !(pag = (char *) page[p/PAGE_SIZE] =
 422                                       (unsigned long *) get_free_page(GFP_USER))) 
 423                                         return 0;
 424                                 if (from_kmem==2)
 425                                         set_fs(new_fs);
 426 
 427                         }
 428                         *(pag + offset) = get_fs_byte(tmp);
 429                 }
 430         }
 431         if (from_kmem==2)
 432                 set_fs(old_fs);
 433         return p;
 434 }
 435 
 436 unsigned long change_ldt(unsigned long text_size,unsigned long * page)
     /* [previous][next][first][last][top][bottom][index][help] */
 437 {
 438         unsigned long code_limit,data_limit,code_base,data_base;
 439         int i;
 440 
 441         code_limit = TASK_SIZE;
 442         data_limit = TASK_SIZE;
 443         code_base = data_base = 0;
 444         current->mm->start_code = code_base;
 445         data_base += data_limit;
 446         for (i=MAX_ARG_PAGES-1 ; i>=0 ; i--) {
 447                 data_base -= PAGE_SIZE;
 448                 if (page[i]) {
 449                         current->mm->rss++;
 450                         put_dirty_page(current,page[i],data_base);
 451                 }
 452         }
 453         return data_limit;
 454 }
 455 
 456 /*
 457  * Read in the complete executable. This is used for "-N" files
 458  * that aren't on a block boundary, and for files on filesystems
 459  * without bmap support.
 460  */
 461 int read_exec(struct inode *inode, unsigned long offset,
     /* [previous][next][first][last][top][bottom][index][help] */
 462         char * addr, unsigned long count)
 463 {
 464         struct file file;
 465         int result = -ENOEXEC;
 466 
 467         if (!inode->i_op || !inode->i_op->default_file_ops)
 468                 goto end_readexec;
 469         file.f_mode = 1;
 470         file.f_flags = 0;
 471         file.f_count = 1;
 472         file.f_inode = inode;
 473         file.f_pos = 0;
 474         file.f_reada = 0;
 475         file.f_op = inode->i_op->default_file_ops;
 476         if (file.f_op->open)
 477                 if (file.f_op->open(inode,&file))
 478                         goto end_readexec;
 479         if (!file.f_op || !file.f_op->read)
 480                 goto close_readexec;
 481         if (file.f_op->lseek) {
 482                 if (file.f_op->lseek(inode,&file,offset,0) != offset)
 483                         goto close_readexec;
 484         } else
 485                 file.f_pos = offset;
 486         if (get_fs() == USER_DS) {
 487                 result = verify_area(VERIFY_WRITE, addr, count);
 488                 if (result)
 489                         goto close_readexec;
 490         }
 491         result = file.f_op->read(inode, &file, addr, count);
 492 close_readexec:
 493         if (file.f_op->release)
 494                 file.f_op->release(inode,&file);
 495 end_readexec:
 496         return result;
 497 }
 498 
 499 
 500 /*
 501  * This function flushes out all traces of the currently running executable so
 502  * that a new one can be started
 503  */
 504 
 505 void flush_old_exec(struct linux_binprm * bprm)
     /* [previous][next][first][last][top][bottom][index][help] */
 506 {
 507         int i;
 508         int ch;
 509         char * name;
 510         struct vm_area_struct * mpnt, *mpnt1;
 511 
 512         current->dumpable = 1;
 513         name = bprm->filename;
 514         for (i=0; (ch = *(name++)) != '\0';) {
 515                 if (ch == '/')
 516                         i = 0;
 517                 else
 518                         if (i < 15)
 519                                 current->comm[i++] = ch;
 520         }
 521         current->comm[i] = '\0';
 522         if (current->shm)
 523                 shm_exit();
 524         if (current->executable) {
 525                 iput(current->executable);
 526                 current->executable = NULL;
 527         }
 528         /* Release all of the old mmap stuff. */
 529 
 530         mpnt = current->mm->mmap;
 531         current->mm->mmap = NULL;
 532         current->mm->stk_vma = NULL;
 533         while (mpnt) {
 534                 mpnt1 = mpnt->vm_next;
 535                 if (mpnt->vm_ops && mpnt->vm_ops->close)
 536                         mpnt->vm_ops->close(mpnt);
 537                 kfree(mpnt);
 538                 mpnt = mpnt1;
 539         }
 540 
 541         /* Flush the old ldt stuff... */
 542         if (current->ldt) {
 543                 free_page((unsigned long) current->ldt);
 544                 current->ldt = NULL;
 545                 for (i=1 ; i<NR_TASKS ; i++) {
 546                         if (task[i] == current)  {
 547                                 set_ldt_desc(gdt+(i<<1)+
 548                                              FIRST_LDT_ENTRY,&default_ldt, 1);
 549                                 load_ldt(i);
 550                         }
 551                 }       
 552         }
 553 
 554         for (i=0 ; i<8 ; i++) current->debugreg[i] = 0;
 555 
 556         if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || 
 557             !permission(bprm->inode,MAY_READ))
 558                 current->dumpable = 0;
 559         current->signal = 0;
 560         for (i=0 ; i<32 ; i++) {
 561                 current->sigaction[i].sa_mask = 0;
 562                 current->sigaction[i].sa_flags = 0;
 563                 if (current->sigaction[i].sa_handler != SIG_IGN)
 564                         current->sigaction[i].sa_handler = NULL;
 565         }
 566         for (i=0 ; i<NR_OPEN ; i++)
 567                 if (FD_ISSET(i,&current->files->close_on_exec))
 568                         sys_close(i);
 569         FD_ZERO(&current->files->close_on_exec);
 570         clear_page_tables(current);
 571         if (last_task_used_math == current)
 572                 last_task_used_math = NULL;
 573         current->used_math = 0;
 574         current->personality = 0;
 575         current->lcall7 = no_lcall7;
 576         current->signal_map = current->signal_invmap = ident_map;
 577 }
 578 
 579 /*
 580  * sys_execve() executes a new program.
 581  */
 582 int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 583 {
 584         struct linux_binprm bprm;
 585         struct linux_binfmt * fmt;
 586         unsigned long old_fs;
 587         int i;
 588         int retval;
 589         int sh_bang = 0;
 590 
 591         if (regs->cs != USER_CS)
 592                 return -EINVAL;
 593         bprm.p = PAGE_SIZE*MAX_ARG_PAGES-4;
 594         for (i=0 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */
 595                 bprm.page[i] = 0;
 596         retval = open_namei(filename, 0, 0, &bprm.inode, NULL);
 597         if (retval)
 598                 return retval;
 599         bprm.filename = filename;
 600         bprm.argc = count(argv);
 601         bprm.envc = count(envp);
 602         
 603 restart_interp:
 604         if (!S_ISREG(bprm.inode->i_mode)) {     /* must be regular file */
 605                 retval = -EACCES;
 606                 goto exec_error2;
 607         }
 608         if (IS_NOEXEC(bprm.inode)) {            /* FS mustn't be mounted noexec */
 609                 retval = -EPERM;
 610                 goto exec_error2;
 611         }
 612         if (!bprm.inode->i_sb) {
 613                 retval = -EACCES;
 614                 goto exec_error2;
 615         }
 616         i = bprm.inode->i_mode;
 617         if (IS_NOSUID(bprm.inode) && (((i & S_ISUID) && bprm.inode->i_uid != current->
 618             euid) || ((i & S_ISGID) && !in_group_p(bprm.inode->i_gid))) &&
 619             !suser()) {
 620                 retval = -EPERM;
 621                 goto exec_error2;
 622         }
 623         /* make sure we don't let suid, sgid files be ptraced. */
 624         if (current->flags & PF_PTRACED) {
 625                 bprm.e_uid = current->euid;
 626                 bprm.e_gid = current->egid;
 627         } else {
 628                 bprm.e_uid = (i & S_ISUID) ? bprm.inode->i_uid : current->euid;
 629                 bprm.e_gid = (i & S_ISGID) ? bprm.inode->i_gid : current->egid;
 630         }
 631         if (current->euid == bprm.inode->i_uid)
 632                 i >>= 6;
 633         else if (in_group_p(bprm.inode->i_gid))
 634                 i >>= 3;
 635         if (!(i & 1) &&
 636             !((bprm.inode->i_mode & 0111) && suser())) {
 637                 retval = -EACCES;
 638                 goto exec_error2;
 639         }
 640         memset(bprm.buf,0,sizeof(bprm.buf));
 641         old_fs = get_fs();
 642         set_fs(get_ds());
 643         retval = read_exec(bprm.inode,0,bprm.buf,128);
 644         set_fs(old_fs);
 645         if (retval < 0)
 646                 goto exec_error2;
 647         if ((bprm.buf[0] == '#') && (bprm.buf[1] == '!') && (!sh_bang)) {
 648                 /*
 649                  * This section does the #! interpretation.
 650                  * Sorta complicated, but hopefully it will work.  -TYT
 651                  */
 652 
 653                 char *cp, *interp, *i_name, *i_arg;
 654 
 655                 iput(bprm.inode);
 656                 bprm.buf[127] = '\0';
 657                 if ((cp = strchr(bprm.buf, '\n')) == NULL)
 658                         cp = bprm.buf+127;
 659                 *cp = '\0';
 660                 while (cp > bprm.buf) {
 661                         cp--;
 662                         if ((*cp == ' ') || (*cp == '\t'))
 663                                 *cp = '\0';
 664                         else
 665                                 break;
 666                 }
 667                 for (cp = bprm.buf+2; (*cp == ' ') || (*cp == '\t'); cp++);
 668                 if (!cp || *cp == '\0') {
 669                         retval = -ENOEXEC; /* No interpreter name found */
 670                         goto exec_error1;
 671                 }
 672                 interp = i_name = cp;
 673                 i_arg = 0;
 674                 for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) {
 675                         if (*cp == '/')
 676                                 i_name = cp+1;
 677                 }
 678                 while ((*cp == ' ') || (*cp == '\t'))
 679                         *cp++ = '\0';
 680                 if (*cp)
 681                         i_arg = cp;
 682                 /*
 683                  * OK, we've parsed out the interpreter name and
 684                  * (optional) argument.
 685                  */
 686                 if (sh_bang++ == 0) {
 687                         bprm.p = copy_strings(bprm.envc, envp, bprm.page, bprm.p, 0);
 688                         bprm.p = copy_strings(--bprm.argc, argv+1, bprm.page, bprm.p, 0);
 689                 }
 690                 /*
 691                  * Splice in (1) the interpreter's name for argv[0]
 692                  *           (2) (optional) argument to interpreter
 693                  *           (3) filename of shell script
 694                  *
 695                  * This is done in reverse order, because of how the
 696                  * user environment and arguments are stored.
 697                  */
 698                 bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p, 2);
 699                 bprm.argc++;
 700                 if (i_arg) {
 701                         bprm.p = copy_strings(1, &i_arg, bprm.page, bprm.p, 2);
 702                         bprm.argc++;
 703                 }
 704                 bprm.p = copy_strings(1, &i_name, bprm.page, bprm.p, 2);
 705                 bprm.argc++;
 706                 if (!bprm.p) {
 707                         retval = -E2BIG;
 708                         goto exec_error1;
 709                 }
 710                 /*
 711                  * OK, now restart the process with the interpreter's inode.
 712                  * Note that we use open_namei() as the name is now in kernel
 713                  * space, and we don't need to copy it.
 714                  */
 715                 retval = open_namei(interp, 0, 0, &bprm.inode, NULL);
 716                 if (retval)
 717                         goto exec_error1;
 718                 goto restart_interp;
 719         }
 720         if (!sh_bang) {
 721                 bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p,0);
 722                 bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p,0);
 723                 if (!bprm.p) {
 724                         retval = -E2BIG;
 725                         goto exec_error2;
 726                 }
 727         }
 728 
 729         bprm.sh_bang = sh_bang;
 730         for (fmt = formats ; fmt ; fmt = fmt->next) {
 731                 int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
 732                 if (!fn)
 733                         break;
 734                 retval = fn(&bprm, regs);
 735                 if (retval == 0) {
 736                         iput(bprm.inode);
 737                         current->did_exec = 1;
 738                         return 0;
 739                 }
 740                 if (retval != -ENOEXEC)
 741                         break;
 742         }
 743 exec_error2:
 744         iput(bprm.inode);
 745 exec_error1:
 746         for (i=0 ; i<MAX_ARG_PAGES ; i++)
 747                 free_page(bprm.page[i]);
 748         return(retval);
 749 }
 750 
 751 /*
 752  * sys_execve() executes a new program.
 753  */
 754 asmlinkage int sys_execve(struct pt_regs regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 755 {
 756         int error;
 757         char * filename;
 758 
 759         error = getname((char *) regs.ebx, &filename);
 760         if (error)
 761                 return error;
 762         error = do_execve(filename, (char **) regs.ecx, (char **) regs.edx, &regs);
 763         putname(filename);
 764         return error;
 765 }
 766 
 767 /*
 768  * signal mapping: this is the default identity mapping used for normal
 769  * linux binaries (it's both the reverse and the normal map, of course)
 770  */
 771 unsigned long ident_map[33] = {
 772         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
 773         13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
 774         23, 24, 25, 26, 27, 28, 29, 30, 31, 32
 775 };
 776 
 777 /*
 778  * default lcall7 handler.. The native linux stuff doesn't
 779  * use it at all, so we just segfault on it.
 780  */
 781 asmlinkage void no_lcall7(struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 782 {
 783         send_sig(SIGSEGV, current, 1);
 784 }
 785 
 786 static void set_brk(unsigned long start, unsigned long end)
     /* [previous][next][first][last][top][bottom][index][help] */
 787 {
 788         start = PAGE_ALIGN(start);
 789         end = PAGE_ALIGN(end);
 790         if (end <= start)
 791                 return;
 792         do_mmap(NULL, start, end - start,
 793                 PROT_READ | PROT_WRITE | PROT_EXEC,
 794                 MAP_FIXED | MAP_PRIVATE, 0);
 795 }
 796 
 797 /*
 798  * These are the functions used to load a.out style executables and shared
 799  * libraries.  There is no binary dependent code anywhere else.
 800  */
 801 
 802 static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 803 {
 804         struct exec ex;
 805         struct file * file;
 806         int fd, error;
 807         unsigned long p = bprm->p;
 808 
 809         ex = *((struct exec *) bprm->buf);              /* exec-header */
 810         if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && 
 811              N_MAGIC(ex) != QMAGIC) ||
 812             ex.a_trsize || ex.a_drsize ||
 813             bprm->inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) {
 814                 return -ENOEXEC;
 815         }
 816 
 817         if (N_MAGIC(ex) == ZMAGIC &&
 818             (N_TXTOFF(ex) < bprm->inode->i_sb->s_blocksize)) {
 819                 printk("N_TXTOFF < BLOCK_SIZE. Please convert binary.");
 820                 return -ENOEXEC;
 821         }
 822 
 823         if (N_TXTOFF(ex) != BLOCK_SIZE && N_MAGIC(ex) == ZMAGIC) {
 824                 printk("N_TXTOFF != BLOCK_SIZE. See a.out.h.");
 825                 return -ENOEXEC;
 826         }
 827         
 828         /* OK, This is the point of no return */
 829         flush_old_exec(bprm);
 830 
 831         current->mm->brk = ex.a_bss +
 832                 (current->mm->start_brk =
 833                 (current->mm->end_data = ex.a_data +
 834                 (current->mm->end_code = ex.a_text +
 835                 (current->mm->start_code = N_TXTADDR(ex)))));
 836         current->mm->rss = 0;
 837         current->mm->mmap = NULL;
 838         current->executable = NULL;  /* for OMAGIC files */
 839         current->suid = current->euid = bprm->e_uid;
 840         current->sgid = current->egid = bprm->e_gid;
 841         if (N_MAGIC(ex) == OMAGIC) {
 842                 do_mmap(NULL, 0, ex.a_text+ex.a_data,
 843                         PROT_READ|PROT_WRITE|PROT_EXEC,
 844                         MAP_FIXED|MAP_PRIVATE, 0);
 845                 read_exec(bprm->inode, 32, (char *) 0, ex.a_text+ex.a_data);
 846         } else {
 847                 if (ex.a_text & 0xfff || ex.a_data & 0xfff)
 848                         printk("%s: executable not page aligned\n", current->comm);
 849                 
 850                 fd = open_inode(bprm->inode, O_RDONLY);
 851                 
 852                 if (fd < 0)
 853                         return fd;
 854                 file = current->files->fd[fd];
 855                 if (!file->f_op || !file->f_op->mmap) {
 856                         sys_close(fd);
 857                         do_mmap(NULL, 0, ex.a_text+ex.a_data,
 858                                 PROT_READ|PROT_WRITE|PROT_EXEC,
 859                                 MAP_FIXED|MAP_PRIVATE, 0);
 860                         read_exec(bprm->inode, N_TXTOFF(ex),
 861                                   (char *) N_TXTADDR(ex), ex.a_text+ex.a_data);
 862                         goto beyond_if;
 863                 }
 864                 error = do_mmap(file, N_TXTADDR(ex), ex.a_text,
 865                                 PROT_READ | PROT_EXEC,
 866                                 MAP_FIXED | MAP_SHARED, N_TXTOFF(ex));
 867 
 868                 if (error != N_TXTADDR(ex)) {
 869                         sys_close(fd);
 870                         send_sig(SIGSEGV, current, 0);
 871                         return 0;
 872                 };
 873                 
 874                 error = do_mmap(file, N_TXTADDR(ex) + ex.a_text, ex.a_data,
 875                                 PROT_READ | PROT_WRITE | PROT_EXEC,
 876                                 MAP_FIXED | MAP_PRIVATE, N_TXTOFF(ex) + ex.a_text);
 877                 sys_close(fd);
 878                 if (error != N_TXTADDR(ex) + ex.a_text) {
 879                         send_sig(SIGSEGV, current, 0);
 880                         return 0;
 881                 };
 882                 current->executable = bprm->inode;
 883                 bprm->inode->i_count++;
 884         }
 885 beyond_if:
 886         set_brk(current->mm->start_brk, current->mm->brk);
 887         
 888         p += change_ldt(ex.a_text,bprm->page);
 889         p -= MAX_ARG_PAGES*PAGE_SIZE;
 890         p = (unsigned long) create_tables((char *)p,bprm->argc,bprm->envc,0);
 891         current->mm->start_stack = p;
 892         regs->eip = ex.a_entry;         /* eip, magic happens :-) */
 893         regs->esp = p;                  /* stack pointer */
 894         if (current->flags & PF_PTRACED)
 895                 send_sig(SIGTRAP, current, 0);
 896         return 0;
 897 }
 898 
 899 
 900 static int load_aout_library(int fd)
     /* [previous][next][first][last][top][bottom][index][help] */
 901 {
 902         struct file * file;
 903         struct exec ex;
 904         struct  inode * inode;
 905         unsigned int len;
 906         unsigned int bss;
 907         unsigned int start_addr;
 908         int error;
 909         
 910         file = current->files->fd[fd];
 911         inode = file->f_inode;
 912         
 913         set_fs(KERNEL_DS);
 914         if (file->f_op->read(inode, file, (char *) &ex, sizeof(ex)) != sizeof(ex)) {
 915                 return -EACCES;
 916         }
 917         set_fs(USER_DS);
 918         
 919         /* We come in here for the regular a.out style of shared libraries */
 920         if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || ex.a_trsize ||
 921             ex.a_drsize || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) ||
 922             inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) {
 923                 return -ENOEXEC;
 924         }
 925         if (N_MAGIC(ex) == ZMAGIC && N_TXTOFF(ex) && 
 926             (N_TXTOFF(ex) < inode->i_sb->s_blocksize)) {
 927                 printk("N_TXTOFF < BLOCK_SIZE. Please convert library\n");
 928                 return -ENOEXEC;
 929         }
 930         
 931         if (N_FLAGS(ex)) return -ENOEXEC;
 932 
 933         /* For  QMAGIC, the starting address is 0x20 into the page.  We mask
 934            this off to get the starting address for the page */
 935 
 936         start_addr =  ex.a_entry & 0xfffff000;
 937 
 938         /* Now use mmap to map the library into memory. */
 939         error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
 940                         PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE,
 941                         N_TXTOFF(ex));
 942         if (error != start_addr)
 943                 return error;
 944         len = PAGE_ALIGN(ex.a_text + ex.a_data);
 945         bss = ex.a_text + ex.a_data + ex.a_bss;
 946         if (bss > len)
 947                 do_mmap(NULL, start_addr + len, bss-len,
 948                         PROT_READ|PROT_WRITE|PROT_EXEC,
 949                         MAP_PRIVATE|MAP_FIXED, 0);
 950         return 0;
 951 }

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