Project

General

Profile

Bug #5798

fexecve() needed per POSIX 2008

Added by Garrett D'Amore over 5 years ago. Updated over 5 years ago.

Status:
In Progress
Priority:
Normal
Category:
kernel
Start date:
2015-04-07
Due date:
% Done:

90%

Estimated time:
Difficulty:
Medium
Tags:
Gerrit CR:

Description

POSIX 2008 introduces fexecve(), which allows for one to execute a file from a file descriptor. This is required to close certain kinds of obscure race conditions; for example, one can open a file, check the signature (using MD5), and then execute it after validating that the executable is properly signed. Without this, implementing such schemes becomes nigh impossible (portably) since the file could be replaced between the checksum and the signature.

With /dev/fd, or a little hack in the kernel, solving this problem becomes pretty straight-forward. This was implemented in illumos-core ages ago.

#1

Updated by Cedric Blancher over 5 years ago

Use of /dev/fd would not be standard conforming - it will not work if a boot shell is required to use fexecve(). Docker on top of RHEL (Redhat Enterprise Linux) is currently under fire for causing problems with exactly that kind of glibc hack.

#2

Updated by Garrett D'Amore over 5 years ago

You didn't read the code. I don't depend on /dev/fd to actually exist. It is special cased in os/exec.c. This allows it to work in chroot(), or in the early boot environments. Please read: http://cr.illumos.org/~webrev/gdamore/fexecve/

#3

Updated by Garrett D'Amore over 5 years ago

That said, there seems to be contention right now. Some want to have a new system call ala execveat() from Linux. I'm arguing against that, at present, as I think adding a new system call (or modifying exece to take new arguments) presents undue risk to consumers of probes, audit events, etc. Whereas resolving this to a /dev/fd path seems to introduce the least risk for everyone involved.

#4

Updated by Igor Pashev over 5 years ago

char path[32];  /* 8 for "/dev/fd/", 10 for %u, + \\0 == 19 */

could be

char path[sizeof("/dev/fd/0123456789")];
#5

Updated by Garrett D'Amore over 5 years ago

Yes, Igor, I could compress this. But what is magic about 10, the 0123456789 loses the fact that the maximum size of %u is 10. (2^32 expressed in decimal is about 4000000000.)

Originally this was longer because the prefix was /proc/<pid>/fd/ (where <pid> was also up to 10 charactes). I didn't reduce the length of the string buffer (which is logically only 19 bytes) because its a stack allocation and alignment works nicely at 32 (possibly 24). Its too long for 16. So, with a stack allocated auto-var, the 32 is always safe (per the comments).

Also available in: Atom PDF