Bug 951728 - proftpd tries to close PAM session while running as non-root user
Summary: proftpd tries to close PAM session while running as non-root user
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: proftpd
Version: 18
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Matthias Saou
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2013-04-12 21:50 UTC by Michal Schmidt
Modified: 2013-04-26 06:32 UTC (History)
4 users (show)

Fixed In Version: proftpd-1.3.4c-2.fc18
Clone Of:
Environment:
Last Closed: 2013-04-26 06:32:07 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Michal Schmidt 2013-04-12 21:50:39 UTC
Description of problem:
Jason Burgess noticed (in https://bugzilla.redhat.com/show_bug.cgi?id=809214#c30) the following messages in system logs:

Apr 11 23:12:28 localhost dbus[594]: [system] Rejected send message, 2 matched rules; type="method_call", sender=":1.174" (uid=505 pid=6971 comm="proftpd: ftpuser- 192.168.1.10: IDLE") interface="org.freedesktop.login1.Manager" member="ReleaseSession" error name="(unset)" requested_reply="0" destination="org.freedesktop.login1" (uid=0 pid=578 comm="/usr/lib/systemd/systemd-logind ")

Note that logind's DBus method ReleaseSession is called from pam_systemd's pam_sm_close_session implementation.

So the error message tells us that a proftpd process tried to close a PAM session (i.e. by calling pam_session_close()) while running as a user other than root (uid=505).

This is incorrect use of PAM by proftpd. Both pam_open_session() and pam_close_session() must be called as root and in the same process.

Version-Release number of selected component (if applicable):
proftpd-1.3.4c-1.fc18

How reproducible:
always

Steps to Reproduce:
1. Start proftpd using the package's default config.
2. Login into FTP as a user, then log out.
3. journalctl -b | grep Reject
  
Actual results:
The above error message proving that pam_close_session was called by unprivileged process.

Expected results:
No error message. PAM session correctly closed.

Additional info:
From looking at proftpd sources I found that proftpd works roughly like this:

accept()
fork()
in the child {
    pam_auth() { /* in mod_auth_pam */
       pam_open_session()
    }
    drop privileges

    ...work..

    auth_pam_exit_ev() {  /* in mod_auth_pam */
       PRIVS_ROOT  /* tries to regain root privileges */
       pam_close_session()
    }
}

PRIVS_ROOT does not have the desired effect because session.disable_id_switching is set. It is set by mod_cap. This leads us to an ugly but effective workaround: Use "CapabilitiesEngine off" in the config file to disable mod_cap.

A proper fix should likely consist of adding another fork(), where the parent would open the PAM session, wait for the child to exit, then close the session. The child would drop privileges and would never have to regain them.

This view on using PAM sessions is supported for example by:
Tomáš Mráz, the PAM maintainer, in an old discussion about a similar issue in OpenSSH:
https://bugzilla.mindrot.org/show_bug.cgi?id=926#c21
Lennart Poettering, more recently about PAM handling in xrdp:
https://bugzilla.redhat.com/show_bug.cgi?id=821569#c23

Comment 1 Paul Howarth 2013-04-13 07:27:59 UTC
(In reply to comment #0)
> PRIVS_ROOT does not have the desired effect because
> session.disable_id_switching is set. It is set by mod_cap. This leads us to
> an ugly but effective workaround: Use "CapabilitiesEngine off" in the config
> file to disable mod_cap.

Which capability should proftpd retain in order for this to work properly with mod_cap enabled? Upstream has been receptive to retaining needed capabilities for proper PAM operation in the past: http://bugs.proftpd.org/show_bug.cgi?id=3257

Comment 2 Michal Schmidt 2013-04-15 17:03:27 UTC
(In reply to comment #1)
> Which capability should proftpd retain in order for this to work properly
> with mod_cap enabled?

I really think the proper way is to split it into two processes as I described in my original comment.

[Adding Tomáš Mráz to CC].

Tomáš,
would you have any comments on the proper way to open and close PAM sessions?

Comment 3 Tomas Mraz 2013-04-15 17:37:34 UTC
I don't have much else to comment than just confirm what you said in the bug description as the proper way to call the pam_close_session(). Additional fork is needed also for the situation where the unprivileged child crashes.

Comment 4 Paul Howarth 2013-04-16 12:54:41 UTC
Raised upstream: http://bugs.proftpd.org/show_bug.cgi?id=3929

Comment 5 Fedora Update System 2013-04-16 19:38:48 UTC
proftpd-1.3.4c-2.fc19 has been submitted as an update for Fedora 19.
https://admin.fedoraproject.org/updates/proftpd-1.3.4c-2.fc19

Comment 6 Fedora Update System 2013-04-16 19:38:59 UTC
proftpd-1.3.4c-2.fc18 has been submitted as an update for Fedora 18.
https://admin.fedoraproject.org/updates/proftpd-1.3.4c-2.fc18

Comment 7 Michal Schmidt 2013-04-17 08:51:13 UTC
I see that proftpd upstream refused to add the fork(), because :
  """
  we'd have another process which does absolutely nothing but shadow the
  original session, taking a slot in the process table, solely for purposes
  of closing some PAM session (which, for some reason, *requires root privs*)
  """

So instead they made sure to restore root privileges before closing the PAM session in the same process:
http://pkgs.fedoraproject.org/cgit/proftpd.git/plain/pam-close-bug3929.patch?id=9f2fb5f2fa5ae0f9cc576ca985f97bc2a8f3e22a

I must say, having a process partially drop privileges, but only so that it can restore them at will later, does not appear as a secure design.

I'll let Jason comment on whether it gets rid of the DBus error messages.

Comment 8 Fedora Update System 2013-04-22 00:41:04 UTC
proftpd-1.3.4c-2.fc19 has been pushed to the Fedora 19 stable repository.  If problems still persist, please make note of it in this bug report.

Comment 9 Fedora Update System 2013-04-26 00:58:37 UTC
proftpd-1.3.4c-2.fc18 has been pushed to the Fedora 18 stable repository.  If problems still persist, please make note of it in this bug report.


Note You need to log in before you can comment on or make changes to this bug.