Skip to content

core: link user session keyring to session keyring#6286

Closed
eworm-de wants to merge 1 commit intosystemd:masterfrom
eworm-de:keyring-link
Closed

core: link user session keyring to session keyring#6286
eworm-de wants to merge 1 commit intosystemd:masterfrom
eworm-de:keyring-link

Conversation

@eworm-de
Copy link
Copy Markdown
Contributor

@eworm-de eworm-de commented Jul 4, 2017

Commit 74dd6b5 (core: run each system
service with a fresh session keyring) broke adding keys to default
keyrings.
Added keys could not be accessed with error message:

keyctl_read_alloc: Permission denied

Commit 437a851 (core: link user keyring
to session keyring (#6275)) fixed this for the user keyring.

Link the user session keyring as well.

@eworm-de
Copy link
Copy Markdown
Contributor Author

eworm-de commented Jul 4, 2017

Arch Linux downstream bug report where eCryptfs breaks:
https://bugs.archlinux.org/task/54670

@arvidjaar
Copy link
Copy Markdown
Contributor

This (and your previous commit) creates huge security hole - now all users logged via the same top-level service (xDM, sshd) have access to each other keys. See https://bugzilla.novell.com/show_bug.cgi?id=1045886#c20

The whole kernel keyring handling should be removed and discussed with someone who actually understands how it works.

Commit  74dd6b5 (core: run each system
service with a fresh session keyring) broke adding keys to default
keyrings.
Added keys could not be accessed with error message:

keyctl_read_alloc: Permission denied

Commit 437a851 (core: link user keyring
to session keyring (systemd#6275)) fixed this for the user keyring.

Link the user session keyring as well.
@fbuihuu
Copy link
Copy Markdown
Contributor

fbuihuu commented Jul 7, 2017

Commit 437a851 (core: link user keyring to session keyring (#6275)) fixed this for the user keyring.

Isnt that commit broken ? it defeats the whole purpose of commit 74dd6b5: session keyring for system services should not be linked up to the user keyring.

@eworm-de , are you sure that your setup is not missing pam_keyinit.so ?

@eworm-de
Copy link
Copy Markdown
Contributor Author

eworm-de commented Jul 7, 2017

My setup breaks at a point where no pam is involved at all.

But you are right, all commits dealing with kernel keyring are broken:

Read the bug report linked by @arvidjaar for details.

@fbuihuu
Copy link
Copy Markdown
Contributor

fbuihuu commented Jul 7, 2017

My setup breaks at a point where no pam is involved at all.

Hmm if PAM is not used by your setup at all, 74dd6b5 might be incomplete indeed.

@poettering
Copy link
Copy Markdown
Member

Hmpf. Sorry for the forth and back, after reading this again I think the current code is actually the way it should be for the general case, except for the specific disk keyrin case here. That's because we "misuse" the kernel UID=0 keyring as kind of a "system-wide" keyring (which is a suggestion by the keyring kernel folks) for this specific purpose.

I kinda hoped we wouldn#t need a config option for the keyring but I figure we do after all... Hence I think we should add a new option for unit files:

KeyringMode=private|shared

If "private" which would be the default, we'd not link up the service keyring with the user keyring. But if "shared" we'd link them up. Then we'd use that for the disk agents, so that the logic can work.

Later on we might want to add more modes to this, for example KeyringMode=off for disabling the keyring for a service altogether (using seccomp), or KeyringMode=locked to make changes impossible (also using seccomp). But that of course can happen in a later commit.

@eworm-de can i convince you to rework your current patch to make the behaviour conditional based on such a setting?

@poettering poettering added pid1 reviewed/needs-rework 🔨 PR has been reviewed and needs another round of reworks labels Jul 11, 2017
poettering added a commit to poettering/systemd that referenced this pull request Jul 12, 2017
This reverts commit 437a851.

The outcome of this isn't that clear, let's revert this for now, see
discussion on systemd#6286.
@poettering
Copy link
Copy Markdown
Member

I posted a temporary revert for the other patch now in #6342. I still think some patch like that one should go in after all, but conditionalized through some service option, as discussed. But we shouldn#t change behaviour on this one again before we settle on an even different longer term fix... I hope that makes sense.

@eworm-de if you rework your patch, can you include both link invocations under the condition?

keszybz pushed a commit that referenced this pull request Jul 12, 2017
This reverts commit 437a851.

The outcome of this isn't that clear, let's revert this for now, see
discussion on #6286.
@fbuihuu
Copy link
Copy Markdown
Contributor

fbuihuu commented Jul 12, 2017

I think the current code is actually the way it should be for the general case, except for the specific disk keyrin case here.

I'm not sure to follow here... what is the "specific disk keyring case" ?

Currently I think the problem is for distros that don't integrate pam_keyinit in their PAM setup.

In this case

  1. all login processes won't access to the user keyring anymore
  2. all children processes from the same login service (sshd, gdm, etc...) share the same session keyring.

In my understanding, commit 437a851 tried to address 1. by linking up the session keyring to the user keyring but because of 2. all users logged via the same "login" service will share their user keyring.

pam_keyinit.so is supposed to fix that but some distros haven't integrate it yet...

@eworm-de
Copy link
Copy Markdown
Contributor Author

I will try to find some time to prepare this.

@nacitar
Copy link
Copy Markdown

nacitar commented Aug 2, 2017

I am running into this problem I believe on gentoo.. tried systemd 233-r4, 234-r2, and the current git head (-9999 in portage terms)... still persists.

$ keyctl add user "testing" "somedata" @u 
653010022 
$ keyctl read 653010022 
keyctl_read_alloc: Permission denied

@halfline
Copy link
Copy Markdown
Contributor

halfline commented Aug 17, 2017

So, today someone pinged me on IRC because that they heard that GDM uses the cryptsetup password for autologin when it can, but it wasn't working for them. We debugged a bit and determined pam_gdm running as root doesn't have permission to read the cryptsetup password from root's user keyring.

I did a bit of googling and found this pull request and the related ones, so here I am to chime in.

Some of this keyctl stuff is a little obscure, so, let me just summarize my understanding of the situation (probably getting some of the details wrong):

  1. the kernel keyring APIs provide access to secure kernel memory for services in both kernel and user space to save passwords and other secrets. One example of a password that is saved, is the disk encryption password the user types at boot to unlock the root partition. systemd tucks what the user typed away on one of root's keyrings, so that other parts of the OS (for instance, GDM) can pick it up later.

  2. A user has access to various keyrings that can be linked together in a hierarchy. One keyring can have another keyring linked to it. For instance, often a user's session keyring (created by pam_keyinit when the pam session is opened) will be linked (by pam_keyinit) to the the user's user keyring (created implicitly by the kernel at the first setuid() for a user).

  3. You can see the hierarchy of keyrings by using keyctl show. For instance to see what keyring the session keyring is linked to, type

$ keyctl show @s
516278881 --alswrv   4153  4153  keyring: _ses
242777222 --alswrv   4153 65534   \_ keyring: _uid.4153

it shows my user keyring, named _uid.4153 is linked to my session keyring named _ses.

  1. for processes that haven't been started in pam session (or have been started in a pam session lacking pam_keyinit in its session stack), they still get a session keyring but it's called the user's default session keyring. It's possible to see the default session keyring's hierarchy, even if you're in a proper session, by using
$ keyctl show @us
643657567 --alswrv   4153 65534  keyring: _uid_ses.4153
242777222 --alswrv   4153 65534   \_ keyring: _uid.4153

(note the @us instead of @s, that means default session keyring instead of current session keyring). it shows my user keyring, named _uid.4153 is linked to my default session keyring named _uid_sess.4153. The kernel does this linking automatically.

  1. There are also per-process and per-thread keyrings. They linked up to the session keyring for a user.

  2. keyrings are kind of like directories, and keys are kind of like files. But it's not exposed as a filesystem, and you don't use POSIX apis to access the secrets. Instead, there are some syscalls for creating keyrings, linking them together, creating keys, setting permissions etc. Also, there's no file paths. key names are just globally unique numbers. Anyway, keyctl exposes most of the functionality into a binary, and there's also a library libkeyutils that wraps the syscalls.

  3. the permission model is also slightly different than POSIX file permissions. instead of having user/group/other, there is posessor/user/group/other. There's also a lot more mode bits. instead of read/write/execute, there's stat/read/write/search/link/setattr. As I understand it, posessor means the key is reachable through the current keyring hiearchy for the process by starting at the thread keyring, then moving up to the process keyring, and continuing through all linked keyrings, presumably up through the session keyring, and then the user keyring. In contrast, user readable keyrings don't need to be reachable through the keyring hiearchy. If a process has the right uid then it can access a key using it's key name.

  4. Since key names are globally unique integers, you don't need to specify which keyring a key is in to access it. key's can have descriptions to, which are strings. So normally you'd like up a key's number from its description.

  5. By default when you create key, it's only readable by the possessor, not the user. This can be changed with a SETPERM call, which is analogous to chown(). (though it's 0x3f3f3f3f instead of 0777 to cover all 7 mode bits of stat/read/write/search/link/setattr instead of just 3 mode bits for read/write/execute)

  6. Before commit 74dd6b5 systemd services ran as root with the default session keyring for root implicitly linked to the user keyring for root. After that commit, services each got their own session keyring, explicitly not linked to the user keyring for root. That means services using the session keyring would no longer have access to keys from other services using the session keyring. of course, all services still have access to the user keyring for root, but since the user keyring is no longer linked to the services session keyring, they would no longer be considered "possessors" of keys on the user keyring, so by default, would be unable to read keys put on the user keyring, unless the permission mask of those keys was changed to allow "user" in addition to "possessor".

  7. cryptsetup currently puts the user's password on the user keyring for root, but doesn't update the permissions of the key. That means it's unreadable by anyone with a session keyring unlinked from the user keyring.

  8. commit 437a851 (which got later reverted) tried to address this unreadability by linking the services session keyrings to the root user keyring. The problem then is, if that service switches uids, the new uid will get a default session keyring that links back to the session keyring for the service. This meant that deafult session keyrings of different users ended up pointing to the service session keyring. Services that use pam_keyinit don't have the problem, of course.

So I wanted to write more, but I gotta run now. In my mind there are two fixes we need,

  • a SETPERM call when doing the cryptsetup key adding so that root can access it even if it's not a posessor
  • pam_keyinit to /etc/pam.d/systemd-user (or equivalent) so systemd --user services get a session keyring that links back to the user keyring.

@halfline
Copy link
Copy Markdown
Contributor

pam_keyinit to /etc/pam.d/systemd-user (or equivalent) so systemd --user services get a session keyring that links back to the user keyring.

Interesting. we've already been doing this upstream, since the end of last year, but it never made it into the fedora package (which ships its own pam config)

poettering added a commit to poettering/systemd that referenced this pull request Sep 14, 2017
…yring

We want that cryptsetup can cache keys between multiple invocations, and
it does so via the root user's user keyring, hence let's share it among
services.

Replaces: systemd#6286
@poettering
Copy link
Copy Markdown
Member

I implemented what I proposed above now in #6832, which hopefully fixes all the caching issues, but I only gave this some partial testing. @eworm-de please have a look, and check if this makes things work for you.

Closing this one in favour of #6832

@poettering poettering closed this Sep 14, 2017
poettering added a commit to poettering/systemd that referenced this pull request Sep 15, 2017
…yring

We want that cryptsetup can cache keys between multiple invocations, and
it does so via the root user's user keyring, hence let's share it among
services.

Replaces: systemd#6286
poettering added a commit to poettering/systemd that referenced this pull request Sep 15, 2017
…yring

We want that cryptsetup can cache keys between multiple invocations, and
it does so via the root user's user keyring, hence let's share it among
services.

Replaces: systemd#6286
@eworm-de eworm-de deleted the keyring-link branch December 7, 2017 12:25
fbuihuu added a commit to openSUSE/systemd that referenced this pull request Feb 2, 2018
It seems that this stuff needs more thoughts...

See also:
systemd/systemd#6286

[fbui: fixes bnc#1045886]
fbuihuu added a commit to openSUSE/systemd that referenced this pull request Mar 1, 2018
Until PAM module "pam_keyinit" is not integrated in the SUSE PAM stack, this
feature has to be disabled.

The integration of pam_keyinit is tracked here:
https://bugzilla.opensuse.org/show_bug.cgi?id=1081947

See also:
systemd/systemd#6286

[fbui: fixes boo#1045886]
fbuihuu added a commit to fbuihuu/systemd-opensuse-next that referenced this pull request Oct 8, 2018
Until PAM module "pam_keyinit" is not integrated in the SUSE PAM stack, this
feature has to be disabled.

The integration of pam_keyinit is tracked here:
https://bugzilla.opensuse.org/show_bug.cgi?id=1081947

See also:
systemd/systemd#6286

[fbui: fixes boo#1045886]
fbuihuu added a commit to openSUSE/systemd that referenced this pull request Mar 5, 2019
Until PAM module "pam_keyinit" is fully integrated in SUSE's PAM stack, this
feature has to be disabled.

openSUSE is still not ready for enabling the keyring stuff (see
bsc#1081947). Some services got fixed (sshd, getty@.service) but some still
haven't (xdm, login, ...)

So leave it disabled again otherwise different users might end up using the
same session keyring - the one created for the service used for logging in
(sshd, getty@.service, xdm, etc...)

The integration of pam_keyinit is tracked here:
https://bugzilla.opensuse.org/show_bug.cgi?id=1081947

See also:
systemd/systemd#6286

[fbui: fixes boo#1045886]
fbuihuu added a commit to openSUSE/systemd that referenced this pull request Apr 30, 2019
Until PAM module "pam_keyinit" is fully integrated in SUSE's PAM stack, this
feature has to be disabled.

openSUSE is still not ready for enabling the keyring stuff (see
bsc#1081947). Some services got fixed (sshd, getty@.service) but some still
haven't (xdm, login, ...)

So leave it disabled again otherwise different users might end up using the
same session keyring - the one created for the service used for logging in
(sshd, getty@.service, xdm, etc...)

The integration of pam_keyinit is tracked here:
https://bugzilla.opensuse.org/show_bug.cgi?id=1081947

See also:
systemd/systemd#6286

[fbui: fixes boo#1045886]
fbuihuu added a commit to openSUSE/systemd that referenced this pull request Apr 30, 2019
Until PAM module "pam_keyinit" is fully integrated in SUSE's PAM stack, this
feature has to be disabled.

openSUSE is still not ready for enabling the keyring stuff (see
bsc#1081947). Some services got fixed (sshd, getty@.service) but some still
haven't (xdm, login, ...)

So leave it disabled again otherwise different users might end up using the
same session keyring - the one created for the service used for logging in
(sshd, getty@.service, xdm, etc...)

The integration of pam_keyinit is tracked here:
https://bugzilla.opensuse.org/show_bug.cgi?id=1081947

See also:
systemd/systemd#6286

[fbui: fixes boo#1045886]
lnussel pushed a commit to lnussel/systemd-opensuse that referenced this pull request Aug 19, 2019
Until PAM module "pam_keyinit" is fully integrated in SUSE's PAM stack, this
feature has to be disabled.

openSUSE is still not ready for enabling the keyring stuff (see
bsc#1081947). Some services got fixed (sshd, getty@.service) but some still
haven't (xdm, login, ...)

So leave it disabled again otherwise different users might end up using the
same session keyring - the one created for the service used for logging in
(sshd, getty@.service, xdm, etc...)

The integration of pam_keyinit is tracked here:
https://bugzilla.opensuse.org/show_bug.cgi?id=1081947

See also:
systemd/systemd#6286

[fbui: fixes boo#1045886]
lnussel pushed a commit to lnussel/systemd-opensuse that referenced this pull request Aug 19, 2019
Until PAM module "pam_keyinit" is fully integrated in SUSE's PAM stack, this
feature has to be disabled.

openSUSE is still not ready for enabling the keyring stuff (see
bsc#1081947). Some services got fixed (sshd, getty@.service) but some still
haven't (xdm, login, ...)

So leave it disabled again otherwise different users might end up using the
same session keyring - the one created for the service used for logging in
(sshd, getty@.service, xdm, etc...)

The integration of pam_keyinit is tracked here:
https://bugzilla.opensuse.org/show_bug.cgi?id=1081947

See also:
systemd/systemd#6286

[fbui: fixes boo#1045886]
lnussel pushed a commit to lnussel/systemd-opensuse that referenced this pull request Aug 22, 2019
Until PAM module "pam_keyinit" is fully integrated in SUSE's PAM stack, this
feature has to be disabled.

openSUSE is still not ready for enabling the keyring stuff (see
bsc#1081947). Some services got fixed (sshd, getty@.service) but some still
haven't (xdm, login, ...)

So leave it disabled again otherwise different users might end up using the
same session keyring - the one created for the service used for logging in
(sshd, getty@.service, xdm, etc...)

The integration of pam_keyinit is tracked here:
https://bugzilla.opensuse.org/show_bug.cgi?id=1081947

See also:
systemd/systemd#6286

[fbui: fixes boo#1045886]
fbuihuu added a commit to openSUSE/systemd that referenced this pull request Sep 3, 2019
Until PAM module "pam_keyinit" is fully integrated in SUSE's PAM stack, this
feature has to be disabled.

openSUSE is still not ready for enabling the keyring stuff (see
bsc#1081947). Some services got fixed (sshd, getty@.service) but some still
haven't (xdm, login, ...)

So leave it disabled again otherwise different users might end up using the
same session keyring - the one created for the service used for logging in
(sshd, getty@.service, xdm, etc...)

The integration of pam_keyinit is tracked here:
https://bugzilla.opensuse.org/show_bug.cgi?id=1081947

See also:
systemd/systemd#6286

[fbui: fixes boo#1045886]
fbuihuu added a commit to openSUSE/systemd that referenced this pull request Dec 12, 2019
Until PAM module "pam_keyinit" is fully integrated in SUSE's PAM stack, this
feature has to be disabled.

openSUSE is still not ready for enabling the keyring stuff (see
bsc#1081947). Some services got fixed (sshd, getty@.service) but some still
haven't (xdm, login, ...)

So leave it disabled again otherwise different users might end up using the
same session keyring - the one created for the service used for logging in
(sshd, getty@.service, xdm, etc...)

The integration of pam_keyinit is tracked here:
https://bugzilla.opensuse.org/show_bug.cgi?id=1081947

See also:
systemd/systemd#6286

[fbui: fixes boo#1045886]
tblume pushed a commit to tblume/systemd-testsuite-suse that referenced this pull request Jan 28, 2020
Until PAM module "pam_keyinit" is fully integrated in SUSE's PAM stack, this
feature has to be disabled.

openSUSE is still not ready for enabling the keyring stuff (see
bsc#1081947). Some services got fixed (sshd, getty@.service) but some still
haven't (xdm, login, ...)

So leave it disabled again otherwise different users might end up using the
same session keyring - the one created for the service used for logging in
(sshd, getty@.service, xdm, etc...)

The integration of pam_keyinit is tracked here:
https://bugzilla.opensuse.org/show_bug.cgi?id=1081947

See also:
systemd/systemd#6286

[fbui: fixes boo#1045886]
fbuihuu added a commit to openSUSE/systemd that referenced this pull request Mar 19, 2020
Until PAM module "pam_keyinit" is fully integrated in SUSE's PAM stack, this
feature has to be disabled.

openSUSE is still not ready for enabling the keyring stuff (see
bsc#1081947). Some services got fixed (sshd, getty@.service) but some still
haven't (xdm, login, ...)

So leave it disabled again otherwise different users might end up using the
same session keyring - the one created for the service used for logging in
(sshd, getty@.service, xdm, etc...)

The integration of pam_keyinit is tracked here:
https://bugzilla.opensuse.org/show_bug.cgi?id=1081947

See also:
systemd/systemd#6286

[fbui: fixes boo#1045886]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pid1 reviewed/needs-rework 🔨 PR has been reviewed and needs another round of reworks

Development

Successfully merging this pull request may close these issues.

6 participants