set_mm_counter(current->mm, rss, 0); 
static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs){	struct file *interpreter = NULL; /* to shut gcc up */ 	unsigned long load_addr = 0, load_bias = 0;	int load_addr_set = 0;	char * elf_interpreter = NULL;	unsigned int interpreter_type = INTERPRETER_NONE;	unsigned char ibcs2_interpreter = 0;	unsigned long error;	struct elf_phdr * elf_ppnt, *elf_phdata;	unsigned long elf_bss, elf_brk;	int elf_exec_fileno;	int retval, i;	unsigned int size;	unsigned long elf_entry, interp_load_addr = 0;	unsigned long start_code, end_code, start_data, end_data;	unsigned long reloc_func_desc = 0;	char passed_fileno[6];	struct files_struct *files;	int have_pt_gnu_stack, executable_stack = EXSTACK_DEFAULT;	unsigned long def_flags = 0;	struct {		struct elfhdr elf_ex;		struct elfhdr interp_elf_ex;  		struct exec interp_ex;	} *loc;	loc = kmalloc(sizeof(*loc), GFP_KERNEL);	if (!loc) {		retval = -ENOMEM;		goto out_ret;	}		/* Get the exec-header */	loc->elf_ex = *((struct elfhdr *) bprm->buf);	retval = -ENOEXEC;	/* First of all, some simple consistency checks */	if (memcmp(loc->elf_ex.e_ident, ELFMAG, SELFMAG) != 0)		goto out;	if (loc->elf_ex.e_type != ET_EXEC && loc->elf_ex.e_type != ET_DYN)		goto out;	if (!elf_check_arch(&loc->elf_ex))		goto out;	if (!bprm->file->f_op||!bprm->file->f_op->mmap)		goto out;	/* Now read in all of the header information */	if (loc->elf_ex.e_phentsize != sizeof(struct elf_phdr))		goto out;	if (loc->elf_ex.e_phnum < 1 ||	 	loc->elf_ex.e_phnum > 65536U / sizeof(struct elf_phdr))		goto out;	size = loc->elf_ex.e_phnum * sizeof(struct elf_phdr);	retval = -ENOMEM;	elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL);	if (!elf_phdata)		goto out;	retval = kernel_read(bprm->file, loc->elf_ex.e_phoff, (char *) elf_phdata, size);	if (retval != size) {		if (retval >= 0)			retval = -EIO;		goto out_free_ph;	}	files = current->files;		/* Refcounted so ok */	retval = unshare_files();	if (retval < 0)		goto out_free_ph;	if (files == current->files) {		put_files_struct(files);		files = NULL;	}	/* exec will make our files private anyway, but for the a.out	   loader stuff we need to do it earlier */	retval = get_unused_fd();	if (retval < 0)		goto out_free_fh;	get_file(bprm->file);	fd_install(elf_exec_fileno = retval, bprm->file);	elf_ppnt = elf_phdata;	elf_bss = 0;	elf_brk = 0;	start_code = ~0UL;	end_code = 0;	start_data = 0;	end_data = 0;	for (i = 0; i < loc->elf_ex.e_phnum; i++) {		if (elf_ppnt->p_type == PT_INTERP) {			/* This is the program interpreter used for			 * shared libraries - for now assume that this			 * is an a.out format binary			 */			retval = -ENOEXEC;			if (elf_ppnt->p_filesz > PATH_MAX || 			    elf_ppnt->p_filesz < 2)				goto out_free_file;			retval = -ENOMEM;			elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz,							   GFP_KERNEL);			if (!elf_interpreter)				goto out_free_file;			retval = kernel_read(bprm->file, elf_ppnt->p_offset,					   elf_interpreter,					   elf_ppnt->p_filesz);			if (retval != elf_ppnt->p_filesz) {				if (retval >= 0)					retval = -EIO;				goto out_free_interp;			}			/* make sure path is NULL terminated */			retval = -ENOEXEC;			if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0')				goto out_free_interp;			/* If the program interpreter is one of these two,			 * then assume an iBCS2 image. Otherwise assume			 * a native linux image.			 */			if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||			    strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0)				ibcs2_interpreter = 1;			/*			 * The early SET_PERSONALITY here is so that the lookup			 * for the interpreter happens in the namespace of the 			 * to-be-execed image.  SET_PERSONALITY can select an			 * alternate root.			 *			 * However, SET_PERSONALITY is NOT allowed to switch			 * this task into the new images's memory mapping			 * policy - that is, TASK_SIZE must still evaluate to			 * that which is appropriate to the execing application.			 * This is because exit_mmap() needs to have TASK_SIZE			 * evaluate to the size of the old image.			 *			 * So if (say) a 64-bit application is execing a 32-bit			 * application it is the architecture's responsibility			 * to defer changing the value of TASK_SIZE until the			 * switch really is going to happen - do this in			 * flush_thread().	- akpm			 */			SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);			interpreter = open_exec(elf_interpreter);			retval = PTR_ERR(interpreter);			if (IS_ERR(interpreter))				goto out_free_interp;			retval = kernel_read(interpreter, 0, bprm->buf, BINPRM_BUF_SIZE);			if (retval != BINPRM_BUF_SIZE) {				if (retval >= 0)					retval = -EIO;				goto out_free_dentry;			}			/* Get the exec headers */			loc->interp_ex = *((struct exec *) bprm->buf);			loc->interp_elf_ex = *((struct elfhdr *) bprm->buf);			break;		}		elf_ppnt++;	}	elf_ppnt = elf_phdata;	for (i = 0; i < loc->elf_ex.e_phnum; i++, elf_ppnt++)		if (elf_ppnt->p_type == PT_GNU_STACK) {			if (elf_ppnt->p_flags & PF_X)				executable_stack = EXSTACK_ENABLE_X;			else				executable_stack = EXSTACK_DISABLE_X;			break;		}	have_pt_gnu_stack = (i < loc->elf_ex.e_phnum);	/* Some simple consistency checks for the interpreter */	if (elf_interpreter) {		interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;		/* Now figure out which format our binary is */		if ((N_MAGIC(loc->interp_ex) != OMAGIC) &&		    (N_MAGIC(loc->interp_ex) != ZMAGIC) &&		    (N_MAGIC(loc->interp_ex) != QMAGIC))			interpreter_type = INTERPRETER_ELF;		if (memcmp(loc->interp_elf_ex.e_ident, ELFMAG, SELFMAG) != 0)			interpreter_type &= ~INTERPRETER_ELF;		retval = -ELIBBAD;		if (!interpreter_type)			goto out_free_dentry;		/* Make sure only one type was selected */		if ((interpreter_type & INTERPRETER_ELF) &&		     interpreter_type != INTERPRETER_ELF) {	     		// FIXME - ratelimit this before re-enabling			// printk(KERN_WARNING "ELF: Ambiguous type, using ELF\n");			interpreter_type = INTERPRETER_ELF;		}		/* Verify the interpreter has a valid arch */		if ((interpreter_type == INTERPRETER_ELF) &&		    !elf_check_arch(&loc->interp_elf_ex))			goto out_free_dentry;	} else {		/* Executables without an interpreter also need a personality  */		SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);	}	/* OK, we are done with that, now set up the arg stuff,	   and then start this sucker up */	if ((!bprm->sh_bang) && (interpreter_type == INTERPRETER_AOUT)) {		char *passed_p = passed_fileno;		sprintf(passed_fileno, "%d", elf_exec_fileno);		if (elf_interpreter) {			retval = copy_strings_kernel(1, &passed_p, bprm);			if (retval)				goto out_free_dentry; 			bprm->argc++;		}	}	/* Flush all traces of the currently running executable */	retval = flush_old_exec(bprm);	if (retval)		goto out_free_dentry;	/* Discard our unneeded old files struct */	if (files) {		steal_locks(files);		put_files_struct(files);		files = NULL;	}	/* OK, This is the point of no return */	current->mm->start_data = 0;	current->mm->end_data = 0;	current->mm->end_code = 0;	current->mm->mmap = NULL;	current->flags &= ~PF_FORKNOEXEC;	current->mm->def_flags = def_flags;	/* Do this immediately, since STACK_TOP as used in setup_arg_pages	   may depend on the personality.  */	SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);	if (elf_read_implies_exec(loc->elf_ex, executable_stack))		current->personality |= READ_IMPLIES_EXEC;	if ( !(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)		current->flags |= PF_RANDOMIZE;	arch_pick_mmap_layout(current->mm);	/* Do this so that we can load the interpreter, if need be.  We will	   change some of these later */	set_mm_counter(current->mm, rss, 0);	current->mm->free_area_cache = current->mm->mmap_base;	current->mm->cached_hole_size = 0;	retval = setup_arg_pages(bprm, randomize_stack_top(STACK_TOP),				 executable_stack);	if (retval < 0) {		send_sig(SIGKILL, current, 0);		goto out_free_dentry;	}		current->mm->start_stack = bprm->p;	/* Now we do a little grungy work by mmaping the ELF image into	   the correct location in memory.  At this point, we assume that	   the image should be loaded at fixed address, not at a variable	   address. */	for(i = 0, elf_ppnt = elf_phdata; i < loc->elf_ex.e_phnum; i++, elf_ppnt++) {		int elf_prot = 0, elf_flags;		unsigned long k, vaddr;		if (elf_ppnt->p_type != PT_LOAD)			continue;		if (unlikely (elf_brk > elf_bss)) {			unsigned long nbyte;	            			/* There was a PT_LOAD segment with p_memsz > p_filesz			   before this one. Map anonymous pages, if needed,			   and clear the area.  */			retval = set_brk (elf_bss + load_bias,					  elf_brk + load_bias);			if (retval) {				send_sig(SIGKILL, current, 0);				goto out_free_dentry;			}			nbyte = ELF_PAGEOFFSET(elf_bss);			if (nbyte) {				nbyte = ELF_MIN_ALIGN - nbyte;				if (nbyte > elf_brk - elf_bss)					nbyte = elf_brk - elf_bss;				if (clear_user((void __user *)elf_bss +							load_bias, nbyte)) {					/*					 * This bss-zeroing can fail if the ELF					 * file specifies odd protections.  So					 * we don't check the return value					 */				}			}		}		if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;		if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;		if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;		elf_flags = MAP_PRIVATE|MAP_DENYWRITE|MAP_EXECUTABLE;		vaddr = elf_ppnt->p_vaddr;		if (loc->elf_ex.e_type == ET_EXEC || load_addr_set) {			elf_flags |= MAP_FIXED;		} else if (loc->elf_ex.e_type == ET_DYN) {			/* Try and get dynamic programs out of the way of the default mmap			   base, as well as whatever program they might try to exec.  This			   is because the brk will follow the loader, and is not movable.  */			load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);		}		error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);		if (BAD_ADDR(error)) {			send_sig(SIGKILL, current, 0);			goto out_free_dentry;		}		if (!load_addr_set) {			load_addr_set = 1;			load_addr = (elf_ppnt->p_vaddr - elf_ppnt->p_offset);			if (loc->elf_ex.e_type == ET_DYN) {				load_bias += error -				             ELF_PAGESTART(load_bias + vaddr);				load_addr += load_bias;				reloc_func_desc = load_bias;			}		}		k = elf_ppnt->p_vaddr;		if (k < start_code) start_code = k;		if (start_data < k) start_data = k;		/*		 * Check to see if the section's size will overflow the		 * allowed task size. Note that p_filesz must always be		 * <= p_memsz so it is only necessary to check p_memsz.		 */		if (k > TASK_SIZE || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||		    elf_ppnt->p_memsz > TASK_SIZE ||		    TASK_SIZE - elf_ppnt->p_memsz < k) {			/* set_brk can never work.  Avoid overflows.  */			send_sig(SIGKILL, current, 0);			goto out_free_dentry;		}		k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;		if (k > elf_bss)			elf_bss = k;		if ((elf_ppnt->p_flags & PF_X) && end_code < k)			end_code = k;		if (end_data < k)			end_data = k;		k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;		if (k > elf_brk)			elf_brk = k;	}	loc->elf_ex.e_entry += load_bias;	elf_bss += load_bias;	elf_brk += load_bias;	start_code += load_bias;	end_code += load_bias;	start_data += load_bias;	end_data += load_bias;	/* Calling set_brk effectively mmaps the pages that we need	 * for the bss and break sections.  We must do this before	 * mapping in the interpreter, to make sure it doesn't wind	 * up getting placed where the bss needs to go.	 */	retval = set_brk(elf_bss, elf_brk);	if (retval) {		send_sig(SIGKILL, current, 0);		goto out_free_dentry;	}	if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {		send_sig(SIGSEGV, current, 0);		retval = -EFAULT; /* Nobody gets to see this, but.. */		goto out_free_dentry;	}	if (elf_interpreter) {		if (interpreter_type == INTERPRETER_AOUT)			elf_entry = load_aout_interp(&loc->interp_ex,						     interpreter);		else			elf_entry = load_elf_interp(&loc->interp_elf_ex,						    interpreter,						    &interp_load_addr);		if (BAD_ADDR(elf_entry)) {			printk(KERN_ERR "Unable to load interpreter %.128s\n",				elf_interpreter);			force_sig(SIGSEGV, current);			retval = -ENOEXEC; /* Nobody gets to see this, but.. */			goto out_free_dentry;		}		reloc_func_desc = interp_load_addr;		allow_write_access(interpreter);		fput(interpreter);		kfree(elf_interpreter);	} else {		elf_entry = loc->elf_ex.e_entry;	}	kfree(elf_phdata);	if (interpreter_type != INTERPRETER_AOUT)		sys_close(elf_exec_fileno);	set_binfmt(&elf_format);#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES	retval = arch_setup_additional_pages(bprm, executable_stack);	if (retval < 0) {		send_sig(SIGKILL, current, 0);		goto out;	}#endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */	compute_creds(bprm);	current->flags &= ~PF_FORKNOEXEC;	create_elf_tables(bprm, &loc->elf_ex, (interpreter_type == INTERPRETER_AOUT),			load_addr, interp_load_addr);	/* N.B. passed_fileno might not be initialized? */	if (interpreter_type == INTERPRETER_AOUT)		current->mm->arg_start += strlen(passed_fileno) + 1;	current->mm->end_code = end_code;	current->mm->start_code = start_code;	current->mm->start_data = start_data;	current->mm->end_data = end_data;	current->mm->start_stack = bprm->p;	if (current->personality & MMAP_PAGE_ZERO) {		/* Why this, you ask???  Well SVr4 maps page 0 as read-only,		   and some applications "depend" upon this behavior.		   Since we do not have the power to recompile these, we		   emulate the SVr4 behavior.  Sigh.  */		down_write(&current->mm->mmap_sem);		error = do_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC,				MAP_FIXED | MAP_PRIVATE, 0);		up_write(&current->mm->mmap_sem);	}#ifdef ELF_PLAT_INIT	/*	 * The ABI may specify that certain registers be set up in special	 * ways (on i386 %edx is the address of a DT_FINI function, for	 * example.  In addition, it may also specify (eg, PowerPC64 ELF)	 * that the e_entry field is the address of the function descriptor	 * for the startup routine, rather than the address of the startup	 * routine itself.  This macro performs whatever initialization to	 * the regs structure is required as well as any relocations to the	 * function descriptor entries when executing dynamically links apps.	 */	ELF_PLAT_INIT(regs, reloc_func_desc);#endif	start_thread(regs, elf_entry, bprm->p);	if (unlikely(current->ptrace & PT_PTRACED)) {		if (current->ptrace & PT_TRACE_EXEC)			ptrace_notify ((PTRACE_EVENT_EXEC << 8) | SIGTRAP);		else			send_sig(SIGTRAP, current, 0);	}	retval = 0;out:	kfree(loc);out_ret:	return retval;	/* error cleanup */out_free_dentry:	allow_write_access(interpreter);	if (interpreter)		fput(interpreter);out_free_interp:	if (elf_interpreter)		kfree(elf_interpreter);out_free_file:	sys_close(elf_exec_fileno);out_free_fh:	if (files) {		put_files_struct(current->files);		current->files = files;	}out_free_ph:	kfree(elf_phdata);	goto out;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/404351e67a9facb475abf1492245374a28d13e90/binfmt_elf.c/clean/fs/binfmt_elf.c