exec函数实现

 
SYSCALL_DEFINE3(execve,
  const char __user *, filename,
  const char __user *const __user *, argv,
  const char __user *const __user *, envp)
{
 return do_execve(getname(filename), argv, envp);
}
 

SYSCALL_DEFINE5(execveat,   int, fd, const char __user *, filename,   const char __user *const __user *, argv,   const char __user *const __user *, envp,   int, flags) {  int lookup_flags = (flags & AT_EMPTY_PATH) ? LOOKUP_EMPTY : 0;

 return do_execveat(fd,       getname_flags(filename, lookup_flags, NULL),       argv, envp, flags); }

#ifdef CONFIG_COMPAT COMPAT_SYSCALL_DEFINE3(execve, const char __user *, filename,  const compat_uptr_t __user *, argv,  const compat_uptr_t __user *, envp) {  return compat_do_execve(getname(filename), argv, envp); }

COMPAT_SYSCALL_DEFINE5(execveat, int, fd,          const char __user *, filename,          const compat_uptr_t __user *, argv,          const compat_uptr_t __user *, envp,          int,  flags) {  int lookup_flags = (flags & AT_EMPTY_PATH) ? LOOKUP_EMPTY : 0;

 return compat_do_execveat(fd,       getname_flags(filename, lookup_flags, NULL),       argv, envp, flags); } #endif

/*  * sys_execve() executes a new program.  */ static int do_execveat_common(int fd, struct filename *filename,          struct user_arg_ptr argv,          struct user_arg_ptr envp,          int flags) {  char *pathbuf = NULL;  struct linux_binprm *bprm;  struct file *file;  struct files_struct *displaced;  int retval;

 if (IS_ERR(filename))   return PTR_ERR(filename);

 /*   * We move the actual failure in case of RLIMIT_NPROC excess from   * set*uid() to execve() because too many poorly written programs   * don't check setuid() return code.  Here we additionally recheck   * whether NPROC limit is still exceeded.   */  if ((current->flags & PF_NPROC_EXCEEDED) &&      atomic_read(&current_user()->processes) > rlimit(RLIMIT_NPROC)) {   retval = -EAGAIN;   goto out_ret;  }

 /* We're below the limit (still or again), so we don't want to make   * further execve() calls fail. */  current->flags &= ~PF_NPROC_EXCEEDED;

 retval = unshare_files(&displaced);  if (retval)   goto out_ret;

 retval = -ENOMEM;  bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);  if (!bprm)   goto out_files;

 retval = prepare_bprm_creds(bprm);  if (retval)   goto out_free;

 check_unsafe_exec(bprm);  current->in_execve = 1;

 file = do_open_execat(fd, filename, flags);  retval = PTR_ERR(file);  if (IS_ERR(file))   goto out_unmark;

 sched_exec();

 bprm->file = file;  if (fd == AT_FDCWD || filename->name[0] == '/') {   bprm->filename = filename->name;  } else {   if (filename->name[0] == '\0')    pathbuf = kasprintf(GFP_TEMPORARY, "/dev/fd/%d", fd);   else    pathbuf = kasprintf(GFP_TEMPORARY, "/dev/fd/%d/%s",          fd, filename->name);   if (!pathbuf) {    retval = -ENOMEM;    goto out_unmark;   }   /*    * Record that a name derived from an O_CLOEXEC fd will be    * inaccessible after exec. Relies on having exclusive access to    * current->files (due to unshare_files above).    */   if (close_on_exec(fd, rcu_dereference_raw(current->files->fdt)))    bprm->interp_flags |= BINPRM_FLAGS_PATH_INACCESSIBLE;   bprm->filename = pathbuf;  }  bprm->interp = bprm->filename;

 retval = bprm_mm_init(bprm);  if (retval)   goto out_unmark;

 bprm->argc = count(argv, MAX_ARG_STRINGS);  if ((retval = bprm->argc) < 0)   goto out;

 bprm->envc = count(envp, MAX_ARG_STRINGS);  if ((retval = bprm->envc) < 0)   goto out;

 retval = prepare_binprm(bprm);  if (retval < 0)   goto out;

 retval = copy_strings_kernel(1, &bprm->filename, bprm);  if (retval < 0)   goto out;

 bprm->exec = bprm->p;  retval = copy_strings(bprm->envc, envp, bprm);  if (retval < 0)   goto out;

 retval = copy_strings(bprm->argc, argv, bprm);  if (retval < 0)   goto out;

 retval = exec_binprm(bprm);  if (retval < 0)   goto out;

 /* execve succeeded */  current->fs->in_exec = 0;  current->in_execve = 0;  acct_update_integrals(current);  task_numa_free(current);  free_bprm(bprm);  kfree(pathbuf);  putname(filename);  if (displaced)   put_files_struct(displaced);  return retval;

out:  if (bprm->mm) {   acct_arg_size(bprm, 0);   mmput(bprm->mm);  }

out_unmark:  current->fs->in_exec = 0;  current->in_execve = 0;

out_free:  free_bprm(bprm);  kfree(pathbuf);

out_files:  if (displaced)   reset_files_struct(displaced); out_ret:  putname(filename);  return retval; }

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值