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 years ago
parent
commit
1cd1925acd
2 changed files with 33 additions and 1 deletions
  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)
+		})
+	}
+}