Re: [PATCHv5 1/3] syscalls,x86: implement execveat() system call
From: Andy Lutomirski <luto@amacapital.net>
Date: 2014-10-27 18:47:52
Also in:
linux-arch, lkml
On Mon, Oct 27, 2014 at 11:03 AM, David Drysdale [off-list ref] wrote:
On Wed, Oct 22, 2014 at 7:44 PM, Andy Lutomirski [off-list ref] wrote:quoted
On Wed, Oct 22, 2014 at 4:44 AM, David Drysdale [off-list ref] wrote:quoted
Add a new system execveat(2) syscall. execveat() is to execve() as openat() is to open(): it takes a file descriptor that refers to a directory, and resolves the filename relative to that.quoted
bprm->file = file; - bprm->filename = bprm->interp = filename->name; + if (fd == AT_FDCWD || filename->name[0] == '/') { + bprm->filename = filename->name; + } else { + /* + * Build a pathname that reflects how we got to the file, + * either "/dev/fd/<fd>" (for an empty filename) or + * "/dev/fd/<fd>/<filename>". + */ + pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY); + if (!pathbuf) { + retval = -ENOMEM; + goto out_unmark; + } + bprm->filename = pathbuf; + if (filename->name[0] == '\0') + sprintf(pathbuf, "/dev/fd/%d", fd);If the fd is O_CLOEXEC, then this will result in a confused child process. Should we fail exec attempts like that for non-static programs? (E.g. set filename to "" or something and fix up the binfmt drivers to handle that?)Isn't it just scripts that get confused here (as normal executables don't get to see brpm->filename)? Given that we don't know which we have at this point, I'd suggest carrying on regardless. Or we could fall back to use the previous best-effort d_path() code for O_CLOEXEC fds. Thoughts?
How hard would it be to mark the bprm as not having a path for the binary? Then we could fail later on if and when we actually need the path. I don't really have a strong opinion here, though. I do prefer actually failing the execveat call over succeeding but invoking a script interpreter than can't possibly work.
quoted
quoted
+ else + snprintf(pathbuf, PATH_MAX, + "/dev/fd/%d/%s", fd, filename->name);Does this need to handle the case where the result exceeds PATH_MAX?I guess we could kmalloc(strlen(filename->name) + 19) to avoid the possibility of failure, but that just defers the inevitable -- the interpreter won't be able to open the script file anyway. But it would at least then generate the appropriate error (ENAMETOOLONG rather than ENOENT).
Depends whether anyone cares about bprm->filename. But I think the code should either return an error or allocate enough space. -- Andy Lutomirski AMA Capital Management, LLC