-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Allow suid, exec, dev mount options to cancel nosuid/noexec/nodev #3876
Allow suid, exec, dev mount options to cancel nosuid/noexec/nodev #3876
Conversation
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: mheon The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
I'll add a few tests after lunch. |
@@ -13,7 +13,7 @@ require ( | |||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc // indirect | |||
github.com/containernetworking/cni v0.7.1 | |||
github.com/containernetworking/plugins v0.8.1 | |||
github.com/containers/buildah v1.10.1 | |||
github.com/containers/buildah v1.8.4-0.20190821140209-376e52ee0142 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vrothberg So I grabbed the top of buildah/master, and it appears to have downgraded, version-wise. We might want to look into that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The important part is behind the last dash (i.e., the commit 376e52ee0142
). It's a bug in go (no joke) which is trying to match a commit to a tag.
Commit 376e52ee0142 looks good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we want to get rid of that, we can do podman run --privileged -v
pwd:/src:Z -it --rm golang:1.13-rc-buster
and go get github.com/containers/buildah@376e52ee0142
inside the container. Go 1.13 will set the correct version/tag.
The annoying thing about that bug is that go mod's min-version algorithm can break here and downgrade a whole bunch of other dependencies.
5150078
to
e5f0781
Compare
pkg/spec/storage.go
Outdated
if _, ok := baseMounts[dest]; ok { | ||
continue | ||
} | ||
localOpts := options | ||
if dest == "/run" { | ||
localOpts = append(localOpts, "noexec", "size=65536k") | ||
localOpts = append(localOpts, "dev", "suid", "noexec", "size=65536k") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you doing this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to make sure that the parser doesn't see the mount is missing nodev
/nosuid
and add those
} | ||
if m.Type == TypeTmpfs && filepath.Clean(m.Destination) != "/dev" { | ||
m.Options = append(m.Options, "tmpcopyup") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you still have tmpcopyup by default for tmpfs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still defaulted
You need to make sure that the mounts look the same with old podman as with this. matches Then add a few other mounts using -v, --tmpfs and --mount and make sure everything is the same. |
Test failures seem to be a mixed bag. It looks like my bind-mount options parsing code simplification over-simplified and broke things, but some of the rest seem like underlying bugs that are now being detected and reported. |
Re-added functionality to infer mount options from those used on the base system. |
I think tests will go green now. Still need to add a few more to cover new functionality. |
Added tests. Good to go once this goes green. |
822a80e
to
8d56081
Compare
One flake, otherwise green |
I did a bigger chunk of review this morning. Maybe I'll find time this afternoon, latest tomorrow morning (EU). |
☔ The latest upstream changes (presumably #3728) made this pull request unmergeable. Please resolve the merge conflicts. |
Vendor some changes to parsing code that we need for Podman. Signed-off-by: Matthew Heon <[email protected]>
Previously, we explicitly set noexec/nosuid/nodev on every mount, with no ability to disable them. The 'mount' command on Linux will accept their inverses without complaint, though - 'noexec' is counteracted by 'exec', 'nosuid' by 'suid', etc. Add support for passing these options at the command line to disable our explicit forcing of security options. This also cleans up mount option handling significantly. We are still parsing options in more than one place, which isn't good, but option parsing for bind and tmpfs mounts has been unified. Fixes: containers#3819 Fixes: containers#3803 Signed-off-by: Matthew Heon <[email protected]>
We already process the options on all tmpfs filesystems during final addition of mounts to the spec. We don't need to do it before that in parseVolumes. Signed-off-by: Matthew Heon <[email protected]>
If I mount, say, /usr/bin into my container - I expect to be able to run the executables in that mount. Unconditionally applying noexec would be a bad idea. Before my patches to change mount options and allow exec/dev/suid being set explicitly, we inferred the mount options from where on the base system the mount originated, and the options it had there. Implement the same functionality for the new option handling. There's a lot of performance left on the table here, but I don't know that this is ever going to take enough time to make it worth optimizing. Signed-off-by: Matthew Heon <[email protected]>
Signed-off-by: Matthew Heon <[email protected]>
For read-only containers set to create tmpfs filesystems over /run and other common destinations, we were incorrectly setting mount options, resulting in duplicate mount options. Signed-off-by: Matthew Heon <[email protected]>
Signed-off-by: Matthew Heon <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just nits. Nice work, @mheon!
Expect(matches[0]).To(Not(ContainSubstring("noexec"))) | ||
Expect(matches[0]).To(Not(ContainSubstring("nodev"))) | ||
Expect(matches[0]).To(Not(ContainSubstring("nosuid"))) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add an additional block box test?
A trivial one could be an executable test.sh
:
#!/bin/sh
echo "Hello World!"
And then mount & execute it once with exec
and grep for Hello World!
and then mount & execute it with noexec
and grep for Permission denied
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done - I just mounted in /bin
from the host, but it should be a sufficient test.
@@ -13,7 +13,7 @@ require ( | |||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc // indirect | |||
github.com/containernetworking/cni v0.7.1 | |||
github.com/containernetworking/plugins v0.8.1 | |||
github.com/containers/buildah v1.10.1 | |||
github.com/containers/buildah v1.8.4-0.20190821140209-376e52ee0142 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we want to get rid of that, we can do podman run --privileged -v
pwd:/src:Z -it --rm golang:1.13-rc-buster
and go get github.com/containers/buildah@376e52ee0142
inside the container. Go 1.13 will set the correct version/tag.
The annoying thing about that bug is that go mod's min-version algorithm can break here and downgrade a whole bunch of other dependencies.
// (Is this necessary?) | ||
case "nosuid", "suid": | ||
if setSuid { | ||
return newMount, errors.Wrapf(optionArgError, "cannot pass 'nosuid' and 'suid' options more than once") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clever trick to group them 👍
return nil, errors.Wrapf(err, "error retrieving system mounts to look up mount options") | ||
} | ||
|
||
// TODO: We probably don't need to re-build the mounts array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I think so too. Operating on inputMounts[i]
should work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll leave it off for now, this is large enough already
LGTM, nothing beyond @vrothbergs comments. |
Signed-off-by: Matthew Heon <[email protected]>
Should be ready for merge. |
/lgtm |
Previously, we explicitly set noexec/nosuid/nodev on every mount, with no ability to disable them. The 'mount' command on Linux will accept their inverses without complaint, though - 'noexec' is counteracted by 'exec', 'nosuid' by 'suid', etc. Add support for passing these options at the command line to disable our explicit forcing of security options.
This also cleans up mount option handling significantly. We are still parsing options in more than one place, which isn't good, but option parsing for bind and tmpfs mounts has been unified.
Fixes: #3819
Fixes: #3803