Re: fexecve, round 2
On Mon, Nov 19, 2012 at 05:23:07AM +, David Holland wrote: Also, it obviously needs to be possible to open files O_RDONLY|O_EXEC for O_EXEC to be useful, and open directories O_RDONLY|O_SEARCH, and so forth. I don't know what POSIX may have been thinking when they tried to forbid this but forbidding it makes about as much sense as forbidding O_RDWR, maybe less. It seems consistent with the check at system call time that you proposed to forbid. Here is how I understand it for an openat/mkdirat sequence: - openat() without O_SEARCH, get a search check at mkdirat() time - openat() with O_SEARCH, mkdirat() performs no search check. and for openat/fexecve: - openat() without O_SEXEC, get a execute check at fexecve() time - openat() with O_EXEC, fexecve() performs no exec check. If you have r-x permission, you open with O_RDONLY and you do not need O_SEARCH/O_EXEC. If you have --x permission, you open with O_SEARCH/O_EXEC -- Emmanuel Dreyfus m...@netbsd.org
Re: fexecve, round 2
On Mon, Nov 19, 2012 at 05:23:07AM +, David Holland wrote: On Sun, Nov 18, 2012 at 06:51:51PM +, David Holland wrote: This appears to contradict either the description of O_EXEC in the standard, or the standard's rationale for adding fexecve(). The standard says O_EXEC causes the file to be open for execution only. In other words, O_EXEC means you can't read nor write the file. Now the rationale for fexecve() doesn't hold, since you cannot read from the fd, then exec from it without a reopen. Further, requiring O_EXEC would seem to directly contravene the standard's language about fexecve()'s behavior. The standard is clearly wrong on a number of points and doesn't match the historical design and behavior of Unix. Let's either implement something correct, or not implement it at all. Also it seems that the specification of O_SEARCH (and I think the implementation we just got, too) is flawed in the same way - it is performing access checks at use time instead of at open time. So, for the record, I think none of these flags should be added unless they behave the same way opening for write does -- the flag cannot be set except at open time, and only if the opening process has permission to make the selected type of access; once opened the resulting file handle functions as a capability that allows the selected type of access. Anything else creates horrible inconsistencies and violates the principle of least surprise, both of which are not acceptable as part of the access control system. Does fchmod() itself have any issues? If I open a file that doesn't have write permissions, I can use fchmod() to add write permissions. My open fd won't magically gain write access, but maybe I can open it again via /dev/fd (possibly after linking the inode back into the filesystem) and gain the extra permissions. Clearly I would need to be the owner, but with chroots that shouldn't be enough if the file might actually be outsde the chroot. David -- David Laight: da...@l8s.co.uk
Re: fexecve, round 2
On Mon, Nov 19, 2012 at 08:08:58AM +, Emmanuel Dreyfus wrote: On Mon, Nov 19, 2012 at 05:23:07AM +, David Holland wrote: Also, it obviously needs to be possible to open files O_RDONLY|O_EXEC for O_EXEC to be useful, and open directories O_RDONLY|O_SEARCH, and so forth. I don't know what POSIX may have been thinking when they tried to forbid this but forbidding it makes about as much sense as forbidding O_RDWR, maybe less. It seems consistent with the check at system call time that you proposed to forbid. Here is how I understand it for an openat/mkdirat sequence: - openat() without O_SEARCH, get a search check at mkdirat() time - openat() with O_SEARCH, mkdirat() performs no search check. and for openat/fexecve: - openat() without O_SEXEC, get a execute check at fexecve() time - openat() with O_EXEC, fexecve() performs no exec check. If you have r-x permission, you open with O_RDONLY and you do not need O_SEARCH/O_EXEC. If you have --x permission, you open with O_SEARCH/O_EXEC I think the standard implied that O_EXEC gave you read and execute permissions. So you can't use it to open files that are --x. I haven't seen a quote for O_SEARCH. Without the xxxat() functions the read/write state of directory fds (as opposed to that of the directory itself) has never mattered. O_SEARCH might be there to allow you to open . when you don't have read (or write) access to it. For openat() it is plausible that write access to the directory fd might be needed as well as write access to the underlying directory in order to create files. David -- David Laight: da...@l8s.co.uk
Re: fexecve, round 2
On Mon, 19 Nov 2012 08:38:11 + David Laight da...@l8s.co.uk wrote: On Mon, Nov 19, 2012 at 08:08:58AM +, Emmanuel Dreyfus wrote: If you have r-x permission, you open with O_RDONLY and you do not need O_SEARCH/O_EXEC. If you have --x permission, you open with O_SEARCH/O_EXEC I think the standard implied that O_EXEC gave you read and execute permissions. So you can't use it to open files that are --x. No, Emmanuel is right: [...] use the O_EXEC flag when opening fd. In this case, the application will not be able to perform a checksum test since it will not be able to read the contents of the file. You can open with --x but (correctly) you can't read from the file. Julian -- 3072D/F3A66B3A Julian Yon (2012 General Use) pgp.2...@jry.me signature.asc Description: PGP signature
Re: fexecve, round 2
On Mon, Nov 19, 2012 at 02:39:36PM +, Julian Yon wrote: No, Emmanuel is right: [...] use the O_EXEC flag when opening fd. In this case, the application will not be able to perform a checksum test since it will not be able to read the contents of the file. You can open with --x but (correctly) you can't read from the file. And it means the standard mandates that one can execute without read access. Weird. -- Emmanuel Dreyfus m...@netbsd.org
Re: fexecve, round 2
On Mon, Nov 19, 2012 at 03:13:02PM +, Emmanuel Dreyfus wrote: On Mon, Nov 19, 2012 at 02:39:36PM +, Julian Yon wrote: No, Emmanuel is right: [...] use the O_EXEC flag when opening fd. In this case, the application will not be able to perform a checksum test since it will not be able to read the contents of the file. You can open with --x but (correctly) you can't read from the file. And it means the standard mandates that one can execute without read access. Weird. What's weird about that? % cp /bin/ls /tmp % chmod 100 /tmp/ls % ls -l /tmp/ls ---x-- 1 tls users 24521 Nov 19 11:24 /tmp/ls % /tmp/ls -l /tmp/ls ---x-- 1 tls users 24521 Nov 19 11:24 /tmp/ls %
Re: fexecve, round 2
On Mon, Nov 19, 2012 at 11:25:07AM -0500, Thor Lancelot Simon wrote: On Mon, Nov 19, 2012 at 03:13:02PM +, Emmanuel Dreyfus wrote: On Mon, Nov 19, 2012 at 02:39:36PM +, Julian Yon wrote: No, Emmanuel is right: [...] use the O_EXEC flag when opening fd. In this case, the application will not be able to perform a checksum test since it will not be able to read the contents of the file. You can open with --x but (correctly) you can't read from the file. Given the comments later about O_SEARCH | O_RDONLY not being distinguishable from O_SEARCH (because, historically, O_RDONLY is zero) and 'similarly for O_EXEC' I suspect the wording of the sections got reworded quite late on - and probably after the bar had opened and everyone at the meeting was hungry! I suspect that, for --x-- items opens with O_EXEC or O_SEARCH might need to succeed, and any later read/mmap requests fail. And it means the standard mandates that one can execute without read access. Weird. What's weird about that? % cp /bin/ls /tmp % chmod 100 /tmp/ls % ls -l /tmp/ls ---x-- 1 tls users 24521 Nov 19 11:24 /tmp/ls % /tmp/ls -l /tmp/ls ---x-- 1 tls users 24521 Nov 19 11:24 /tmp/ls % More fun are #! scripts that are --s-- Typically they can be executed by everyone except the owner! (Provided suid scripts are allowed - and I don't know any reason why they shouldn't be provided the kernel passes the open fd to the interpreter.) David -- David Laight: da...@l8s.co.uk
Re: fexecve, round 2
David Laight da...@l8s.co.uk wrote: Given the comments later about O_SEARCH | O_RDONLY not being distinguishable from O_SEARCH The satandard forbids O_SEARCH | O_RDONLY anyway, so it should not be a problem. -- Emmanuel Dreyfus http://hcpnet.free.fr/pubz m...@netbsd.org
Re: fexecve, round 2
On Apr 11, 9:48am, Emmanuel Dreyfus wrote: } On Mon, Nov 19, 2012 at 02:39:36PM +, Julian Yon wrote: } No, Emmanuel is right: [...] use the O_EXEC flag when opening fd. In } this case, the application will not be able to perform a checksum test } since it will not be able to read the contents of the file. You can } open with --x but (correctly) you can't read from the file. } } And it means the standard mandates that one can execute without } read access. Weird. Not weird at all. This is the way Unix systems have been behaving for as long as I can remember, and I've been working with Unix systems for aproximately 20 years. }-- End of excerpt from Emmanuel Dreyfus
Re: fexecve, round 2
On Sat, Nov 17, 2012 at 11:48:20AM +0100, Emmanuel Dreyfus wrote: Here is an attempt to address what was said about implementing fexecve() fexecve() checks that the vnode underlying the fd : - is of type VREG - grants execution right O_EXEC cause open()/openat() to fail if the file mode does not grant execute rights There are security concerns with fd passed to chrooted processes, which could help executing code. Here is a proposal for chrooted processes: 1) if current process and executed vnode have different roots, then fexecve() fails I'm not sure how you were intending determining that. You can follow .. for directories, but not files. 2) if the fd was not open with O_EXEC, fexecve() fails. First point avoids executing code from outside the chroot Second point enforces W^X inside the chroot. If we don't want to allow chroot'ed process to exec a file that is outside the chroot, then maybe the kernel could hold a reference to the directory vnode (in the file vnode) whenever a file is opened for execute (including the existing exec() family of calls calls). As well as being used to police fexecve() withing a chroot, it could be used by the dynamic linker for $ORIGIN processing (Probably by some special flags to openat().). David -- David Laight: da...@l8s.co.uk
Re: fexecve, round 2
Rhialto rhia...@falu.nl wrote: The definition is really vague. As I understand, nothing forbids opening O_EXEC|O_RDWR. Applications shall specify exactly one of the first five values (file access modes) below in the value of oflag: Right, I missed that point. -- Emmanuel Dreyfus http://hcpnet.free.fr/pubz m...@netbsd.org
Re: fexecve, round 2
On Sat, Nov 17, 2012 at 06:42:50PM -0500, Thor Lancelot Simon wrote: O_EXEC cause open()/openat() to fail if the file mode does not grant execute rights There are security concerns with fd passed to chrooted processes, which could help executing code. Here is a proposal for chrooted processes: 1) if current process and executed vnode have different roots, then fexecve() fails 2) if the fd was not open with O_EXEC, fexecve() fails. This appears to contradict either the description of O_EXEC in the standard, or the standard's rationale for adding fexecve(). The standard says O_EXEC causes the file to be open for execution only. In other words, O_EXEC means you can't read nor write the file. Now the rationale for fexecve() doesn't hold, since you cannot read from the fd, then exec from it without a reopen. Further, requiring O_EXEC would seem to directly contravene the standard's language about fexecve()'s behavior. The standard is clearly wrong on a number of points and doesn't match the historical design and behavior of Unix. Let's either implement something correct, or not implement it at all. This to me is illustrative of the danger of slavishly substituting the XPG group's technical judgment for our own. They frequently standardise poorly thought out Linux hacks; twisting ourselves into knots to make what they half-designed safe, at which point it doesn't conform to their standard any more, does not seem like a good general plan to me. Indeed. -- David A. Holland dholl...@netbsd.org
Re: fexecve, round 2
David Holland dholland-t...@netbsd.org wrote: The standard is clearly wrong on a number of points and doesn't match the historical design and behavior of Unix. Let's either implement something correct, or not implement it at all. Do you have something correct to sugest? -- Emmanuel Dreyfus http://hcpnet.free.fr/pubz m...@netbsd.org
Re: fexecve, round 2
On Sun, Nov 18, 2012 at 06:16:00PM +, David Holland wrote: This appears to contradict either the description of O_EXEC in the standard, or the standard's rationale for adding fexecve(). The standard says O_EXEC causes the file to be open for execution only. In other words, O_EXEC means you can't read nor write the file. Now the rationale for fexecve() doesn't hold, since you cannot read from the fd, then exec from it without a reopen. Further, requiring O_EXEC would seem to directly contravene the standard's language about fexecve()'s behavior. The standard is clearly wrong on a number of points and doesn't match the historical design and behavior of Unix. Let's either implement something correct, or not implement it at all. Also it seems that the specification of O_SEARCH (and I think the implementation we just got, too) is flawed in the same way - it is performing access checks at use time instead of at open time. (Also the implementation we just got seems to be missing any access check at open time -- this seems entirely wrong.) -- David A. Holland dholl...@netbsd.org
Re: fexecve, round 2
On Sun, Nov 18, 2012 at 07:42:43PM +0100, Emmanuel Dreyfus wrote: The standard is clearly wrong on a number of points and doesn't match the historical design and behavior of Unix. Let's either implement something correct, or not implement it at all. Do you have something correct to sugest? Not off the top of my head. Rushing it through and going off half-cocked as a result is how these things get to us broken in the first place; let's not repeat the mistake. -- David A. Holland dholl...@netbsd.org
Re: fexecve, round 2
On Sun, 18 Nov 2012 18:16:00 + David Holland dholland-t...@netbsd.org wrote: On Sat, Nov 17, 2012 at 06:42:50PM -0500, Thor Lancelot Simon wrote: Further, requiring O_EXEC would seem to directly contravene the standard's language about fexecve()'s behavior. The standard is clearly wrong on a number of points and doesn't match the historical design and behavior of Unix. Let's either implement something correct, or not implement it at all. What if the only process that was allowed to fexecve was the one which opened the fd (or possibly extend this to children, but I'm not sure if that's safe), and any other failed with EBADF? Seems to me this would allow the intended usage (tenuous as the rationale is) while closing the chroot based holes that have been discussed. Julian -- 3072D/F3A66B3A Julian Yon (2012 General Use) pgp.2...@jry.me signature.asc Description: PGP signature
Re: fexecve, round 2
On Sun, Nov 18, 2012 at 06:51:51PM +, David Holland wrote: This appears to contradict either the description of O_EXEC in the standard, or the standard's rationale for adding fexecve(). The standard says O_EXEC causes the file to be open for execution only. In other words, O_EXEC means you can't read nor write the file. Now the rationale for fexecve() doesn't hold, since you cannot read from the fd, then exec from it without a reopen. Further, requiring O_EXEC would seem to directly contravene the standard's language about fexecve()'s behavior. The standard is clearly wrong on a number of points and doesn't match the historical design and behavior of Unix. Let's either implement something correct, or not implement it at all. Also it seems that the specification of O_SEARCH (and I think the implementation we just got, too) is flawed in the same way - it is performing access checks at use time instead of at open time. So, for the record, I think none of these flags should be added unless they behave the same way opening for write does -- the flag cannot be set except at open time, and only if the opening process has permission to make the selected type of access; once opened the resulting file handle functions as a capability that allows the selected type of access. Anything else creates horrible inconsistencies and violates the principle of least surprise, both of which are not acceptable as part of the access control system. Also, it obviously needs to be possible to open files O_RDONLY|O_EXEC for O_EXEC to be useful, and open directories O_RDONLY|O_SEARCH, and so forth. I don't know what POSIX may have been thinking when they tried to forbid this but forbidding it makes about as much sense as forbidding O_RDWR, maybe less. Someone needs to sit down and figure out what restrictions need to be applied to fd passing to make this safe, both in general and in connection with chroot. One point riastradh@ raised is that if you get a fd for a directory outside your current chroot, you shouldn't be able to use it to openat() or with any of the *at() calls. There is currently no mechanism in place to enforce this. I have a feeling that what we want may be not a restriction on fd-passing sockets or a restriction on file handles, but a restriction on chroots. Also there was a thread back in February titled O_NOACCESS that everyone interested in this stuff should review. (Also the implementation we just got seems to be missing any access check at open time -- this seems entirely wrong.) It turns out to be unexploitable but it's definitely wrong in several ways (unrelated to whether its semantics are poorly chosen); I have asked for it to be reverted. -- David A. Holland dholl...@netbsd.org
Re: fexecve, round 2
On Nov 17, 2012, at 2:48 AM, Emmanuel Dreyfus wrote: Here is an attempt to address what was said about implementing fexecve() fexecve() checks that the vnode underlying the fd : - is of type VREG - grants execution right O_EXEC cause open()/openat() to fail if the file mode does not grant execute rights Also marks the executable with vn_marktext. Fails if opened with any of O_CREATE, O_WRONLY, O_RDWR There are security concerns with fd passed to chrooted processes, which could help executing code. Here is a proposal for chrooted processes: 1) if current process and executed vnode have different roots, then fexecve() fails 2) if the fd was not open with O_EXEC, fexecve() fails. 1) seems overkill.
Re: fexecve, round 2
On Sat, Nov 17, 2012 at 11:48:20AM +0100, Emmanuel Dreyfus wrote: Here is an attempt to address what was said about implementing fexecve() fexecve() checks that the vnode underlying the fd : - is of type VREG - grants execution right O_EXEC cause open()/openat() to fail if the file mode does not grant execute rights There are security concerns with fd passed to chrooted processes, which could help executing code. Here is a proposal for chrooted processes: 1) if current process and executed vnode have different roots, then fexecve() fails 2) if the fd was not open with O_EXEC, fexecve() fails. This appears to contradict either the description of O_EXEC in the standard, or the standard's rationale for adding fexecve(). The standard says O_EXEC causes the file to be open for execution only. In other words, O_EXEC means you can't read nor write the file. Now the rationale for fexecve() doesn't hold, since you cannot read from the fd, then exec from it without a reopen. Further, requiring O_EXEC would seem to directly contravene the standard's language about fexecve()'s behavior. Since the principal reason why we should add this is allegedly standards conformance I can't see how adding a nonconformant implementation of O_EXEC or fexecve fits with the overall goal here. This to me is illustrative of the danger of slavishly substituting the XPG group's technical judgment for our own. They frequently standardise poorly thought out Linux hacks; twisting ourselves into knots to make what they half-designed safe, at which point it doesn't conform to their standard any more, does not seem like a good general plan to me. (If we're really going to go down this road, I did make an alternate proposal for making fexecve() safer in the presence of file descriptor passing, one that I think doesn't break stuff that's in the standard; did you see it?) Thor
Re: fexecve, round 2
Thor Lancelot Simon t...@panix.com wrote: This appears to contradict either the description of O_EXEC in the standard, or the standard's rationale for adding fexecve(). The standard says O_EXEC causes the file to be open for execution only. The definition is really vague. As I understand, nothing forbids opening O_EXEC|O_RDWR. I understood O_EXEC as I explicitely say I will execute this fd will fexecve, so let me open even if I cannot read How do you understand it? -- Emmanuel Dreyfus http://hcpnet.free.fr/pubz m...@netbsd.org