linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* setfsuid() and access() syscall
@ 2009-08-04 20:55 Ondrej Palkovsky
  2009-08-04 21:29 ` Matthew Wilcox
  2009-08-04 21:53 ` Serge E. Hallyn
  0 siblings, 2 replies; 4+ messages in thread
From: Ondrej Palkovsky @ 2009-08-04 20:55 UTC (permalink / raw)
  To: linux-fsdevel

Hello,

the access() syscall (to find out if the user has permission to do 
something on file) does not seem to reflect the setfsuid() syscall. 
There are 2 conflicting pieces of information:

- kernel/sys.c:
/*
 * "setfsuid()" sets the fsuid - the uid used for filesystem checks. This
 * is used for "access()" and for the NFS daemon (letting nfsd stay at
 * whatever uid it wants to). It normally shadows "euid", except when
 * explicitly set by setfsuid() or for access..
 */
- fs/namei.c
/*
 * access() needs to use the real uid/gid, not the effective uid/gid.
 * We do this by temporarily clearing all FS-related capabilities and
 * switching the fsuid/fsgid around to the real ones.
 */

The resulting behaviour (2.6.18, 2.6.28, source code for 2.6.30 seems to 
be the same) seems to be that access() is dependent on uid, not fsuid - 
this seems to me to be a bug, which unfortunately somewhat inhibits 
multithreaded file servers that want to use access() e.g. for ACL 
checks. Is there some reason why it is implemented the way it is as it 
looks like an intention?

Best regards
Ondrej Palkovsky


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: setfsuid() and access() syscall
  2009-08-04 20:55 setfsuid() and access() syscall Ondrej Palkovsky
@ 2009-08-04 21:29 ` Matthew Wilcox
  2009-08-05  7:57   ` Ondrej Palkovsky
  2009-08-04 21:53 ` Serge E. Hallyn
  1 sibling, 1 reply; 4+ messages in thread
From: Matthew Wilcox @ 2009-08-04 21:29 UTC (permalink / raw)
  To: Ondrej Palkovsky; +Cc: linux-fsdevel

On Tue, Aug 04, 2009 at 10:55:35PM +0200, Ondrej Palkovsky wrote:
> /*
> * access() needs to use the real uid/gid, not the effective uid/gid.
> * We do this by temporarily clearing all FS-related capabilities and
> * switching the fsuid/fsgid around to the real ones.
> */
>
> The resulting behaviour (2.6.18, 2.6.28, source code for 2.6.30 seems to  
> be the same) seems to be that access() is dependent on uid, not fsuid -  
> this seems to me to be a bug, which unfortunately somewhat inhibits  
> multithreaded file servers that want to use access() e.g. for ACL  
> checks. Is there some reason why it is implemented the way it is as it  
> looks like an intention?

Unfortunately, POSIX specifies that we have to do it that way:

    The access() function shall check the file named by the pathname
    pointed to by the path argument for accessibility according to the
    bit pattern contained in amode, using the real user ID in place of
    the effective user ID and the real group ID in place of the effective
    group ID.

(http://www.opengroup.org/onlinepubs/000095399/functions/access.html)

Why does this fileserver want to use access()?  WHy not just open the
file and report the error if one happens?

-- 
Matthew Wilcox				Intel Open Source Technology Centre
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours.  We can't possibly take such
a retrograde step."

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: setfsuid() and access() syscall
  2009-08-04 20:55 setfsuid() and access() syscall Ondrej Palkovsky
  2009-08-04 21:29 ` Matthew Wilcox
@ 2009-08-04 21:53 ` Serge E. Hallyn
  1 sibling, 0 replies; 4+ messages in thread
From: Serge E. Hallyn @ 2009-08-04 21:53 UTC (permalink / raw)
  To: Ondrej Palkovsky; +Cc: linux-fsdevel

Quoting Ondrej Palkovsky (ondrap@penguin.cz):
> Hello,
>
> the access() syscall (to find out if the user has permission to do  
> something on file) does not seem to reflect the setfsuid() syscall.  
> There are 2 conflicting pieces of information:
>
> - kernel/sys.c:
> /*
> * "setfsuid()" sets the fsuid - the uid used for filesystem checks. This
> * is used for "access()" and for the NFS daemon (letting nfsd stay at

Good catch that.  This comment needs to be fixed (proposed patch below).

> * whatever uid it wants to). It normally shadows "euid", except when
> * explicitly set by setfsuid() or for access..
> */
> - fs/namei.c
> /*
> * access() needs to use the real uid/gid, not the effective uid/gid.
> * We do this by temporarily clearing all FS-related capabilities and
> * switching the fsuid/fsgid around to the real ones.
> */
>
> The resulting behaviour (2.6.18, 2.6.28, source code for 2.6.30 seems to  
> be the same) seems to be that access() is dependent on uid, not fsuid -  
> this seems to me to be a bug, which unfortunately somewhat inhibits  
> multithreaded file servers that want to use access() e.g. for ACL  
> checks. Is there some reason why it is implemented the way it is as it  
> looks like an intention?
>
> Best regards
> Ondrej Palkovsky

>From d0450cb216753d8c1d2d941bb5f4e15fe7aa2caf Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serue@us.ibm.com>
Date: Tue, 4 Aug 2009 16:49:46 -0500
Subject: [PATCH 1/1] fix setfsuid comment: fsuid is not used for access

Fix the comment above setfsuid which currently says that the
fsuid is used for access().  In fact, ruid is used for access.

Signed-off-by: Serge Hallyn <serue@us.ibm.com>
---
 kernel/sys.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/kernel/sys.c b/kernel/sys.c
index b3f1097..94e6622 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -835,9 +835,11 @@ SYSCALL_DEFINE3(getresgid, gid_t __user *, rgid, gid_t __user *, egid, gid_t __u
 
 /*
  * "setfsuid()" sets the fsuid - the uid used for filesystem checks. This
- * is used for "access()" and for the NFS daemon (letting nfsd stay at
- * whatever uid it wants to). It normally shadows "euid", except when
- * explicitly set by setfsuid() or for access..
+ * is used when setting uid for a new file, for calculating file permissions,
+ * and for the NFS daemon (letting nfsd stay at whatever uid it wants to).
+ *
+ * It normally shadows "euid", except when explicitly set by setfsuid() or
+ * for access..
  */
 SYSCALL_DEFINE1(setfsuid, uid_t, uid)
 {
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: setfsuid() and access() syscall
  2009-08-04 21:29 ` Matthew Wilcox
@ 2009-08-05  7:57   ` Ondrej Palkovsky
  0 siblings, 0 replies; 4+ messages in thread
From: Ondrej Palkovsky @ 2009-08-05  7:57 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: linux-fsdevel

Matthew Wilcox napsal(a):
> Why does this fileserver want to use access()?  WHy not just open the
> file and report the error if one happens
Suppose you want to filter directory and show only the files that the 
user can access - yes, this can be solved by opening the file/directory, 
however this seems to me overkill.
I have recently been implementing a HTTP file server and I wanted to 
show slightly different screens if the user has or does not have write 
access - based on ACL. There is no easy way to do it in multithreaded 
application
 - the access() function does not work. There is an 
euidaccess()/eaccess() libc function, which is not currently syscall - 
it is probably supposed to do the ACL checks in userspace and it doesn't 
currently support ACL's anyway (NotYetImplemented). But doing ACL checks 
in userspace is IMO the wrong way to go - the ACL models differ.

(I have since switched to fork()ed model, but this option might not 
always be available).

And if I understand it correctly, the posix says that there is a problem 
- and it won't be solved.... :(

2. The superuser has complete access to all files on a system. As a 
consequence, programs started by the superuser and switched to the 
effective user ID with lesser privileges cannot use /access/() to test 
their file access permissions.
It was also argued that problem (2) is more easily solved by using 
/open/() 
<http://www.opengroup.org/onlinepubs/000095399/functions/open.html>, 
/chdir/() 
<http://www.opengroup.org/onlinepubs/000095399/functions/chdir.html>, or 
one of the /exec 
<http://www.opengroup.org/onlinepubs/000095399/functions/exec.html>/ 
functions as appropriate and responding to the error, rather than 
creating a new function that would not be as reliable. Therefore, 
/eaccess/() is not included in this volume of IEEE Std 1003.1-2001.

Ondrej



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2009-08-05  7:57 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-08-04 20:55 setfsuid() and access() syscall Ondrej Palkovsky
2009-08-04 21:29 ` Matthew Wilcox
2009-08-05  7:57   ` Ondrej Palkovsky
2009-08-04 21:53 ` Serge E. Hallyn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).