Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

keyctl_read_alloc: permission denied #95928

Open
ralsei opened this issue Aug 21, 2020 · 5 comments
Open

keyctl_read_alloc: permission denied #95928

ralsei opened this issue Aug 21, 2020 · 5 comments

Comments

@ralsei
Copy link
Contributor

ralsei commented Aug 21, 2020

Describe the bug
keyctl from the keyutils package is unable to read from the user session, even as root.

To Reproduce

~
λ keyctl add user test payload @u
736202180
~
λ keyctl show @u
Keyring
 466901436 --alswrv   1000 65534  keyring: _uid.1000
 736202180 --alswrv   1000   100   \_ user: test
~
λ keyctl read 736202180
keyctl_read_alloc: Permission denied
~
λ sudo keyctl read 736202180
keyctl_read_alloc: Permission denied

This is very similar to an old systemd bug. Replacing @u with @s here functions fine.

Expected behavior
keyctl read <id> should... read the data at the given ID.

Metadata

 - system: `"x86_64-linux"`
 - host os: `Linux 5.4.58, NixOS, 20.03.2806.cb1996818ed (Markhor)`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.3.6`
 - channels(root): `"home-manager-20.03, nixos-20.03.2806.cb1996818ed, nixos-hardware, nixos-unstable-20.09pre239139.a19e16756b6"`
 - channels(hazel): `""`
 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixos`
@stale
Copy link

stale bot commented Feb 18, 2021

I marked this as stale due to inactivity. → More info

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Feb 18, 2021
@RaitoBezarius
Copy link
Member

Did you figure out something @ralsei ? Just ran into this myself on unstable. Linking @us and @s re-enables reading from the user keyring. What's going on?

@ralsei
Copy link
Contributor Author

ralsei commented Oct 12, 2021

I wasn't able to figure this out, no. Sorry.

@pmiddend
Copy link
Contributor

pmiddend commented Apr 8, 2023

This is still an issue with the latest nixos-unstable.

@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Apr 8, 2023
@RaitoBezarius
Copy link
Member

From my understanding, the problem resides in user@.service which we probably use for NixOS (upstream systemd unit):

#  SPDX-License-Identifier: LGPL-2.1-or-later
#
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=User Manager for UID %i
Documentation=man:user@.service(5)
After=user-runtime-dir@%i.service dbus.service systemd-oomd.service
Requires=user-runtime-dir@%i.service
IgnoreOnIsolate=yes

[Service]
User=%i
PAMName=systemd-user
Type=notify-reload
ExecStart=/nix/store/28njqxn2gywvz45pfgwim5b2g1dqdymv-systemd-253.2/lib/systemd/systemd --user
Slice=user-%i.slice
KillMode=mixed
Delegate=pids memory cpu
TasksMax=infinity
TimeoutStopSec=120s
KeyringMode=inherit
OOMScoreAdjust=100

The KeyringMode=inherit induces:

KeyringMode=
Controls how the kernel session keyring is set up for the service (see session-keyring(7) for details on the session keyring). Takes one of inherit, private, shared. If set to inherit no special
keyring setup is done, and the kernel's default behaviour is applied. If private is used a new session keyring is allocated when a service process is invoked, and it is not linked up with any
user keyring. This is the recommended setting for system services, as this ensures that multiple services running under the same system user ID (in particular the root user) do not share their
key material among each other. If shared is used a new session keyring is allocated as for private, but the user keyring of the user configured with User= is linked into it, so that keys assigned
to the user may be requested by the unit's processes. In this modes multiple units running processes under the same user ID may share key material. Unless inherit is selected the unique
invocation ID for the unit (see below) is added as a protected key by the name "invocation_id" to the newly created session keyring. Defaults to private for services of the system service manager
and to inherit for non-service units and for services of the user service manager.

I am unable to understand what is the default kernel's behavior, probably, we should have shared for user@.service which would enable user services to share keyring material if needed.
But that would be done over all user systemd services. I'm not sure this is something we want.

Though, if we want this to work in our "graphical session", we probably need to put it at the session scope level.

If we want this to work in our "user session" (i.e. (P|T)TY - including ssh -, graphical session), we need to put it at the slice level but user@$uid.service is included there too, so we share the secrets to the user systemd services.

Probably the smart thing to do to exploit the features completely is to determine the usecases.

(1) "unsecure" config: KeyringMode=shared on user-$uid.slice
(2) "secure" usecases:

  • define a set of services to share their keyring, put them under a slice/scope, add KeyringMode=shared on the slice/scope

In all the cases, I feel like this is suboptimal, what I want is probably process-level keyring but handled by systemd that survives across restarts which is KeyringMode=private on the keys I am interested in.

(An alternative is to use LoadCredentials and a UNIX socket server to fetch the data from the keyring.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants