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

[WIP] many: non-setuid snap-confine, caps v4 #15094

Draft
wants to merge 36 commits into
base: master
Choose a base branch
from

Conversation

bboozzoo
Copy link
Contributor

This is a work-in-progress branch of non-setuid snap-confine. Originally based on #14970 and attempts to address the comments made in that PR.

@bboozzoo bboozzoo added ⛔ Blocked Skip spread Indicate that spread job should not run labels Feb 18, 2025
@bboozzoo bboozzoo force-pushed the bboozzoo/snap-confine-caps-v4-wip branch from 4a85a28 to 71c268a Compare February 18, 2025 12:57
Copy link

github-actions bot commented Feb 18, 2025

Wed Feb 26 13:23:33 UTC 2025
The following results are from: https://github.com/canonical/snapd/actions/runs/13542856525

Failures:

Executing:

  • openstack:fedora-41-64:tests/main/snap-confine-undesired-mode-group
  • google-core:ubuntu-core-18-64:tests/core/kernel-base-gadget-pair-single-reboot:kernel_gadget
  • google-core:ubuntu-core-18-64:tests/main/snap-confine-undesired-mode-group
  • google-core:ubuntu-core-20-64:tests/main/snap-confine-undesired-mode-group
  • google:ubuntu-20.04-64:tests/main/interfaces-network-control
  • google:ubuntu-20.04-64:tests/main/snap-confine-undesired-mode-group
  • google:ubuntu-24.10-64:tests/main/snap-confine-undesired-mode-group

Restoring:

  • google-core:ubuntu-core-20-64:tests/main/snap-quota

@bboozzoo bboozzoo removed the Skip spread Indicate that spread job should not run label Feb 18, 2025
@bboozzoo bboozzoo force-pushed the bboozzoo/snap-confine-caps-v4-wip branch from 09ab743 to 517ac1b Compare February 18, 2025 13:46
Copy link

codecov bot commented Feb 18, 2025

Codecov Report

Attention: Patch coverage is 57.14286% with 3 lines in your changes missing coverage. Please review.

Project coverage is 78.06%. Comparing base (a272aac) to head (c304154).
Report is 54 commits behind head on master.

Files with missing lines Patch % Lines
cmd/snap-update-ns/system.go 40.00% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #15094      +/-   ##
==========================================
- Coverage   78.07%   78.06%   -0.01%     
==========================================
  Files        1182     1185       +3     
  Lines      157743   158161     +418     
==========================================
+ Hits       123154   123476     +322     
- Misses      26943    27010      +67     
- Partials     7646     7675      +29     
Flag Coverage Δ
unittests 78.06% <57.14%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@@ -717,8 +717,8 @@ static int sc_udev_open_cgroup_v1(const char *security_tag, int flags, sc_cgroup
if (fchownat(devices_fd, security_tag_relpath, 0, 0, AT_SYMLINK_NOFOLLOW) < 0) {
die("cannot set root ownership on %s/%s/%s", cgroup_path, devices_relpath, security_tag_relpath);
}
if (fchmodat(devices_fd, security_tag_relpath, 0755, 0) < 0) {
die("cannot set 0755 permissions on %s/%s/%s", cgroup_path, devices_relpath, security_tag_relpath);
if (fchmodat(devices_fd, security_tag_relpath, 0700, 0) < 0) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to be checked

die("cannot create cgroup hierarchy %s/%s", parent, name);
}
(void)sc_set_effective_identity(old);
if (errno == 0) {
if (fchownat(parent_fd, name, 0, 0, 0) < 0 || fchmodat(parent_fd, name, 0700, 0) < 0) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

permissions to be checked

@@ -268,3 +277,31 @@ static bool _sc_is_in_container(const char *p) {
}

bool sc_is_in_container(void) { return _sc_is_in_container(run_systemd_container); }

int sc_ensure_mkdirat(int fd, const char *name, mode_t mode, uid_t uid, uid_t gid) {
if (mkdirat(fd, name, mode) < 0) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use 0o000 mode and chmod later on

Comment on lines +856 to +859
/* TODO:nonsetuid: workaround PR_SET_KEEPCAPS */
sc_identity old = sc_set_effective_identity(sc_root_group_identity());
sc_cgroup_freezer_join(inv->snap_instance, getpid());
(void)sc_set_effective_identity(old);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use caps

Since snap-confine is eventually going to be run under an ordinary user,
make sure that the snaps' cgroup directories are created as the root
user and group. Also, since we do not have direct control over the
ownership of the leaf files defining the cgroup (they are automatically
created using the effective user of the process that creates the
cgroup), remove the execute permission from the parent directory, so
that only the root user will be able to alter the snap's cgroup
configuration.
Create a wrapper that works well with 64 bit capabilities.
Read the process state (for the time being, that's just the current
working directory) as the real user who started the application, because
if we do this operation while we are setuid root, it would fail on some
filesystems (like SSHFS and NFS) which restrict access to the root user.
mardy and others added 23 commits February 26, 2025 08:37
Move the AppArmor check up, right after checking that the effective user
is root. Remove the check on the effective user being 0, since we assert
it right above.
Avoid calling getuid() and use the freshly obtained `real_uid` instead.
When needed, add code to explicitly adjust the group ownership.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
…eezer, otherwise this will fail under lxd

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>

snapcraft: require libcap tools

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
Add test which verifies snap-confine file capabilities.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
Use fakeroot when extracting snapd snap, so that unsquashfs does not
complai about xattrs.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
When buildin on older systems like Ubuntu 18.04, the libcap library
version available there does not have
cap_set_ambient()/cap_reset_ambient(). Provide alternative
implementations based on the upstream sources.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
…ndling at runtime

Introduce smarter capability handling at runtime. We expect the
snap-confine to have file capabilities defining only the permitted set.
The effective capabilities are changed at runtime as needed.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
…ng to snap-update-ns

There's no longer a need to switch identity when forking into
snap-update-ns. Privileges are transferred as ambient capabilities.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
Do not switch uid/gid during bootstrap, as s-u-n will be invoked as a
target user. Verify that when running, CAP_SYS_ADMIN is effective.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
Use CAP_MODE_NOPRIV which is more strict than what was set earlier.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
Assert process capabilities, to ensure correctness when invoked from
snap-confine.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
…ap-discard-ns

Do not change identity when invokign snap-discard-ns, rely on
capabilities.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
@bboozzoo bboozzoo force-pushed the bboozzoo/snap-confine-caps-v4-wip branch from f7f0f4d to 0159d2c Compare February 26, 2025 07:40
We're trying to identify a failure in spread tests which is manifested
by the following output:

    + tr '\r' '\n'
    + socat 'system:snap install test-snapd-tools-core24,pty,raw,echo=0' -
    2025/02/25 20:01:47 socat[182348] W exiting on signal 15
    + socat 'system:snap remove test-snapd-tools-core24,pty,raw,echo=0' -
    + tr '\r' '\n'

However, it is unclear which socat process receives SIGTERM and why.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
…store

Despite groups not being assigned to any snaps, there are quota groups
related files created by system under /sys/fs/cgroup/. Make sure to
remove all groups and check that no files are left behind.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
The test is not looking for writable files, but rather directories which
have g+x or o+x.

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants