⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exec.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 2 页
字号:
			return -ENOMEM;		printk("exec mmap count >1 new %p old %p\n", mm, current->mm);		*mm = *current->mm;		init_new_context(mm);		mm->def_flags = 0;	/* should future lockings be kept? */		mm->count = 1;		mm->mmap = NULL;		mm->mmap_avl = NULL;		mm->total_vm = 0;		mm->rss = 0;		old_mm = current->mm;		current->mm = mm;		if (new_page_tables(current)) {			current->mm = old_mm;			exit_mmap(mm);			destroy_context(mm);			kfree(mm);			return -ENOMEM;		}		if ((old_mm != &init_mm) && (!--old_mm->count)) {			/*			 * all threads exited while we were sleeping, 'old_mm' is held			 * by us exclusively, lets get rid of it:			 */			exit_mmap(old_mm);			free_page_tables(old_mm);			destroy_context(old_mm);			kfree(old_mm);		}		/* since we have switched to a new mm now, we need to make sure		 * it gets a new mmu context as well. init_new_context just marks		 * it as NO_CONTEXT (since we dont allocate contexts until the		 * processes actually are scheduled).		 */		get_mmu_context(current);		return 0;	}	flush_cache_mm(current->mm);	exit_mmap(current->mm);	clear_page_tables(current);	flush_tlb_mm(current->mm);	return 0;}#else /* NO_MM */static int exec_mmap(void){	/*	 * The clear_page_tables done later on exec does the right thing	 * to the page directory when shared, except for graceful abort	 */#ifdef CONFIG_SHARE_SHLIB_CORE        shlibmod_exit(&current->shlib_deps);#endif	if (current->mm->count > 1) {		struct mm_struct *old_mm, *mm = kmalloc(sizeof(*mm), GFP_KERNEL);		if (!mm)			return -ENOMEM;		*mm = *current->mm;		mm->def_flags = 0;	/* should future lockings be kept? */		mm->count = 1;		mm->total_vm = 0;		mm->rss = 0;		old_mm = current->mm;		current->mm = mm;		if (new_page_tables(current)) {			current->mm = old_mm;			exit_mmap(mm);			kfree(mm);			return -ENOMEM;		}		if ((old_mm != &init_mm) && (!--old_mm->count)) {			/*			 * all threads exited while we were sleeping, 'old_mm' is held			 * by us exclusively, lets get rid of it:			 */			exit_mmap(old_mm);			free_page_tables(old_mm);			kfree(old_mm);		}		return 0;	}	exit_mmap(current->mm);	clear_page_tables(current);	return 0;}#endif /* NO_MM *//* * These functions flushes out all traces of the currently running executable * so that a new one can be started */static inline void flush_old_signals(struct signal_struct *sig){	int i;	struct sigaction * sa = sig->action;	for (i=32 ; i != 0 ; i--) {		sa->sa_mask = 0;		sa->sa_flags = 0;		if (sa->sa_handler != SIG_IGN)			sa->sa_handler = NULL;		sa++;	}}static inline void flush_old_files(struct files_struct * files){	unsigned long j;	j = 0;	for (;;) {		unsigned long set, i;		i = j * __NFDBITS;		if (i >= NR_OPEN)			break;		set = files->close_on_exec.fds_bits[j];		files->close_on_exec.fds_bits[j] = 0;		j++;		for ( ; set ; i++,set >>= 1) {			if (set & 1)				sys_close(i);		}	}}int flush_old_exec(struct linux_binprm * bprm){	int i;	int ch;	char * name;	if (current->euid == current->uid && current->egid == current->gid)		current->dumpable = 1;	name = bprm->filename;	for (i=0; (ch = *(name++)) != '\0';) {		if (ch == '/')			i = 0;		else			if (i < 15)				current->comm[i++] = ch;	}	current->comm[i] = '\0';	/* Release all of the old mmap stuff. */	if (exec_mmap())		return -ENOMEM;	flush_thread();	if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || 	    permission(bprm->inode,MAY_READ))		current->dumpable = 0;	flush_old_signals(current->sig);	flush_old_files(current->files);	return 0;}/*  * Fill the binprm structure from the inode.  * Check permissions, then read the first 512 bytes */int prepare_binprm(struct linux_binprm *bprm){	int mode;	int retval,id_change;	mode = bprm->inode->i_mode;	if (!S_ISREG(mode))			/* must be regular file */		return -EACCES;	if (!(mode & 0111))			/* with at least _one_ execute bit set */		return -EACCES;	if (IS_NOEXEC(bprm->inode))		/* FS mustn't be mounted noexec */		return -EACCES;	if (!bprm->inode->i_sb)		return -EACCES;	if ((retval = permission(bprm->inode, MAY_EXEC)) != 0)		return retval;	/* better not execute files which are being written to */	if (bprm->inode->i_writecount > 0)		return -ETXTBSY;	bprm->e_uid = current->euid;	bprm->e_gid = current->egid;	id_change = 0;	/* Set-uid? */	if (mode & S_ISUID) {		bprm->e_uid = bprm->inode->i_uid;		if (bprm->e_uid != current->euid)			id_change = 1;	}	/* Set-gid? */	/*	 * If setgid is set but no group execute bit then this	 * is a candidate for mandatory locking, not a setgid	 * executable.	 */	if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {		bprm->e_gid = bprm->inode->i_gid;		if (!in_group_p(bprm->e_gid))			id_change = 1;	}	if (id_change) {		/* We can't suid-execute if we're sharing parts of the executable */		/* or if we're being traced (or if suid execs are not allowed)    */		/* (current->mm->count > 1 is ok, as we'll get a new mm anyway)   */		if (IS_NOSUID(bprm->inode)		    || (current->flags & PF_PTRACED)		    || (current->fs->count > 1)		    || (current->sig->count > 1)		    || (current->files->count > 1)) {			if (!suser())				return -EPERM;		}	}	memset(bprm->buf,0,sizeof(bprm->buf));	return read_exec(bprm->inode,0,bprm->buf,128,1);}#ifndef NO_MMvoid remove_arg_zero(struct linux_binprm *bprm){	if (bprm->argc) {		unsigned long offset;		char * page;		offset = bprm->p % PAGE_SIZE;		page = (char*)bprm->page[bprm->p/PAGE_SIZE];		while(bprm->p++,*(page+offset++))			if(offset==PAGE_SIZE){				offset=0;				page = (char*)bprm->page[bprm->p/PAGE_SIZE];			}		bprm->argc--;	}}#endif/* * cycle the list of binary formats handler, until one recognizes the image */int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs){	int try,retval=0;	struct linux_binfmt *fmt;#ifdef __alpha__	/* handle /sbin/loader.. */	{	    struct exec * eh = (struct exec *) bprm->buf;	    if (!bprm->loader && eh->fh.f_magic == 0x183 &&		(eh->fh.f_flags & 0x3000) == 0x3000)	    {		char * dynloader[] = { "/sbin/loader" };		iput(bprm->inode);		bprm->dont_iput = 1;		remove_arg_zero(bprm);		bprm->p = copy_strings(1, dynloader, bprm->page, bprm->p, 2);		bprm->argc++;		bprm->loader = bprm->p;		retval = open_namei(dynloader[0], 0, 0, &bprm->inode, NULL);		if (retval)			return retval;		bprm->dont_iput = 0;		retval = prepare_binprm(bprm);		if (retval<0)			return retval;		/* should call search_binary_handler recursively here,		   but it does not matter */	    }	}#endif	for (try=0; try<2; try++) {		for (fmt = formats ; fmt ; fmt = fmt->next) {			int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;			if (!fn)				continue;			retval = fn(bprm, regs);			if (retval >= 0) {				if(!bprm->dont_iput)					iput(bprm->inode);				bprm->dont_iput=1;				current->did_exec = 1;				return retval;			}			if (retval != -ENOEXEC)				break;			if (bprm->dont_iput) /* We don't have the inode anymore*/				return retval;		}		if (retval != -ENOEXEC) {			break;#ifdef CONFIG_KERNELD		}else{#define printable(c) (((c)=='\t') || ((c)=='\n') || (0x20<=(c) && (c)<=0x7e))			char modname[20];			if (printable(bprm->buf[0]) &&			    printable(bprm->buf[1]) &&			    printable(bprm->buf[2]) &&			    printable(bprm->buf[3]))				break; /* -ENOEXEC */			sprintf(modname, "binfmt-%hd", *(short*)(&bprm->buf));			request_module(modname);#endif		}	}	return retval;}/* * sys_execve() executes a new program. */int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs){	struct linux_binprm bprm;	int retval;#ifndef NO_MM	int i;#endif	#ifdef DEBUG	printk("dp_execve invoked with filename '%s', argv: %x, envp: %x\n",		filename,		(unsigned long)argv,		(unsigned long)envp);#endif#ifndef NO_MM	bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);	for (i=0 ; i<MAX_ARG_PAGES ; i++)	/* clear page-table */		bprm.page[i] = 0;#endif	retval = open_namei(filename, 0, 0, &bprm.inode, NULL);	if (retval)		return retval;	bprm.filename = filename;	bprm.sh_bang = 0;	bprm.loader = 0;	bprm.exec = 0;	bprm.dont_iput = 0;	if ((bprm.argc = count(argv)) < 0)		return bprm.argc;	if ((bprm.envc = count(envp)) < 0)		return bprm.envc;	retval = prepare_binprm(&bprm);	#ifndef NO_MM	if(retval>=0) {		bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p, 2);		bprm.exec = bprm.p;		bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p,0);		bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p,0);		if (!bprm.p)			retval = -E2BIG;	}#else	bprm.envp = envp;	bprm.argv = argv;#endif	if(retval>=0)		retval = search_binary_handler(&bprm,regs);		if(retval>=0) {#ifdef NO_MM		/* If the parent to this process did a vfork, we need to wake it up 		   because it's supposed to sleep until the child does an exec. */		wake_up(&current->vforkwait);#endif		/* execve success */		return retval;	}		/* Something went wrong, return the inode and free the argument pages*/	if(!bprm.dont_iput)		iput(bprm.inode);	#ifndef NO_MM	for (i=0 ; i<MAX_ARG_PAGES ; i++)		free_page(bprm.page[i]);#endif	return(retval);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -