Thread (9 messages) 9 messages, 2 authors, 2014-10-28

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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help