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

[bug] when started as a nonroot user, Pebble doesn't run services with the user's own UID #166

Closed
cjdcordeiro opened this issue Dec 1, 2022 · 2 comments · Fixed by #239

Comments

@cjdcordeiro
Copy link
Collaborator

Let's assume the nonroot user:group "ubuntu:ubuntu" with UID:GID "1000:1000".

SOTA

At the moment, it is possible to run Pebble as a nonroot user. So, given the following layer:

summary: test layer

services:
  svc1:
    override: replace
    command: /app.py
    startup: enabled

pebble run would work just fine:

# ps -u ubuntu
    PID TTY          TIME CMD
     75 pts/1    00:00:00 bash
    102 pts/1    00:00:00 pebble
    149 pts/1    00:00:00 python3
(...)

Problem

However, if a user*/group* attribute is specified in the layer, then we would expect:

  • if user is not "me" (i.e. the user running Pebble), then fail
    • this is the case ✔️
  • if user is "me", then continue
    • this is NOT the case, as Pebble fails to start the service, with permission denied ❌

E.g.:

summary: test layer

services:
  svc1:
    override: replace
    command: /app.py
    startup: enabled
    user-id: 1000
    group-id: 1000

and the pebble run, will not start the svc1. And we I try to force start it, I get:

# pebble start svc1
error: cannot perform the following tasks:
- Start service "svc1" (cannot start service: fork/exec /app.py: operation not permitted)

Conclusion

I believe this is being caused by https://github.com/canonical/pebble/blob/master/internal/overlord/servstate/handlers.go#L342, where Pebble is trying to set the Credentials attribute for the cmd, whenever uid and gid are defined (no matter what they are). I'd expect instead, that if the give UID and GID match the Pebble user, then the SysProcAttr->Credential can be ignored.

@benhoyt
Copy link
Contributor

benhoyt commented Dec 1, 2022

Yeah, I've noticed this too: if you set uid/user-id/gid/group-id, Pebble must be running as root. Is this an issue in practice, though? If Pebble is running as "ben" and you wanted to run the service as "ben", you could just leave out the user/group fields, right? Can you give a bit more of a use case for needing this?

@cjdcordeiro
Copy link
Collaborator Author

While it can be worked around and it does feel like a non-blocker, it is just a matter of coherence. Despite being a corner case, one can imagine a scenario where the Pebble layer has been written to be executed by a specific user, and only that user. In the context of ROCKs, the explicit user attributes in the Pebble service will hint towards the definition of the default OCI user when building the ROCK and derivative images.

benhoyt added a commit to benhoyt/pebble that referenced this issue Jun 19, 2023
This goes for services, exec, and health checks of type "exec".

This also fixes a long-standing bug in the user/group parameters for
"exec" health checks not working at all. This was due to not setting
cmd.SysProcAttr, so the "cmd.SysProcAttr.Credential =" line would panic
with a nil pointer error.

Also a drive-by fix to the README to update to the new terminology.
See also canonical/operator#950

Fixes canonical#166
niemeyer pushed a commit that referenced this issue Jun 19, 2023
When user and group (or user ID and group ID) options are given when running services and they're equal to the current user and group, avoid setting os/exec's syscall.Credential Uid and Gid, because they require root. In the case when they're explicitly asking to run the command as the current user, we can just run it directly, without requiring root.

This goes for services, exec (one-shot commands), and health checks of type "exec".

This PR also fixes a long-standing bug in the user/group options for "exec" health checks not working at all. This was due to not setting cmd.SysProcAttr, so the cmd.SysProcAttr.Credential = ... line would panic with a nil pointer error.

Also a drive-by fix to the README to update to the new terminology. See also canonical/operator#950.

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

Successfully merging a pull request may close this issue.

2 participants