Browse Source

oci.Device() fix FileMode to match runtime spec

The runtime spec expects the FileMode field to only hold file permissions,
however `unix.Stat_t.Mode` contains both file type and mode.

This patch strips file type so that only file mode is included in the Device.

Thanks to Iceber Gu, who noticed the same issue in containerd and runc.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Sebastiaan van Stijn 4 năm trước cách đây
mục cha
commit
1cd1925acd
2 tập tin đã thay đổi với 33 bổ sung1 xóa
  1. 2 1
      oci/devices_linux.go
  2. 31 0
      oci/devices_linux_test.go

+ 2 - 1
oci/devices_linux.go

@@ -9,6 +9,7 @@ import (
 	"github.com/opencontainers/runc/libcontainer/configs"
 	"github.com/opencontainers/runc/libcontainer/devices"
 	specs "github.com/opencontainers/runtime-spec/specs-go"
+	"golang.org/x/sys/unix"
 )
 
 // Device transforms a libcontainer configs.Device to a specs.LinuxDevice object.
@@ -18,7 +19,7 @@ func Device(d *configs.Device) specs.LinuxDevice {
 		Path:     d.Path,
 		Major:    d.Major,
 		Minor:    d.Minor,
-		FileMode: fmPtr(int64(d.FileMode)),
+		FileMode: fmPtr(int64(d.FileMode &^ unix.S_IFMT)), // strip file type, as OCI spec only expects file-mode to be included
 		UID:      u32Ptr(int64(d.Uid)),
 		GID:      u32Ptr(int64(d.Gid)),
 	}

+ 31 - 0
oci/devices_linux_test.go

@@ -0,0 +1,31 @@
+package oci
+
+import (
+	"os"
+	"testing"
+
+	"github.com/opencontainers/runc/libcontainer/configs"
+	"golang.org/x/sys/unix"
+	"gotest.tools/v3/assert"
+)
+
+func TestDeviceMode(t *testing.T) {
+	tests := []struct {
+		name string
+		in   os.FileMode
+		out  os.FileMode
+	}{
+		{name: "regular permissions", in: 0777, out: 0777},
+		{name: "block device", in: 0777 | unix.S_IFBLK, out: 0777},
+		{name: "character device", in: 0777 | unix.S_IFCHR, out: 0777},
+		{name: "fifo device", in: 0777 | unix.S_IFIFO, out: 0777},
+	}
+
+	for _, tc := range tests {
+		tc := tc
+		t.Run(tc.name, func(t *testing.T) {
+			d := Device(&configs.Device{FileMode: tc.in})
+			assert.Equal(t, *d.FileMode, tc.out)
+		})
+	}
+}