Bug 115442

Summary: pam_limits.so cannot set privlidged limit settings
Product: Red Hat Enterprise Linux 3 Reporter: Neil Horman <nhorman>
Component: pamAssignee: Nalin Dahyabhai <nalin>
Status: CLOSED NOTABUG QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: 3.0CC: tao
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2004-02-16 18:45:20 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:
Bug Depends On:    
Bug Blocks: 111175    

Description Neil Horman 2004-02-12 16:19:26 UTC
Description of problem:
Under RHEL3, some limit settings set by pam_limits.so (specifically
memlock in this test), are not able to be set.  This appears to be the
case because the session setup is run as the users uid, so when
setrlimit is called to raise a system limit beyond the current
maximum, EPERM is returned.  I've instrumented a copy of pam_limits
and verified the behavior:

Feb 11 22:41:52 hmsvengance pam_limits[14546]: PAM_LIMITS parsing now....
Feb 11 22:41:52 hmsvengance pam_limits[14546]: found a memlock paramter
Feb 11 22:41:52 hmsvengance pam_limits[14546]: PAM_LIMITS parsing now....
Feb 11 22:41:52 hmsvengance pam_limits[14546]: found a memlock paramter
Feb 11 22:41:52 hmsvengance pam_limits[14546]: Starting setup_limits
with uid 502
Feb 11 22:41:52 hmsvengance pam_limits[14546]: Setting limits for RLIM_0  
Feb 11 22:41:52 hmsvengance pam_limits[14546]: Return code from
setrlimit is 0, errno is 0
Feb 11 22:41:52 hmsvengance pam_limits[14546]: Setting limits for RLIM_1  
Feb 11 22:41:52 hmsvengance pam_limits[14546]: Return code from
setrlimit is 0, errno is 0
Feb 11 22:41:52 hmsvengance pam_limits[14546]: Setting limits for RLIM_2  
Feb 11 22:41:52 hmsvengance pam_limits[14546]: Return code from
setrlimit is 0, errno is 0
Feb 11 22:41:52 hmsvengance pam_limits[14546]: Setting limits for RLIM_3  
Feb 11 22:41:52 hmsvengance pam_limits[14546]: Return code from
setrlimit is 0, errno is 0
Feb 11 22:41:52 hmsvengance pam_limits[14546]: Setting limits for RLIM_4  
Feb 11 22:41:52 hmsvengance pam_limits[14546]: Return code from
setrlimit is 0, errno is 0
Feb 11 22:41:52 hmsvengance pam_limits[14546]: Setting limits for RLIM_5
Feb 11 22:41:52 hmsvengance pam_limits[14546]: Return code from
setrlimit is 0, errno is 0
Feb 11 22:41:52 hmsvengance pam_limits[14546]: Setting limits for RLIM_6
Feb 11 22:41:52 hmsvengance pam_limits[14546]: Return code from
setrlimit is 0, errno is 0 
Feb 11 22:41:52 hmsvengance pam_limits[14546]: Setting limits for RLIM_7
Feb 11 22:41:52 hmsvengance pam_limits[14546]: Return code from
setrlimit is 0, errno is 0 
Feb 11 22:41:52 hmsvengance pam_limits[14546]: Setting limits for RLIM_8 
Feb 11 22:41:52 hmsvengance pam_limits[14546]: FOUND MEMLOCK SETTING 
Feb 11 22:41:52 hmsvengance pam_limits[14546]: rlim_cur = 8192 
Feb 11 22:41:53 hmsvengance pam_limits[14546]: rlim_max = 8192 
Feb 11 22:41:53 hmsvengance pam_limits[14546]: Return code from
setrlimit is -1, errno is 1
Feb 11 22:41:53 hmsvengance pam_limits[14546]: Setting limits for RLIM_9
Feb 11 22:41:53 hmsvengance pam_limits[14546]: Return code from
setrlimit is -1, errno is 1
Feb 11 22:41:53 hmsvengance pam_limits[14546]: Setting limits for RLIM_10
Feb 11 22:41:53 hmsvengance pam_limits[14546]: Return code from
setrlimit is -1, errno is 1


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


How reproducible:
always

Steps to Reproduce:
1.configure a hard limit for memlock for any user in limits.conf to be
larger than the default
2.log in with that user
3.check the current limit for memlock with ulimit -l
  
Actual results:
the memlock limit is unchanged from the result

Expected results:
the memlock limit configured in limits.conf is set.

Additional info:

Comment 1 Neil Horman 2004-02-16 18:45:20 UTC
Sorry, this isn't really a bug.  I just realized that this is the
result of the UsePrivlidgeSeparation setting of sshd.  When enabled,
sshd attempts to authenticate the user by accessessing pam with the
uid of the user attempting to login.  This means that upon successful
authentication, the session setup routines are also invoked as the uid
of the user logging in.  Since soft ulmit settings can't be increased
beyond the hard max by, and hard limits can't be increased at all by
anyone other than root, the pam_limits.so module can't do much when
used with ssh with UsePrivlidgeSeparation enabled.  This strikes me as
a trade off when using Privlidge Separation, and so is not a bug.

Comment 2 Neil Horman 2004-02-20 13:18:21 UTC
*** Bug 110944 has been marked as a duplicate of this bug. ***

Comment 3 Sven Nielsen 2004-04-15 21:01:10 UTC
A workaround I found for this bug is to pre-set the limit to the 
maximum you might want in /etc/init.d/sshd, before sshd gets started, 
then set them to lower values for the users in /etc/security/limits.
conf.

So after the variable definitions in /etc/init.d/sshd, I have:

  ulimit -n 16384

(since this is a bash script) and I have the following in 
/etc/security/limits.conf:

  * nofile hard 16384
  * nofile soft 8192
  user1 nofile hard 1024

Do /etc/init.d/sshd restart, and your higher-than-default limits
should be applied for each user that logs in via sshd.

Comment 4 Daniel Berrangé 2004-09-01 13:02:40 UTC
According to this diagram from the docs about the original 
implementation, (http://www.citi.umich.edu/u/provos/ssh/privsep.html):

http://www.citi.umich.edu/u/provos/ssh/priv.jpg

After the unprivileged process has complete authentication, control 
switches back to the privileged monitor process to fork the actual 
session. Thus it appears that it would be possible to maintain use of 
PrivilegeSeparation for purposes of securing the PAM call for the 
authentication process, but then have a 2nd PAM call done by the 
privileged process prior to forking the actual user child process, 
only for the purposes of setting up session state which required root 
privileges. 

Comment 5 Neil Horman 2004-09-01 13:24:30 UTC
That might be what the picture in the document describes, but the
actual implementation appears to differ.  An strace of the monitor
process only indicates one clone (fork) actually ever takes place. 
Perhaps this issue could be addressed if the implementation actually
followed the description you provide, but that would seem to me (at
least at the moment) to be more of a major design overhaul rather than
a bug to fix in the current implementation.