Skip to content

Commit 7b414f5

Browse files
committed
daemon: move getUnprivilegedMountFlags to internal package
This code is currently only used in the daemon, but is also needed in other places. We should consider moving this code to github.com/moby/sys, so that BuildKit can also use the same implementation instead of maintaining a fork; moving it to internal allows us to reuse this code inside the repository, but does not allow external consumers to depend on it (which we don't want as it's not a permanent location). As our code only uses this in linux files, I did not add a stub for other platforms (but we may decide to do that in the moby/sys repository). Signed-off-by: Sebastiaan van Stijn <[email protected]>
1 parent ff05850 commit 7b414f5

2 files changed

Lines changed: 41 additions & 34 deletions

File tree

daemon/oci_linux.go

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"github.com/docker/docker/container"
2020
dconfig "github.com/docker/docker/daemon/config"
2121
"github.com/docker/docker/errdefs"
22+
"github.com/docker/docker/internal/rootless/mountopts"
2223
"github.com/docker/docker/oci"
2324
"github.com/docker/docker/oci/caps"
2425
"github.com/docker/docker/pkg/idtools"
@@ -30,7 +31,6 @@ import (
3031
"github.com/opencontainers/runc/libcontainer/cgroups"
3132
specs "github.com/opencontainers/runtime-spec/specs-go"
3233
"github.com/pkg/errors"
33-
"golang.org/x/sys/unix"
3434
)
3535

3636
const inContainerInitPath = "/sbin/" + dconfig.DefaultInitBinary
@@ -445,38 +445,6 @@ func ensureSharedOrSlave(path string) error {
445445
return nil
446446
}
447447

448-
// Get the set of mount flags that are set on the mount that contains the given
449-
// path and are locked by CL_UNPRIVILEGED. This is necessary to ensure that
450-
// bind-mounting "with options" will not fail with user namespaces, due to
451-
// kernel restrictions that require user namespace mounts to preserve
452-
// CL_UNPRIVILEGED locked flags.
453-
func getUnprivilegedMountFlags(path string) ([]string, error) {
454-
var statfs unix.Statfs_t
455-
if err := unix.Statfs(path, &statfs); err != nil {
456-
return nil, err
457-
}
458-
459-
// The set of keys come from https://github.com/torvalds/linux/blob/v4.13/fs/namespace.c#L1034-L1048.
460-
unprivilegedFlags := map[uint64]string{
461-
unix.MS_RDONLY: "ro",
462-
unix.MS_NODEV: "nodev",
463-
unix.MS_NOEXEC: "noexec",
464-
unix.MS_NOSUID: "nosuid",
465-
unix.MS_NOATIME: "noatime",
466-
unix.MS_RELATIME: "relatime",
467-
unix.MS_NODIRATIME: "nodiratime",
468-
}
469-
470-
var flags []string
471-
for mask, flag := range unprivilegedFlags {
472-
if uint64(statfs.Flags)&mask == mask {
473-
flags = append(flags, flag)
474-
}
475-
}
476-
477-
return flags, nil
478-
}
479-
480448
var (
481449
mountPropagationMap = map[string]int{
482450
"private": mount.PRIVATE,
@@ -661,7 +629,7 @@ func withMounts(daemon *Daemon, daemonCfg *configStore, c *container.Container,
661629
// when runc sets up the root filesystem, it is already inside a user
662630
// namespace, and thus cannot change any flags that are locked.
663631
if daemonCfg.RemappedRoot != "" || userns.RunningInUserNS() {
664-
unprivOpts, err := getUnprivilegedMountFlags(m.Source)
632+
unprivOpts, err := mountopts.UnprivilegedMountFlags(m.Source)
665633
if err != nil {
666634
return err
667635
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package mountopts
2+
3+
import (
4+
"golang.org/x/sys/unix"
5+
)
6+
7+
// UnprivilegedMountFlags gets the set of mount flags that are set on the mount that contains the given
8+
// path and are locked by CL_UNPRIVILEGED. This is necessary to ensure that
9+
// bind-mounting "with options" will not fail with user namespaces, due to
10+
// kernel restrictions that require user namespace mounts to preserve
11+
// CL_UNPRIVILEGED locked flags.
12+
//
13+
// TODO: Move to github.com/moby/sys/mount, and update BuildKit copy of this code as well (https://github.com/moby/buildkit/blob/v0.13.0/util/rootless/mountopts/mountopts_linux.go#L11-L18)
14+
func UnprivilegedMountFlags(path string) ([]string, error) {
15+
var statfs unix.Statfs_t
16+
if err := unix.Statfs(path, &statfs); err != nil {
17+
return nil, err
18+
}
19+
20+
// The set of keys come from https://github.com/torvalds/linux/blob/v4.13/fs/namespace.c#L1034-L1048.
21+
unprivilegedFlags := map[uint64]string{
22+
unix.MS_RDONLY: "ro",
23+
unix.MS_NODEV: "nodev",
24+
unix.MS_NOEXEC: "noexec",
25+
unix.MS_NOSUID: "nosuid",
26+
unix.MS_NOATIME: "noatime",
27+
unix.MS_RELATIME: "relatime",
28+
unix.MS_NODIRATIME: "nodiratime",
29+
}
30+
31+
var flags []string
32+
for mask, flag := range unprivilegedFlags {
33+
if uint64(statfs.Flags)&mask == mask {
34+
flags = append(flags, flag)
35+
}
36+
}
37+
38+
return flags, nil
39+
}

0 commit comments

Comments
 (0)