Package: nfs-common Version: 1:1.2.6-3 Severity: grave Tags: security Justification: user security hole
Dear Maintainers, I've recetly set up an NFSv4 server and I found that ID mapping does always work as expected, allowing a user to read files they should not have access to (and preventing them to access files they should have access to). To demonstrate, I have set up a test NFS client and server pair, both running wheezy. I've created users test1 and test2 in /etc/passwd, but with swapped UID's: SERVER ---------------------------------------- test1:x:5000:5000::/home/test1:/bin/bash test2:x:5001:5001::/home/test2:/bin/bash ---------------------------------------- CLIENT ---------------------------------------- test2:x:5000:5000::/home/test2:/bin/bash test1:x:5001:5001::/home/test1:/bin/bash ---------------------------------------- On the server, I have /srv/nfs exported; the output of "exportfs -a" is: ---------------------------------------- /srv/nfs <world> ---------------------------------------- To demonstrate the problem, I've crafted a script, which does the following: * creates a file on the client as user test1 (a); * created two files on the server, one as user test1 (b), one as user test2 (c); * runs "ls -l" on the files, both on the server and the client, to check the ownerships/permissions reported; * tries to read the files, both as user test1 and test2, both on the server and the client. What I've found is that * the file created on the client by user1 (a) shows up owned by user2 both on the server and the client --> BUG * the files created on the server (b and c) appear as expected both on the client and the server --> OK * on the client, user1 - can open the file created by user1 on the client (a) --> OK - cannot open the file created by user1 on the server (b) --> BUG - can open the file created by user2 on the server (c) --> SECURITY * on the client, user2 - cannot open the file created by user1 on client (a) --> OK - can open the file created by user1 on the server (b) --> SECURITY - cannot open the file created by user2 on the server (c) --> BUG * on the server, user1 - cannot open the file created by user1 on client (a) --> BUG - can open the file created by user1 on the server (b) --> OK - cannot open the file created by user2 on the server (c) --> OK * on the server, user2 - can open the file created by user1 on client (a) --> SECURITY - cannot open the file created by user1 on the server (b) --> OK - cannot open the file created by user2 on the server (c) --> OK The transscript and the debug output of rpc.idmapd on both the server and the client is attached. While my understanding of ID mapping is limited, I found it strange that according to the debug log, nfs4_name_to_uid doesn't get called on the client for user1 when creating the file. The transcript is the following: (NB: the script started on the client, and before it started, nfs-common was stopped on both client and server, there were no nfs mounts on the client, and the test directory was empty) ---------------------------------------- # date Wed Mar 6 17:15:57 CET 2013 # SRV=192.168.56.102 # /etc/init.d/nfs-common start Starting NFS common utilities: statd idmapd. rpc.idmapd: libnfsidmap: using domain: localdomain rpc.idmapd: libnfsidmap: Realms list: 'LOCALDOMAIN' rpc.idmapd: libnfsidmap: loaded plugin /lib/i386-linux-gnu/libnfsidmap/nsswitch.so for method nsswitch # ssh $SRV /etc/init.d/nfs-common start Starting NFS common utilities: statd idmapd. rpc.idmapd: libnfsidmap: using domain: localdomain rpc.idmapd: libnfsidmap: Realms list: 'LOCALDOMAIN' rpc.idmapd: libnfsidmap: loaded plugin /lib/i386-linux-gnu/libnfsidmap/nsswitch.so for method nsswitch # mount $SRV:/ /mnt; mount -t nfs,nfs4 192.168.56.102:/ on /mnt type nfs4 (rw,relatime,vers=4,rsize=65536,wsize=65536,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.56.101,minorversion=0,local_lock=none,addr=192.168.56.102) # sudo -u test1 sh -c "touch /mnt/srv/nfs/test/a; chmod 600 /mnt/srv/nfs/test/a" # ssh $SRV sudo -u test1 "touch /srv/nfs/test/b; chmod 600 /srv/nfs/test/b" # ssh $SRV sudo -u test2 "touch /srv/nfs/test/c; chmod 600 /srv/nfs/test/c" # sleep 3; date Wed Mar 6 17:16:01 CET 2013 # ls --full-time /mnt/srv/nfs/test total 0 -rw------- 1 test2 test2 0 2013-03-06 17:15:58.000000000 +0100 a -rw------- 1 test1 test1 0 2013-03-06 17:15:58.000000000 +0100 b -rw------- 1 test2 test2 0 2013-03-06 17:15:58.000000000 +0100 c # ssh $SRV ls --full-time /srv/nfs/test total 0 -rw------- 1 test2 test2 0 2013-03-06 17:15:58.000000000 +0100 a -rw------- 1 test1 test1 0 2013-03-06 17:15:58.000000000 +0100 b -rw------- 1 test2 test2 0 2013-03-06 17:15:58.000000000 +0100 c # sudo -u test1 cat /mnt/srv/nfs/test/* cat: /mnt/srv/nfs/test/b: Permission denied # sudo -u test2 cat /mnt/srv/nfs/test/* cat: /mnt/srv/nfs/test/a: Permission denied cat: /mnt/srv/nfs/test/c: Permission denied # ssh $SRV sudo -u test1 cat /srv/nfs/test/* cat: /srv/nfs/test/a: Permission denied cat: /srv/nfs/test/c: Permission denied # ssh $SRV sudo -u test2 cat /srv/nfs/test/* cat: /srv/nfs/test/b: Permission denied ---------------------------------------- The log on the client shows the following: ---------------------------------------- Mar 6 17:15:57 adeb rpc.idmapd[11306]: libnfsidmap: using domain: localdomain Mar 6 17:15:57 adeb rpc.idmapd[11306]: libnfsidmap: Realms list: 'LOCALDOMAIN' Mar 6 17:15:57 adeb rpc.idmapd[11306]: libnfsidmap: loaded plugin /lib/i386-linux-gnu/libnfsidmap/nsswitch.so for method nsswitch Mar 6 17:15:57 adeb rpc.idmapd[11307]: Expiration time is 600 seconds. Mar 6 17:15:57 adeb rpc.idmapd[11307]: Opened /proc/net/rpc/nfs4.nametoid/channel Mar 6 17:15:57 adeb rpc.idmapd[11307]: Opened /proc/net/rpc/nfs4.idtoname/channel Mar 6 17:15:58 adeb rpc.idmapd[11307]: New client: 65 Mar 6 17:15:58 adeb rpc.idmapd[11307]: Opened /var/lib/nfs/rpc_pipefs/nfs/clnt65/idmap Mar 6 17:15:58 adeb rpc.idmapd[11307]: New client: 66 Mar 6 17:15:58 adeb rpc.idmapd[11307]: nfs4_name_to_uid: calling nsswitch->name_to_uid Mar 6 17:15:58 adeb rpc.idmapd[11307]: nss_getpwnam: name 'root@localdomain' domain 'localdomain': resulting localname 'root' Mar 6 17:15:58 adeb rpc.idmapd[11307]: nfs4_name_to_uid: nsswitch->name_to_uid returned 0 Mar 6 17:15:58 adeb rpc.idmapd[11307]: nfs4_name_to_uid: final return value is 0 Mar 6 17:15:58 adeb rpc.idmapd[11307]: Client 65: (user) name "root@localdomain" -> id "0" Mar 6 17:15:58 adeb rpc.idmapd[11307]: nfs4_name_to_gid: calling nsswitch->name_to_gid Mar 6 17:15:58 adeb rpc.idmapd[11307]: nfs4_name_to_gid: nsswitch->name_to_gid returned 0 Mar 6 17:15:58 adeb rpc.idmapd[11307]: nfs4_name_to_gid: final return value is 0 Mar 6 17:15:58 adeb rpc.idmapd[11307]: Client 65: (group) name "root@localdomain" -> id "0" Mar 6 17:15:58 adeb rpc.idmapd[11307]: New client: 67 Mar 6 17:15:58 adeb rpc.idmapd[11307]: nfs4_name_to_uid: calling nsswitch->name_to_uid Mar 6 17:15:58 adeb rpc.idmapd[11307]: nss_getpwnam: name 'test2@localdomain' domain 'localdomain': resulting localname 'test2' Mar 6 17:15:58 adeb rpc.idmapd[11307]: nfs4_name_to_uid: nsswitch->name_to_uid returned 0 Mar 6 17:15:58 adeb rpc.idmapd[11307]: nfs4_name_to_uid: final return value is 0 Mar 6 17:15:58 adeb rpc.idmapd[11307]: Client 65: (user) name "test2@localdomain" -> id "5000" Mar 6 17:15:58 adeb rpc.idmapd[11307]: nfs4_name_to_gid: calling nsswitch->name_to_gid Mar 6 17:15:58 adeb rpc.idmapd[11307]: nfs4_name_to_gid: nsswitch->name_to_gid returned 0 Mar 6 17:15:58 adeb rpc.idmapd[11307]: nfs4_name_to_gid: final return value is 0 Mar 6 17:15:58 adeb rpc.idmapd[11307]: Client 65: (group) name "test2@localdomain" -> id "5000" Mar 6 17:16:01 adeb rpc.idmapd[11307]: nfs4_name_to_uid: calling nsswitch->name_to_uid Mar 6 17:16:01 adeb rpc.idmapd[11307]: nss_getpwnam: name 'test1@localdomain' domain 'localdomain': resulting localname 'test1' Mar 6 17:16:01 adeb rpc.idmapd[11307]: nfs4_name_to_uid: nsswitch->name_to_uid returned 0 Mar 6 17:16:01 adeb rpc.idmapd[11307]: nfs4_name_to_uid: final return value is 0 Mar 6 17:16:01 adeb rpc.idmapd[11307]: Client 65: (user) name "test1@localdomain" -> id "5001" Mar 6 17:16:01 adeb rpc.idmapd[11307]: nfs4_name_to_gid: calling nsswitch->name_to_gid Mar 6 17:16:01 adeb rpc.idmapd[11307]: nfs4_name_to_gid: nsswitch->name_to_gid returned 0 Mar 6 17:16:01 adeb rpc.idmapd[11307]: nfs4_name_to_gid: final return value is 0 Mar 6 17:16:01 adeb rpc.idmapd[11307]: Client 65: (group) name "test1@localdomain" -> id "5001" ---------------------------------------- The log on the server is as follows: ---------------------------------------- Mar 6 17:15:58 adeb-srv rpc.idmapd[31323]: libnfsidmap: using domain: localdomain Mar 6 17:15:58 adeb-srv rpc.idmapd[31323]: libnfsidmap: Realms list: 'LOCALDOMAIN' Mar 6 17:15:58 adeb-srv rpc.idmapd[31323]: libnfsidmap: loaded plugin /lib/i386-linux-gnu/libnfsidmap/nsswitch.so for method nsswitch Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: Expiration time is 600 seconds. Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: Opened /proc/net/rpc/nfs4.nametoid/channel Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: Opened /proc/net/rpc/nfs4.idtoname/channel Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: nfsdcb: authbuf=* authtype=user Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: nfs4_uid_to_name: calling nsswitch->uid_to_name Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: nfs4_uid_to_name: nsswitch->uid_to_name returned 0 Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: nfs4_uid_to_name: final return value is 0 Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: Server : (user) id "0" -> name "root@localdomain" Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: nfsdcb: authbuf=* authtype=group Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: nfs4_gid_to_name: calling nsswitch->gid_to_name Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: nfs4_gid_to_name: nsswitch->gid_to_name returned 0 Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: nfs4_gid_to_name: final return value is 0 Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: Server : (group) id "0" -> name "root@localdomain" Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: nfsdcb: authbuf=* authtype=user Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: nfs4_uid_to_name: calling nsswitch->uid_to_name Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: nfs4_uid_to_name: nsswitch->uid_to_name returned 0 Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: nfs4_uid_to_name: final return value is 0 Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: Server : (user) id "5001" -> name "test2@localdomain" Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: nfsdcb: authbuf=* authtype=group Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: nfs4_gid_to_name: calling nsswitch->gid_to_name Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: nfs4_gid_to_name: nsswitch->gid_to_name returned 0 Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: nfs4_gid_to_name: final return value is 0 Mar 6 17:15:58 adeb-srv rpc.idmapd[31324]: Server : (group) id "5001" -> name "test2@localdomain" Mar 6 17:16:01 adeb-srv rpc.idmapd[31324]: nfsdcb: authbuf=* authtype=user Mar 6 17:16:01 adeb-srv rpc.idmapd[31324]: nfs4_uid_to_name: calling nsswitch->uid_to_name Mar 6 17:16:01 adeb-srv rpc.idmapd[31324]: nfs4_uid_to_name: nsswitch->uid_to_name returned 0 Mar 6 17:16:01 adeb-srv rpc.idmapd[31324]: nfs4_uid_to_name: final return value is 0 Mar 6 17:16:01 adeb-srv rpc.idmapd[31324]: Server : (user) id "5000" -> name "test1@localdomain" Mar 6 17:16:01 adeb-srv rpc.idmapd[31324]: nfsdcb: authbuf=* authtype=group Mar 6 17:16:01 adeb-srv rpc.idmapd[31324]: nfs4_gid_to_name: calling nsswitch->gid_to_name Mar 6 17:16:01 adeb-srv rpc.idmapd[31324]: nfs4_gid_to_name: nsswitch->gid_to_name returned 0 Mar 6 17:16:01 adeb-srv rpc.idmapd[31324]: nfs4_gid_to_name: final return value is 0 Mar 6 17:16:01 adeb-srv rpc.idmapd[31324]: Server : (group) id "5000" -> name "test1@localdomain" ---------------------------------------- -- Package-specific info (client): -- rpcinfo -- program vers proto port service 100000 4 tcp 111 portmapper 100000 3 tcp 111 portmapper 100000 2 tcp 111 portmapper 100000 4 udp 111 portmapper 100000 3 udp 111 portmapper 100000 2 udp 111 portmapper 100024 1 udp 54629 status 100024 1 tcp 53767 status -- /etc/default/nfs-common -- NEED_STATD= STATDOPTS= NEED_IDMAPD= NEED_GSSD= -- /etc/idmapd.conf -- [General] Verbosity = 5 Pipefs-Directory = /var/lib/nfs/rpc_pipefs Domain = localdomain [Mapping] Nobody-User = nobody Nobody-Group = nogroup -- /etc/fstab -- -- System Information (client): Debian Release: 7.0 APT prefers testing-updates APT policy: (500, 'testing-updates'), (500, 'testing') Architecture: i386 (i686) Kernel: Linux 3.2.0-4-686-pae (SMP w/1 CPU core) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages nfs-common depends on: ii adduser 3.113+nmu3 ii initscripts 2.88dsf-41 ii libc6 2.13-38 ii libcap2 1:2.22-1.2 ii libcomerr2 1.42.5-1 ii libdevmapper1.02.1 2:1.02.74-6 ii libevent-2.0-5 2.0.19-stable-3 ii libgssglue1 0.4-2 ii libk5crypto3 1.10.1+dfsg-4 ii libkeyutils1 1.5.5-3 ii libkrb5-3 1.10.1+dfsg-4 ii libmount1 2.20.1-5.3 ii libnfsidmap2 0.25-4 ii libtirpc1 0.2.2-5 ii libwrap0 7.6.q-24 ii lsb-base 4.1+Debian8 ii rpcbind 0.2.0-8 ii ucf 3.0025+nmu3 Versions of packages nfs-common recommends: ii python 2.7.3-4 Versions of packages nfs-common suggests: pn open-iscsi <none> pn watchdog <none> -- Package-specific info (server): -- rpcinfo -- program vers proto port service 100000 4 tcp 111 portmapper 100000 3 tcp 111 portmapper 100000 2 tcp 111 portmapper 100000 4 udp 111 portmapper 100000 3 udp 111 portmapper 100000 2 udp 111 portmapper 100003 2 tcp 2049 nfs 100003 3 tcp 2049 nfs 100003 4 tcp 2049 nfs 100227 2 tcp 2049 100227 3 tcp 2049 100003 2 udp 2049 nfs 100003 3 udp 2049 nfs 100003 4 udp 2049 nfs 100227 2 udp 2049 100227 3 udp 2049 100021 1 udp 46234 nlockmgr 100021 3 udp 46234 nlockmgr 100021 4 udp 46234 nlockmgr 100021 1 tcp 33838 nlockmgr 100021 3 tcp 33838 nlockmgr 100021 4 tcp 33838 nlockmgr 100005 1 udp 34897 mountd 100005 1 tcp 44933 mountd 100005 2 udp 36170 mountd 100005 2 tcp 43139 mountd 100005 3 udp 48328 mountd 100005 3 tcp 39413 mountd 100024 1 udp 42556 status 100024 1 tcp 45143 status -- /etc/default/nfs-common -- NEED_STATD= STATDOPTS= NEED_IDMAPD= NEED_GSSD= -- /etc/idmapd.conf -- [General] Verbosity = 5 Pipefs-Directory = /var/lib/nfs/rpc_pipefs Domain = localdomain [Mapping] Nobody-User = nobody Nobody-Group = nogroup -- System Information (server): Debian Release: 7.0 APT prefers testing-updates APT policy: (500, 'testing-updates'), (500, 'testing') Architecture: i386 (i686) Kernel: Linux 3.2.0-4-686-pae (SMP w/1 CPU core) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages nfs-common depends on: ii adduser 3.113+nmu3 ii initscripts 2.88dsf-41 ii libc6 2.13-38 ii libcap2 1:2.22-1.2 ii libcomerr2 1.42.5-1 ii libdevmapper1.02.1 2:1.02.74-6 ii libevent-2.0-5 2.0.19-stable-3 ii libgssglue1 0.4-2 ii libk5crypto3 1.10.1+dfsg-4 ii libkeyutils1 1.5.5-3 ii libkrb5-3 1.10.1+dfsg-4 ii libmount1 2.20.1-5.3 ii libnfsidmap2 0.25-4 ii libtirpc1 0.2.2-5 ii libwrap0 7.6.q-24 ii lsb-base 4.1+Debian8 ii rpcbind 0.2.0-8 ii ucf 3.0025+nmu3 Versions of packages nfs-common recommends: ii python 2.7.3-4 Versions of packages nfs-common suggests: pn open-iscsi <none> pn watchdog <none> Versions of packages nfs-kernel-server depends on: ii libblkid1 2.20.1-5.3 ii libc6 2.13-38 ii libtirpc1 0.2.2-5 ii libwrap0 7.6.q-24 ii lsb-base 4.1+Debian8 ii ucf 3.0025+nmu3 -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org