diff mbox series

suggested patch to allow user to access their own file...

Message ID 5FEB204B.9090109@tlinx.org (mailing list archive)
State New, archived
Headers show
Series suggested patch to allow user to access their own file... | expand

Commit Message

L A Walsh Dec. 29, 2020, 12:25 p.m. UTC
xfs_io checks for CAP_SYS_ADMIN in order to open a
file_by_inode -- however, if the file one is opening
is owned by the user performing the call, the call should
not fail.

(i.e. it opens the user's own file).

patch against 5.10.2 is attached.

It gets rid of some unnecessary error messages if you
run xfs_restore to restore one of your own files.

Comments

Brian Foster Jan. 4, 2021, 5:08 p.m. UTC | #1
On Tue, Dec 29, 2020 at 04:25:47AM -0800, L.A. Walsh wrote:
> xfs_io checks for CAP_SYS_ADMIN in order to open a
> file_by_inode -- however, if the file one is opening
> is owned by the user performing the call, the call should
> not fail.
> 
> (i.e. it opens the user's own file).
> 
> patch against 5.10.2 is attached.
> 
> It gets rid of some unnecessary error messages if you
> run xfs_restore to restore one of your own files.
> 

The current logic seems to go a ways back. Can you or somebody elaborate
on whether there's any risks with loosening the permissions as such?
E.g., any reason we might not want to allow regular users to perform
handle lookups, etc.? If not, should some of the other _by_handle() ops
get similar treatment?

> --- fs/xfs/xfs_ioctl.c	2020-12-22 21:11:02.000000000 -0800
> +++ fs/xfs/xfs_ioctl.c	2020-12-29 04:14:48.681102804 -0800
> @@ -194,15 +194,21 @@
>  	struct dentry		*dentry;
>  	fmode_t			fmode;
>  	struct path		path;
> +	bool conditional_perm = 0;

Variable name alignment and I believe we try to use true/false for
boolean values.

>  
> -	if (!capable(CAP_SYS_ADMIN))
> -		return -EPERM;
> +	if (!capable(CAP_SYS_ADMIN)) conditional_perm=1;

This should remain two lines..

>  
>  	dentry = xfs_handlereq_to_dentry(parfilp, hreq);
>  	if (IS_ERR(dentry))
>  		return PTR_ERR(dentry);
>  	inode = d_inode(dentry);
>  
> +	/* only allow user access to their own file */
> +	if (conditional_perm && !inode_owner_or_capable(inode)) {
> +		error = -EPERM;
> +		goto out_dput;
> +	}
> +

... but then again, is there any reason we couldn't just move the
capable() check down to this hunk and avoid the new variable?

Brian

>  	/* Restrict xfs_open_by_handle to directories & regular files. */
>  	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
>  		error = -EPERM;
Darrick J. Wong Jan. 4, 2021, 6:44 p.m. UTC | #2
On Mon, Jan 04, 2021 at 12:08:15PM -0500, Brian Foster wrote:
> On Tue, Dec 29, 2020 at 04:25:47AM -0800, L.A. Walsh wrote:
> > xfs_io checks for CAP_SYS_ADMIN in order to open a
> > file_by_inode -- however, if the file one is opening
> > is owned by the user performing the call, the call should
> > not fail.
> > 
> > (i.e. it opens the user's own file).
> > 
> > patch against 5.10.2 is attached.
> > 
> > It gets rid of some unnecessary error messages if you
> > run xfs_restore to restore one of your own files.

No S-o-B on the patch so I was hesitant to reply, but since Brian did,
I'll reply to that.  This message brought to you by the letters Z, F,
and S.

> The current logic seems to go a ways back. Can you or somebody elaborate
> on whether there's any risks with loosening the permissions as such?

This would open a huge security hole because users can use it to bypass
directory access checks.

Let's say I have a file /home/djwong/bin/pwnme that can be read or
written by the evil bitcom miner in my open Firefox process.  (Hey,
browsers can flash USB device firmware now, ~/bin is the least of my
problems!)

Then let's say the BOFH decides I'm too much of a security risk and
issues:

$ sudo chmod 0000 /home/djwong/bin; sudo chown root:root /home/djwong/bin

(Our overworked BOFH forgot -r and only changed ~/bin.)

Now I cannot access pwnme anymore, because I've been cut off from ~/bin.

With the below patch applied I can now bypass that restriction because I
still own ~/bin/pwnme and therefore can (now) open it by file handle.

We /could/ relax the check so that the caller only has to have one of
CAP_{SYS_ADMIN,DAC_READ_SEARCH,DAC_OVERRIDE} and let the sysadmin decide
if they want to bless xfsrestore with any of those capabilities...

--D

> E.g., any reason we might not want to allow regular users to perform
> handle lookups, etc.? If not, should some of the other _by_handle() ops
> get similar treatment?
> 
> > --- fs/xfs/xfs_ioctl.c	2020-12-22 21:11:02.000000000 -0800
> > +++ fs/xfs/xfs_ioctl.c	2020-12-29 04:14:48.681102804 -0800
> > @@ -194,15 +194,21 @@
> >  	struct dentry		*dentry;
> >  	fmode_t			fmode;
> >  	struct path		path;
> > +	bool conditional_perm = 0;
> 
> Variable name alignment and I believe we try to use true/false for
> boolean values.
> 
> >  
> > -	if (!capable(CAP_SYS_ADMIN))
> > -		return -EPERM;
> > +	if (!capable(CAP_SYS_ADMIN)) conditional_perm=1;
> 
> This should remain two lines..
> 
> >  
> >  	dentry = xfs_handlereq_to_dentry(parfilp, hreq);
> >  	if (IS_ERR(dentry))
> >  		return PTR_ERR(dentry);
> >  	inode = d_inode(dentry);
> >  
> > +	/* only allow user access to their own file */
> > +	if (conditional_perm && !inode_owner_or_capable(inode)) {
> > +		error = -EPERM;
> > +		goto out_dput;
> > +	}
> > +
> 
> ... but then again, is there any reason we couldn't just move the
> capable() check down to this hunk and avoid the new variable?
> 
> Brian
> 
> >  	/* Restrict xfs_open_by_handle to directories & regular files. */
> >  	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
> >  		error = -EPERM;
>
Darrick J. Wong Jan. 4, 2021, 11:15 p.m. UTC | #3
> Cc: bfoster@redhat.com, xfs-oss <xfs@e29208.dscx.akamaiedge.net>

akamaiedge.net ??

Er, did my mailer do that, or did yours?

[re-adding linux-xfs to cc]

On Mon, Jan 04, 2021 at 12:24:14PM -0800, L A Walsh wrote:
> 
> 
> On 2021/01/04 10:44, Darrick J. Wong wrote:
> > This would open a huge security hole because users can use it to bypass
> > directory access checks.
> ---
> 	Can't say I entirely disagree.  Though given the prevalence of that
> behavior being "normal" on NT due to the "Bypass Traverse Checking" "right"
> being on by default in a standard Windows setup,

That might be true on Windows, but CAP_DAC_* isn't given out by default
on Linux.

> I would question it being a 'huge' security hole, though it would be
> an unwanted change in behavior.

I think people would consider it a hole of /some/ kind, since this patch
wouldn't even require the process to hold CAP_DAC_* privilege.

> 	If a user has a shell open to a directory that is made
> inaccessible in the way you describe, though, simply staying connected
> would seem to allow opening FD's that would be otherwise inaccessible.
> 
> 	Further, can't a user pass an open file descriptor through
> some type of IPC call for the other side to use?  I may be misremembering
> something similar, so I'd have to dig unless someone else remembers.

Yes, they can do both of those things, since the Unix DAC only checks
access at open time.

> 	Though, in the following case:
> > 
> >  have a file /home/djwong/bin/pwnme, r/w by EBM (evil Bitcom minor).
> > then someone issues chmod 0000 on a dir above it...
> > Now I cannot access pwnme anymore, because I've been cut off from ~/bin.
> ----
> 	Oh...but if they hard linked it to someone else's open dir,
> they still could.  It seems if you want to secure the object, you really
> need to alter the perms on object, not on what might be 1 of
> several paths to it.  It might be bind-mounted elsewhere as well.

I /did/ say that the BOFH omitted -r... ;)

> 	Additionally you aren't dealing with removing more permissive
> ACL's...  That said, you're still right in that it opens a new
> potential security hole that anyone from MS would be used to/expecting
> (that's not to be taken as a justification to do it, just as context
> for expectations and level of the security hole.
> 
> 	Conversely, while users may have ownership rights in their
> home dir, they may not have write permissions above that -- possibly
> not even read permissions if that 'nt-right' is ever supported.
> 
> 	I'm guessing it's not easy to check if they might have path
> permissions to get there, though the intervening files could be accessible
> through a group ACL, that the user is a member of. Might
> be good to keep such files only executable by owner.
> 
> 	So I'd beg off on supporting that change now, without some
> other way of checking accessibility (which could be np-hard given
> the number of ways its possible to get around a simple directory blockade).
> 
> 	Given the wide use of linux as a file server, I'm wondering
> how one might support the extra 'right's from windows in some context.
> 
> 	Certainly, if the above scenario was used within a Linux-subsystem running
> on windows, the resulting access modes could
> be complicated.
> 
> 	This is way beyond this question (here, don't patch unless you
> check other CAPs), but wouldn't it make sense to have the ability
> to apply an LSM-model (or set of rules) only to some specific domain
> (in this case path traversal/access over diverse file systems that
> have different rules and capabilities)?

Yeah.  As far as I can tell, CAP_DAC_OVERRIDE actually /does/ give you
the security permissions that you want.  The sysadmin can then decide
who gets to have that permission, so you /could/ propose doing that.

> 	If it isn't possible already, I'm sure it soon will be
> the case that users will be on systems that have different file
> systems mounted.  If an xfs file system is mounted under an NT
> file system and the user is running Windows, wouldn't NT-rights
> (like ignoring traversal issues) apply by default, as NT would
> be in charge of enforcing security as it walked through a locally
> mounted XFS file system?

When would NT be walking through a locally mounted XFS filesystem?

--D
L A Walsh Jan. 5, 2021, 12:03 a.m. UTC | #4
On 2021/01/04 15:15, Darrick J. Wong wrote:
>> Cc: bfoster@redhat.com, xfs-oss <xfs@e29208.dscx.akamaiedge.net>
> 
> akamaiedge.net ??
---
First I've seen that...

> 
> Er, did my mailer do that, or did yours?
> 
> [re-adding linux-xfs to cc]
> 
> On Mon, Jan 04, 2021 at 12:24:14PM -0800, L A Walsh wrote:
>>
>> On 2021/01/04 10:44, Darrick J. Wong wrote:
>>> This would open a huge security hole because users can use it to bypass
>>> directory access checks.
>> ---
>> 	Can't say I entirely disagree.  Though given the prevalence of that
>> behavior being "normal" on NT due to the "Bypass Traverse Checking" "right"
>> being on by default in a standard Windows setup,
> 
> That might be true on Windows, but CAP_DAC_* isn't given out by default
> on Linux.
----
	Not quite the same as I understand it -- it allows ignoring 
an 'X' permission of directories above the target, I believe, but not other
DAC permissions.  I'd have to experiment to be sure.  In their security
settings dialogue, they warn you against changing it away from the default
as it might cause compatibility problems.


> 
>> I would question it being a 'huge' security hole, though it would be
>> an unwanted change in behavior.
> 
> I think people would consider it a hole of /some/ kind, since this patch
> wouldn't even require the process to hold CAP_DAC_* privilege.
---
	Yeah, though it doesn't allow overriding DAC settings on files
or directories that have them when trying to access them, just bypassing
directory traversal permissions for items lower in the hierarchy.


> 
> Yeah.  As far as I can tell, CAP_DAC_OVERRIDE actually /does/ give you
> the security permissions that you want.  The sysadmin can then decide
> who gets to have that permission, so you /could/ propose doing that.
----
	Except that it does more than just allowing directory traversal
to a set of files you own.  Like I think it might not be uncommon to have
some common home dir set restrictively, so you couldn't read who else had
home directories on the system, perhaps, but you could still cd through
it to your own directory.  It may be more like allowing you to 'x' through
parent directories without being able to read/write to them.  CAP_DAC_OVERRIDE
would allow you to override any DAC permissions on any file -- not just
ignore lack of 'X' on a directory.


> 
>> 	If it isn't possible already, I'm sure it soon will be
>> the case that users will be on systems that have different file
>> systems mounted.  If an xfs file system is mounted under an NT
>> file system and the user is running Windows, wouldn't NT-rights
>> (like ignoring traversal issues) apply by default, as NT would
>> be in charge of enforcing security as it walked through a locally
>> mounted XFS file system?
> 
> When would NT be walking through a locally mounted XFS filesystem?
 
Well, at least when it is mounted in a linux subsystem -- I haven't checked
out what's possible, but am told explorer can then be used to move through 
file systems that are locally mounted through the linux drivers.

The other possibility -- is a stretch of locally mounted, in having
an XFS drive mounted via CIFS as a "local" drive.  I'd think it would
allow bypassing traverse checking in the same way that having
NT-admin privileges can give you root access to exported drives, but
you have to set it up so that your login has those privs on the target server,
but less drastic privs, like bypassing traverse checking and having
a read/write access for a user that has the backup+restore privs are likely
also supported.  

As an example, a Domain administrator on my NT workstation has root access
to my server (not by accident, but because it is meant to be that way).

I use Win as a desktop, but lin as my diskspace+server.  My Win desktop barely
has enough diskspace for the OS + programs I have installed.
Dave Chinner Jan. 9, 2021, 9:13 p.m. UTC | #5
On Tue, Dec 29, 2020 at 04:25:47AM -0800, L.A. Walsh wrote:
> xfs_io checks for CAP_SYS_ADMIN in order to open a
> file_by_inode -- however, if the file one is opening
> is owned by the user performing the call, the call should
> not fail.

No. xfs_open_by_handle() requires root permissions because it
bypasses lots of security checks, such as parent directory
permissions, ACLs and security labels.

e.g. backups under a root-only directory heirarchy should not be
accessible to users because users are not allowed to traverse into
those root:root 0700 backup directories because permissions on the 
directory inodes do not allow non-root users to enter them.

Hence ...

> (i.e. it opens the user's own file).

... the user doesn't actually own that file, even though it has
their own UID in it...

> It gets rid of some unnecessary error messages if you
> run xfs_restore to restore one of your own files.

That's not really a user case xfs_restore is intended to support.
It's an admin tool to be run by admins, not end users....

Cheers,

Dave.
diff mbox series

Patch

--- fs/xfs/xfs_ioctl.c	2020-12-22 21:11:02.000000000 -0800
+++ fs/xfs/xfs_ioctl.c	2020-12-29 04:14:48.681102804 -0800
@@ -194,15 +194,21 @@ 
 	struct dentry		*dentry;
 	fmode_t			fmode;
 	struct path		path;
+	bool conditional_perm = 0;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
+	if (!capable(CAP_SYS_ADMIN)) conditional_perm=1;
 
 	dentry = xfs_handlereq_to_dentry(parfilp, hreq);
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 	inode = d_inode(dentry);
 
+	/* only allow user access to their own file */
+	if (conditional_perm && !inode_owner_or_capable(inode)) {
+		error = -EPERM;
+		goto out_dput;
+	}
+
 	/* Restrict xfs_open_by_handle to directories & regular files. */
 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
 		error = -EPERM;