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

config.md: allow empty mappings for [r]idmap #1224

Merged

Conversation

giuseppe
Copy link
Member

@giuseppe giuseppe commented Sep 5, 2023

crun currently allows to specify an empty mapping for [r]idmap, and to default to the mappings specified for the container user namespace.

Change the specifications to allow such behavior.

@AkihiroSuda AkihiroSuda added this to the v1.1.1 milestone Sep 5, 2023
config.md Show resolved Hide resolved
@giuseppe giuseppe force-pushed the allow-empty-mapping-for-idmap branch 2 times, most recently from 977d7ba to ba0a750 Compare September 6, 2023 08:02
Copy link
Member

@rata rata left a comment

Choose a reason for hiding this comment

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

LGTM, left some minor comments :)

config.md Outdated Show resolved Hide resolved
config.md Outdated
`idmap` | SHOULD | Indicates that the mount has `uidMappings` and `gidMappings` specified. This option SHOULD NOT be passed to the underlying [`mount(2)`][mount.2] call. If supported, the runtime MUST return an error if this option is provided and either of `uidMappings` or `gidMappings` are empty or not present.
`ridmap` | SHOULD | Indicates that the mount has `uidMappings` and `gidMappings` specified, and the mapping is applied recursively [^3]. This option SHOULD NOT be passed to the underlying [`mount(2)`][mount.2] call. If supported, the runtime MUST return an error if this option is provided and either of `uidMappings` or `gidMappings` are empty or not present.
`idmap` | SHOULD | Indicates that the mount must have an idmapping applied. This option SHOULD NOT be passed to the underlying [`mount(2)`][mount.2] call. If `uidMappings` or `gidMappings` are not specified, the runtime MAY use the container's user namespace mapping. If there are no `uidMappings` and `gidMappings` specified and the container isn't using user namespaces, an error MUST be returned. This SHOULD be implemented using [`mount_setattr(MOUNT_ATTR_IDMAP)`][mount_setattr.2], available since Linux 5.12.
`ridmap` | SHOULD | Indicates that the mount must have an idmapping applied, and the mapping is applied recursively [^3]. This option SHOULD NOT be passed to the underlying [`mount(2)`][mount.2] call. If `uidMappings` or `gidMappings` are not specified, the runtime MAY use the container's user namespace mapping. If there are no `uidMappings` and `gidMappings` specified and the container isn't using user namespaces, an error MUST be returned. This SHOULD be implemented using [`mount_setattr(MOUNT_ATTR_IDMAP)`][mount_setattr.2], available since Linux 5.12.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
`ridmap` | SHOULD | Indicates that the mount must have an idmapping applied, and the mapping is applied recursively [^3]. This option SHOULD NOT be passed to the underlying [`mount(2)`][mount.2] call. If `uidMappings` or `gidMappings` are not specified, the runtime MAY use the container's user namespace mapping. If there are no `uidMappings` and `gidMappings` specified and the container isn't using user namespaces, an error MUST be returned. This SHOULD be implemented using [`mount_setattr(MOUNT_ATTR_IDMAP)`][mount_setattr.2], available since Linux 5.12.
`ridmap` | SHOULD | Indicates that the mount MUST have an idmapping applied, and the mapping is applied recursively [^3]. This option SHOULD NOT be passed to the underlying [`mount(2)`][mount.2] call. If `uidMappings` or `gidMappings` are not specified, the runtime MAY use the container's user namespace mapping. If there are no `uidMappings` and `gidMappings` specified and the container isn't using user namespaces, [error MUST be returned](runtime.md#errors). This SHOULD be implemented using [`mount_setattr(MOUNT_ATTR_IDMAP)`][mount_setattr.2], available since Linux 5.12.

@giuseppe giuseppe force-pushed the allow-empty-mapping-for-idmap branch from ba0a750 to 656e466 Compare September 6, 2023 13:00
Copy link
Member

@rata rata left a comment

Choose a reason for hiding this comment

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

I think the current version can make the high-level container runtime's lifes more difficult for no good reason. IMHO it is simpler if these options MUST be specified with mappings in the mount.

config.md Outdated
@@ -146,8 +146,8 @@ Runtimes MUST/SHOULD/MAY implement the following option strings for Linux:
`sync` | MUST | [^1]
`tmpcopyup` | MAY | copy up the contents to a tmpfs
`unbindable` | MUST | [^2] (bind mounts)
`idmap` | SHOULD | Indicates that the mount has `uidMappings` and `gidMappings` specified. This option SHOULD NOT be passed to the underlying [`mount(2)`][mount.2] call. If supported, the runtime MUST return an error if this option is provided and either of `uidMappings` or `gidMappings` are empty or not present.
`ridmap` | SHOULD | Indicates that the mount has `uidMappings` and `gidMappings` specified, and the mapping is applied recursively [^3]. This option SHOULD NOT be passed to the underlying [`mount(2)`][mount.2] call. If supported, the runtime MUST return an error if this option is provided and either of `uidMappings` or `gidMappings` are empty or not present.
`idmap` | SHOULD | Indicates that the mount MUST have an idmapping applied. This option SHOULD NOT be passed to the underlying [`mount(2)`][mount.2] call. If `uidMappings` or `gidMappings` are not specified, the runtime MAY use the container's user namespace mapping. If there are no `uidMappings` and `gidMappings` specified and the container isn't using user namespaces, an [error MUST be returned](runtime.md#errors). This SHOULD be implemented using [`mount_setattr(MOUNT_ATTR_IDMAP)`][mount_setattr.2], available since Linux 5.12.
Copy link
Member

Choose a reason for hiding this comment

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

Using my high-level container development hat, what is the point of this flag?

We can't use idmap mounts safely without checking two things: (a) if we will request idmap mounts to the low-level container runtime, (b) if the low level container runtime supports idmap mounts.

Having to do both things now is not ideal, but that is the reality today. But these flags adds more ways in which idmap mounts can be enabled, that is: userns are enabled and some mount has one of these flags. Checking for more ways is just more painful. And is convenient to check for the use at the config.json level, as that is where we have the runtime features subcommand exposed.

Furthermore, the fact that it MAY be enabled or not if no mappings are used, it is just not something we can use safely: if we expect the runtime to use idmap mounts, we pass this flag and it is not honored, then the volumes will have garbage as UID/GID. So we will always either use it with mappings or not use the flag, the MAY behavior doesn't help high-level container runtimes, given the particularities of this feature.

I think this flag can just be removed. We can also keep it, although it doesn't add any new info: we can say it can be used to signal that idmap mounts MUST be used and mappings MUST be specified, but if the mappings are specified is enough for the runtime to MUST do an idmap mount or generate an error anyways, so I see no point on having this flag.

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 think the reason is that runtimes that do not support idmap will pass down this option to the mount, thus the mount will fail. So this is a valid alternative to check for its support through features. If the runtime doesn't support idmapped mounts, the container creation will fail

Copy link
Member

Choose a reason for hiding this comment

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

Hmm, more or less, for runc, for bind-mounts it is ignored: #1222 (comment).

And there you said it was ignored in crun too: #1222 (comment)

I'm okay with keeping this one if you want, but I'd change it so the mappings in the mount are a MUST. This way, high-level container runtimes don't have to check lot of different ways that might enable this functionality before using it.

Copy link
Member

@cyphar cyphar Sep 9, 2023

Choose a reason for hiding this comment

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

The mount won't fail for bind-mounts unless you have special handling for it, though I have sent a runc PR for us to block it in the case of bind-mounts. I had hoped this would allow us to avoid the need for features to figure out if it would be silently ignored, but we needed both.

I don't have a preference for whether we should have default behaviour if there are no mappings specified. Crun already does this and the behaviour seems reasonable so I suggested we include it. As for why we need the flag at all -- we need ridmap and it seems strange to not have idmap (and, once we have the check I mentioned above this would be a way to ensure within config.json that the idmapping arguments are being checked).

Copy link
Member

Choose a reason for hiding this comment

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

Furthermore, the fact that it MAY be enabled or not if no mappings are used, it is just not something we can use safely: if we expect the runtime to use idmap mounts, we pass this flag and it is not honored, then the volumes will have garbage as UID/GID.

I missed this on the first reading -- it seems to me that you are misreading the old (and new) text. It says if uidMappings and gidMappings are unspecified, you MAY use the container's mappings. If they are specified, obviously that line doesn't apply and you MUST use the specified mappings (the MUST line for this is in the definition of uidMappings and gidMappings, not here). If you want it to be more explicit we could do something like:

Suggested change
`idmap` | SHOULD | Indicates that the mount MUST have an idmapping applied. This option SHOULD NOT be passed to the underlying [`mount(2)`][mount.2] call. If `uidMappings` or `gidMappings` are not specified, the runtime MAY use the container's user namespace mapping. If there are no `uidMappings` and `gidMappings` specified and the container isn't using user namespaces, an [error MUST be returned](runtime.md#errors). This SHOULD be implemented using [`mount_setattr(MOUNT_ATTR_IDMAP)`][mount_setattr.2], available since Linux 5.12.
`idmap` | SHOULD | Indicates that the mount MUST have an idmapping applied. This option SHOULD NOT be passed to the underlying [`mount(2)`][mount.2] call. If `uidMappings` or `gidMappings` are specified for the mount, the runtime MUST use those values for the mount's mapping. If they are not specified, the runtime MAY use the container's user namespace mapping, otherwise an [error MUST be returned](runtime.md#errors). If there are no `uidMappings` and `gidMappings` specified and the container isn't using user namespaces, an [error MUST be returned](runtime.md#errors). This SHOULD be implemented using [`mount_setattr(MOUNT_ATTR_IDMAP)`][mount_setattr.2], available since Linux 5.12.

But it seems somewhat redundant 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.

thanks, I've amended these changes and pushed a new version

Copy link
Member

@rata rata Oct 24, 2023

Choose a reason for hiding this comment

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

@cyphar I'm not missing that, I'm saying exactly that is problematic.

these flags adds more ways in which idmap mounts can be enabled, that is: userns are enabled and some mount has one of these flags. Checking for more ways is just more painful.

High-level runtimes sometimes need to check the config.json to see if idmap mounts are used (as to carry the info of the features subcommand higher in the call-stack is sometimes inconvenient). This adds one more way that they could be used and therefore one more way the high-level runtimes need to check to see if idmap mounts will be used.

Exactly that is not convenient. We have to check for the uidMapping/gidMapping of all mounts to see if it is used. With this PR, we will have to check that and see if maybe some other flag was used, because that can mean they are used too.

IMHO, it is just not helping for most use cases.

Copy link
Member

Choose a reason for hiding this comment

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

The practical issue here is that crun already has this feature, and we've introduced the flag into the spec with slightly different semantics. In practice, this isn't the end of the world because there isn't a MUST requirement that uidMapping and gidMapping need to be specified (in fact, this PR actually improves the language to describe how these flags work -- my original wording was a bit rushed). It seems unlikely that crun will be able to remove the feature without impacting users, meaning that you will need to check for idmap anyway (unless you plan to only support runc as the OCI runtime). The difference is that now all OCI runtimes will have uniform behaviour.

FWIW, it would've been nice if crun had used something like crun-... as a prefix to its extensions to avoid this issue, but runc has tmpcopyup so this isn't a crun-only issue and so it's understandable that we ended up in this situation.


In retrospect, I think we should have added ridmap and idmap from the outset and required their use for id-mapped mounts. This would've resolved the issues that resulted in the need for the extra features bits. Right now all we can do is SHOULD their use (which we already do).

Ideally you would only have to check for one thing (presence of idmap or ridmap) but unfortunately you also need to check for uidMappings and gidMappings because they aren't required. However, as I mentioned above, if you support using crun then you will need to check for idmap as well anyway.

config.md Outdated
`idmap` | SHOULD | Indicates that the mount has `uidMappings` and `gidMappings` specified. This option SHOULD NOT be passed to the underlying [`mount(2)`][mount.2] call. If supported, the runtime MUST return an error if this option is provided and either of `uidMappings` or `gidMappings` are empty or not present.
`ridmap` | SHOULD | Indicates that the mount has `uidMappings` and `gidMappings` specified, and the mapping is applied recursively [^3]. This option SHOULD NOT be passed to the underlying [`mount(2)`][mount.2] call. If supported, the runtime MUST return an error if this option is provided and either of `uidMappings` or `gidMappings` are empty or not present.
`idmap` | SHOULD | Indicates that the mount MUST have an idmapping applied. This option SHOULD NOT be passed to the underlying [`mount(2)`][mount.2] call. If `uidMappings` or `gidMappings` are not specified, the runtime MAY use the container's user namespace mapping. If there are no `uidMappings` and `gidMappings` specified and the container isn't using user namespaces, an [error MUST be returned](runtime.md#errors). This SHOULD be implemented using [`mount_setattr(MOUNT_ATTR_IDMAP)`][mount_setattr.2], available since Linux 5.12.
`ridmap` | SHOULD | Indicates that the mount MUST have an idmapping applied, and the mapping is applied recursively [^3]. This option SHOULD NOT be passed to the underlying [`mount(2)`][mount.2] call. If `uidMappings` or `gidMappings` are not specified, the runtime MAY use the container's user namespace mapping. If there are no `uidMappings` and `gidMappings` specified and the container isn't using user namespaces, an [error MUST be returned](runtime.md#errors). This SHOULD be implemented using [`mount_setattr(MOUNT_ATTR_IDMAP)`][mount_setattr.2], available since Linux 5.12.
Copy link
Member

Choose a reason for hiding this comment

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

Idem, I think this flag MUST only be used with mappings (otherwise generate an error) and, of course, signal that the idmap mounts MUST be recursive.

Copy link
Member

Choose a reason for hiding this comment

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

The text "Indicates that the mount MUST have an idmapping applied, and the mapping is applied recursively" IMHO is sufficient to say that the mapping MUST be recursive. As for the first point, the discussion in the other thread applies -- this allows for easier configuration and matches crun's behaviour for idmap.

Copy link
Member

@rata rata left a comment

Choose a reason for hiding this comment

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

IMHO, changing this as I've just suggested is better. Let me know what others think

@giuseppe
Copy link
Member Author

giuseppe commented Sep 8, 2023

@cyphar @AkihiroSuda could you please take a look?

@cyphar
Copy link
Member

cyphar commented Sep 9, 2023

I will take a proper look when I get home tomorrow evening

@giuseppe
Copy link
Member Author

@cyphar any chance you can take a look? :-)

@AkihiroSuda
Copy link
Member

Needs rebase

@AkihiroSuda
Copy link
Member

@cyphar PTAL, and let's release v1.1.1 soon

@giuseppe
Copy link
Member Author

rebased

@giuseppe
Copy link
Member Author

@cyphar PTAL

Copy link
Member

@cyphar cyphar left a comment

Choose a reason for hiding this comment

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

LGTM. I've left a suggestion for more explicit wording that might make @rata happier, but I don't think it's necessary (a reading of this section along with the section defining uidMappings and gidMappings leads to the clear understanding that specifying uidMappings and gidMappings takes precedence over this extra idmap and ridmap behaviour).

crun currently allows to specify an empty mapping for [r]idmap, and to
default to the mappings specified for the container user namespace.

Change the specifications to allow such behavior.

Signed-off-by: Giuseppe Scrivano <[email protected]>
@AkihiroSuda
Copy link
Member

@cyphar May I assume your LGTM is still valid?

Copy link
Member

@cyphar cyphar left a comment

Choose a reason for hiding this comment

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

Still LGTM.

@AkihiroSuda AkihiroSuda merged commit 9923541 into opencontainers:main Nov 16, 2023
3 checks passed
rata added a commit to kinvolk/containerd that referenced this pull request Dec 4, 2023
The runtime-spec just merged this PR:
	opencontainers/runtime-spec#1224

This means that it is now possible to request idmap mounts by specifying
"idmap" or "ridmap" in the mount options, without any mappings.

Let's add a check to see if they are requested in that way too.

Signed-off-by: Rodrigo Campos <[email protected]>
rata added a commit to kinvolk/containerd that referenced this pull request Dec 4, 2023
The runtime-spec just merged this PR:
	opencontainers/runtime-spec#1224

This means that it is now possible to request idmap mounts by specifying
"idmap" or "ridmap" in the mount options, without any mappings.

Let's add a check to see if they are requested in that way too.

Signed-off-by: Rodrigo Campos <[email protected]>
smallfoot47 pushed a commit to smallfoot47/containerd that referenced this pull request Dec 11, 2023
The runtime-spec just merged this PR:
	opencontainers/runtime-spec#1224

This means that it is now possible to request idmap mounts by specifying
"idmap" or "ridmap" in the mount options, without any mappings.

Let's add a check to see if they are requested in that way too.

Signed-off-by: Rodrigo Campos <[email protected]>
Signed-off-by: Vivek Radhakrishnan <[email protected]>
@utam0k utam0k mentioned this pull request Jan 5, 2024
12 tasks
juliusl pushed a commit to juliusl/containerd that referenced this pull request Jan 26, 2024
The runtime-spec just merged this PR:
	opencontainers/runtime-spec#1224

This means that it is now possible to request idmap mounts by specifying
"idmap" or "ridmap" in the mount options, without any mappings.

Let's add a check to see if they are requested in that way too.

Signed-off-by: Rodrigo Campos <[email protected]>
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 this pull request may close these issues.

4 participants