Bug 481233

Summary: cifs mounted home directory breaks ssh security checks on authorized_keys file
Product: Red Hat Enterprise Linux 5 Reporter: Rob Henderson <robh>
Component: kernelAssignee: Jeff Layton <jlayton>
Status: CLOSED DUPLICATE QA Contact: Red Hat Kernel QE team <kernel-qe>
Severity: medium Docs Contact:
Priority: low    
Version: 5.3CC: rwheeler, steved
Target Milestone: rc   
Target Release: ---   
Hardware: i686   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
: 484261 (view as bug list) Environment:
Last Closed: 2009-04-22 18:56:43 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
reproducer program
none
patch -- add missing else statement in cifs_open_inode_helper none

Description Rob Henderson 2009-01-22 22:05:31 UTC
Description of problem:

We have cifs mounted home directories on an RHEL5.3 client from an RHEL4 or RHEL5 samba server and are seeing incorrect file permissions via ssh.  This breaks the security checks performed by ssh on the authorized_keys file.


Version-Release number of selected component (if applicable):

Client running kernel 2.6.18-128.el5
Server running rhel4 or rhel5


How reproducible:

always


Steps to Reproduce:
1. Mount your home directory via cifs from an RHEL samba server with unix extensions enabled.

2. Set permissions on ~/.ssh/authorized_keys to various values

3. Try to ssh with your keys loaded
  
Actual results:

It fails with:

  Authentication refused: bad ownership or modes for file /home/username/.ssh/authorized_keys

with any permission on the authorized_keys file that includes the owner write bit (such as 600).

It *works* with any permissions on the authorized_keys file that doesn't include the owner write bit, including obviously bad values like 466 and 477.


Expected results:

It should refuse to use the authorized_keys file if group or world writable but accept it otherwise.


Additional info:

This problem shows up with authorized_keys permissions but is a general problem of permissions being interpreted improperly.  For example, I'm logged into a system named 'test' and see the following when I ssh back to this machine:

% chmod 466 .ssh/authorized_keys
% ls -l .ssh/authorized_keys
-r--rw-rw- 1 robh staff 677 Sep 18 16:02 .ssh/authorized_keys
% ssh test ls -l .ssh/authorized_keys
-r-xr-Sr-x 1 robh staff 677 Sep 18 16:02 .ssh/authorized_keys
% ssh test ls -l .ssh |grep authorized_keys
-r--rw-rw- 1 robh staff  677 Sep 18 16:02 authorized_keys
% chmod 600 .ssh/authorized_keys
% ssh test ls -l .ssh/authorized_keys
robh@test's password: 
-rw------- 1 robh staff 677 Sep 18 16:02 .ssh/authorized_keys
% ssh test ls -l .ssh | grep authorized_keys
robh@test's password: 
-rw------- 1 robh staff  677 Sep 18 16:02 authorized_keys
% 

Note that the ssh with permissions set to 466 didn't prompt for a password (I have my key loaded) but it did prompt for a password with valid permissions of 600.

Comment 2 Jeff Layton 2009-01-23 15:36:22 UTC
Ok, I was able to reproduce this on RHEL5 but not on rawhide. Looks like we're getting a different mode in the lstat call:

3002  lstat("/home/testuser/.ssh/authorized_keys", {st_dev=makedev(0, 24), st_ino=9484, st_mode=S_IFREG|S_ISGID|0767, st_nlink=1, st_uid=50
000, st_gid=50000, st_blksize=16384, st_blocks=8, st_size=413, st_atime=2009/01/23-08:29:14, st_mtime=2009/01/23-08:29:14, st_ctime=2009/01
/23-08:29:14}) = 0

...that st_mode typically the mode we see when unix extensions are disabled.

Comment 3 Jeff Layton 2009-01-23 15:59:54 UTC
Actually, it's even stranger:

3002  stat("/home/testuser/.ssh/authorized_keys", {st_dev=makedev(0, 24), st_ino=9484, st_mode=S_IFREG|0644, st_nlink=1, st_uid=50000, st_g
id=50000, st_blksize=16384, st_blocks=8, st_size=413, st_atime=2009/01/23-08:29:14, st_mtime=2009/01/23-08:29:14, st_ctime=2009/01/23-08:30
:19}) = 0
3002  open("/home/testuser/.ssh/authorized_keys", O_RDONLY) = 4
...
3002  lstat("/home/testuser/.ssh/authorized_keys", {st_dev=makedev(0, 24), st_ino=9484, st_mode=S_IFREG|S_ISGID|0767, st_nlink=1, st_uid=50
000, st_gid=50000, st_blksize=16384, st_blocks=8, st_size=413, st_atime=2009/01/23-08:29:14, st_mtime=2009/01/23-08:29:14, st_ctime=2009/01
/23-08:29:14}) = 0

...I may be able to roll up a reproducer from that.

Comment 4 Jeff Layton 2009-01-23 16:11:45 UTC
Created attachment 329849 [details]
reproducer program

Looks like this can reproduce it. We stat the file, then open it and lstat it. The mode on the lstat is wrong.

# ./reproducer /home/testuser/.ssh/authorized_keys
mode1 = 100644
mode2 = 102767

Comment 5 Jeff Layton 2009-01-23 16:13:37 UTC
On rawhide the results of the reproducer are correct:

mode1 = 100644
mode2 = 100644

Comment 6 Rob Henderson 2009-01-23 17:03:34 UTC
You might want to try it on rawhide with a mode other than 644 (like 477).  I am seeing cases where 644 doesn't expose the bug but other modes do.  For example:

Case 1:  2.6.18-92.1.22.el5 kernel with file mode 644

mode1 = 100644
mode2 = 100644

Case 2:  2.6.18-92.1.22.el5 kernel with file mode 477

mode1 = 100477
mode2 = 100455

Case 3:  2.6.18-128.el5 kernel with file mode 644

mode1 = 100644
mode2 = 102767

Case 4:  2.6.18-128.el5 kernel with file mode 477

mode1 = 100477
mode2 = 102545


So, both RHEL 5.2 and 5.3 kernels have problems but they are behaving differently.

Comment 7 Jeff Layton 2009-01-23 17:21:27 UTC
What's happening is that we're falling into non-unix extension codepaths incorrectly.

The 5.3 kernels have some patches to give files sane modes when unix extensions aren't enabled. When you set the mode to 0477, then samba is setting the ATTR_READONLY bit when you do a QueryPathInfo call.

The default file mode for cifs is 02767. When the ATTR_READONLY bit is set, we clear all the write bits from the mode, so you end up with 02545.

I see the bug and have a patch that I'll attach in a few mins.

Comment 8 Jeff Layton 2009-01-23 17:23:43 UTC
Created attachment 329857 [details]
patch -- add missing else statement in cifs_open_inode_helper

This patch should fix it. The problem was a missing else statement in cifs_open_inode_helper(). I'll plan to add this to my test kernels for now and will propose it as part of the CIFS update for 5.4.

Comment 9 Jeff Layton 2009-01-28 19:53:06 UTC
I've added this patch to the test kernels on my people.redhat.com page:

http://people.redhat.com/jlayton

...if you're able to test them somewhere non-critical then please do and report back whether this fixes the problem for you.

Comment 10 Rob Henderson 2009-01-28 20:48:32 UTC
I applied your patch to the stock rhel5.3 2.6.18-128 kernel and it resolved this problem in all of my testing.  I also grabbed your jtltest.60 kernel and that one also seems to have resolved this problem.  Thanks!

Comment 11 RHEL Program Management 2009-02-12 19:41:18 UTC
This request was evaluated by Red Hat Product Management for inclusion in a Red
Hat Enterprise Linux maintenance release.  Product Management has requested
further review of this request by Red Hat Engineering, for potential
inclusion in a Red Hat Enterprise Linux Update release for currently deployed
products.  This request is not yet committed for inclusion in an Update
release.

Comment 12 RHEL Program Management 2009-02-16 15:45:36 UTC
Updating PM score.

Comment 14 Jeff Layton 2009-04-22 18:56:43 UTC

*** This bug has been marked as a duplicate of bug 465143 ***