On 09/12, Oleg Nesterov wrote: > > On 09/12, Rob Landley wrote: > > > > On 09/11/2017 10:15 AM, Oleg Nesterov wrote: > > > On 09/08, Rob Landley wrote: > > >> > > >> So is exec(NULL, argv, envp) a reasonable thing to want? > > > > > > I think that something like prctl(PR_OPEN_EXE_FILE) which does > > > > > > dentry_open(current->mm->exe_file->path, O_PATH) > > > > > > and returns fd make more sense. > > > > > > Then you can do execveat(fd, "", ..., AT_EMPTY_PATH). > > I'm all for it? That sounds like a cosmetic difference, a more verbose > > way of achieving the same outcome. > > Simpler to implement. Something like the (untested) patch below. Not sure > it is correct, not sure it is good idea, etc. OTOH... with the trivial patch below execveat(AT_FDCWD, "", NULL, NULL, AT_EMPTY_PATH); should always work, even if the binary is not in scope after chroot, or if it is no longer executable, or unlinked. But I am not sure what else should we do to avoid the security problems. Oleg. --- x/fs/exec.c +++ x/fs/exec.c @@ -832,23 +832,32 @@ static struct file *do_open_execat(int fd, struct filename *name, int flags) { struct file *file; int err; - struct open_flags open_exec_flags = { - .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, - .acc_mode = MAY_EXEC, - .intent = LOOKUP_OPEN, - .lookup_flags = LOOKUP_FOLLOW, - }; - - if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0) - return ERR_PTR(-EINVAL); - if (flags & AT_SYMLINK_NOFOLLOW) - open_exec_flags.lookup_flags &= ~LOOKUP_FOLLOW; - if (flags & AT_EMPTY_PATH) - open_exec_flags.lookup_flags |= LOOKUP_EMPTY; - file = do_filp_open(fd, name, &open_exec_flags); - if (IS_ERR(file)) - goto out; + if (fd == AT_FDCWD && name->name[0] == '\0' && flags == AT_EMPTY_PATH) { + file = get_mm_exe_file(current->mm); + if (!file) { + file = ERR_PTR(-ENOENT); + goto out; + } + } else { + struct open_flags open_exec_flags = { + .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, + .acc_mode = MAY_EXEC, + .intent = LOOKUP_OPEN, + .lookup_flags = LOOKUP_FOLLOW, + }; + + if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0) + return ERR_PTR(-EINVAL); + if (flags & AT_SYMLINK_NOFOLLOW) + open_exec_flags.lookup_flags &= ~LOOKUP_FOLLOW; + if (flags & AT_EMPTY_PATH) + open_exec_flags.lookup_flags |= LOOKUP_EMPTY; + + file = do_filp_open(fd, name, &open_exec_flags); + if (IS_ERR(file)) + goto out; + } err = -EACCES; if (!S_ISREG(file_inode(file)->i_mode)) -- To unsubscribe from this list: send the line "unsubscribe linux-embedded" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html