Bug 83 - PAM limits applied incorrectly (pam_session being called as non-root)
Summary: PAM limits applied incorrectly (pam_session being called as non-root)
Status: CLOSED FIXED
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: PAM support (show other bugs)
Version: -current
Hardware: ix86 Linux
: P2 normal
Assignee: OpenSSH Bugzilla mailing list
URL:
Keywords: patch
: 301 354 419 (view as bug list)
Depends on:
Blocks:
 
Reported: 2002-01-29 23:47 AEDT by Vasil Kolev
Modified: 2004-04-14 12:24 AEST (History)
4 users (show)

See Also:


Attachments
Call pam_session after child fork() (1.51 KB, patch)
2003-03-10 15:49 AEDT, Damien Miller
no flags Details | Diff
Call pam_session after fork, before setusercontext (1.04 KB, patch)
2003-03-27 22:08 AEDT, Damien Miller
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Vasil Kolev 2002-01-29 23:47:25 AEDT
Background: debian woody, kernel 2.4.17

 The problem is, when you set some resource limits in /etc/security/limits.conf
for group X - nproc 20 ( maximum of running user processes - 20 ), and try to
log with some user with group X, sshd says 'fork failed - resource temporary
unavialable'. There are no other processes running for this user, and as far as
i've seen, it makes something like authenticate-set limits-fork()-setuid() , and
because there is a moment when it's running under root with really lowered
limits, it bombs out. 
  Any solutions?
Comment 1 Damien Miller 2002-01-31 21:46:26 AEDT
I'm putting some replies from the openssh-unix-dev mailing list into the bug so
we capture the history in one place.

On Thu, 2002-01-31 at 21:11, Frank Cusack wrote:
> On Thu, Jan 31, 2002 at 09:54:36AM +0000, Matthew Vernon wrote:
> > My understanding of this is that it's a result of a fundamental
> > mis-design of PAM - you have to do the entire PAM conversation in one
> > go (as root), so this sort of PAM-based limiting is always going to be
> > prone to this sort of error.
> 
> I don't see how this is a problem with PAM?  You do have to do the
> entire conversation in one go, but not as root (other than a possible
> requirement for access to some resources like /etc/shadow -- but, eg,
> with krb5 you MUST NOT be root when doing PAM auth).  Regardless, why
> would PAM trip up here, and why would the conversation matter?  Limits
> such as described would not be managed during pam_authenticate() (when the
> conversation happens).  Perhaps I am not familiar enough with nuances
> of debian's PAM implementation.

The problem is that we call pam_session as root, before we fork the child.
Therefore the server picks up the limits, rather than the child. 

I recall that we tried moving the pam_session call to the child a while (~18
months) ago to avoid this problem, but other stuff broke much worse. IIRC the
breakage was because we did pam_session stuff in one process (as non-root) and
then did cleanup in another process (as root).

A possible way around this is with a gratuitous fork() before we call
pam_session, but that is pretty ugly.
Comment 2 Rob Mosher 2002-02-12 17:28:31 AEDT
in do_exec_no_pty i put do_pam_session it above do_child, in  do_exec_pty i put
it right before you record the login and right after close(ttyfd).  i do not see
any problems with this, what problems have you seen this produce? i've been
running it like this on my server and it seems to set limits properly, log users
in properly, etc.
Comment 3 Damien Miller 2002-02-12 17:34:51 AEDT
IIRC we saw segfaults on Solaris and other weirdness on HPUX, but is was a while
ago and my memory was rusty. What OS are you using your patch on?

If you can gather success stories from the PAM-aware OSs (openssh-unix-dev@ is
the place to ask for these), then we can apply the patch.
Comment 4 Rob Mosher 2002-02-13 01:20:54 AEDT
unfortunately, i dont have the time to pursue this deeper right now,  but it
would be good if someone else did so this can get fixed.  im running debian
(unstable).
Comment 5 Damien Miller 2002-10-16 13:09:44 AEST
*** Bug 301 has been marked as a duplicate of this bug. ***
Comment 6 Damien Miller 2003-01-07 18:31:22 AEDT
*** Bug 354 has been marked as a duplicate of this bug. ***
Comment 7 Damien Miller 2003-03-10 15:49:32 AEDT
Created attachment 247 [details]
Call pam_session after child fork()

Hopefully this patch will allow people to gather the feedback necessary to
close this bug.
Comment 8 Damien Miller 2003-03-10 15:51:30 AEDT
If you want to see this bug closed, please try the attached patch and see if
things work correctly. We'll need feedback from (at least) Solaris, Linux, HP/UX
users.
Comment 9 Damien Miller 2003-03-22 08:29:54 AEDT
*** Bug 419 has been marked as a duplicate of this bug. ***
Comment 10 Todd Bowden 2003-03-27 04:11:26 AEDT
The system is configured as HP-UX 11.0 in trusted system mode, running OpenSSH 
3.5p1 in privilege seperation mode.  If the user is forced to change their 
password it exits immediately.

I have tried using the patch supplied by Damien Miller on HP-UX.  The results 
were the following:

error messages in the syslog.log:

Mar 26 12:10:30 uspenp4 sshd[25577]: PAM rejected by account configuration[10]: 
Get new authentication token
Mar 26 12:10:30 uspenp4 sshd[25577]: fatal: monitor_read: unsupported request: 
24

output of ssh -v -v -l <username> <hostname>:

OpenSSH_3.5p1, SSH protocols 1.5/2.0, OpenSSL 0x0090701f
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Rhosts Authentication disabled, originating port will not be trusted.
debug1: ssh_connect: needpriv 0
debug1: Connecting to uspenp4 [130.140.173.134] port 22.
debug1: Connection established.
debug1: identity file /.ssh/identity type -1
debug1: identity file /.ssh/id_rsa type -1
debug1: identity file /.ssh/id_dsa type -1
debug1: Remote protocol version 2.0, remote software version OpenSSH_3.5p1
debug1: match: OpenSSH_3.5p1 pat OpenSSH*
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_3.5p1
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug2: kex_parse_kexinit: diffie-hellman-group-exchange-sha1,diffie-hellman-
group1-sha1
debug2: kex_parse_kexinit: ssh-rsa,ssh-dss
debug2: kex_parse_kexinit: aes128-cbc,3des-cbc,blowfish-cbc,cast128-
cbc,arcfour,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se
debug2: kex_parse_kexinit: aes128-cbc,3des-cbc,blowfish-cbc,cast128-
cbc,arcfour,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se
debug2: kex_parse_kexinit: hmac-md5,hmac-sha1,hmac-ripemd160,hmac-
ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96
debug2: kex_parse_kexinit: hmac-md5,hmac-sha1,hmac-ripemd160,hmac-
ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96
debug2: kex_parse_kexinit: none,zlib
debug2: kex_parse_kexinit: none,zlib
debug2: kex_parse_kexinit:
debug2: kex_parse_kexinit:
debug2: kex_parse_kexinit: first_kex_follows 0
debug2: kex_parse_kexinit: reserved 0
debug2: kex_parse_kexinit: diffie-hellman-group-exchange-sha1,diffie-hellman-
group1-sha1
debug2: kex_parse_kexinit: ssh-rsa,ssh-dss
debug2: kex_parse_kexinit: aes128-cbc,3des-cbc,blowfish-cbc,cast128-
cbc,arcfour,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se
debug2: kex_parse_kexinit: aes128-cbc,3des-cbc,blowfish-cbc,cast128-
cbc,arcfour,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se
debug2: kex_parse_kexinit: hmac-md5,hmac-sha1,hmac-ripemd160,hmac-
ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96
debug2: kex_parse_kexinit: hmac-md5,hmac-sha1,hmac-ripemd160,hmac-
ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96
debug2: kex_parse_kexinit: none,zlib
debug2: kex_parse_kexinit: none,zlib
debug2: kex_parse_kexinit:
debug2: kex_parse_kexinit:
debug2: kex_parse_kexinit: first_kex_follows 0
debug2: kex_parse_kexinit: reserved 0
debug2: mac_init: found hmac-md5
debug1: kex: server->client aes128-cbc hmac-md5 none
debug2: mac_init: found hmac-md5
debug1: kex: client->server aes128-cbc hmac-md5 none
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
debug1: dh_gen_key: priv key bits set: 140/256
debug1: bits set: 1580/3191
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
debug1: Host 'uspenp4' is known and matches the RSA host key.
debug1: Found key in /.ssh/known_hosts:1
debug1: bits set: 1608/3191
debug1: ssh_rsa_verify: signature correct
debug1: kex_derive_keys
debug1: newkeys: mode 1
debug1: SSH2_MSG_NEWKEYS sent
debug1: waiting for SSH2_MSG_NEWKEYS
debug1: newkeys: mode 0
debug1: SSH2_MSG_NEWKEYS received
debug1: done: ssh_kex2.
debug1: send SSH2_MSG_SERVICE_REQUEST
debug1: service_accept: ssh-userauth
debug1: got SSH2_MSG_SERVICE_ACCEPT
debug1: authentications that can continue: publickey,password,keyboard-
interactive
debug1: next auth method to try is publickey
debug1: try privkey: /.ssh/identity
debug1: try privkey: /.ssh/id_rsa
debug1: try privkey: /.ssh/id_dsa
debug2: we did not send a packet, disable method
debug1: next auth method to try is keyboard-interactive
debug2: userauth_kbdint
debug2: we sent a keyboard-interactive packet, wait for reply
debug1: authentications that can continue: publickey,password,keyboard-
interactive
debug2: we did not send a packet, disable method
debug1: next auth method to try is password
us14592@uspenp4's password:
debug2: we sent a password packet, wait for reply
debug1: ssh-userauth2 successful: method password
debug1: channel 0: new [client-session]
debug1: send channel open 0
debug1: Entering interactive session.
debug1: channel_free: channel 0: client-session, nchannels 1
Connection to uspenp4 closed by remote host.
Connection to uspenp4 closed.
debug1: Transferred: stdin 0, stdout 0, stderr 77 bytes in 0.1 seconds
debug1: Bytes per second: stdin 0.0, stdout 0.0, stderr 1291.6
debug1: Exit status -1
Comment 11 Arkadiusz Miskiewicz 2003-03-27 20:53:12 AEDT
I've applied patch posted here but it doesn't change nothing since still 
do_pam_session() is not called as root! 
 
See strace here: 
http://bugzilla.mindrot.org/show_bug.cgi?id=301 
 
And this: 
[misiek@arm ~/rpm/BUILD/openssh-3.5p1]$ diff -u 
~/rpm/SOURCES/openssh-3.5p1/session.c session.c 
--- /home/users/misiek/rpm/SOURCES/openssh-3.5p1/session.c      Thu Mar 27 
10:46:17 2003 
+++ session.c   Thu Mar 27 10:52:33 2003 
@@ -604,6 +604,7 @@ 
                close(ttyfd); 
 
 #if defined(USE_PAM) 
+               log("uid=%d, euid=%d\n", getuid(), geteuid()); 
                do_pam_session(s->pw->pw_name, s->tty); 
                do_pam_setcred(1); 
 #endif 
 
Mar 27 10:53:18 arm sshd[3951]: Accepted password for misiek from ::ffff:127.0.0.1 port 
4992 ssh2 
Mar 27 10:53:18 arm sshd[4645]: uid=1000, euid=1000 
Mar 27 10:53:18 arm sshd(pam_unix)[4645]: session opened for user misiek by 
misiek(uid=1000) 
Mar 27 10:53:18 arm sshd[4645]: fatal: PAM session setup failed[6]: Permission 
denied 
 
You _cannot_ increase your limits (like core size limit) when you are not root. See bug 
301 for details. 
 
Comment 12 Damien Miller 2003-03-27 22:08:37 AEDT
Created attachment 263 [details]
Call pam_session after fork, before setusercontext

This moves the call to pam_session to after the fork() but before the call to
do_setusercontext (which gives up root privs).
Comment 13 Arkadiusz Miskiewicz 2003-03-28 00:45:33 AEDT
but whole do_exec_pty() is run with user rights: 
 
Mar 27 14:51:53 arm sshd[16580]: Accepted password for misiek from ::ffff:127.0.0.1 
port 1354 ssh2 
Mar 27 14:51:53 arm sshd[10120]: server_input_channel_req: uid=1000 euid=1000 
Mar 27 14:51:53 arm sshd[10120]: server_input_channel_req: uid=1000 euid=1000 
Mar 27 14:51:53 arm sshd[10120]: session_shell_req: uid=1000 euid=1000 
Mar 27 14:51:53 arm sshd[10120]: do_exec_pty: uid=1000 euid=1000 
Mar 27 14:51:53 arm sshd[21054]: just before do_pam_session() uid=1000 euid=1000 
Mar 27 14:51:53 arm sshd(pam_unix)[21054]: session opened for user misiek by 
misiek(uid=1000) 
Mar 27 14:51:53 arm sshd[21054]: fatal: PAM session setup failed[6]: Permission 
denied 
 
separation enabled of course 
Comment 14 Damien Miller 2003-03-28 10:48:36 AEDT
Most of session.c runs with user privs in privsep mode. if you need to raise
ulimits, you may need to raise the hard-limits for sshd itself. The last patch
may help if you are not using privsep.

There are two issues here: 1) That all pam_limits calls are happening in the
server process, rather than the child (this is the greater problem) 2) the
ulimit calls are happening as non-root.

2) is arguably not a bug.
Comment 15 Arkadiusz Miskiewicz 2003-04-02 08:32:44 AEST
Valid sshd config, valid limits.conf and with privseparation enabled I'm not allowed to 
login, with privseparation disabled I'm allowed to login :/ 
 
Maybe just ignore errors from pam if it's called with user rights? (but thats sounds bad 
for me). 
 
Anyway I can live with privseparation disabled. 
Comment 16 Darren Tucker 2003-09-15 12:13:43 AEST
Hey, isn't this fixed in -current?  do_pam_session is now called before
permanently_set_uid.

Could you please try a snapshot?
Comment 17 Darren Tucker 2003-12-22 22:07:38 AEDT
3 months no reply = closed bug.
Comment 18 Damien Miller 2004-04-14 12:24:17 AEST
Mass change of RESOLVED bugs to CLOSED