Skip to content

Commit ad6ed08

Browse files
committed
Fix operation not permitted with systemd-homed
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 <[email protected]>
1 parent cc1b6e0 commit ad6ed08

File tree

5 files changed

+25
-5
lines changed

5 files changed

+25
-5
lines changed

cmd/nerdctl/container_run_mount.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/containerd/containerd/errdefs"
3030
"github.com/containerd/containerd/mount"
3131
"github.com/containerd/containerd/oci"
32+
"github.com/containerd/containerd/pkg/userns"
3233
"github.com/containerd/continuity/fs"
3334
"github.com/containerd/nerdctl/pkg/api/types"
3435
"github.com/containerd/nerdctl/pkg/idgen"
@@ -189,6 +190,25 @@ func generateMountOpts(ctx context.Context, cmd *cobra.Command, client *containe
189190
return nil, nil, nil, err
190191
}
191192
}
193+
} else if runtime.GOOS == "linux" {
194+
defer unmounter(tempDir)
195+
for _, m := range mounts {
196+
m := m
197+
if m.Type == "bind" && userns.RunningInUserNS() {
198+
// For https://github.com/containerd/nerdctl/issues/2056
199+
unpriv, err := mountutil.UnprivilegedMountFlags(m.Source)
200+
if err != nil {
201+
return nil, nil, nil, err
202+
}
203+
m.Options = strutil.DedupeStrSlice(append(m.Options, unpriv...))
204+
}
205+
if err := m.Mount(tempDir); err != nil {
206+
if rmErr := s.Remove(ctx, tempDir); rmErr != nil && !errdefs.IsNotFound(rmErr) {
207+
return nil, nil, nil, rmErr
208+
}
209+
return nil, nil, nil, fmt.Errorf("failed to mount %+v on %q: %w", m, tempDir, err)
210+
}
211+
}
192212
} else {
193213
defer unmounter(tempDir)
194214
if err := mount.All(mounts, tempDir); err != nil {

pkg/mountutil/mountutil.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ func ProcessFlagV(s string, volStore volumestore.VolumeStore) (*Processed, error
144144
Options: options,
145145
}
146146
if userns.RunningInUserNS() {
147-
unpriv, err := getUnprivilegedMountFlags(src)
147+
unpriv, err := UnprivilegedMountFlags(src)
148148
if err != nil {
149149
return nil, err
150150
}

pkg/mountutil/mountutil_freebsd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import (
2626
"github.com/sirupsen/logrus"
2727
)
2828

29-
func getUnprivilegedMountFlags(path string) ([]string, error) {
29+
func UnprivilegedMountFlags(path string) ([]string, error) {
3030
m := []string{}
3131
return m, nil
3232
}

pkg/mountutil/mountutil_linux.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,14 @@ import (
4343
NOTICE: https://github.com/moby/moby/blob/v20.10.5/NOTICE
4444
*/
4545

46-
// getUnprivilegedMountFlags is from https://github.com/moby/moby/blob/v20.10.5/daemon/oci_linux.go#L420-L450
46+
// UnprivilegedMountFlags is from https://github.com/moby/moby/blob/v20.10.5/daemon/oci_linux.go#L420-L450
4747
//
4848
// Get the set of mount flags that are set on the mount that contains the given
4949
// path and are locked by CL_UNPRIVILEGED. This is necessary to ensure that
5050
// bind-mounting "with options" will not fail with user namespaces, due to
5151
// kernel restrictions that require user namespace mounts to preserve
5252
// CL_UNPRIVILEGED locked flags.
53-
func getUnprivilegedMountFlags(path string) ([]string, error) {
53+
func UnprivilegedMountFlags(path string) ([]string, error) {
5454
var statfs unix.Statfs_t
5555
if err := unix.Statfs(path, &statfs); err != nil {
5656
return nil, err

pkg/mountutil/mountutil_windows.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import (
2626
"github.com/sirupsen/logrus"
2727
)
2828

29-
func getUnprivilegedMountFlags(path string) ([]string, error) {
29+
func UnprivilegedMountFlags(path string) ([]string, error) {
3030
m := []string{}
3131
return m, nil
3232
}

0 commit comments

Comments
 (0)