diff mbox

[cifs-utils,v4,2/4] cifs.upcall: switch group IDs when handling an upcall

Message ID 20170215161522.17063-3-jlayton@samba.org (mailing list archive)
State New, archived
Headers show

Commit Message

Jeff Layton Feb. 15, 2017, 4:15 p.m. UTC
Currently, we leave the group ID alone, but in a later patch we'll be
changing cifs.upcall to scrape $KRB5CCNAME out of the originating
process. At that point, we want to be a little more careful with the
process credentials we'll be using.

After we get the uid, do a getpwuid and grab the default gid for the
user. Then use setgid to set it before calling setuid.

Signed-off-by: Jeff Layton <jlayton@samba.org>
---
 cifs.upcall.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

Comments

Jeff Layton Feb. 23, 2017, 12:45 p.m. UTC | #1
On Wed, 2017-02-22 at 11:32 -0600, Chad William Seys wrote:
> Hi Jeff,
>    I'm testing the most recent cifs.upcall (most recent commit 
> "cifs.upcall: trim even more capabilities") .
>    I copied cifs.upcall over the one provided in Debian package of 
> cifs-utils 6.6
>    While testing, one of the things I did was destroy my kerberos ticket 
> and then try to enter a directory in which the user did not have a 
> listing in the ACL, except through membership in a group.  I wasn't able 
> to ls the directory (fine).  However, kinit failed.  ls-ing shows that 
> the credential cache kinit tries to create already exists, but is owned 
> by root.  Uh oh.  :)
>    Looks like root must go create a credential cache file with same name 
> instead of just looking for an existing one.
>    The steps are below:
> 
> cwseys:
> # kdestroy
> # cd /
> 
> root:
> # umount /smb
> # umount /smb  # to be sure!
> 
> cwseys:
> # kinit
> Password for cwseys@PHYSICS.WISC.EDU:
> # ls /tmp/krb5cc_* -al
> -rw------- 1 cwseys cwseys  939 Feb 22 11:06 /tmp/krb5cc_1494_sM11PG
> 
> root:
> # mount -t cifs //smb.physics.wisc.edu/smb /smb 
> -osec=krb5,multiuser,username=smbadmin@PHYSICS.WISC.EDU,cruid='0',uid=0 
> --verbose
> 
> cwseys:
> # cd /smb
> # kdestroy
> # ls /tmp/krb5cc_* -al
> [user's credential cache not listed]
> # cd to a directory on which cwseys not listed directly in ACLs (but
> # indirectly as part of a group)
> # cd obs-cos
> # ls
> ls: reading directory '.': Permission denied
> # kerberos cache file created with root owner/group !
> # The file has bytes in it, but not matching the size above. Wonder
> # what's in it... ?
> # ls /tmp/krb5cc_* -al
> -rw------- 1 root   root   1050 Feb 22 11:09 /tmp/krb5cc_1494_sM11PG
> # now cannot kinit
> # kinit
> Password for cwseys@PHYSICS.WISC.EDU:
> kinit: Failed to store credentials: Internal credentials cache error 
> (filename: /tmp/krb5cc_1494_sM11PG) while getting initial credentials
> 
> root:
> # lets look in the credential cache that was created by root.
> # looks like credentials used by root to mount /smb:
> # klist -c /tmp/krb5cc_1494_sM11PG
> Ticket cache: FILE:/tmp/krb5cc_1494_sM11PG
> Default principal: smbadmin@PHYSICS.WISC.EDU
> 
> Valid starting       Expires              Service principal
> 02/22/2017 11:27:41  03/04/2017 11:27:41 
> krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> 02/22/2017 11:27:41  03/04/2017 11:27:41 
> cifs/smb02.physics.wisc.edu@PHYSICS.WISC.EDU
> 


Let's take this to the linux-cifs mailing list...

To be clear...I assume that you have a keytab set up someplace that has
the smbadmin@ credentials in it, correct? That's the only way that
cifs.upcall would instantiate a new credcache.

It sounds like you're walking into the DFS mount in a task that is
running as root, but that has inherited a KRB5CCNAME environment
variable from a cwseys@ login session.

It might be nice to see the debug level output from syslog, so we can
tell what's actually happening in the upcall. Can you provide that?

Thanks,
Chad William Seys Feb. 23, 2017, 8:18 p.m. UTC | #2
> To be clear...I assume that you have a keytab set up someplace that
> has the smbadmin@ credentials in it, correct? That's the only way
> that cifs.upcall would instantiate a new credcache.

Right.  smbadmin@ credentials are in /etc/krb5.keytab.  'mount' must
check there by default.

> It sounds like you're walking into the DFS mount in a task that is
> running as root, but that has inherited a KRB5CCNAME environment
> variable from a cwseys@ login session.

The task that is walking into the DFS mount is running as 'cwseys' .  My
guess is that when cwseys tries to cd into DFS mount, cifs.upcall or the
kernel is using the wrong name for root's credential cache.

> It might be nice to see the debug level output from syslog, so we can
> tell what's actually happening in the upcall. Can you provide that?


cwseys:
$ kdestroy
$ cd /

root:
# umount /smb
# umount /smb  # to be sure!
# kdestroy
#  ls /tmp/krb5cc_* -al
ls: cannot access '/tmp/krb5cc_*': No such file or directory

cwseys:
$ kinit
Password for cwseys@PHYSICS.WISC.EDU:
$ ls /tmp/krb5cc_* -al
-rw------- 1 cwseys cwseys 939 Feb 23 12:59 /tmp/krb5cc_1494_sM11PG

$ klist -c /tmp/krb5cc_1494_sM11PG
Ticket cache: FILE:/tmp/krb5cc_1494_sM11PG
Default principal: cwseys@PHYSICS.WISC.EDU

Valid starting       Expires              Service principal
02/23/2017 12:59:00  03/05/2017 12:58:57
krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU


root:
# mount -t cifs //smb.physics.wisc.edu/smb /smb
-osec=krb5,multiuser,username=smbadmin@PHYSICS.WISC.EDU --verbose
mount.cifs kernel mount options:
ip=128.104.160.17,unc=\\smb.physics.wisc.edu\smb,sec=krb5,multiuser,user=smbadmin@PHYSICS.WISC.EDU,pass=********

#  ls /tmp/krb5cc_* -al
-rw------- 1 root   root   1046 Feb 23 13:00 /tmp/krb5cc_0
-rw------- 1 cwseys cwseys  939 Feb 23 12:59 /tmp/krb5cc_1494_sM11PG

# klist -c /tmp/krb5cc_0
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: smbadmin@PHYSICS.WISC.EDU

Valid starting       Expires              Service principal
02/23/2017 13:00:01  03/05/2017 13:00:01
krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
02/23/2017 13:00:01  03/05/2017 13:00:01
cifs/smb.physics.wisc.edu@PHYSICS.WISC.EDU

[debug.log after mount]
Feb 23 13:00:01 trog cifs.upcall: key description:
cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160
.17;sec=krb5;uid=0x0;creduid=0x0;user=smbadmin@PHYSICS.WISC.EDU;pid=0x6abf
Feb 23 13:00:01 trog cifs.upcall: ver=2
Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
Feb 23 13:00:01 trog cifs.upcall: sec=1
Feb 23 13:00:01 trog cifs.upcall: uid=0
Feb 23 13:00:01 trog cifs.upcall: creduid=0
Feb 23 13:00:01 trog cifs.upcall: user=smbadmin@PHYSICS.WISC.EDU
Feb 23 13:00:01 trog cifs.upcall: pid=27327
Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
pathname=/proc/27327/environ
Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
FILE:/tmp/krb5cc_0
Feb 23 13:00:01 trog cifs.upcall: get_tgt_time: unable to get principal
Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: getting service
ticket for smb.physics.wisc.edu
Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: obtained service ticket
Feb 23 13:00:01 trog cifs.upcall: Exit status 0
Feb 23 13:00:01 trog cifs.upcall: key description:
cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x0;creduid=0x0;user=smbadmin@PHYSICS.WISC.EDU;pid=0x6abf
Feb 23 13:00:01 trog cifs.upcall: ver=2
Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
Feb 23 13:00:01 trog cifs.upcall: sec=1
Feb 23 13:00:01 trog cifs.upcall: uid=0
Feb 23 13:00:01 trog cifs.upcall: creduid=0
Feb 23 13:00:01 trog cifs.upcall: user=smbadmin@PHYSICS.WISC.EDU
Feb 23 13:00:01 trog cifs.upcall: pid=27327
Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
pathname=/proc/27327/environ
Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
FILE:/tmp/krb5cc_0
Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: getting service
ticket for smb.physics.wisc.edu
Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: obtained service ticket
Feb 23 13:00:01 trog cifs.upcall: Exit status 0
Feb 23 13:00:01 trog cifs.upcall: key description:
cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x5d6;creduid=0x5d6;pid=0x6725
Feb 23 13:00:01 trog cifs.upcall: ver=2
Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
Feb 23 13:00:01 trog cifs.upcall: sec=1
Feb 23 13:00:01 trog cifs.upcall: uid=1494
Feb 23 13:00:01 trog cifs.upcall: creduid=1494
Feb 23 13:00:01 trog cifs.upcall: pid=26405
Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
pathname=/proc/26405/environ
Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
cachename = FILE:/tmp/krb5cc_1494_bkfO2z
Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
FILE:/tmp/krb5cc_1494_bkfO2z
Feb 23 13:00:01 trog cifs.upcall: get_tgt_time: unable to get principal
Feb 23 13:00:01 trog cifs.upcall: Exit status 1

cwseys:
$ cd /smb

[debug.log after cd /smb]
Feb 23 13:05:20 trog cifs.upcall: key description:
cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x5d6;creduid=0x5d6;pid=0x3397
Feb 23 13:05:20 trog cifs.upcall: ver=2
Feb 23 13:05:20 trog cifs.upcall: host=smb.physics.wisc.edu
Feb 23 13:05:20 trog cifs.upcall: ip=128.104.160.17
Feb 23 13:05:20 trog cifs.upcall: sec=1
Feb 23 13:05:20 trog cifs.upcall: uid=1494
Feb 23 13:05:20 trog cifs.upcall: creduid=1494
Feb 23 13:05:20 trog cifs.upcall: pid=13207
Feb 23 13:05:20 trog cifs.upcall: get_cachename_from_process_env:
pathname=/proc/13207/environ
Feb 23 13:05:20 trog cifs.upcall: get_cachename_from_process_env:
cachename = FILE:/tmp/krb5cc_1494_sM11PG
Feb 23 13:05:20 trog cifs.upcall: get_existing_cc: default ccache is
FILE:/tmp/krb5cc_1494_sM11PG
Feb 23 13:05:20 trog cifs.upcall: handle_krb5_mech: getting service
ticket for smb.physics.wisc.edu
Feb 23 13:05:20 trog cifs.upcall: handle_krb5_mech: obtained service ticket
Feb 23 13:05:20 trog cifs.upcall: Exit status 0

$ kdestroy
$ ls /tmp/krb5cc_* -al
-rw------- 1 root root 1046 Feb 23 13:00 /tmp/krb5cc_0

# obs-cos is on a different server - DFS linked.
$ cd obs-cos
$ ls
ls: cannot open directory '.': Permission denied

# kerberos cache file created with root owner/group !
# The file has bytes in it, but not matching the size above. Wonder
# what's in it... ?
$ ls /tmp/krb5cc_* -al
-rw------- 1 root root 1046 Feb 23 13:00 /tmp/krb5cc_0
-rw------- 1 root root 1050 Feb 23 13:05 /tmp/krb5cc_1494_sM11PG

# now cannot kinit
$ kinit
Password for cwseys@PHYSICS.WISC.EDU:
kinit: Failed to store credentials: Internal credentials cache error
(filename: /tmp/krb5cc_1494_sM11PG) while getting initial credentials

root:
# lets look in the credential cache that was created by root.
# looks like credentials used by root to mount /smb:
# My guess is the kernel was trying to stash the
# cifs/smb02.physics.wisc.edu@PHYSICS.WISC.EDU
# kerberos ticket, but put it in krb5cc_1494_sM11PG instead
# of krb5cc_0
# klist -c /tmp/krb5cc_1494_sM11PG
Ticket cache: FILE:/tmp/krb5cc_1494_sM11PG
Default principal: smbadmin@PHYSICS.WISC.EDU

Valid starting       Expires              Service principal
02/23/2017 13:05:59  03/05/2017 13:05:59
krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
02/23/2017 13:05:59  03/05/2017 13:05:59
cifs/smb02.physics.wisc.edu@PHYSICS.WISC.EDU

# klist -c /tmp/krb5cc_0
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: smbadmin@PHYSICS.WISC.EDU

Valid starting       Expires              Service principal
02/23/2017 13:00:01  03/05/2017 13:00:01
krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
02/23/2017 13:00:01  03/05/2017 13:00:01
cifs/smb.physics.wisc.edu@PHYSICS.WISC.EDU

[debug.log after trying to cd obs-cos]
vvvvvvvvvvvvvvvvvvvvvvvvvvvv
I think the error is here:  Notice pid=13207, that belongs
to cwseys but cifs.upcall key description is trying to use uid=0 and 
creduid=0 . The credential cache file is correct, but the uid/creduid 
are not.

cwseys   13207 /bin/bash

Also, in the above the log from 'cd /smb' cifs.upcall used  uid=1494 and 
creduid=1494 .
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Feb 23 13:05:59 trog cifs.upcall: key description:
cifs.spnego;0;0;39010000;ver=0x2;host=smb02.physics.wisc.edu;ip4=128.104.164.79;sec=krb5;uid=0x0;creduid=0x0;user=smbadmin@PHYSICS.WISC.EDU;pid=0x3397
Feb 23 13:05:59 trog cifs.upcall: ver=2
Feb 23 13:05:59 trog cifs.upcall: host=smb02.physics.wisc.edu
Feb 23 13:05:59 trog cifs.upcall: ip=128.104.164.79
Feb 23 13:05:59 trog cifs.upcall: sec=1
Feb 23 13:05:59 trog cifs.upcall: uid=0
Feb 23 13:05:59 trog cifs.upcall: creduid=0
Feb 23 13:05:59 trog cifs.upcall: user=smbadmin@PHYSICS.WISC.EDU
Feb 23 13:05:59 trog cifs.upcall: pid=13207
Feb 23 13:05:59 trog cifs.upcall: get_cachename_from_process_env:
pathname=/proc/13207/environ
Feb 23 13:05:59 trog cifs.upcall: get_cachename_from_process_env:
cachename = FILE:/tmp/krb5cc_1494_sM11PG
Feb 23 13:05:59 trog cifs.upcall: get_existing_cc: default ccache is
FILE:/tmp/krb5cc_1494_sM11PG
Feb 23 13:05:59 trog cifs.upcall: get_tgt_time: unable to get principal
Feb 23 13:05:59 trog cifs.upcall: handle_krb5_mech: getting service
ticket for smb02.physics.wisc.edu
Feb 23 13:05:59 trog cifs.upcall: handle_krb5_mech: obtained service ticket
Feb 23 13:05:59 trog cifs.upcall: Exit status 0
Feb 23 13:05:59 trog cifs.upcall: key description:
cifs.spnego;0;0;39010000;ver=0x2;host=smb02.physics.wisc.edu;ip4=128.104.164.79;sec=krb5;uid=0x5d6;creduid=0x5d6;pid=0x6725
Feb 23 13:05:59 trog cifs.upcall: ver=2
Feb 23 13:05:59 trog cifs.upcall: host=smb02.physics.wisc.edu
Feb 23 13:05:59 trog cifs.upcall: ip=128.104.164.79
Feb 23 13:05:59 trog cifs.upcall: sec=1
Feb 23 13:05:59 trog cifs.upcall: uid=1494
Feb 23 13:05:59 trog cifs.upcall: creduid=1494
Feb 23 13:05:59 trog cifs.upcall: pid=26405
Feb 23 13:05:59 trog cifs.upcall: get_cachename_from_process_env:
pathname=/proc/26405/environ
Feb 23 13:05:59 trog cifs.upcall: get_cachename_from_process_env:
cachename = FILE:/tmp/krb5cc_1494_bkfO2z
Feb 23 13:05:59 trog cifs.upcall: get_existing_cc: default ccache is
FILE:/tmp/krb5cc_1494_bkfO2z
Feb 23 13:05:59 trog cifs.upcall: get_tgt_time: unable to get principal
Feb 23 13:05:59 trog cifs.upcall: Exit status 1
Feb 23 13:06:03 trog cifs.upcall: key description:
cifs.spnego;0;0;39010000;ver=0x2;host=smb02.physics.wisc.edu;ip4=128.104.164.79;sec=krb5;uid=0x5d6;creduid=0x5d6;pid=0x6ba0
Feb 23 13:06:03 trog cifs.upcall: ver=2
Feb 23 13:06:03 trog cifs.upcall: host=smb02.physics.wisc.edu
Feb 23 13:06:03 trog cifs.upcall: ip=128.104.164.79
Feb 23 13:06:03 trog cifs.upcall: sec=1
Feb 23 13:06:03 trog cifs.upcall: uid=1494
Feb 23 13:06:03 trog cifs.upcall: creduid=1494
Feb 23 13:06:03 trog cifs.upcall: pid=27552
Feb 23 13:06:03 trog cifs.upcall: get_cachename_from_process_env:
pathname=/proc/27552/environ
Feb 23 13:06:03 trog cifs.upcall: get_cachename_from_process_env:
cachename = FILE:/tmp/krb5cc_1494_sM11PG
Feb 23 13:06:03 trog cifs.upcall: get_existing_cc: default ccache is
FILE:/tmp/krb5cc_1494_sM11PG
Feb 23 13:06:03 trog cifs.upcall: get_tgt_time: unable to get principal
Feb 23 13:06:03 trog cifs.upcall: Exit status 1

Thanks for your work!
Chad.
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jeff Layton Feb. 23, 2017, 9:10 p.m. UTC | #3
On Thu, 2017-02-23 at 14:18 -0600, Chad William Seys wrote:
> > To be clear...I assume that you have a keytab set up someplace that
> > has the smbadmin@ credentials in it, correct? That's the only way
> > that cifs.upcall would instantiate a new credcache.
> 
> Right.  smbadmin@ credentials are in /etc/krb5.keytab.  'mount' must
> check there by default.
> 
> > It sounds like you're walking into the DFS mount in a task that is
> > running as root, but that has inherited a KRB5CCNAME environment
> > variable from a cwseys@ login session.
> 
> The task that is walking into the DFS mount is running as 'cwseys' .  My
> guess is that when cwseys tries to cd into DFS mount, cifs.upcall or the
> kernel is using the wrong name for root's credential cache.
> 
> > It might be nice to see the debug level output from syslog, so we can
> > tell what's actually happening in the upcall. Can you provide that?
> 
> 
> cwseys:
> $ kdestroy
> $ cd /
> 
> root:
> # umount /smb
> # umount /smb  # to be sure!
> # kdestroy
> #  ls /tmp/krb5cc_* -al
> ls: cannot access '/tmp/krb5cc_*': No such file or directory
> 
> cwseys:
> $ kinit
> Password for cwseys@PHYSICS.WISC.EDU:
> $ ls /tmp/krb5cc_* -al
> -rw------- 1 cwseys cwseys 939 Feb 23 12:59 /tmp/krb5cc_1494_sM11PG
> 
> $ klist -c /tmp/krb5cc_1494_sM11PG
> Ticket cache: FILE:/tmp/krb5cc_1494_sM11PG
> Default principal: cwseys@PHYSICS.WISC.EDU
> 
> Valid starting       Expires              Service principal
> 02/23/2017 12:59:00  03/05/2017 12:58:57
> krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> 
> 
> root:
> # mount -t cifs //smb.physics.wisc.edu/smb /smb
> -osec=krb5,multiuser,username=smbadmin@PHYSICS.WISC.EDU --verbose
> mount.cifs kernel mount options:
> ip=128.104.160.17,unc=\\smb.physics.wisc.edu\smb,sec=krb5,multiuser,user=smbadmin@PHYSICS.WISC.EDU,pass=********
> 
> #  ls /tmp/krb5cc_* -al
> -rw------- 1 root   root   1046 Feb 23 13:00 /tmp/krb5cc_0
> -rw------- 1 cwseys cwseys  939 Feb 23 12:59 /tmp/krb5cc_1494_sM11PG
> 
> # klist -c /tmp/krb5cc_0
> Ticket cache: FILE:/tmp/krb5cc_0
> Default principal: smbadmin@PHYSICS.WISC.EDU
> 
> Valid starting       Expires              Service principal
> 02/23/2017 13:00:01  03/05/2017 13:00:01
> krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> 02/23/2017 13:00:01  03/05/2017 13:00:01
> cifs/smb.physics.wisc.edu@PHYSICS.WISC.EDU
> 
> [debug.log after mount]
> Feb 23 13:00:01 trog cifs.upcall: key description:
> cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160
> .17;sec=krb5;uid=0x0;creduid=0x0;user=smbadmin@PHYSICS.WISC.EDU;pid=0x6abf
> Feb 23 13:00:01 trog cifs.upcall: ver=2
> Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
> Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
> Feb 23 13:00:01 trog cifs.upcall: sec=1
> Feb 23 13:00:01 trog cifs.upcall: uid=0
> Feb 23 13:00:01 trog cifs.upcall: creduid=0
> Feb 23 13:00:01 trog cifs.upcall: user=smbadmin@PHYSICS.WISC.EDU
> Feb 23 13:00:01 trog cifs.upcall: pid=27327
> Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> pathname=/proc/27327/environ
> Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
> FILE:/tmp/krb5cc_0
> Feb 23 13:00:01 trog cifs.upcall: get_tgt_time: unable to get principal
> Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: getting service
> ticket for smb.physics.wisc.edu
> Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: obtained service ticket
> Feb 23 13:00:01 trog cifs.upcall: Exit status 0
> Feb 23 13:00:01 trog cifs.upcall: key description:
> cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x0;creduid=0x0;user=smbadmin@PHYSICS.WISC.EDU;pid=0x6abf
> Feb 23 13:00:01 trog cifs.upcall: ver=2
> Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
> Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
> Feb 23 13:00:01 trog cifs.upcall: sec=1
> Feb 23 13:00:01 trog cifs.upcall: uid=0
> Feb 23 13:00:01 trog cifs.upcall: creduid=0
> Feb 23 13:00:01 trog cifs.upcall: user=smbadmin@PHYSICS.WISC.EDU
> Feb 23 13:00:01 trog cifs.upcall: pid=27327
> Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> pathname=/proc/27327/environ
> Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
> FILE:/tmp/krb5cc_0
> Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: getting service
> ticket for smb.physics.wisc.edu
> Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: obtained service ticket
> Feb 23 13:00:01 trog cifs.upcall: Exit status 0
> Feb 23 13:00:01 trog cifs.upcall: key description:
> cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x5d6;creduid=0x5d6;pid=0x6725
> Feb 23 13:00:01 trog cifs.upcall: ver=2
> Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
> Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
> Feb 23 13:00:01 trog cifs.upcall: sec=1
> Feb 23 13:00:01 trog cifs.upcall: uid=1494
> Feb 23 13:00:01 trog cifs.upcall: creduid=1494
> Feb 23 13:00:01 trog cifs.upcall: pid=26405
> Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> pathname=/proc/26405/environ
> Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> cachename = FILE:/tmp/krb5cc_1494_bkfO2z
> Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
> FILE:/tmp/krb5cc_1494_bkfO2z
> Feb 23 13:00:01 trog cifs.upcall: get_tgt_time: unable to get principal
> Feb 23 13:00:01 trog cifs.upcall: Exit status 1
> 
> cwseys:
> $ cd /smb
> 
> [debug.log after cd /smb]
> Feb 23 13:05:20 trog cifs.upcall: key description:
> cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x5d6;creduid=0x5d6;pid=0x3397
> Feb 23 13:05:20 trog cifs.upcall: ver=2
> Feb 23 13:05:20 trog cifs.upcall: host=smb.physics.wisc.edu
> Feb 23 13:05:20 trog cifs.upcall: ip=128.104.160.17
> Feb 23 13:05:20 trog cifs.upcall: sec=1
> Feb 23 13:05:20 trog cifs.upcall: uid=1494
> Feb 23 13:05:20 trog cifs.upcall: creduid=1494
> Feb 23 13:05:20 trog cifs.upcall: pid=13207
> Feb 23 13:05:20 trog cifs.upcall: get_cachename_from_process_env:
> pathname=/proc/13207/environ
> Feb 23 13:05:20 trog cifs.upcall: get_cachename_from_process_env:
> cachename = FILE:/tmp/krb5cc_1494_sM11PG
> Feb 23 13:05:20 trog cifs.upcall: get_existing_cc: default ccache is
> FILE:/tmp/krb5cc_1494_sM11PG
> Feb 23 13:05:20 trog cifs.upcall: handle_krb5_mech: getting service
> ticket for smb.physics.wisc.edu
> Feb 23 13:05:20 trog cifs.upcall: handle_krb5_mech: obtained service ticket
> Feb 23 13:05:20 trog cifs.upcall: Exit status 0
> 
> $ kdestroy
> $ ls /tmp/krb5cc_* -al
> -rw------- 1 root root 1046 Feb 23 13:00 /tmp/krb5cc_0
> 
> # obs-cos is on a different server - DFS linked.
> $ cd obs-cos
> $ ls
> ls: cannot open directory '.': Permission denied
> 
> # kerberos cache file created with root owner/group !
> # The file has bytes in it, but not matching the size above. Wonder
> # what's in it... ?
> $ ls /tmp/krb5cc_* -al
> -rw------- 1 root root 1046 Feb 23 13:00 /tmp/krb5cc_0
> -rw------- 1 root root 1050 Feb 23 13:05 /tmp/krb5cc_1494_sM11PG
> 
> # now cannot kinit
> $ kinit
> Password for cwseys@PHYSICS.WISC.EDU:
> kinit: Failed to store credentials: Internal credentials cache error
> (filename: /tmp/krb5cc_1494_sM11PG) while getting initial credentials
> 
> root:
> # lets look in the credential cache that was created by root.
> # looks like credentials used by root to mount /smb:
> # My guess is the kernel was trying to stash the
> # cifs/smb02.physics.wisc.edu@PHYSICS.WISC.EDU
> # kerberos ticket, but put it in krb5cc_1494_sM11PG instead
> # of krb5cc_0
> # klist -c /tmp/krb5cc_1494_sM11PG
> Ticket cache: FILE:/tmp/krb5cc_1494_sM11PG
> Default principal: smbadmin@PHYSICS.WISC.EDU
> 
> Valid starting       Expires              Service principal
> 02/23/2017 13:05:59  03/05/2017 13:05:59
> krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> 02/23/2017 13:05:59  03/05/2017 13:05:59
> cifs/smb02.physics.wisc.edu@PHYSICS.WISC.EDU
> 
> # klist -c /tmp/krb5cc_0
> Ticket cache: FILE:/tmp/krb5cc_0
> Default principal: smbadmin@PHYSICS.WISC.EDU
> 
> Valid starting       Expires              Service principal
> 02/23/2017 13:00:01  03/05/2017 13:00:01
> krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> 02/23/2017 13:00:01  03/05/2017 13:00:01
> cifs/smb.physics.wisc.edu@PHYSICS.WISC.EDU
> 
> [debug.log after trying to cd obs-cos]
> vvvvvvvvvvvvvvvvvvvvvvvvvvvv
> I think the error is here:  Notice pid=13207, that belongs
> to cwseys but cifs.upcall key description is trying to use uid=0 and 
> creduid=0 . The credential cache file is correct, but the uid/creduid 
> are not.
> 
> cwseys   13207 /bin/bash
> 
> Also, in the above the log from 'cd /smb' cifs.upcall used  uid=1494 and 
> creduid=1494 .
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 

Yep, that's clearly the issue. The question is how you're ending up in
that situation...

Regardless of how it's happening to you, it's probably possible to fool
the environment scraping like this, by triggering a krb5 upcall from
the context of a setuid program that has inherited the KRB5CCNAME
environment variable from an unprivileged process.

I'm not sure what we can reasonably do about that. I suppose it might
be interesting to dump the Uid: line from /proc/pid/status when we do
this upcall, and see what all of the values are set to. Maybe we can
reject using the credcache if the uid in the upcall doesn't match one
of the values?

I'll see if I can cook up a debug patch sometime soon for that.

> Feb 23 13:05:59 trog cifs.upcall: key description:
> cifs.spnego;0;0;39010000;ver=0x2;host=smb02.physics.wisc.edu;ip4=128.104.164.79;sec=krb5;uid=0x0;creduid=0x0;user=smbadmin@PHYSICS.WISC.EDU;pid=0x3397
> Feb 23 13:05:59 trog cifs.upcall: ver=2
> Feb 23 13:05:59 trog cifs.upcall: host=smb02.physics.wisc.edu
> Feb 23 13:05:59 trog cifs.upcall: ip=128.104.164.79
> Feb 23 13:05:59 trog cifs.upcall: sec=1
> Feb 23 13:05:59 trog cifs.upcall: uid=0
> Feb 23 13:05:59 trog cifs.upcall: creduid=0
> Feb 23 13:05:59 trog cifs.upcall: user=smbadmin@PHYSICS.WISC.EDU
> Feb 23 13:05:59 trog cifs.upcall: pid=13207
> Feb 23 13:05:59 trog cifs.upcall: get_cachename_from_process_env:
> pathname=/proc/13207/environ
> Feb 23 13:05:59 trog cifs.upcall: get_cachename_from_process_env:
> cachename = FILE:/tmp/krb5cc_1494_sM11PG
> Feb 23 13:05:59 trog cifs.upcall: get_existing_cc: default ccache is
> FILE:/tmp/krb5cc_1494_sM11PG
> Feb 23 13:05:59 trog cifs.upcall: get_tgt_time: unable to get principal
> Feb 23 13:05:59 trog cifs.upcall: handle_krb5_mech: getting service
> ticket for smb02.physics.wisc.edu
> Feb 23 13:05:59 trog cifs.upcall: handle_krb5_mech: obtained service ticket
> Feb 23 13:05:59 trog cifs.upcall: Exit status 0
> Feb 23 13:05:59 trog cifs.upcall: key description:
> cifs.spnego;0;0;39010000;ver=0x2;host=smb02.physics.wisc.edu;ip4=128.104.164.79;sec=krb5;uid=0x5d6;creduid=0x5d6;pid=0x6725
> Feb 23 13:05:59 trog cifs.upcall: ver=2
> Feb 23 13:05:59 trog cifs.upcall: host=smb02.physics.wisc.edu
> Feb 23 13:05:59 trog cifs.upcall: ip=128.104.164.79
> Feb 23 13:05:59 trog cifs.upcall: sec=1
> Feb 23 13:05:59 trog cifs.upcall: uid=1494
> Feb 23 13:05:59 trog cifs.upcall: creduid=1494
> Feb 23 13:05:59 trog cifs.upcall: pid=26405
> Feb 23 13:05:59 trog cifs.upcall: get_cachename_from_process_env:
> pathname=/proc/26405/environ
> Feb 23 13:05:59 trog cifs.upcall: get_cachename_from_process_env:
> cachename = FILE:/tmp/krb5cc_1494_bkfO2z
> Feb 23 13:05:59 trog cifs.upcall: get_existing_cc: default ccache is
> FILE:/tmp/krb5cc_1494_bkfO2z
> Feb 23 13:05:59 trog cifs.upcall: get_tgt_time: unable to get principal
> Feb 23 13:05:59 trog cifs.upcall: Exit status 1
> Feb 23 13:06:03 trog cifs.upcall: key description:
> cifs.spnego;0;0;39010000;ver=0x2;host=smb02.physics.wisc.edu;ip4=128.104.164.79;sec=krb5;uid=0x5d6;creduid=0x5d6;pid=0x6ba0
> Feb 23 13:06:03 trog cifs.upcall: ver=2
> Feb 23 13:06:03 trog cifs.upcall: host=smb02.physics.wisc.edu
> Feb 23 13:06:03 trog cifs.upcall: ip=128.104.164.79
> Feb 23 13:06:03 trog cifs.upcall: sec=1
> Feb 23 13:06:03 trog cifs.upcall: uid=1494
> Feb 23 13:06:03 trog cifs.upcall: creduid=1494
> Feb 23 13:06:03 trog cifs.upcall: pid=27552
> Feb 23 13:06:03 trog cifs.upcall: get_cachename_from_process_env:
> pathname=/proc/27552/environ
> Feb 23 13:06:03 trog cifs.upcall: get_cachename_from_process_env:
> cachename = FILE:/tmp/krb5cc_1494_sM11PG
> Feb 23 13:06:03 trog cifs.upcall: get_existing_cc: default ccache is
> FILE:/tmp/krb5cc_1494_sM11PG
> Feb 23 13:06:03 trog cifs.upcall: get_tgt_time: unable to get principal
> Feb 23 13:06:03 trog cifs.upcall: Exit status 1
> 
> Thanks for your work!
> Chad.
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jeff Layton Feb. 23, 2017, 9:30 p.m. UTC | #4
On Thu, 2017-02-23 at 16:10 -0500, Jeff Layton wrote:
> On Thu, 2017-02-23 at 14:18 -0600, Chad William Seys wrote:
> > > To be clear...I assume that you have a keytab set up someplace that
> > > has the smbadmin@ credentials in it, correct? That's the only way
> > > that cifs.upcall would instantiate a new credcache.
> > 
> > Right.  smbadmin@ credentials are in /etc/krb5.keytab.  'mount' must
> > check there by default.
> > 
> > > It sounds like you're walking into the DFS mount in a task that is
> > > running as root, but that has inherited a KRB5CCNAME environment
> > > variable from a cwseys@ login session.
> > 
> > The task that is walking into the DFS mount is running as 'cwseys' .  My
> > guess is that when cwseys tries to cd into DFS mount, cifs.upcall or the
> > kernel is using the wrong name for root's credential cache.
> > 
> > > It might be nice to see the debug level output from syslog, so we can
> > > tell what's actually happening in the upcall. Can you provide that?
> > 
> > 
> > cwseys:
> > $ kdestroy
> > $ cd /
> > 
> > root:
> > # umount /smb
> > # umount /smb  # to be sure!
> > # kdestroy
> > #  ls /tmp/krb5cc_* -al
> > ls: cannot access '/tmp/krb5cc_*': No such file or directory
> > 
> > cwseys:
> > $ kinit
> > Password for cwseys@PHYSICS.WISC.EDU:
> > $ ls /tmp/krb5cc_* -al
> > -rw------- 1 cwseys cwseys 939 Feb 23 12:59 /tmp/krb5cc_1494_sM11PG
> > 
> > $ klist -c /tmp/krb5cc_1494_sM11PG
> > Ticket cache: FILE:/tmp/krb5cc_1494_sM11PG
> > Default principal: cwseys@PHYSICS.WISC.EDU
> > 
> > Valid starting       Expires              Service principal
> > 02/23/2017 12:59:00  03/05/2017 12:58:57
> > krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> > 
> > 
> > root:
> > # mount -t cifs //smb.physics.wisc.edu/smb /smb
> > -osec=krb5,multiuser,username=smbadmin@PHYSICS.WISC.EDU --verbose
> > mount.cifs kernel mount options:
> > ip=128.104.160.17,unc=\\smb.physics.wisc.edu\smb,sec=krb5,multiuser,user=smbadmin@PHYSICS.WISC.EDU,pass=********
> > 
> > #  ls /tmp/krb5cc_* -al
> > -rw------- 1 root   root   1046 Feb 23 13:00 /tmp/krb5cc_0
> > -rw------- 1 cwseys cwseys  939 Feb 23 12:59 /tmp/krb5cc_1494_sM11PG
> > 
> > # klist -c /tmp/krb5cc_0
> > Ticket cache: FILE:/tmp/krb5cc_0
> > Default principal: smbadmin@PHYSICS.WISC.EDU
> > 
> > Valid starting       Expires              Service principal
> > 02/23/2017 13:00:01  03/05/2017 13:00:01
> > krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> > 02/23/2017 13:00:01  03/05/2017 13:00:01
> > cifs/smb.physics.wisc.edu@PHYSICS.WISC.EDU
> > 
> > [debug.log after mount]
> > Feb 23 13:00:01 trog cifs.upcall: key description:
> > cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160
> > .17;sec=krb5;uid=0x0;creduid=0x0;user=smbadmin@PHYSICS.WISC.EDU;pid=0x6abf
> > Feb 23 13:00:01 trog cifs.upcall: ver=2
> > Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
> > Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
> > Feb 23 13:00:01 trog cifs.upcall: sec=1
> > Feb 23 13:00:01 trog cifs.upcall: uid=0
> > Feb 23 13:00:01 trog cifs.upcall: creduid=0
> > Feb 23 13:00:01 trog cifs.upcall: user=smbadmin@PHYSICS.WISC.EDU
> > Feb 23 13:00:01 trog cifs.upcall: pid=27327
> > Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> > pathname=/proc/27327/environ
> > Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
> > FILE:/tmp/krb5cc_0
> > Feb 23 13:00:01 trog cifs.upcall: get_tgt_time: unable to get principal
> > Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: getting service
> > ticket for smb.physics.wisc.edu
> > Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: obtained service ticket
> > Feb 23 13:00:01 trog cifs.upcall: Exit status 0
> > Feb 23 13:00:01 trog cifs.upcall: key description:
> > cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x0;creduid=0x0;user=smbadmin@PHYSICS.WISC.EDU;pid=0x6abf
> > Feb 23 13:00:01 trog cifs.upcall: ver=2
> > Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
> > Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
> > Feb 23 13:00:01 trog cifs.upcall: sec=1
> > Feb 23 13:00:01 trog cifs.upcall: uid=0
> > Feb 23 13:00:01 trog cifs.upcall: creduid=0
> > Feb 23 13:00:01 trog cifs.upcall: user=smbadmin@PHYSICS.WISC.EDU
> > Feb 23 13:00:01 trog cifs.upcall: pid=27327
> > Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> > pathname=/proc/27327/environ
> > Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
> > FILE:/tmp/krb5cc_0
> > Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: getting service
> > ticket for smb.physics.wisc.edu
> > Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: obtained service ticket
> > Feb 23 13:00:01 trog cifs.upcall: Exit status 0
> > Feb 23 13:00:01 trog cifs.upcall: key description:
> > cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x5d6;creduid=0x5d6;pid=0x6725
> > Feb 23 13:00:01 trog cifs.upcall: ver=2
> > Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
> > Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
> > Feb 23 13:00:01 trog cifs.upcall: sec=1
> > Feb 23 13:00:01 trog cifs.upcall: uid=1494
> > Feb 23 13:00:01 trog cifs.upcall: creduid=1494
> > Feb 23 13:00:01 trog cifs.upcall: pid=26405
> > Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> > pathname=/proc/26405/environ
> > Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> > cachename = FILE:/tmp/krb5cc_1494_bkfO2z
> > Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
> > FILE:/tmp/krb5cc_1494_bkfO2z
> > Feb 23 13:00:01 trog cifs.upcall: get_tgt_time: unable to get principal
> > Feb 23 13:00:01 trog cifs.upcall: Exit status 1
> > 
> > cwseys:
> > $ cd /smb
> > 
> > [debug.log after cd /smb]
> > Feb 23 13:05:20 trog cifs.upcall: key description:
> > cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x5d6;creduid=0x5d6;pid=0x3397
> > Feb 23 13:05:20 trog cifs.upcall: ver=2
> > Feb 23 13:05:20 trog cifs.upcall: host=smb.physics.wisc.edu
> > Feb 23 13:05:20 trog cifs.upcall: ip=128.104.160.17
> > Feb 23 13:05:20 trog cifs.upcall: sec=1
> > Feb 23 13:05:20 trog cifs.upcall: uid=1494
> > Feb 23 13:05:20 trog cifs.upcall: creduid=1494
> > Feb 23 13:05:20 trog cifs.upcall: pid=13207
> > Feb 23 13:05:20 trog cifs.upcall: get_cachename_from_process_env:
> > pathname=/proc/13207/environ
> > Feb 23 13:05:20 trog cifs.upcall: get_cachename_from_process_env:
> > cachename = FILE:/tmp/krb5cc_1494_sM11PG
> > Feb 23 13:05:20 trog cifs.upcall: get_existing_cc: default ccache is
> > FILE:/tmp/krb5cc_1494_sM11PG
> > Feb 23 13:05:20 trog cifs.upcall: handle_krb5_mech: getting service
> > ticket for smb.physics.wisc.edu
> > Feb 23 13:05:20 trog cifs.upcall: handle_krb5_mech: obtained service ticket
> > Feb 23 13:05:20 trog cifs.upcall: Exit status 0
> > 
> > $ kdestroy
> > $ ls /tmp/krb5cc_* -al
> > -rw------- 1 root root 1046 Feb 23 13:00 /tmp/krb5cc_0
> > 
> > # obs-cos is on a different server - DFS linked.
> > $ cd obs-cos
> > $ ls
> > ls: cannot open directory '.': Permission denied
> > 
> > # kerberos cache file created with root owner/group !
> > # The file has bytes in it, but not matching the size above. Wonder
> > # what's in it... ?
> > $ ls /tmp/krb5cc_* -al
> > -rw------- 1 root root 1046 Feb 23 13:00 /tmp/krb5cc_0
> > -rw------- 1 root root 1050 Feb 23 13:05 /tmp/krb5cc_1494_sM11PG
> > 
> > # now cannot kinit
> > $ kinit
> > Password for cwseys@PHYSICS.WISC.EDU:
> > kinit: Failed to store credentials: Internal credentials cache error
> > (filename: /tmp/krb5cc_1494_sM11PG) while getting initial credentials
> > 
> > root:
> > # lets look in the credential cache that was created by root.
> > # looks like credentials used by root to mount /smb:
> > # My guess is the kernel was trying to stash the
> > # cifs/smb02.physics.wisc.edu@PHYSICS.WISC.EDU
> > # kerberos ticket, but put it in krb5cc_1494_sM11PG instead
> > # of krb5cc_0
> > # klist -c /tmp/krb5cc_1494_sM11PG
> > Ticket cache: FILE:/tmp/krb5cc_1494_sM11PG
> > Default principal: smbadmin@PHYSICS.WISC.EDU
> > 
> > Valid starting       Expires              Service principal
> > 02/23/2017 13:05:59  03/05/2017 13:05:59
> > krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> > 02/23/2017 13:05:59  03/05/2017 13:05:59
> > cifs/smb02.physics.wisc.edu@PHYSICS.WISC.EDU
> > 
> > # klist -c /tmp/krb5cc_0
> > Ticket cache: FILE:/tmp/krb5cc_0
> > Default principal: smbadmin@PHYSICS.WISC.EDU
> > 
> > Valid starting       Expires              Service principal
> > 02/23/2017 13:00:01  03/05/2017 13:00:01
> > krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> > 02/23/2017 13:00:01  03/05/2017 13:00:01
> > cifs/smb.physics.wisc.edu@PHYSICS.WISC.EDU
> > 
> > [debug.log after trying to cd obs-cos]
> > vvvvvvvvvvvvvvvvvvvvvvvvvvvv
> > I think the error is here:  Notice pid=13207, that belongs
> > to cwseys but cifs.upcall key description is trying to use uid=0 and 
> > creduid=0 . The credential cache file is correct, but the uid/creduid 
> > are not.
> > 
> > cwseys   13207 /bin/bash
> > 
> > Also, in the above the log from 'cd /smb' cifs.upcall used  uid=1494 and 
> > creduid=1494 .
> > ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > 
> 
> Yep, that's clearly the issue. The question is how you're ending up in
> that situation...
> 
> Regardless of how it's happening to you, it's probably possible to fool
> the environment scraping like this, by triggering a krb5 upcall from
> the context of a setuid program that has inherited the KRB5CCNAME
> environment variable from an unprivileged process.
> 
> I'm not sure what we can reasonably do about that. I suppose it might
> be interesting to dump the Uid: line from /proc/pid/status when we do
> this upcall, and see what all of the values are set to. Maybe we can
> reject using the credcache if the uid in the upcall doesn't match one
> of the values?
> 
> I'll see if I can cook up a debug patch sometime soon for that.
> 

Just out of curiousity. As that unprivileged user, what do you get back
 if you do this?

    $ which cd ; ls -l `which cd`

Thanks,
Jeff Layton Feb. 23, 2017, 9:42 p.m. UTC | #5
On Thu, 2017-02-23 at 16:30 -0500, Jeff Layton wrote:
> On Thu, 2017-02-23 at 16:10 -0500, Jeff Layton wrote:
> > On Thu, 2017-02-23 at 14:18 -0600, Chad William Seys wrote:
> > > > To be clear...I assume that you have a keytab set up someplace that
> > > > has the smbadmin@ credentials in it, correct? That's the only way
> > > > that cifs.upcall would instantiate a new credcache.
> > > 
> > > Right.  smbadmin@ credentials are in /etc/krb5.keytab.  'mount' must
> > > check there by default.
> > > 
> > > > It sounds like you're walking into the DFS mount in a task that is
> > > > running as root, but that has inherited a KRB5CCNAME environment
> > > > variable from a cwseys@ login session.
> > > 
> > > The task that is walking into the DFS mount is running as 'cwseys' .  My
> > > guess is that when cwseys tries to cd into DFS mount, cifs.upcall or the
> > > kernel is using the wrong name for root's credential cache.
> > > 
> > > > It might be nice to see the debug level output from syslog, so we can
> > > > tell what's actually happening in the upcall. Can you provide that?
> > > 
> > > 
> > > cwseys:
> > > $ kdestroy
> > > $ cd /
> > > 
> > > root:
> > > # umount /smb
> > > # umount /smb  # to be sure!
> > > # kdestroy
> > > #  ls /tmp/krb5cc_* -al
> > > ls: cannot access '/tmp/krb5cc_*': No such file or directory
> > > 
> > > cwseys:
> > > $ kinit
> > > Password for cwseys@PHYSICS.WISC.EDU:
> > > $ ls /tmp/krb5cc_* -al
> > > -rw------- 1 cwseys cwseys 939 Feb 23 12:59 /tmp/krb5cc_1494_sM11PG
> > > 
> > > $ klist -c /tmp/krb5cc_1494_sM11PG
> > > Ticket cache: FILE:/tmp/krb5cc_1494_sM11PG
> > > Default principal: cwseys@PHYSICS.WISC.EDU
> > > 
> > > Valid starting       Expires              Service principal
> > > 02/23/2017 12:59:00  03/05/2017 12:58:57
> > > krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> > > 
> > > 
> > > root:
> > > # mount -t cifs //smb.physics.wisc.edu/smb /smb
> > > -osec=krb5,multiuser,username=smbadmin@PHYSICS.WISC.EDU --verbose
> > > mount.cifs kernel mount options:
> > > ip=128.104.160.17,unc=\\smb.physics.wisc.edu\smb,sec=krb5,multiuser,user=smbadmin@PHYSICS.WISC.EDU,pass=********
> > > 
> > > #  ls /tmp/krb5cc_* -al
> > > -rw------- 1 root   root   1046 Feb 23 13:00 /tmp/krb5cc_0
> > > -rw------- 1 cwseys cwseys  939 Feb 23 12:59 /tmp/krb5cc_1494_sM11PG
> > > 
> > > # klist -c /tmp/krb5cc_0
> > > Ticket cache: FILE:/tmp/krb5cc_0
> > > Default principal: smbadmin@PHYSICS.WISC.EDU
> > > 
> > > Valid starting       Expires              Service principal
> > > 02/23/2017 13:00:01  03/05/2017 13:00:01
> > > krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> > > 02/23/2017 13:00:01  03/05/2017 13:00:01
> > > cifs/smb.physics.wisc.edu@PHYSICS.WISC.EDU
> > > 
> > > [debug.log after mount]
> > > Feb 23 13:00:01 trog cifs.upcall: key description:
> > > cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160
> > > .17;sec=krb5;uid=0x0;creduid=0x0;user=smbadmin@PHYSICS.WISC.EDU;pid=0x6abf
> > > Feb 23 13:00:01 trog cifs.upcall: ver=2
> > > Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
> > > Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
> > > Feb 23 13:00:01 trog cifs.upcall: sec=1
> > > Feb 23 13:00:01 trog cifs.upcall: uid=0
> > > Feb 23 13:00:01 trog cifs.upcall: creduid=0
> > > Feb 23 13:00:01 trog cifs.upcall: user=smbadmin@PHYSICS.WISC.EDU
> > > Feb 23 13:00:01 trog cifs.upcall: pid=27327
> > > Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> > > pathname=/proc/27327/environ
> > > Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
> > > FILE:/tmp/krb5cc_0
> > > Feb 23 13:00:01 trog cifs.upcall: get_tgt_time: unable to get principal
> > > Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: getting service
> > > ticket for smb.physics.wisc.edu
> > > Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: obtained service ticket
> > > Feb 23 13:00:01 trog cifs.upcall: Exit status 0
> > > Feb 23 13:00:01 trog cifs.upcall: key description:
> > > cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x0;creduid=0x0;user=smbadmin@PHYSICS.WISC.EDU;pid=0x6abf
> > > Feb 23 13:00:01 trog cifs.upcall: ver=2
> > > Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
> > > Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
> > > Feb 23 13:00:01 trog cifs.upcall: sec=1
> > > Feb 23 13:00:01 trog cifs.upcall: uid=0
> > > Feb 23 13:00:01 trog cifs.upcall: creduid=0
> > > Feb 23 13:00:01 trog cifs.upcall: user=smbadmin@PHYSICS.WISC.EDU
> > > Feb 23 13:00:01 trog cifs.upcall: pid=27327
> > > Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> > > pathname=/proc/27327/environ
> > > Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
> > > FILE:/tmp/krb5cc_0
> > > Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: getting service
> > > ticket for smb.physics.wisc.edu
> > > Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: obtained service ticket
> > > Feb 23 13:00:01 trog cifs.upcall: Exit status 0
> > > Feb 23 13:00:01 trog cifs.upcall: key description:
> > > cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x5d6;creduid=0x5d6;pid=0x6725
> > > Feb 23 13:00:01 trog cifs.upcall: ver=2
> > > Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
> > > Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
> > > Feb 23 13:00:01 trog cifs.upcall: sec=1
> > > Feb 23 13:00:01 trog cifs.upcall: uid=1494
> > > Feb 23 13:00:01 trog cifs.upcall: creduid=1494
> > > Feb 23 13:00:01 trog cifs.upcall: pid=26405
> > > Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> > > pathname=/proc/26405/environ
> > > Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> > > cachename = FILE:/tmp/krb5cc_1494_bkfO2z
> > > Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
> > > FILE:/tmp/krb5cc_1494_bkfO2z
> > > Feb 23 13:00:01 trog cifs.upcall: get_tgt_time: unable to get principal
> > > Feb 23 13:00:01 trog cifs.upcall: Exit status 1
> > > 
> > > cwseys:
> > > $ cd /smb
> > > 
> > > [debug.log after cd /smb]
> > > Feb 23 13:05:20 trog cifs.upcall: key description:
> > > cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x5d6;creduid=0x5d6;pid=0x3397
> > > Feb 23 13:05:20 trog cifs.upcall: ver=2
> > > Feb 23 13:05:20 trog cifs.upcall: host=smb.physics.wisc.edu
> > > Feb 23 13:05:20 trog cifs.upcall: ip=128.104.160.17
> > > Feb 23 13:05:20 trog cifs.upcall: sec=1
> > > Feb 23 13:05:20 trog cifs.upcall: uid=1494
> > > Feb 23 13:05:20 trog cifs.upcall: creduid=1494
> > > Feb 23 13:05:20 trog cifs.upcall: pid=13207
> > > Feb 23 13:05:20 trog cifs.upcall: get_cachename_from_process_env:
> > > pathname=/proc/13207/environ
> > > Feb 23 13:05:20 trog cifs.upcall: get_cachename_from_process_env:
> > > cachename = FILE:/tmp/krb5cc_1494_sM11PG
> > > Feb 23 13:05:20 trog cifs.upcall: get_existing_cc: default ccache is
> > > FILE:/tmp/krb5cc_1494_sM11PG
> > > Feb 23 13:05:20 trog cifs.upcall: handle_krb5_mech: getting service
> > > ticket for smb.physics.wisc.edu
> > > Feb 23 13:05:20 trog cifs.upcall: handle_krb5_mech: obtained service ticket
> > > Feb 23 13:05:20 trog cifs.upcall: Exit status 0
> > > 
> > > $ kdestroy
> > > $ ls /tmp/krb5cc_* -al
> > > -rw------- 1 root root 1046 Feb 23 13:00 /tmp/krb5cc_0
> > > 
> > > # obs-cos is on a different server - DFS linked.
> > > $ cd obs-cos
> > > $ ls
> > > ls: cannot open directory '.': Permission denied
> > > 
> > > # kerberos cache file created with root owner/group !
> > > # The file has bytes in it, but not matching the size above. Wonder
> > > # what's in it... ?
> > > $ ls /tmp/krb5cc_* -al
> > > -rw------- 1 root root 1046 Feb 23 13:00 /tmp/krb5cc_0
> > > -rw------- 1 root root 1050 Feb 23 13:05 /tmp/krb5cc_1494_sM11PG
> > > 
> > > # now cannot kinit
> > > $ kinit
> > > Password for cwseys@PHYSICS.WISC.EDU:
> > > kinit: Failed to store credentials: Internal credentials cache error
> > > (filename: /tmp/krb5cc_1494_sM11PG) while getting initial credentials
> > > 
> > > root:
> > > # lets look in the credential cache that was created by root.
> > > # looks like credentials used by root to mount /smb:
> > > # My guess is the kernel was trying to stash the
> > > # cifs/smb02.physics.wisc.edu@PHYSICS.WISC.EDU
> > > # kerberos ticket, but put it in krb5cc_1494_sM11PG instead
> > > # of krb5cc_0
> > > # klist -c /tmp/krb5cc_1494_sM11PG
> > > Ticket cache: FILE:/tmp/krb5cc_1494_sM11PG
> > > Default principal: smbadmin@PHYSICS.WISC.EDU
> > > 
> > > Valid starting       Expires              Service principal
> > > 02/23/2017 13:05:59  03/05/2017 13:05:59
> > > krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> > > 02/23/2017 13:05:59  03/05/2017 13:05:59
> > > cifs/smb02.physics.wisc.edu@PHYSICS.WISC.EDU
> > > 
> > > # klist -c /tmp/krb5cc_0
> > > Ticket cache: FILE:/tmp/krb5cc_0
> > > Default principal: smbadmin@PHYSICS.WISC.EDU
> > > 
> > > Valid starting       Expires              Service principal
> > > 02/23/2017 13:00:01  03/05/2017 13:00:01
> > > krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> > > 02/23/2017 13:00:01  03/05/2017 13:00:01
> > > cifs/smb.physics.wisc.edu@PHYSICS.WISC.EDU
> > > 
> > > [debug.log after trying to cd obs-cos]
> > > vvvvvvvvvvvvvvvvvvvvvvvvvvvv
> > > I think the error is here:  Notice pid=13207, that belongs
> > > to cwseys but cifs.upcall key description is trying to use uid=0 and 
> > > creduid=0 . The credential cache file is correct, but the uid/creduid 
> > > are not.
> > > 
> > > cwseys   13207 /bin/bash
> > > 
> > > Also, in the above the log from 'cd /smb' cifs.upcall used  uid=1494 and 
> > > creduid=1494 .
> > > ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > > 
> > 
> > Yep, that's clearly the issue. The question is how you're ending up in
> > that situation...
> > 
> > Regardless of how it's happening to you, it's probably possible to fool
> > the environment scraping like this, by triggering a krb5 upcall from
> > the context of a setuid program that has inherited the KRB5CCNAME
> > environment variable from an unprivileged process.
> > 
> > I'm not sure what we can reasonably do about that. I suppose it might
> > be interesting to dump the Uid: line from /proc/pid/status when we do
> > this upcall, and see what all of the values are set to. Maybe we can
> > reject using the credcache if the uid in the upcall doesn't match one
> > of the values?
> > 
> > I'll see if I can cook up a debug patch sometime soon for that.
> > 
> 
> Just out of curiousity. As that unprivileged user, what do you get back
>  if you do this?
> 
>     $ which cd ; ls -l `which cd`
> 
> Thanks,

Nevermind, I see the problem. From follow_automount in the pathwalking
code:

        old_cred = override_creds(&init_cred);
        mnt = path->dentry->d_op->d_automount(path);
        revert_creds(old_cred);

So we end up overriding the process creds in order to do the automount,
which leads to exactly this problem.

I think the best we can do here is probably to just not do the
environment scraping if the uid is 0. It's pretty hacky, but hey, we're
already in rather nasty hack territory as it is.

Thoughts?
Simo Sorce Feb. 23, 2017, 11:46 p.m. UTC | #6
On Thu, 2017-02-23 at 16:42 -0500, Jeff Layton wrote:
> On Thu, 2017-02-23 at 16:30 -0500, Jeff Layton wrote:
> > On Thu, 2017-02-23 at 16:10 -0500, Jeff Layton wrote:
> > > On Thu, 2017-02-23 at 14:18 -0600, Chad William Seys wrote:
> > > > > To be clear...I assume that you have a keytab set up someplace that
> > > > > has the smbadmin@ credentials in it, correct? That's the only way
> > > > > that cifs.upcall would instantiate a new credcache.
> > > > 
> > > > Right.  smbadmin@ credentials are in /etc/krb5.keytab.  'mount' must
> > > > check there by default.
> > > > 
> > > > > It sounds like you're walking into the DFS mount in a task that is
> > > > > running as root, but that has inherited a KRB5CCNAME environment
> > > > > variable from a cwseys@ login session.
> > > > 
> > > > The task that is walking into the DFS mount is running as 'cwseys' .  My
> > > > guess is that when cwseys tries to cd into DFS mount, cifs.upcall or the
> > > > kernel is using the wrong name for root's credential cache.
> > > > 
> > > > > It might be nice to see the debug level output from syslog, so we can
> > > > > tell what's actually happening in the upcall. Can you provide that?
> > > > 
> > > > 
> > > > cwseys:
> > > > $ kdestroy
> > > > $ cd /
> > > > 
> > > > root:
> > > > # umount /smb
> > > > # umount /smb  # to be sure!
> > > > # kdestroy
> > > > #  ls /tmp/krb5cc_* -al
> > > > ls: cannot access '/tmp/krb5cc_*': No such file or directory
> > > > 
> > > > cwseys:
> > > > $ kinit
> > > > Password for cwseys@PHYSICS.WISC.EDU:
> > > > $ ls /tmp/krb5cc_* -al
> > > > -rw------- 1 cwseys cwseys 939 Feb 23 12:59 /tmp/krb5cc_1494_sM11PG
> > > > 
> > > > $ klist -c /tmp/krb5cc_1494_sM11PG
> > > > Ticket cache: FILE:/tmp/krb5cc_1494_sM11PG
> > > > Default principal: cwseys@PHYSICS.WISC.EDU
> > > > 
> > > > Valid starting       Expires              Service principal
> > > > 02/23/2017 12:59:00  03/05/2017 12:58:57
> > > > krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> > > > 
> > > > 
> > > > root:
> > > > # mount -t cifs //smb.physics.wisc.edu/smb /smb
> > > > -osec=krb5,multiuser,username=smbadmin@PHYSICS.WISC.EDU --verbose
> > > > mount.cifs kernel mount options:
> > > > ip=128.104.160.17,unc=\\smb.physics.wisc.edu\smb,sec=krb5,multiuser,user=smbadmin@PHYSICS.WISC.EDU,pass=********
> > > > 
> > > > #  ls /tmp/krb5cc_* -al
> > > > -rw------- 1 root   root   1046 Feb 23 13:00 /tmp/krb5cc_0
> > > > -rw------- 1 cwseys cwseys  939 Feb 23 12:59 /tmp/krb5cc_1494_sM11PG
> > > > 
> > > > # klist -c /tmp/krb5cc_0
> > > > Ticket cache: FILE:/tmp/krb5cc_0
> > > > Default principal: smbadmin@PHYSICS.WISC.EDU
> > > > 
> > > > Valid starting       Expires              Service principal
> > > > 02/23/2017 13:00:01  03/05/2017 13:00:01
> > > > krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> > > > 02/23/2017 13:00:01  03/05/2017 13:00:01
> > > > cifs/smb.physics.wisc.edu@PHYSICS.WISC.EDU
> > > > 
> > > > [debug.log after mount]
> > > > Feb 23 13:00:01 trog cifs.upcall: key description:
> > > > cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160
> > > > .17;sec=krb5;uid=0x0;creduid=0x0;user=smbadmin@PHYSICS.WISC.EDU;pid=0x6abf
> > > > Feb 23 13:00:01 trog cifs.upcall: ver=2
> > > > Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
> > > > Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
> > > > Feb 23 13:00:01 trog cifs.upcall: sec=1
> > > > Feb 23 13:00:01 trog cifs.upcall: uid=0
> > > > Feb 23 13:00:01 trog cifs.upcall: creduid=0
> > > > Feb 23 13:00:01 trog cifs.upcall: user=smbadmin@PHYSICS.WISC.EDU
> > > > Feb 23 13:00:01 trog cifs.upcall: pid=27327
> > > > Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> > > > pathname=/proc/27327/environ
> > > > Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
> > > > FILE:/tmp/krb5cc_0
> > > > Feb 23 13:00:01 trog cifs.upcall: get_tgt_time: unable to get principal
> > > > Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: getting service
> > > > ticket for smb.physics.wisc.edu
> > > > Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: obtained service ticket
> > > > Feb 23 13:00:01 trog cifs.upcall: Exit status 0
> > > > Feb 23 13:00:01 trog cifs.upcall: key description:
> > > > cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x0;creduid=0x0;user=smbadmin@PHYSICS.WISC.EDU;pid=0x6abf
> > > > Feb 23 13:00:01 trog cifs.upcall: ver=2
> > > > Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
> > > > Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
> > > > Feb 23 13:00:01 trog cifs.upcall: sec=1
> > > > Feb 23 13:00:01 trog cifs.upcall: uid=0
> > > > Feb 23 13:00:01 trog cifs.upcall: creduid=0
> > > > Feb 23 13:00:01 trog cifs.upcall: user=smbadmin@PHYSICS.WISC.EDU
> > > > Feb 23 13:00:01 trog cifs.upcall: pid=27327
> > > > Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> > > > pathname=/proc/27327/environ
> > > > Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
> > > > FILE:/tmp/krb5cc_0
> > > > Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: getting service
> > > > ticket for smb.physics.wisc.edu
> > > > Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: obtained service ticket
> > > > Feb 23 13:00:01 trog cifs.upcall: Exit status 0
> > > > Feb 23 13:00:01 trog cifs.upcall: key description:
> > > > cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x5d6;creduid=0x5d6;pid=0x6725
> > > > Feb 23 13:00:01 trog cifs.upcall: ver=2
> > > > Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
> > > > Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
> > > > Feb 23 13:00:01 trog cifs.upcall: sec=1
> > > > Feb 23 13:00:01 trog cifs.upcall: uid=1494
> > > > Feb 23 13:00:01 trog cifs.upcall: creduid=1494
> > > > Feb 23 13:00:01 trog cifs.upcall: pid=26405
> > > > Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> > > > pathname=/proc/26405/environ
> > > > Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> > > > cachename = FILE:/tmp/krb5cc_1494_bkfO2z
> > > > Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
> > > > FILE:/tmp/krb5cc_1494_bkfO2z
> > > > Feb 23 13:00:01 trog cifs.upcall: get_tgt_time: unable to get principal
> > > > Feb 23 13:00:01 trog cifs.upcall: Exit status 1
> > > > 
> > > > cwseys:
> > > > $ cd /smb
> > > > 
> > > > [debug.log after cd /smb]
> > > > Feb 23 13:05:20 trog cifs.upcall: key description:
> > > > cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x5d6;creduid=0x5d6;pid=0x3397
> > > > Feb 23 13:05:20 trog cifs.upcall: ver=2
> > > > Feb 23 13:05:20 trog cifs.upcall: host=smb.physics.wisc.edu
> > > > Feb 23 13:05:20 trog cifs.upcall: ip=128.104.160.17
> > > > Feb 23 13:05:20 trog cifs.upcall: sec=1
> > > > Feb 23 13:05:20 trog cifs.upcall: uid=1494
> > > > Feb 23 13:05:20 trog cifs.upcall: creduid=1494
> > > > Feb 23 13:05:20 trog cifs.upcall: pid=13207
> > > > Feb 23 13:05:20 trog cifs.upcall: get_cachename_from_process_env:
> > > > pathname=/proc/13207/environ
> > > > Feb 23 13:05:20 trog cifs.upcall: get_cachename_from_process_env:
> > > > cachename = FILE:/tmp/krb5cc_1494_sM11PG
> > > > Feb 23 13:05:20 trog cifs.upcall: get_existing_cc: default ccache is
> > > > FILE:/tmp/krb5cc_1494_sM11PG
> > > > Feb 23 13:05:20 trog cifs.upcall: handle_krb5_mech: getting service
> > > > ticket for smb.physics.wisc.edu
> > > > Feb 23 13:05:20 trog cifs.upcall: handle_krb5_mech: obtained service ticket
> > > > Feb 23 13:05:20 trog cifs.upcall: Exit status 0
> > > > 
> > > > $ kdestroy
> > > > $ ls /tmp/krb5cc_* -al
> > > > -rw------- 1 root root 1046 Feb 23 13:00 /tmp/krb5cc_0
> > > > 
> > > > # obs-cos is on a different server - DFS linked.
> > > > $ cd obs-cos
> > > > $ ls
> > > > ls: cannot open directory '.': Permission denied
> > > > 
> > > > # kerberos cache file created with root owner/group !
> > > > # The file has bytes in it, but not matching the size above. Wonder
> > > > # what's in it... ?
> > > > $ ls /tmp/krb5cc_* -al
> > > > -rw------- 1 root root 1046 Feb 23 13:00 /tmp/krb5cc_0
> > > > -rw------- 1 root root 1050 Feb 23 13:05 /tmp/krb5cc_1494_sM11PG
> > > > 
> > > > # now cannot kinit
> > > > $ kinit
> > > > Password for cwseys@PHYSICS.WISC.EDU:
> > > > kinit: Failed to store credentials: Internal credentials cache error
> > > > (filename: /tmp/krb5cc_1494_sM11PG) while getting initial credentials
> > > > 
> > > > root:
> > > > # lets look in the credential cache that was created by root.
> > > > # looks like credentials used by root to mount /smb:
> > > > # My guess is the kernel was trying to stash the
> > > > # cifs/smb02.physics.wisc.edu@PHYSICS.WISC.EDU
> > > > # kerberos ticket, but put it in krb5cc_1494_sM11PG instead
> > > > # of krb5cc_0
> > > > # klist -c /tmp/krb5cc_1494_sM11PG
> > > > Ticket cache: FILE:/tmp/krb5cc_1494_sM11PG
> > > > Default principal: smbadmin@PHYSICS.WISC.EDU
> > > > 
> > > > Valid starting       Expires              Service principal
> > > > 02/23/2017 13:05:59  03/05/2017 13:05:59
> > > > krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> > > > 02/23/2017 13:05:59  03/05/2017 13:05:59
> > > > cifs/smb02.physics.wisc.edu@PHYSICS.WISC.EDU
> > > > 
> > > > # klist -c /tmp/krb5cc_0
> > > > Ticket cache: FILE:/tmp/krb5cc_0
> > > > Default principal: smbadmin@PHYSICS.WISC.EDU
> > > > 
> > > > Valid starting       Expires              Service principal
> > > > 02/23/2017 13:00:01  03/05/2017 13:00:01
> > > > krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> > > > 02/23/2017 13:00:01  03/05/2017 13:00:01
> > > > cifs/smb.physics.wisc.edu@PHYSICS.WISC.EDU
> > > > 
> > > > [debug.log after trying to cd obs-cos]
> > > > vvvvvvvvvvvvvvvvvvvvvvvvvvvv
> > > > I think the error is here:  Notice pid=13207, that belongs
> > > > to cwseys but cifs.upcall key description is trying to use uid=0 and 
> > > > creduid=0 . The credential cache file is correct, but the uid/creduid 
> > > > are not.
> > > > 
> > > > cwseys   13207 /bin/bash
> > > > 
> > > > Also, in the above the log from 'cd /smb' cifs.upcall used  uid=1494 and 
> > > > creduid=1494 .
> > > > ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > > > 
> > > 
> > > Yep, that's clearly the issue. The question is how you're ending up in
> > > that situation...
> > > 
> > > Regardless of how it's happening to you, it's probably possible to fool
> > > the environment scraping like this, by triggering a krb5 upcall from
> > > the context of a setuid program that has inherited the KRB5CCNAME
> > > environment variable from an unprivileged process.
> > > 
> > > I'm not sure what we can reasonably do about that. I suppose it might
> > > be interesting to dump the Uid: line from /proc/pid/status when we do
> > > this upcall, and see what all of the values are set to. Maybe we can
> > > reject using the credcache if the uid in the upcall doesn't match one
> > > of the values?
> > > 
> > > I'll see if I can cook up a debug patch sometime soon for that.
> > > 
> > 
> > Just out of curiousity. As that unprivileged user, what do you get back
> >  if you do this?
> > 
> >     $ which cd ; ls -l `which cd`
> > 
> > Thanks,
> 
> Nevermind, I see the problem. From follow_automount in the pathwalking
> code:
> 
>         old_cred = override_creds(&init_cred);
>         mnt = path->dentry->d_op->d_automount(path);
>         revert_creds(old_cred);
> 
> So we end up overriding the process creds in order to do the automount,
> which leads to exactly this problem.
> 
> I think the best we can do here is probably to just not do the
> environment scraping if the uid is 0. It's pretty hacky, but hey, we're
> already in rather nasty hack territory as it is.
> 
> Thoughts?


Can't we detect that the process has changed id ?
Cutting off root may be a way, but I can see how some peoepl may want
root too to be able to mount and walk cifs shares ...

Simo.

--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jeff Layton Feb. 24, 2017, 12:35 a.m. UTC | #7
On Thu, 2017-02-23 at 18:46 -0500, Simo Sorce wrote:
> On Thu, 2017-02-23 at 16:42 -0500, Jeff Layton wrote:
> > On Thu, 2017-02-23 at 16:30 -0500, Jeff Layton wrote:
> > > On Thu, 2017-02-23 at 16:10 -0500, Jeff Layton wrote:
> > > > On Thu, 2017-02-23 at 14:18 -0600, Chad William Seys wrote:
> > > > > > To be clear...I assume that you have a keytab set up someplace that
> > > > > > has the smbadmin@ credentials in it, correct? That's the only way
> > > > > > that cifs.upcall would instantiate a new credcache.
> > > > > 
> > > > > Right.  smbadmin@ credentials are in /etc/krb5.keytab.  'mount' must
> > > > > check there by default.
> > > > > 
> > > > > > It sounds like you're walking into the DFS mount in a task that is
> > > > > > running as root, but that has inherited a KRB5CCNAME environment
> > > > > > variable from a cwseys@ login session.
> > > > > 
> > > > > The task that is walking into the DFS mount is running as 'cwseys' .  My
> > > > > guess is that when cwseys tries to cd into DFS mount, cifs.upcall or the
> > > > > kernel is using the wrong name for root's credential cache.
> > > > > 
> > > > > > It might be nice to see the debug level output from syslog, so we can
> > > > > > tell what's actually happening in the upcall. Can you provide that?
> > > > > 
> > > > > 
> > > > > cwseys:Simo.> 
> > > > > > --> To unsubscribe from this list: send the line
> > > > > "unsubscribe linux-cifs" in> the body of a message to
> > > > > majordomo@vger.kernel.org> More majordomo info at  http://vge
> > > > > r.kernel.org/majordomo-info.html
> > > > > 
> > > > > $ kdestroy
> > > > > $ cd /
> > > > > 
> > > > > root:
> > > > > # umount /smb
> > > > > # umount /smb  # to be sure!
> > > > > # kdestroy
> > > > > #  ls /tmp/krb5cc_* -al
> > > > > ls: cannot access '/tmp/krb5cc_*': No such file or directory
> > > > > 
> > > > > cwseys:
> > > > > $ kinit
> > > > > Password for cwseys@PHYSICS.WISC.EDU:
> > > > > $ ls /tmp/krb5cc_* -al
> > > > > -rw------- 1 cwseys cwseys 939 Feb 23 12:59 /tmp/krb5cc_1494_sM11PG
> > > > > 
> > > > > $ klist -c /tmp/krb5cc_1494_sM11PG
> > > > > Ticket cache: FILE:/tmp/krb5cc_1494_sM11PG
> > > > > Default principal: cwseys@PHYSICS.WISC.EDU
> > > > > 
> > > > > Valid starting       Expires              Service principal
> > > > > 02/23/2017 12:59:00  03/05/2017 12:58:57
> > > > > krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> > > > > 
> > > > > 
> > > > > root:
> > > > > # mount -t cifs //smb.physics.wisc.edu/smb /smb
> > > > > -osec=krb5,multiuser,username=smbadmin@PHYSICS.WISC.EDU --verbose
> > > > > mount.cifs kernel mount options:
> > > > > ip=128.104.160.17,unc=\\smb.physics.wisc.edu\smb,sec=krb5,multiuser,user=smbadmin@PHYSICS.WISC.EDU,pass=********
> > > > > 
> > > > > #  ls /tmp/krb5cc_* -al
> > > > > -rw------- 1 root   root   1046 Feb 23 13:00 /tmp/krb5cc_0
> > > > > -rw------- 1 cwseys cwseys  939 Feb 23 12:59 /tmp/krb5cc_1494_sM11PG
> > > > > 
> > > > > # klist -c /tmp/krb5cc_0
> > > > > Ticket cache: FILE:/tmp/krb5cc_0
> > > > > Default principal: smbadmin@PHYSICS.WISC.EDU
> > > > > 
> > > > > Valid starting       Expires              Service principal
> > > > > 02/23/2017 13:00:01  03/05/2017 13:00:01
> > > > > krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> > > > > 02/23/2017 13:00:01  03/05/2017 13:00:01
> > > > > cifs/smb.physics.wisc.edu@PHYSICS.WISC.EDU
> > > > > 
> > > > > [debug.log after mount]
> > > > > Feb 23 13:00:01 trog cifs.upcall: key description:
> > > > > cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160
> > > > > .17;sec=krb5;uid=0x0;creduid=0x0;user=smbadmin@PHYSICS.WISC.EDU;pid=0x6abf
> > > > > Feb 23 13:00:01 trog cifs.upcall: ver=2
> > > > > Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
> > > > > Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
> > > > > Feb 23 13:00:01 trog cifs.upcall: sec=1
> > > > > Feb 23 13:00:01 trog cifs.upcall: uid=0
> > > > > Feb 23 13:00:01 trog cifs.upcall: creduid=0
> > > > > Feb 23 13:00:01 trog cifs.upcall: user=smbadmin@PHYSICS.WISC.EDU
> > > > > Feb 23 13:00:01 trog cifs.upcall: pid=27327
> > > > > Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> > > > > pathname=/proc/27327/environ
> > > > > Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
> > > > > FILE:/tmp/krb5cc_0
> > > > > Feb 23 13:00:01 trog cifs.upcall: get_tgt_time: unable to get principal
> > > > > Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: getting service
> > > > > ticket for smb.physics.wisc.edu
> > > > > Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: obtained service ticket
> > > > > Feb 23 13:00:01 trog cifs.upcall: Exit status 0
> > > > > Feb 23 13:00:01 trog cifs.upcall: key description:
> > > > > cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x0;creduid=0x0;user=smbadmin@PHYSICS.WISC.EDU;pid=0x6abf
> > > > > Feb 23 13:00:01 trog cifs.upcall: ver=2
> > > > > Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
> > > > > Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
> > > > > Feb 23 13:00:01 trog cifs.upcall: sec=1
> > > > > Feb 23 13:00:01 trog cifs.upcall: uid=0
> > > > > Feb 23 13:00:01 trog cifs.upcall: creduid=0
> > > > > Feb 23 13:00:01 trog cifs.upcall: user=smbadmin@PHYSICS.WISC.EDU
> > > > > Feb 23 13:00:01 trog cifs.upcall: pid=27327
> > > > > Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> > > > > pathname=/proc/27327/environ
> > > > > Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
> > > > > FILE:/tmp/krb5cc_0
> > > > > Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: getting service
> > > > > ticket for smb.physics.wisc.edu
> > > > > Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: obtained service ticket
> > > > > Feb 23 13:00:01 trog cifs.upcall: Exit status 0
> > > > > Feb 23 13:00:01 trog cifs.upcall: key description:
> > > > > cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x5d6;creduid=0x5d6;pid=0x6725
> > > > > Feb 23 13:00:01 trog cifs.upcall: ver=2
> > > > > Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
> > > > > Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
> > > > > Feb 23 13:00:01 trog cifs.upcall: sec=1
> > > > > Feb 23 13:00:01 trog cifs.upcall: uid=1494
> > > > > Feb 23 13:00:01 trog cifs.upcall: creduid=1494
> > > > > Feb 23 13:00:01 trog cifs.upcall: pid=26405
> > > > > Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> > > > > pathname=/proc/26405/environ
> > > > > Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> > > > > cachename = FILE:/tmp/krb5cc_1494_bkfO2z
> > > > > Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
> > > > > FILE:/tmp/krb5cc_1494_bkfO2z
> > > > > Feb 23 13:00:01 trog cifs.upcall: get_tgt_time: unable to
> > > > > gSimo.> 
> > > > > > --> To unsubscribe from this list: send the line
> > > > > "unsubscribe linux-cifs" in> the body of a message to
> > > > > majordomo@vger.kernel.org> More majordomo info at  http://vge
> > > > > r.kernel.org/majordomo-info.html
> > > > > et principal
> > > > > Feb 23 13:00:01 trog cifs.upcall: Exit status 1
> > > > > 
> > > > > cwseys:
> > > > > $ cd /smb
> > > > > 
> > > > > [debug.log after cd /smb]
> > > > > Feb 23 13:05:20 trog cifs.upcall: key description:
> > > > > cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x5d6;creduid=0x5d6;pid=0x3397
> > > > > Feb 23 13:05:20 trog cifs.upcall: ver=2
> > > > > Feb 23 13:05:20 trog cifs.upcall: host=smb.physics.wisc.edu
> > > > > Feb 23 13:05:20 trog cifs.upcall: ip=128.104.160.17
> > > > > Feb 23 13:05:20 trog cifs.upcall: sec=1
> > > > > Feb 23 13:05:20 trog cifs.upcall: uid=1494
> > > > > Feb 23 13:05:20 trog cifs.upcall: creduid=1494
> > > > > Feb 23 13:05:20 trog cifs.upcall: pid=13207
> > > > > Feb 23 13:05:20 trog cifs.upcall: get_cachename_from_process_env:
> > > > > pathname=/proc/13207/environ
> > > > > Feb 23 13:05:20 trog cifs.upcall: get_cachename_from_process_env:
> > > > > cachename = FILE:/tmp/krb5cc_1494_sM11PG
> > > > > Feb 23 13:05:20 trog cifs.upcall: get_existing_cc: default ccache is
> > > > > FILE:/tmp/krb5cc_1494_sM11PG
> > > > > Feb 23 13:05:20 trog cifs.upcall: handle_krb5_mech: getting service
> > > > > ticket for smb.physics.wisc.edu
> > > > > Feb 23 13:05:20 trog cifs.upcall: handle_krb5_mech: obtained service ticket
> > > > > Feb 23 13:05:20 trog cifs.upcall: Exit status 0
> > > > > 
> > > > > $ kdestroy
> > > > > $ ls /tmp/krb5cc_* -al
> > > > > -rw------- 1 root root 1046 Feb 23 13:00 /tmp/krb5cc_0
> > > > > 
> > > > > # obs-cos is on a different server - DFS linked.
> > > > > $ cd obs-cos
> > > > > $ ls
> > > > > ls: cannot open directory '.': Permission denied
> > > > > 
> > > > > # kerberos cache file created with root owner/group !
> > > > > # The file has bytes in it, but not matching the size above. Wonder
> > > > > # what's in it... ?
> > > > > $ ls /tmp/krb5cc_* -al
> > > > > -rw------- 1 root root 1046 Feb 23 13:00 /tmp/krb5cc_0
> > > > > -rw------- 1 root root 1050 Feb 23 13:05 /tmp/krb5cc_1494_sM11PG
> > > > > 
> > > > > # now cannot kinit
> > > > > $ kinit
> > > > > Password for cwseys@PHYSICS.WISC.EDU:
> > > > > kinit: Failed to store credentials: Internal credentials cache error
> > > > > (filename: /tmp/krb5cc_1494_sM11PG) while getting initial credentials
> > > > > 
> > > > > root:
> > > > > # lets look in the credential cache that was created by root.
> > > > > # looks like credentials used by root to mount /smb:
> > > > > # My guess is the kernel was trying to stash the
> > > > > # cifs/smb02.physics.wisc.edu@PHYSICS.WISC.EDU
> > > > > # kerberos ticket, but put it in krb5cc_1494_sM11PG instead
> > > > > # of krb5cc_0
> > > > > # klist -c /tmp/krb5cc_1494_sM11PG
> > > > > Ticket cache: FILE:/tmp/krb5cc_1494_sM11PG
> > > > > Default principal: smbadmin@PHYSICS.WISC.EDU
> > > > > 
> > > > > Valid starting       Expires              Service principal
> > > > > 02/23/2017 13:05:59  03/05/2017 13:05:59
> > > > > krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> > > > > 02/23/2017 13:05:59  03/05/2017 13:05:59
> > > > > cifs/smb02.physics.wisc.edu@PHYSICS.WISC.EDU
> > > > > 
> > > > > # klist -c /tmp/krb5cc_0
> > > > > Ticket cache: FILE:/tmp/krb5cc_0
> > > > > Default principal: smbadmin@PHYSICS.WISC.EDU
> > > > > 
> > > > > Valid starting       Expires              Service principal
> > > > > 02/23/2017 13:00:01  03/05/2017 13:00:01
> > > > > krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> > > > > 02/23/2017 13:00:01  03/05/2017 13:00:01
> > > > > cifs/smb.physics.wisc.edu@PHYSICS.WISC.EDU
> > > > > 
> > > > > [debug.log after trying to cd obs-cos]
> > > > > vvvvvvvvvvvvvvvvvvvvvvvvvvvv
> > > > > I think the error is here:  Notice pid=13207, that belongs
> > > > > to cwseys but cifs.upcall key description is trying to use uid=0 and 
> > > > > creduid=0 . The credential cache file is correct, but the uid/creduid 
> > > > > are not.
> > > > > 
> > > > > cwseys   13207 /bin/bash
> > > > > 
> > > > > Also, in the above the log from 'cd /smb' cifs.upcall used  uid=1494 and 
> > > > > creduid=1494 .
> > > > > ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > > > > 
> > > > 
> > > > Yep, that's clearly the issue. The question is how you're ending up in
> > > > that situation...
> > > > 
> > > > Regardless of how it's happening to you, it's probably possible to fool
> > > > the environment scraping like this, by triggering a krb5 upcall from
> > > > the context of a setuid program that has inherited the KRB5CCNAME
> > > > environment variable from an unprivileged process.
> > > > 
> > > > I'm not sure what we can reasonably do about that. I suppose it might
> > > > be interesting to dump the Uid: line from /proc/pid/status when we do
> > > > this upcall, and see what all of the values are set to. Maybe we can
> > > > reject using the credcache if the uid in the upcall doesn't match one
> > > > of the values?
> > > > 
> > > > I'll see if I can cook up a debug patch sometime soon for that.
> > > > 
> > > 
> > > Just out of curiousity. As that unprivileged user, what do you get back
> > >  if you do this?
> > > 
> > >     $ which cd ; ls -l `which cd`
> > > 
> > > Thanks,
> > 
> > Nevermind, I see the problem. From follow_automount in the pathwalking
> > code:
> > 
> >         old_cred = override_creds(&init_cred);
> >         mnt = path->dentry->d_op->d_automount(path);
> >         revert_creds(old_cred);
> > 
> > So we end up overriding the process creds in order to do the automount,
> > which leads to exactly this problem.
> > 
> > I think the best we can do here is probably to just not do the
> > environment scraping if the uid is 0. It's pretty hacky, but hey, we're
> > already in rather nasty hack territory as it is.
> > 
> > Thoughts?
> 
> 
> Can't we detect that the process has changed id ?

How? The credentials are completely overridden with the init_creds once
we get into d_automount.

> Cutting off root may be a way, but I can see how some peoepl may want
> root too to be able to mount and walk cifs shares ...
> 
> 

Well, root still can with this patch -- just not if his credcache is in
a non-default location.

The other option is to just unset the environment var. That will
probably fix Chad's issue, but my worry there is that root's session
setup can end up being done with the wrong credcache if cwseys had a
valid one when he triggers the automount.

Maybe the right fix is to have mount creds be separate from root's
creds altogether. You'd have a duplicate session for root in most
cases, but maybe that's ok?
Simo Sorce Feb. 24, 2017, 1:14 a.m. UTC | #8
On Thu, 2017-02-23 at 19:35 -0500, Jeff Layton wrote:
> On Thu, 2017-02-23 at 18:46 -0500, Simo Sorce wrote:
> > On Thu, 2017-02-23 at 16:42 -0500, Jeff Layton wrote:
> > > On Thu, 2017-02-23 at 16:30 -0500, Jeff Layton wrote:
> > > > On Thu, 2017-02-23 at 16:10 -0500, Jeff Layton wrote:
> > > > > On Thu, 2017-02-23 at 14:18 -0600, Chad William Seys wrote:
> > > > > > > To be clear...I assume that you have a keytab set up someplace that
> > > > > > > has the smbadmin@ credentials in it, correct? That's the only way
> > > > > > > that cifs.upcall would instantiate a new credcache.
> > > > > > 
> > > > > > Right.  smbadmin@ credentials are in /etc/krb5.keytab.  'mount' must
> > > > > > check there by default.
> > > > > > 
> > > > > > > It sounds like you're walking into the DFS mount in a task that is
> > > > > > > running as root, but that has inherited a KRB5CCNAME environment
> > > > > > > variable from a cwseys@ login session.
> > > > > > 
> > > > > > The task that is walking into the DFS mount is running as 'cwseys' .  My
> > > > > > guess is that when cwseys tries to cd into DFS mount, cifs.upcall or the
> > > > > > kernel is using the wrong name for root's credential cache.
> > > > > > 
> > > > > > > It might be nice to see the debug level output from syslog, so we can
> > > > > > > tell what's actually happening in the upcall. Can you provide that?
> > > > > > 
> > > > > > 
> > > > > > cwseys:Simo.> 
> > > > > > > --> To unsubscribe from this list: send the line
> > > > > > "unsubscribe linux-cifs" in> the body of a message to
> > > > > > majordomo@vger.kernel.org> More majordomo info at  http://vge
> > > > > > r.kernel.org/majordomo-info.html
> > > > > > 
> > > > > > $ kdestroy
> > > > > > $ cd /
> > > > > > 
> > > > > > root:
> > > > > > # umount /smb
> > > > > > # umount /smb  # to be sure!
> > > > > > # kdestroy
> > > > > > #  ls /tmp/krb5cc_* -al
> > > > > > ls: cannot access '/tmp/krb5cc_*': No such file or directory
> > > > > > 
> > > > > > cwseys:
> > > > > > $ kinit
> > > > > > Password for cwseys@PHYSICS.WISC.EDU:
> > > > > > $ ls /tmp/krb5cc_* -al
> > > > > > -rw------- 1 cwseys cwseys 939 Feb 23 12:59 /tmp/krb5cc_1494_sM11PG
> > > > > > 
> > > > > > $ klist -c /tmp/krb5cc_1494_sM11PG
> > > > > > Ticket cache: FILE:/tmp/krb5cc_1494_sM11PG
> > > > > > Default principal: cwseys@PHYSICS.WISC.EDU
> > > > > > 
> > > > > > Valid starting       Expires              Service principal
> > > > > > 02/23/2017 12:59:00  03/05/2017 12:58:57
> > > > > > krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> > > > > > 
> > > > > > 
> > > > > > root:
> > > > > > # mount -t cifs //smb.physics.wisc.edu/smb /smb
> > > > > > -osec=krb5,multiuser,username=smbadmin@PHYSICS.WISC.EDU --verbose
> > > > > > mount.cifs kernel mount options:
> > > > > > ip=128.104.160.17,unc=\\smb.physics.wisc.edu\smb,sec=krb5,multiuser,user=smbadmin@PHYSICS.WISC.EDU,pass=********
> > > > > > 
> > > > > > #  ls /tmp/krb5cc_* -al
> > > > > > -rw------- 1 root   root   1046 Feb 23 13:00 /tmp/krb5cc_0
> > > > > > -rw------- 1 cwseys cwseys  939 Feb 23 12:59 /tmp/krb5cc_1494_sM11PG
> > > > > > 
> > > > > > # klist -c /tmp/krb5cc_0
> > > > > > Ticket cache: FILE:/tmp/krb5cc_0
> > > > > > Default principal: smbadmin@PHYSICS.WISC.EDU
> > > > > > 
> > > > > > Valid starting       Expires              Service principal
> > > > > > 02/23/2017 13:00:01  03/05/2017 13:00:01
> > > > > > krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> > > > > > 02/23/2017 13:00:01  03/05/2017 13:00:01
> > > > > > cifs/smb.physics.wisc.edu@PHYSICS.WISC.EDU
> > > > > > 
> > > > > > [debug.log after mount]
> > > > > > Feb 23 13:00:01 trog cifs.upcall: key description:
> > > > > > cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160
> > > > > > .17;sec=krb5;uid=0x0;creduid=0x0;user=smbadmin@PHYSICS.WISC.EDU;pid=0x6abf
> > > > > > Feb 23 13:00:01 trog cifs.upcall: ver=2
> > > > > > Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
> > > > > > Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
> > > > > > Feb 23 13:00:01 trog cifs.upcall: sec=1
> > > > > > Feb 23 13:00:01 trog cifs.upcall: uid=0
> > > > > > Feb 23 13:00:01 trog cifs.upcall: creduid=0
> > > > > > Feb 23 13:00:01 trog cifs.upcall: user=smbadmin@PHYSICS.WISC.EDU
> > > > > > Feb 23 13:00:01 trog cifs.upcall: pid=27327
> > > > > > Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> > > > > > pathname=/proc/27327/environ
> > > > > > Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
> > > > > > FILE:/tmp/krb5cc_0
> > > > > > Feb 23 13:00:01 trog cifs.upcall: get_tgt_time: unable to get principal
> > > > > > Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: getting service
> > > > > > ticket for smb.physics.wisc.edu
> > > > > > Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: obtained service ticket
> > > > > > Feb 23 13:00:01 trog cifs.upcall: Exit status 0
> > > > > > Feb 23 13:00:01 trog cifs.upcall: key description:
> > > > > > cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x0;creduid=0x0;user=smbadmin@PHYSICS.WISC.EDU;pid=0x6abf
> > > > > > Feb 23 13:00:01 trog cifs.upcall: ver=2
> > > > > > Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
> > > > > > Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
> > > > > > Feb 23 13:00:01 trog cifs.upcall: sec=1
> > > > > > Feb 23 13:00:01 trog cifs.upcall: uid=0
> > > > > > Feb 23 13:00:01 trog cifs.upcall: creduid=0
> > > > > > Feb 23 13:00:01 trog cifs.upcall: user=smbadmin@PHYSICS.WISC.EDU
> > > > > > Feb 23 13:00:01 trog cifs.upcall: pid=27327
> > > > > > Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> > > > > > pathname=/proc/27327/environ
> > > > > > Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
> > > > > > FILE:/tmp/krb5cc_0
> > > > > > Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: getting service
> > > > > > ticket for smb.physics.wisc.edu
> > > > > > Feb 23 13:00:01 trog cifs.upcall: handle_krb5_mech: obtained service ticket
> > > > > > Feb 23 13:00:01 trog cifs.upcall: Exit status 0
> > > > > > Feb 23 13:00:01 trog cifs.upcall: key description:
> > > > > > cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x5d6;creduid=0x5d6;pid=0x6725
> > > > > > Feb 23 13:00:01 trog cifs.upcall: ver=2
> > > > > > Feb 23 13:00:01 trog cifs.upcall: host=smb.physics.wisc.edu
> > > > > > Feb 23 13:00:01 trog cifs.upcall: ip=128.104.160.17
> > > > > > Feb 23 13:00:01 trog cifs.upcall: sec=1
> > > > > > Feb 23 13:00:01 trog cifs.upcall: uid=1494
> > > > > > Feb 23 13:00:01 trog cifs.upcall: creduid=1494
> > > > > > Feb 23 13:00:01 trog cifs.upcall: pid=26405
> > > > > > Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> > > > > > pathname=/proc/26405/environ
> > > > > > Feb 23 13:00:01 trog cifs.upcall: get_cachename_from_process_env:
> > > > > > cachename = FILE:/tmp/krb5cc_1494_bkfO2z
> > > > > > Feb 23 13:00:01 trog cifs.upcall: get_existing_cc: default ccache is
> > > > > > FILE:/tmp/krb5cc_1494_bkfO2z
> > > > > > Feb 23 13:00:01 trog cifs.upcall: get_tgt_time: unable to
> > > > > > gSimo.> 
> > > > > > > --> To unsubscribe from this list: send the line
> > > > > > "unsubscribe linux-cifs" in> the body of a message to
> > > > > > majordomo@vger.kernel.org> More majordomo info at  http://vge
> > > > > > r.kernel.org/majordomo-info.html
> > > > > > et principal
> > > > > > Feb 23 13:00:01 trog cifs.upcall: Exit status 1
> > > > > > 
> > > > > > cwseys:
> > > > > > $ cd /smb
> > > > > > 
> > > > > > [debug.log after cd /smb]
> > > > > > Feb 23 13:05:20 trog cifs.upcall: key description:
> > > > > > cifs.spnego;0;0;39010000;ver=0x2;host=smb.physics.wisc.edu;ip4=128.104.160.17;sec=krb5;uid=0x5d6;creduid=0x5d6;pid=0x3397
> > > > > > Feb 23 13:05:20 trog cifs.upcall: ver=2
> > > > > > Feb 23 13:05:20 trog cifs.upcall: host=smb.physics.wisc.edu
> > > > > > Feb 23 13:05:20 trog cifs.upcall: ip=128.104.160.17
> > > > > > Feb 23 13:05:20 trog cifs.upcall: sec=1
> > > > > > Feb 23 13:05:20 trog cifs.upcall: uid=1494
> > > > > > Feb 23 13:05:20 trog cifs.upcall: creduid=1494
> > > > > > Feb 23 13:05:20 trog cifs.upcall: pid=13207
> > > > > > Feb 23 13:05:20 trog cifs.upcall: get_cachename_from_process_env:
> > > > > > pathname=/proc/13207/environ
> > > > > > Feb 23 13:05:20 trog cifs.upcall: get_cachename_from_process_env:
> > > > > > cachename = FILE:/tmp/krb5cc_1494_sM11PG
> > > > > > Feb 23 13:05:20 trog cifs.upcall: get_existing_cc: default ccache is
> > > > > > FILE:/tmp/krb5cc_1494_sM11PG
> > > > > > Feb 23 13:05:20 trog cifs.upcall: handle_krb5_mech: getting service
> > > > > > ticket for smb.physics.wisc.edu
> > > > > > Feb 23 13:05:20 trog cifs.upcall: handle_krb5_mech: obtained service ticket
> > > > > > Feb 23 13:05:20 trog cifs.upcall: Exit status 0
> > > > > > 
> > > > > > $ kdestroy
> > > > > > $ ls /tmp/krb5cc_* -al
> > > > > > -rw------- 1 root root 1046 Feb 23 13:00 /tmp/krb5cc_0
> > > > > > 
> > > > > > # obs-cos is on a different server - DFS linked.
> > > > > > $ cd obs-cos
> > > > > > $ ls
> > > > > > ls: cannot open directory '.': Permission denied
> > > > > > 
> > > > > > # kerberos cache file created with root owner/group !
> > > > > > # The file has bytes in it, but not matching the size above. Wonder
> > > > > > # what's in it... ?
> > > > > > $ ls /tmp/krb5cc_* -al
> > > > > > -rw------- 1 root root 1046 Feb 23 13:00 /tmp/krb5cc_0
> > > > > > -rw------- 1 root root 1050 Feb 23 13:05 /tmp/krb5cc_1494_sM11PG
> > > > > > 
> > > > > > # now cannot kinit
> > > > > > $ kinit
> > > > > > Password for cwseys@PHYSICS.WISC.EDU:
> > > > > > kinit: Failed to store credentials: Internal credentials cache error
> > > > > > (filename: /tmp/krb5cc_1494_sM11PG) while getting initial credentials
> > > > > > 
> > > > > > root:
> > > > > > # lets look in the credential cache that was created by root.
> > > > > > # looks like credentials used by root to mount /smb:
> > > > > > # My guess is the kernel was trying to stash the
> > > > > > # cifs/smb02.physics.wisc.edu@PHYSICS.WISC.EDU
> > > > > > # kerberos ticket, but put it in krb5cc_1494_sM11PG instead
> > > > > > # of krb5cc_0
> > > > > > # klist -c /tmp/krb5cc_1494_sM11PG
> > > > > > Ticket cache: FILE:/tmp/krb5cc_1494_sM11PG
> > > > > > Default principal: smbadmin@PHYSICS.WISC.EDU
> > > > > > 
> > > > > > Valid starting       Expires              Service principal
> > > > > > 02/23/2017 13:05:59  03/05/2017 13:05:59
> > > > > > krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> > > > > > 02/23/2017 13:05:59  03/05/2017 13:05:59
> > > > > > cifs/smb02.physics.wisc.edu@PHYSICS.WISC.EDU
> > > > > > 
> > > > > > # klist -c /tmp/krb5cc_0
> > > > > > Ticket cache: FILE:/tmp/krb5cc_0
> > > > > > Default principal: smbadmin@PHYSICS.WISC.EDU
> > > > > > 
> > > > > > Valid starting       Expires              Service principal
> > > > > > 02/23/2017 13:00:01  03/05/2017 13:00:01
> > > > > > krbtgt/PHYSICS.WISC.EDU@PHYSICS.WISC.EDU
> > > > > > 02/23/2017 13:00:01  03/05/2017 13:00:01
> > > > > > cifs/smb.physics.wisc.edu@PHYSICS.WISC.EDU
> > > > > > 
> > > > > > [debug.log after trying to cd obs-cos]
> > > > > > vvvvvvvvvvvvvvvvvvvvvvvvvvvv
> > > > > > I think the error is here:  Notice pid=13207, that belongs
> > > > > > to cwseys but cifs.upcall key description is trying to use uid=0 and 
> > > > > > creduid=0 . The credential cache file is correct, but the uid/creduid 
> > > > > > are not.
> > > > > > 
> > > > > > cwseys   13207 /bin/bash
> > > > > > 
> > > > > > Also, in the above the log from 'cd /smb' cifs.upcall used  uid=1494 and 
> > > > > > creduid=1494 .
> > > > > > ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > > > > > 
> > > > > 
> > > > > Yep, that's clearly the issue. The question is how you're ending up in
> > > > > that situation...
> > > > > 
> > > > > Regardless of how it's happening to you, it's probably possible to fool
> > > > > the environment scraping like this, by triggering a krb5 upcall from
> > > > > the context of a setuid program that has inherited the KRB5CCNAME
> > > > > environment variable from an unprivileged process.
> > > > > 
> > > > > I'm not sure what we can reasonably do about that. I suppose it might
> > > > > be interesting to dump the Uid: line from /proc/pid/status when we do
> > > > > this upcall, and see what all of the values are set to. Maybe we can
> > > > > reject using the credcache if the uid in the upcall doesn't match one
> > > > > of the values?
> > > > > 
> > > > > I'll see if I can cook up a debug patch sometime soon for that.
> > > > > 
> > > > 
> > > > Just out of curiousity. As that unprivileged user, what do you get back
> > > >  if you do this?
> > > > 
> > > >     $ which cd ; ls -l `which cd`
> > > > 
> > > > Thanks,
> > > 
> > > Nevermind, I see the problem. From follow_automount in the pathwalking
> > > code:
> > > 
> > >         old_cred = override_creds(&init_cred);
> > >         mnt = path->dentry->d_op->d_automount(path);
> > >         revert_creds(old_cred);
> > > 
> > > So we end up overriding the process creds in order to do the automount,
> > > which leads to exactly this problem.
> > > 
> > > I think the best we can do here is probably to just not do the
> > > environment scraping if the uid is 0. It's pretty hacky, but hey, we're
> > > already in rather nasty hack territory as it is.
> > > 
> > > Thoughts?
> > 
> > 
> > Can't we detect that the process has changed id ?
> 
> How? The credentials are completely overridden with the init_creds once
> we get into d_automount.
> 
> > Cutting off root may be a way, but I can see how some peoepl may want
> > root too to be able to mount and walk cifs shares ...
> > 
> > 
> 
> Well, root still can with this patch -- just not if his credcache is in
> a non-default location.
> 
> The other option is to just unset the environment var. That will
> probably fix Chad's issue, but my worry there is that root's session
> setup can end up being done with the wrong credcache if cwseys had a
> valid one when he triggers the automount.
> 
> Maybe the right fix is to have mount creds be separate from root's
> creds altogether. You'd have a duplicate session for root in most
> cases, but maybe that's ok?

Sounds sensible, with cifs specifically you may want to use "machine
creds" to mount, and then root creds to walk on the filesystem.

Simo.




--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/cifs.upcall.c b/cifs.upcall.c
index 418b179d7f29..2b535a133a30 100644
--- a/cifs.upcall.c
+++ b/cifs.upcall.c
@@ -46,6 +46,8 @@ 
 #include <netdb.h>
 #include <arpa/inet.h>
 #include <ctype.h>
+#include <pwd.h>
+#include <grp.h>
 
 #include "replace.h"
 #include "data_blob.h"
@@ -694,6 +696,7 @@  int main(const int argc, char *const argv[])
 	uid_t uid;
 	char *keytab_name = NULL;
 	krb5_ccache ccache = NULL;
+	struct passwd *pw;
 
 	hostbuf[0] = '\0';
 	memset(&arg, 0, sizeof(arg));
@@ -795,15 +798,49 @@  int main(const int argc, char *const argv[])
 		goto out;
 	}
 
+	/*
+	 * The kernel doesn't pass down the gid, so we resort here to scraping
+	 * one out of the passwd nss db. Note that this might not reflect the
+	 * actual gid of the process that initiated the upcall. While we could
+	 * scrape that out of /proc, relying on that is a bit more risky.
+	 */
+	pw = getpwuid(uid);
+	if (!pw) {
+		syslog(LOG_ERR, "Unable to find pw entry for uid %d: %s\n",
+			uid, strerror(errno));
+		rc = 1;
+		goto out;
+	}
+
+	/*
+	 * The kernel should send down a zero-length grouplist already, but
+	 * just to be on the safe side...
+	 */
+	rc = setgroups(0, NULL);
+	if (rc == -1) {
+		syslog(LOG_ERR, "setgroups: %s", strerror(errno));
+		rc = 1;
+		goto out;
+	}
+
+	rc = setgid(pw->pw_gid);
+	if (rc == -1) {
+		syslog(LOG_ERR, "setgid: %s", strerror(errno));
+		rc = 1;
+		goto out;
+	}
+
 	rc = setuid(uid);
 	if (rc == -1) {
 		syslog(LOG_ERR, "setuid: %s", strerror(errno));
+		rc = 1;
 		goto out;
 	}
 
 	rc = krb5_init_context(&context);
 	if (rc) {
 		syslog(LOG_ERR, "unable to init krb5 context: %ld", rc);
+		rc = 1;
 		goto out;
 	}