Re: fexecve, round 2

2012-11-19 Thread Emmanuel Dreyfus
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

2012-11-19 Thread David Laight
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

2012-11-19 Thread David Laight
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

2012-11-19 Thread Julian Yon
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

2012-11-19 Thread Emmanuel Dreyfus
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

2012-11-19 Thread Thor Lancelot Simon
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

2012-11-19 Thread David Laight
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

2012-11-19 Thread Emmanuel Dreyfus
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

2012-11-19 Thread John Nemeth
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

2012-11-18 Thread David Laight
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

2012-11-18 Thread Emmanuel Dreyfus
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

2012-11-18 Thread David Holland
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

2012-11-18 Thread Emmanuel Dreyfus
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

2012-11-18 Thread David Holland
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

2012-11-18 Thread David Holland
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

2012-11-18 Thread Julian Yon
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

2012-11-18 Thread David Holland
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


fexecve, round 2

2012-11-17 Thread Emmanuel Dreyfus
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.

First point avoids executing code from outside the chroot
Second point enforces W^X inside the chroot.

Opinions?

-- 
Emmanuel Dreyfus
http://hcpnet.free.fr/pubz
m...@netbsd.org


Re: fexecve, round 2

2012-11-17 Thread Matt Thomas

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

2012-11-17 Thread Thor Lancelot Simon
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

2012-11-17 Thread Emmanuel Dreyfus
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