3

I have a partition that's NFS-mounted from a Netapp SAN. I can create files in that partition, and I can chown those files to another user, any user, even root. How am I able to do so? I thought the kernel would prevent such a thing. I have done this again and again today, using multiple user IDs on the file.

I cannot do this in /tmp or in my home directory, which is locally-mounted.

I've never seen this behaviour before. Also, I note that setcap/getcap are not found on this machine.

I have checked my shell's capabilities and they are all 0's:

$ echo $$
15007
$ cat /proc/15007/task/15007/status 
Name:   bash
State:  S (sleeping)
SleepAVG:       98%
Tgid:   15007
Pid:    15007
PPid:   14988
TracerPid:      0
Uid:    71579   71579   71579   71579
Gid:    10000   10000   10000   10000
FDSize: 256
Groups: 9000 10000 10001 10013 10018 10420 24611 36021 
...
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000

I am on a Red Hat 5.3 virtual machine:

$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 5.3 (Tikanga)

Running an old kernel:

$ uname -r
2.6.18-274.7.1.el5

The NFS mount uses defaults:

$ cat /etc/fstab
...
mynetapp00:/home /mnt/home nfs defaults 0 0

For user authentication, we're using Windows Active Directory with ldap on the Linux side:

$ grep passwd /etc/nsswitch.conf 
passwd:     files ldap

I'm able to do anthing as sudo:

User mikes may run the following commands on this host:
    (ALL) ALL

because I'm one of the ADMINS (contents of /etc/sudoers):

User_Alias      ADMINS = fred, tom, mikes
ADMINS          ALL=(ALL) ALL

...But I don't know how that's germaine, because sudo isn't involved. In any event, I was able to create a file and give it my ownership as a user "john" who's not found in /etc/sudoers:

# grep john /etc/sudoers
# su - john
$ touch /mnt/home/blah
$ chown mikes /mnt/home/blah   
$ ls -l /mnt/home/blah
-rwxrwxrwx 1 mikes DomainUsers 0 Oct 23 19:45 /mnt/home/blah

...and chown is not aliased (but we knew that, because if chown was an alias or some other program, then I would be able to change ownership in /tmp too):

$ alias
alias l.='ls -d .* --color=tty'
alias ll='ls -l --color=tty'
alias ls='ls --color=tty'
alias vi='vim'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
$ which chown
/bin/chown

P.S. I'm not kidding:

$ id
uid=71579(mikes) gid=10000(DomainUsers)
$ touch /mnt/home/blah
$ chown john /mnt/home/blah
$ ls -l /mnt/home/blah
-rwxrwxrwx 1 john DomainUsers 0 Oct 23 19:04 /mnt/home/blah
$ id john
uid=37554(john) gid=10000(DomainUsers)
$ chmod 755 /mnt/home/blah
chmod: changing permissions of `/mnt/home/blah': Operation not permitted
$ rm /mnt/home/blah
$ ls -l /mnt/home/blah
ls: /mnt/home/blah: No such file or directory
$ touch /tmp/blah
$ chown john /tmp/blah
chown: changing ownership of `/tmp/blah': Operation not permitted
5
  • @Christopher I have assumed that chown was the purview of the kernel. By what mechanism is the NetApp able to tell the kernel, "Pay no attention to your security concerns!"
    – Mike S
    Commented Oct 23, 2017 at 18:14
  • @IporSircer If that was the case (and I thought it was), I'd have no reason to post this question... along with evidence.
    – Mike S
    Commented Oct 23, 2017 at 18:15
  • what does sudo -l show . The args is a lower case L
    – z atef
    Commented Oct 23, 2017 at 18:26
  • @zee added sudo -l stuff.
    – Mike S
    Commented Oct 23, 2017 at 18:51
  • At least I've seen this behaviour before: E.g. on HP-UX, chown had no restrictions (which was a nice way to get around disk quotas...). I can only guess that NFS for some reason doesn't implement _POSIX_CHOWN_RESTRICTED. NFS is quite old, so it could be an oversight ...
    – dirkt
    Commented Oct 23, 2017 at 18:59

3 Answers 3

2

Yes, chown is the purview of the kernel, but remember that the NetApp is beyond the kernel’s arm reach.  For local filesystems, the kernel translates user I/O requests into local hardware I/O operations (on the storage device).  For remote (e.g., NFS) filesystems, the kernel translates user I/O requests into network communications, asking / telling the server to do what the user wants.

There is no guarantee that the server will do as requested.  For example, NetApp servers can be configured to support Unix-style permissions and Windows-style permissions simultaneously.  Unix/Linux clients will see the Unix-style permissions (user, group, mode, and maybe ACL).  Windows clients will see the Windows-style permissions (user but not group, attributes, ACL, and maybe extended attributes).  The NetApp internally stores a combination of the file properties, and enforces access based on some murky, proprietary algorithm, so a Unix operation might be refused because of a Windows-style permission restriction that the Unix client can’t see.

TL;DR
The NetApp server enforces permissions.  Therefore, the NFS driver for NetApp might be written not to do any permission checks, but to send all user requests to the server.  And so the decision to allow the chown to execute is probably being done 100% at the NetApp.

I don’t know why that would happen.  It might be a bug.  That would surprise me a little, since NetApp has been around for 25 years; I would expect a bug that big to be reported and fixed by now.  It might be a configuration setting on the NetApp.  That doesn’t really make sense, but maybe the administrator of the server doesn’t quite understand what he’s doing (or perhaps there is some obscure policy reason why it would be configured this way).

4
  • From the chown Section 2 man page: "Only a privileged process (Linux: one with the CAP_CHOWN capability) may change the owner of a file." Thus, in my mind, the system should be: User -> chown(3) -> chown (2, system call) == kernel, (which checks if the process is privileged) -> NFS subsystem -> NetApp . But you're telling me that Linux sends the request to the NetApp without checking that I have a privileged process, correct? I mean, it could, but it's not...? I get that the NetApp can do what it wants, but the kernel is the gatekeeper.
    – Mike S
    Commented Oct 23, 2017 at 22:19
  • Ok, I was poking around the kernel source and I saw specific filesystem code relegated it their own files. So I think I get it now; I'm going to take a guess: When you said "The NetApp server enforces..." you were too narrow. What's really happening is, "It's up to each filesystem to enforce permissions." Each will have different ways of resolving permissions; NFS has a more complicated job than say ext2 so one size does not fit all. Therefore, the kernel simply hands the chown request to the filesystem (NFS client), who makes the request to the server, who (in this case) blithely accepts it.
    – Mike S
    Commented Oct 23, 2017 at 22:42
  • @Mike the client has no business enforcing security. It will just get in the way, and stop you doing stuff, that may be possible on a different client. It will not add security for the same reason (just use a different client). Security needs to be on the server. Privilege escalation checks however need to be on the client (nodev, nosuid, etc). Commented Oct 9, 2019 at 16:46
  • @ctrl-alt-delor thanks for the clarification. I think we're in agreement on all counts.
    – Mike S
    Commented Oct 27, 2019 at 17:08
0

Another guess is that NFS anonymous access is directly mapped to uid 0 -aka root-, hence you're able to chown as you like, this can be done using anonuid nfs server config parameter and in netapp using the export policy config.

one more note: the shell output you pasted does not prove owner has changed, you have not run "ls -l" before running "chown", so another possibility is that you accessed the NFS export anonymously and the server was configured to map anonymous access to the user name "john", hence the chown command did not have to change anything.

refs:

https://serverfault.com/questions/539267/nfs-share-with-root-for-anonuid-anongid

https://kb.netapp.com/app/answers/answer_view/a_id/1029865/~/how-to-create-a-root-squash-export-policy-rule-on-clustered-data-ontap-

https://linux.die.net/man/5/exports

0

This may shed some light. I use sshfs. It allows me to mount file-systems from remote machines using ssh.

Whenever I do this. All file operations are governed by the user, on the remote machine, that I used to mount the file-system. So if I do:

sshsf «remote-user-name»@«remote-machine-name»:~ «local-mount-point»

Then all operations are done as remote-user. And sudo makes no difference.

If the remote-user has escalated privileges, then any local user gaining access to the mount, will have these escalated privileges.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .