Skip to content

Commit

Permalink
Fix operation not permitted with systemd-homed
Browse files Browse the repository at this point in the history
Fix issue 2056

Note: in addition to this PR, the subid ranges in`/etc/subuid` and `/etc/subgid` have to begin from 524288
e.g.,
```
test:524288:65536
```

Otherwise running most images will fail with `value too large for defined data type`

```console
$ ./nerdctl run -it --rm alpine:3.17.0
docker.io/library/alpine:3.17.0:                                                  resolved       |++++++++++++++++++++++++++++++++++++++|
index-sha256:8914eb54f968791faf6a8638949e480fef81e697984fba772b3976835194c6d4:    done           |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:c0d488a800e4127c334ad20d61d7bc21b4097540327217dfab52262adc02380c: waiting        |--------------------------------------|
config-sha256:49176f190c7e9cdb51ac85ab6c6d5e4512352218190cd69b08e6fd803ffbf3da:   done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:c158987b05517b6f2c5913f3acef1f2182a32345a304fe357e3ace5fadcad715:    downloading    |+++++++++++++++++++++++---------------|  2.0 MiB/3.2 MiB
elapsed: 10.4s                                                                    total:  2.0 Mi (197.1 KiB/s)
FATA[0010] failed to extract layer sha256:ded7a220bb058e28ee3254fbba04ca90b679070424424761a53a043b93b612bf: mount callback failed on /var/lib/containerd/tmpmounts/containerd-mount762573051:
failed to Lchown "/var/lib/containerd/tmpmounts/containerd-mount762573051/etc/shadow" for UID 0, GID 42: lchown /var/lib/containerd/tmpmounts/containerd-mount762573051/etc/shadow: value too large for defined data type: unknown
```

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
  • Loading branch information
AkihiroSuda committed Mar 1, 2023
1 parent cc1b6e0 commit ad6ed08
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 5 deletions.
20 changes: 20 additions & 0 deletions cmd/nerdctl/container_run_mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/oci"
"github.com/containerd/containerd/pkg/userns"
"github.com/containerd/continuity/fs"
"github.com/containerd/nerdctl/pkg/api/types"
"github.com/containerd/nerdctl/pkg/idgen"
Expand Down Expand Up @@ -189,6 +190,25 @@ func generateMountOpts(ctx context.Context, cmd *cobra.Command, client *containe
return nil, nil, nil, err
}
}
} else if runtime.GOOS == "linux" {
defer unmounter(tempDir)
for _, m := range mounts {
m := m
if m.Type == "bind" && userns.RunningInUserNS() {
// For https://github.com/containerd/nerdctl/issues/2056
unpriv, err := mountutil.UnprivilegedMountFlags(m.Source)
if err != nil {
return nil, nil, nil, err
}
m.Options = strutil.DedupeStrSlice(append(m.Options, unpriv...))
}
if err := m.Mount(tempDir); err != nil {
if rmErr := s.Remove(ctx, tempDir); rmErr != nil && !errdefs.IsNotFound(rmErr) {
return nil, nil, nil, rmErr
}
return nil, nil, nil, fmt.Errorf("failed to mount %+v on %q: %w", m, tempDir, err)
}
}
} else {
defer unmounter(tempDir)
if err := mount.All(mounts, tempDir); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion pkg/mountutil/mountutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func ProcessFlagV(s string, volStore volumestore.VolumeStore) (*Processed, error
Options: options,
}
if userns.RunningInUserNS() {
unpriv, err := getUnprivilegedMountFlags(src)
unpriv, err := UnprivilegedMountFlags(src)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/mountutil/mountutil_freebsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
"github.com/sirupsen/logrus"
)

func getUnprivilegedMountFlags(path string) ([]string, error) {
func UnprivilegedMountFlags(path string) ([]string, error) {
m := []string{}
return m, nil
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/mountutil/mountutil_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ import (
NOTICE: https://github.com/moby/moby/blob/v20.10.5/NOTICE
*/

// getUnprivilegedMountFlags is from https://github.com/moby/moby/blob/v20.10.5/daemon/oci_linux.go#L420-L450
// UnprivilegedMountFlags is from https://github.com/moby/moby/blob/v20.10.5/daemon/oci_linux.go#L420-L450
//
// Get the set of mount flags that are set on the mount that contains the given
// path and are locked by CL_UNPRIVILEGED. This is necessary to ensure that
// bind-mounting "with options" will not fail with user namespaces, due to
// kernel restrictions that require user namespace mounts to preserve
// CL_UNPRIVILEGED locked flags.
func getUnprivilegedMountFlags(path string) ([]string, error) {
func UnprivilegedMountFlags(path string) ([]string, error) {
var statfs unix.Statfs_t
if err := unix.Statfs(path, &statfs); err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion pkg/mountutil/mountutil_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
"github.com/sirupsen/logrus"
)

func getUnprivilegedMountFlags(path string) ([]string, error) {
func UnprivilegedMountFlags(path string) ([]string, error) {
m := []string{}
return m, nil
}
Expand Down

0 comments on commit ad6ed08

Please sign in to comment.