Re: fexecve
>> How does fexecve() make anything possible here that wasn't possible >> before? It seems to me that updating .so libraries has always >> carried this risk, so I must be missing something. > Without fexecve() it's at least theoretically possible to remove the > old bins first, update the libraries, and install new bins, so that > the old bins are gone and can't be exec'd when the new libraries > appear. Hmm, good point. But, even with fexecve() it's possible to destroy the old bins before removing them (truncate to zero size is perhaps the simplest way), so descriptors onto them, if any, no longer point to executable content. Admittedly, that requires at least a tiny update to installation procedures. It's also theoretically racy, in that you could have process A other process(es) fexecve() file page in executable prepare to load libs destroy file unlink file replace libs start loading libs but that race is (a) highly unlikely and (b) equally possible with plain execve(). (In my experience, a paged-in executable continues to work as long as it stays paged in even if its backing file is destroyed; perhaps that's changed in -current.) /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Re: fexecve
On Sun, Sep 08, 2019 at 04:43:50PM -0400, Mouse wrote: > > (2) Losing the command name isn't good; lots of people turn process > > accounting on for logging (in fact, I'd assume 99.9% of people who > > turn process accounting on use it purely for logging) and it > > substantially decreases the utility if it's easily circumvented. > > Isn't the command name easy to lose and/or forge already, with links if > nothng else? Yes, though not without leaving traces and not necessarily at all in a sufficiently restricted chroot. > > (3) Setugid processes should be prohibited, or at least setugid > > dynamically-linked processes, because otherwise there's a window > > where a live update of a library might be used to run the old binary > > with a new set of libraries. > > How does fexecve() make anything possible here that wasn't possible > before? It seems to me that updating .so libraries has always carried > this risk, so I must be missing something. Without fexecve() it's at least theoretically possible to remove the old bins first, update the libraries, and install new bins, so that the old bins are gone and can't be exec'd when the new libraries appear. -- David A. Holland dholl...@netbsd.org
Re: fexecve
On Sun, Sep 08, 2019 at 09:53:50PM +, Taylor R Campbell wrote: > > What can we do about that? > > It sounds like you're positing: > > - there is a chrooted process A > - there is a colluding process B outside the chroot > - they share a socket > - B can open setuid executables and send their fds over the socket > - A can now execute setuid executables outside the chroot > > How is this substantively different from the following? > > - there is a chrooted process A > - there is a colluding process B outside the chroot > - they share a socket > - A can ask B to execute files by pathname and B will happily oblige > - A can now execute setuid executables outside the chroot > > That is, under what meaningful circumstances can you rule out the > first scenario but not the second one? The difference in the second scenario is that A can now execute setuid executables from outside the chroot *in* the chroot, where paths the executables implicitly or explicitly trust are resolved differently. So for example it becomes pretty trivial to escalate to root inside the chroot, and then with such collusion if the whole thing isn't mounted nosuid it's also trivial to escalate to root outside. -- David A. Holland dholl...@netbsd.org
re: fexecve
not really commenting on the proposal itself, but .. > Let us not forget that you need a binary inside the chroot that can > call fexecve() on a file descriptor or the ability to build such a > binary. this is only one buffer overflow away... ie, strength in layers would imply you should not rely this. .mrg.
Re: fexecve
>> (I'd actually _like_ to see something capabilityish, in which case >> "can use fexecve" would be a capability that could be removed, from >> init if need be, on systems that care about this sort of thing.) > Couldn't we have an enable/disable sysctl variable for this? Certainly. I would count that as "something capabilityish" - after all, assuming it's per-process, in what ways, aside from the APIs used to control it, does that differ from a capability? Or, to return for a moment to my roots, $ SET PROC/PRIV=FEXECVE /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Re: fexecve
> Date: Sun, 8 Sep 2019 14:03:03 -0400 > From: Thor Lancelot Simon > > On Sun, Sep 08, 2019 at 01:23:46PM -0400, Christos Zoulas wrote: > > > > Here's a simple fexecve(2) implementation. Comments? > > I think this is dangerous in systems which use chroot into filesystems > mounted noexec (or nosuid) and file-descriptor passing into the constrained > environment to feed data. Now new executables (and even setuid ones) can > be fed in, too. > > What can we do about that? It sounds like you're positing: - there is a chrooted process A - there is a colluding process B outside the chroot - they share a socket - B can open setuid executables and send their fds over the socket - A can now execute setuid executables outside the chroot How is this substantively different from the following? - there is a chrooted process A - there is a colluding process B outside the chroot - they share a socket - A can ask B to execute files by pathname and B will happily oblige - A can now execute setuid executables outside the chroot That is, under what meaningful circumstances can you rule out the first scenario but not the second one?
Re: fexecve
On Sun, 8 Sep 2019, Mouse wrote: (2) Losing the command name isn't good; lots of people turn process accounting on for logging (in fact, I'd assume 99.9% of people who turn process accounting on use it purely for logging) and it substantially decreases the utility if it's easily circumvented. Isn't the command name easy to lose and/or forge already, with links if nothng else? In any case, it seems to me this is one reason to make fexecve() optional. (I'd actually _like_ to see something capabilityish, in which case "can use fexecve" would be a capability that could be removed, from init if need be, on systems that care about this sort of thing.) Couldn't we have an enable/disable sysctl variable for this? (3) Setugid processes should be prohibited, or at least setugid dynamically-linked processes, because otherwise there's a window where a live update of a library might be used to run the old binary with a new set of libraries. How does fexecve() make anything possible here that wasn't possible before? It seems to me that updating .so libraries has always carried this risk, so I must be missing something. /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTML mo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B !DSPAM:5d756850213181273910470! ++--+---+ | Paul Goyette | PGP Key fingerprint: | E-mail addresses: | | (Retired) | FA29 0E3B 35AF E8AE 6651 | p...@whooppee.com | | Software Developer | 0786 F758 55DE 53BA 7731 | pgoye...@netbsd.org | ++--+---+
Re: fexecve
> (2) Losing the command name isn't good; lots of people turn process > accounting on for logging (in fact, I'd assume 99.9% of people who > turn process accounting on use it purely for logging) and it > substantially decreases the utility if it's easily circumvented. Isn't the command name easy to lose and/or forge already, with links if nothng else? In any case, it seems to me this is one reason to make fexecve() optional. (I'd actually _like_ to see something capabilityish, in which case "can use fexecve" would be a capability that could be removed, from init if need be, on systems that care about this sort of thing.) > (3) Setugid processes should be prohibited, or at least setugid > dynamically-linked processes, because otherwise there's a window > where a live update of a library might be used to run the old binary > with a new set of libraries. How does fexecve() make anything possible here that wasn't possible before? It seems to me that updating .so libraries has always carried this risk, so I must be missing something. /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Re: fexecve
Christos Zoulas wrote: > - We can completely dissallow fexecve in chrooted environments. Full disk encryption (loaded with cgdroot.kmod) requires a complete system to be chrooted. -- Alex
Re: fexecve
> Here's a simple fexecve(2) implementation. Comments? Strikes me as a very good thing to have optionally available. I'd need to think a good deal more to decide whether I think it's a reasonable thing to have enabled by default. /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Re: fexecve
On Sun, Sep 08, 2019 at 01:23:46PM -0400, Christos Zoulas wrote: > Here's a simple fexecve(2) implementation. Comments? Two additional things come to mind besides the chroot issue: (1) For consistency of permission handling, it ought to require that the file be opened with O_EXEC, and check the execute bit at open time, not at exec time. However, I imagine that doing so is against whoever defined fexecve(). It also would create a gap in which a process could store up references to files that were previously executable and execute them later, perhaps after they've been modified. So that isn't unproblematic. But without that there are going to be a pile of odd corner cases, which I doubt we'll be able to identify in full beforehand, and some of which may turn out to be problematic as well. One that comes to mind is: if you open a program file for write while it's initially being written out, you can save that handle and use it later (after chmod) to both alter the program and execute it. On its own this isn't much use, but I'm not convinced that it can't be in combination with other circumstances. (2) Losing the command name isn't good; lots of people turn process accounting on for logging (in fact, I'd assume 99.9% of people who turn process accounting on use it purely for logging) and it substantially decreases the utility if it's easily circumvented. Also, breaking $ORIGIN for fexecve will probably lead to howling eventually. Not trivial to fix though. (3) Setugid processes should be prohibited, or at least setugid dynamically-linked processes, because otherwise there's a window where a live update of a library might be used to run the old binary with a new set of libraries. At least with ELF this can easily lead to UB that might be exploitable. -- David A. Holland dholl...@netbsd.org
Re: fexecve
In article <20190908183938.ga25...@panix.com>, Thor Lancelot Simon wrote: >On Sun, Sep 08, 2019 at 06:27:11PM -, Christos Zoulas wrote: >> In article <20190908180303.ga6...@panix.com>, >> Thor Lancelot Simon wrote: >> >On Sun, Sep 08, 2019 at 01:23:46PM -0400, Christos Zoulas wrote: >> >> >> >> Here's a simple fexecve(2) implementation. Comments? >> > >> >I think this is dangerous in systems which use chroot into filesystems >> >mounted noexec (or nosuid) and file-descriptor passing into the constrained >> >environment to feed data. Now new executables (and even setuid ones) can >> >be fed in, too. >> > >> >What can we do about that? >> >> - We can completely dissallow fexecve in chrooted environments. >> >> or >> >> - We can check the permissions of the mountpoint of the current working >> directory in addition to checking the mountpoint of the executable's >> vnode. > >I'd like to figure out a way to make this _optional_ in chrooted environments >because I think in a system designed to use it, it actually could provide a >security enhancement. At the same time, I'm worried about the effect on >systems designed as sketched out above but without this feature in mind. > >But I'm having trouble thinking through how it'd work. A flag of course and >a test, but on what -- the receive side of the socket when the chroot's >performed, perhaps? > >Or, maybe: > >1) Find a way to take the properties of the listen socket from which the > received-on socket was cloned into account; so if I chroot-then-listen > and I don't have a writable, executable filesystem in which to create > my listening socket, I can't receive an executable fd that way > >2) At chroot time, block executable fd passing on any socket that hasn't > been deliberately marked as "can receive executables" with fcntl > >Maybe those two in combination (neither looks easy, from my memory of the >relevant code, particularly #1) would work? Let us not forget that you need a binary inside the chroot that can call fexecve() on a file descriptor or the ability to build such a binary. christos
Re: fexecve
On Sun, Sep 08, 2019 at 06:27:11PM -, Christos Zoulas wrote: > In article <20190908180303.ga6...@panix.com>, > Thor Lancelot Simon wrote: > >On Sun, Sep 08, 2019 at 01:23:46PM -0400, Christos Zoulas wrote: > >> > >> Here's a simple fexecve(2) implementation. Comments? > > > >I think this is dangerous in systems which use chroot into filesystems > >mounted noexec (or nosuid) and file-descriptor passing into the constrained > >environment to feed data. Now new executables (and even setuid ones) can > >be fed in, too. > > > >What can we do about that? > > - We can completely dissallow fexecve in chrooted environments. > > or > > - We can check the permissions of the mountpoint of the current working > directory in addition to checking the mountpoint of the executable's > vnode. I'd like to figure out a way to make this _optional_ in chrooted environments because I think in a system designed to use it, it actually could provide a security enhancement. At the same time, I'm worried about the effect on systems designed as sketched out above but without this feature in mind. But I'm having trouble thinking through how it'd work. A flag of course and a test, but on what -- the receive side of the socket when the chroot's performed, perhaps? Or, maybe: 1) Find a way to take the properties of the listen socket from which the received-on socket was cloned into account; so if I chroot-then-listen and I don't have a writable, executable filesystem in which to create my listening socket, I can't receive an executable fd that way 2) At chroot time, block executable fd passing on any socket that hasn't been deliberately marked as "can receive executables" with fcntl Maybe those two in combination (neither looks easy, from my memory of the relevant code, particularly #1) would work? Thor
Re: fexecve
In article <20190908180303.ga6...@panix.com>, Thor Lancelot Simon wrote: >On Sun, Sep 08, 2019 at 01:23:46PM -0400, Christos Zoulas wrote: >> >> Here's a simple fexecve(2) implementation. Comments? > >I think this is dangerous in systems which use chroot into filesystems >mounted noexec (or nosuid) and file-descriptor passing into the constrained >environment to feed data. Now new executables (and even setuid ones) can >be fed in, too. > >What can we do about that? - We can completely dissallow fexecve in chrooted environments. or - We can check the permissions of the mountpoint of the current working directory in addition to checking the mountpoint of the executable's vnode. christos
Re: fexecve
On Sun, Sep 08, 2019 at 01:23:46PM -0400, Christos Zoulas wrote: > > Here's a simple fexecve(2) implementation. Comments? I think this is dangerous in systems which use chroot into filesystems mounted noexec (or nosuid) and file-descriptor passing into the constrained environment to feed data. Now new executables (and even setuid ones) can be fed in, too. What can we do about that? Thor
Re: fexecve, round 3
On Sun, Nov 25, 2012 at 10:58:01PM -0500, Thor Lancelot Simon wrote: Yes, I agree there is no security hazard introduced: if help from a process outside the chroot is assumed, there are already many ways to cirumvent chroot security. And I strongly disagree. We've discussed this at painful length in the earlier threads on this topic and I don't really, at this time, want to restate the entire discussion; nor do I think I should need to. Then please point me to the message that addresses the objection above. I did not meant to shortcut your contribution to the discussion, I just must have missed it in the long threads, I think this is an unfortunate effect of the way we are discussing this (round 1, round 2, round 3, each as a separate thread The idea is to try summing up the previous discussions. I may sometimes fail at this task, but the intent is to make the rthing more readable. -- Emmanuel Dreyfus m...@netbsd.org
Re: fexecve, round 3
Does anyone know of a setup that uses a process outside of a chroot doing descriptor passing to a chrooted process? I wonder if we should disallow that completely (i.e. fail the anxiliary data send if sender and recipient have different p_cwdi-cwdi_rdir)? Martin
Re: fexecve, round 3
On Mon, Nov 26, 2012 at 10:18:42AM +0100, Martin Husemann wrote: Does anyone know of a setup that uses a process outside of a chroot doing descriptor passing to a chrooted process? Yes. I mentioned some earlier in this discussion, before the thread jumps. I don't have time to write it up again now. I'll try to find the time later today. Thor
Re: fexecve, round 3
On Mon, Nov 26, 2012 at 10:18:42AM +0100, Martin Husemann wrote: Does anyone know of a setup that uses a process outside of a chroot doing descriptor passing to a chrooted process? Yes. I can point to the same example as Thor has described, but I think that it is easy to cook up numerous useful examples. I wonder if we should disallow that completely (i.e. fail the anxiliary data send if sender and recipient have different p_cwdi-cwdi_rdir)? This idea of failing the ancillary data transmission seems unnecessarily inflexible to me. I think that if process A has a send descriptors privilege, and process B has a receive descriptors privilege, and there is some communications channel from A to B, then A should be able to send a descriptor to B regardless of the origin or properties of that descriptor. B's privileges may not be sufficient to use certain methods of the descriptor---for example, to fexecve() the descriptor---but I think that is ok, because B's entire purpose may be to send the descriptor to a third process that can use the descriptor. Dave -- David Young dyo...@pobox.comUrbana, IL(217) 721-9981
Re: fexecve, round 3
On Sat, Nov 24, 2012 at 06:53:16PM +0100, Emmanuel Dreyfus wrote: Let's try to move forward, and I will start will a sum up of what I understand from the standard. It would be nice if we could at least reach consensus on standard interpretation. I think your interpretation of the standard is correct. The particularly problematic part is: O_EXEC is mutually exclusive with O_RDONLY, O_WRONLY, or O_RDWR This -- along with the basic shift from checking permissions when a handle to an object is obtained to checking them when it's used -- is exemplary of the poor design that seems to have gone into this set of features. Does everyone agrees on this interpretation? If we do, next steps are - describe threats this introduce to chrooted processes - decide if they are acceptable and if they are not, propose mitigation. I think you left out part of the solution space: - simply don't include this poorly-designed functionality in NetBSD. Thor
Re: fexecve, round 3
In article 20121125152520.ga17...@panix.com, Thor Lancelot Simon t...@panix.com wrote: On Sat, Nov 24, 2012 at 06:53:16PM +0100, Emmanuel Dreyfus wrote: Let's try to move forward, and I will start will a sum up of what I understand from the standard. It would be nice if we could at least reach consensus on standard interpretation. I think your interpretation of the standard is correct. The particularly problematic part is: O_EXEC is mutually exclusive with O_RDONLY, O_WRONLY, or O_RDWR This -- along with the basic shift from checking permissions when a handle to an object is obtained to checking them when it's used -- is exemplary of the poor design that seems to have gone into this set of features. Does everyone agrees on this interpretation? If we do, next steps are - describe threats this introduce to chrooted processes - decide if they are acceptable and if they are not, propose mitigation. I think you left out part of the solution space: - simply don't include this poorly-designed functionality in NetBSD. Unless you want to change O_RDONLY to be non-zero and version all the syscalls that use it :-) christos
Re: fexecve, round 3
O_EXEC is mutually exclusive with O_RDONLY, O_WRONLY, or O_RDWR - simply don't include this poorly-designed functionality in NetBSD. Unless you want to change O_RDONLY to be non-zero and version all the syscalls that use it :-) I don't see any need to do that, unless they were crazy enough to _require_ that the implementation error out if O_EXEC is combined with one of the other three. (I would expect that to just be an application error, which an implementation may choose to assign meaning to.) /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Re: fexecve, round 3
On Sun, Nov 25, 2012 at 07:54:59PM +, Christos Zoulas wrote: Does everyone agrees on this interpretation? If we do, next steps are - describe threats this introduce to chrooted processes Given a chrooted process would need a helping process outside the chroot (to pass it the fd), why is allowing the chrooted proccess to exec something any different from it arranging to get the helper to do it? I think it can only matter if the uid of the chroot is root. Even then you could (probably) do nothing you couldn;t do by mmaping some anon space with exec permissions and writing code to it. FWIW IIRC the standard says that O_EXEC can't be applied with O_READONLY (Or O_RDWR) but does it say that you can't read from a file opened O_EXEC ? David -- David Laight: da...@l8s.co.uk
Re: fexecve, round 3
On Sun, Nov 25, 2012 at 11:47:14PM +, David Laight wrote: On Sun, Nov 25, 2012 at 07:54:59PM +, Christos Zoulas wrote: Does everyone agrees on this interpretation? If we do, next steps are - describe threats this introduce to chrooted processes Given a chrooted process would need a helping process outside the chroot (to pass it the fd), why is allowing the chrooted proccess to exec something any different from it arranging to get the helper to do it? I think it can only matter if the uid of the chroot is root. Even then you could (probably) do nothing you couldn;t do by mmaping some anon space with exec permissions and writing code to it. This thread has been a little long so I am not sure if the setuid programs have been adequately addressed but certainly it is not necessarily safe to execute those in a chroot(2)ed environment as many of them will have assumptions about files such as /etc/spwd.db and so on. We should not just consider setuid programs that we ship but also designs that previously were safe that this model would make unsafe. Another example that I've seen people do is putting secret information such as passwds into programs and give them mode 111 so that it is not easy to read the information. Granted, it doesn't make it terribly difficult to get the information but it still might not be appropriate to allow chrooted applications to exec these programs as I don't think that even if passed an fd that they could mmap(2) and jump. -- Roland Dowdeswell http://Imrryr.ORG/~elric/
Re: fexecve, round 3
David Laight da...@l8s.co.uk wrote: Given a chrooted process would need a helping process outside the chroot (to pass it the fd), why is allowing the chrooted proccess to exec something any different from it arranging to get the helper to do it? Yes, I agree there is no security hazard introduced: if help from a process outside the chroot is assumed, there are already many ways to cirumvent chroot security. FWIW IIRC the standard says that O_EXEC can't be applied with O_READONLY (Or O_RDWR) but does it say that you can't read from a file opened O_EXEC ? I understand you could not, and this bit is annoying to implement. -- Emmanuel Dreyfus http://hcpnet.free.fr/pubz m...@netbsd.org
Re: fexecve, round 3
On Mon, Nov 26, 2012 at 03:22:42AM +0100, Emmanuel Dreyfus wrote: David Laight da...@l8s.co.uk wrote: Given a chrooted process would need a helping process outside the chroot (to pass it the fd), why is allowing the chrooted proccess to exec something any different from it arranging to get the helper to do it? Yes, I agree there is no security hazard introduced: if help from a process outside the chroot is assumed, there are already many ways to cirumvent chroot security. And I strongly disagree. We've discussed this at painful length in the earlier threads on this topic and I don't really, at this time, want to restate the entire discussion; nor do I think I should need to. I think this is an unfortunate effect of the way we are discussing this (round 1, round 2, round 3, each as a separate thread starting with a call for anyone objecting to restate their objections to this code going into the tree). There have been many objections, some subtle and not trivial to restate, and much discussion besides of the broken nature of this specification itself. Why must we go 'round in circles? NetBSD's only blanket statement on standards conformance of which I am aware is that NetBSD tries to confirm to reasonable standards, specifically calling out the ancestor of the standard we're talking about here as an unreasonable one. Why should this discussion take place under what seems to be the basic assumption that if those opposed to this code going into the tree can simply be forced to talk until they're sick of talking any more, these interfaces should go into the tree because they're (poorly) described in some standard, somewhere? That seems wrong. Thor
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