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

core: do not enforce PrivateTmp with DynamicUser if /tmp and /var/tmp are already private tmpfs #32724

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

bluca
Copy link
Member

@bluca bluca commented May 8, 2024

DynamicUser= enables PrivateTmp= implicitly to avoid files owned by reusable uids
leaking into the host. Configuring TemporaryFileSystem=/tmp/ /var/ also ensures
this, so allow it as an alternative, since it has less impactful semantics with
respect to PrivateTmp=yes, which links the mount namespace to the host's /tmp/
instead.

@github-actions github-actions bot added documentation tests portable Anything to do with systemd-portable and portablectl and portables please-review PR is ready for (re-)review by a maintainer labels May 8, 2024
Copy link

github-actions bot commented May 8, 2024

Important

An -rc1 tag has been created and a release is being prepared, so please note that PRs introducing new features and APIs will be held back until the new version has been released.

src/core/unit.c Outdated Show resolved Hide resolved
src/core/unit.c Outdated Show resolved Hide resolved
@bluca bluca force-pushed the dynamic_user_no_private_tmp branch from 8e1acb1 to 35570fa Compare May 8, 2024 19:34
@bluca bluca force-pushed the dynamic_user_no_private_tmp branch from 35570fa to cf0dd4e Compare May 8, 2024 22:34
@bluca bluca changed the title core: do not enforce PrivateTmp with DynamicUser if /tmp and /var/tmp are tmpfs core: do not enforce PrivateTmp with DynamicUser if /tmp and /var/tmp are already private tmpfs May 9, 2024
@bluca bluca added this to the v256 milestone May 9, 2024
@YHNdnzj YHNdnzj requested a review from poettering May 9, 2024 16:38
Copy link
Member

@yuwata yuwata left a comment

Choose a reason for hiding this comment

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

Should we also check InaccessiblePaths=, BindReadOnlyPaths= ??

src/core/unit.c Outdated Show resolved Hide resolved
@bluca bluca removed the tests label May 10, 2024
src/core/unit.c Outdated Show resolved Hide resolved
src/core/unit.c Outdated

if (!tmp_found || !var_tmp_found)
ec->private_tmp = true;

Copy link
Member

Choose a reason for hiding this comment

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

that said, maybe a simple fix is to not imply PrivateTmp= in case of DynamicUser=1 but instead imply TemporaryFileSystem=/tmp /var/tmp?

wouldn't that be better and simpler?

i mean, there definitely is value in keeping dynamic uids/gids local to file systems that are destroyed when the service is dead, hence changing the logic liek that would make sense to me.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok I've applied this change, it's slightly backward incompatible unlike the original version but if that's what it takes

@poettering poettering added reviewed/needs-rework 🔨 PR has been reviewed and needs another round of reworks and removed please-review PR is ready for (re-)review by a maintainer labels May 10, 2024
@poettering
Copy link
Member

or well, i generally think that things such as PrivateTmp=1 as high-level knobs are the way to go, and they should abstract what happens in the bg a bit.

so i think we should just make sure it has a different effect in case DynamicUser=1 is used, i.e. make it act like TemporaryFs=/tmp + Bind=/var/tmp:/tmp

@bluca bluca force-pushed the dynamic_user_no_private_tmp branch from 07f51a2 to 772b5b8 Compare May 10, 2024 20:51
@github-actions github-actions bot added documentation tests please-review PR is ready for (re-)review by a maintainer and removed reviewed/needs-rework 🔨 PR has been reviewed and needs another round of reworks labels May 10, 2024
@bluca
Copy link
Member Author

bluca commented May 10, 2024

or well, i generally think that things such as PrivateTmp=1 as high-level knobs are the way to go, and they should abstract what happens in the bg a bit.

so i think we should just make sure it has a different effect in case DynamicUser=1 is used, i.e. make it act like TemporaryFs=/tmp + Bind=/var/tmp:/tmp

This is logically equivalent to your comment above - we do want to enforce that private tmpfses are used with DynamicUser=yes, so the PrivateTmp knob becomes essentially meaningless in that case - whether it's enabled or disabled, same result applies

I am not making /tmp an alias of /var/tmp as that changes too much the existing setup, where they are different directories, we can't just change that from one version to another as it is most likely going to break things, DynamicUser is used by hundreds of units in Debian alone, plus it's the default for portables

@bluca bluca force-pushed the dynamic_user_no_private_tmp branch from 772b5b8 to 7cc35c8 Compare May 10, 2024 23:50
@bluca bluca modified the milestones: v256, v257 May 13, 2024
bluca added 2 commits May 22, 2024 23:14
… are tmpfs

DynamicUser= enables PrivateTmp= implicitly to avoid files owned by reusable uids
leaking into the host. Configuring TemporaryFileSystem=/tmp/ /var/ also ensures
this, so allow it as an alternative, since it has less impactful semantics with
respect to PrivateTmp=yes, which links the mount namespace to the host's /tmp
instead.
It is already implied by DynamicUser=yes if not set, but dropping it
allows users to instead define TemporaryFileSystem=/tmp/ /var/tmp/
in their portable services, which has fewer side effects.
@bluca bluca force-pushed the dynamic_user_no_private_tmp branch from 7cc35c8 to bf4784a Compare May 22, 2024 22:14
@poettering
Copy link
Member

I am not making /tmp an alias of /var/tmp as that changes too much the existing setup, where they are different directories, we can't just change that from one version to another as it is most likely going to break things, DynamicUser is used by hundreds of units in Debian alone, plus it's the default for portables

We explicitly support that /tmp and /var/tmp is the same thing, and it's what I keep telling people: if they really want a persistent /tmp, then they should bind mount them, and not make them separate.

Apps must be able to deal with the fact that /tmp + /var/tmp are a shared namespace, they must be ready to deal with concurrent access and other tools creating files there. Hence they should not be surprised at all if a conflicting inode appears any time.

Hence, please, let's share the superblock there. and make one a bind mount of the other.

@@ -4279,7 +4279,6 @@ int unit_patch_contexts(Unit *u) {
* UID/GID around in the file system or on IPC objects. Hence enforce a strict
* sandbox. */

ec->private_tmp = true;
Copy link
Member

Choose a reason for hiding this comment

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

i'd still imply this, it's prettier that way, because it tells external tools that we do not share the regular /tmp/ on these services

Copy link
Member Author

Choose a reason for hiding this comment

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

I removed it to avoid triggering all the machinery that sets up the directories in the host filesystem, passes the pipes, adds the tracking, etc since it's not needed

Copy link
Member Author

Choose a reason for hiding this comment

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

And actually given the exact semantics on PrivateTmp, where the storage is actually on the host and it is visible to root there, and it can be shared, I think we should not toggle this, because it would not correspond to what actually happens, and suddenly it could mean either the new thing or the old thing.

@poettering poettering added reviewed/needs-rework 🔨 PR has been reviewed and needs another round of reworks and removed please-review PR is ready for (re-)review by a maintainer labels May 23, 2024
@bluca
Copy link
Member Author

bluca commented May 23, 2024

I am not making /tmp an alias of /var/tmp as that changes too much the existing setup, where they are different directories, we can't just change that from one version to another as it is most likely going to break things, DynamicUser is used by hundreds of units in Debian alone, plus it's the default for portables

We explicitly support that /tmp and /var/tmp is the same thing, and it's what I keep telling people: if they really want a persistent /tmp, then they should bind mount them, and not make them separate.

Apps must be able to deal with the fact that /tmp + /var/tmp are a shared namespace, they must be ready to deal with concurrent access and other tools creating files there. Hence they should not be surprised at all if a conflicting inode appears any time.

Hence, please, let's share the superblock there. and make one a bind mount of the other.

Where is that documented?

@bluca
Copy link
Member Author

bluca commented May 23, 2024

I am not making /tmp an alias of /var/tmp as that changes too much the existing setup, where they are different directories, we can't just change that from one version to another as it is most likely going to break things, DynamicUser is used by hundreds of units in Debian alone, plus it's the default for portables

We explicitly support that /tmp and /var/tmp is the same thing, and it's what I keep telling people: if they really want a persistent /tmp, then they should bind mount them, and not make them separate.
Apps must be able to deal with the fact that /tmp + /var/tmp are a shared namespace, they must be ready to deal with concurrent access and other tools creating files there. Hence they should not be surprised at all if a conflicting inode appears any time.
Hence, please, let's share the superblock there. and make one a bind mount of the other.

Where is that documented?

I checked the following:

docs/TEMPORARY_DIRECTORIES.md (most comprehensive writeup we have for tmp and var/tmp)
man/file-hierarchy.7 (next one, lots of details of all base directories)
systemd.exec (for PrivateTmp)

All of these mention that /tmp and /var/tmp are different, and have different semantics (persistent vs volatile, large file vs small files, etc), and nowhere it says they can be the same.

@bluca bluca added please-review PR is ready for (re-)review by a maintainer and removed reviewed/needs-rework 🔨 PR has been reviewed and needs another round of reworks labels May 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation pid1 please-review PR is ready for (re-)review by a maintainer portable Anything to do with systemd-portable and portablectl and portables tests
Development

Successfully merging this pull request may close these issues.

None yet

4 participants