Repository: opencontainers/runc
Pull request #4555 (2024-12-16 19:20:49)

Re-add tun/tap to default device rules
Since v1.2.0 was released, a number of users complained that the removal of tun/tap device access from the default device ruleset is causing a regression in their workloads.

Additionally, it seems that some upper-level orchestration tools (Docker Swarm, Kubernetes) makes it either impossible or impractical to supply additional device rules.

While it's probably not right to have /dev/net/tun in a default device list, it was there from the very beginning, and users rely on it.

This reverts commit 2ce40b6ad72b4bd4391380cafc5ef1bad1fa0b31 / PR #3468.

AkihiroSuda: > either impossible or impractical to supply additional device rules.

Probably s/impractical/cumbersome/.

For Kubernetes, an additional device rule can be specified via the Generic Device Plugin: https://github.com/squat/generic-device-plugin
Installing a plugin is not as straightforward as adding a single line to a Pod manifest, though.
kolyshkin: > It took 2+ years between the date of the original commit and when it was rolled out in Docker. So if it will take another two years until this revert is effectuated, it will be a bit pointless because by that time everyone already changed their compose files to workaround it.

Unfortunately, the scope of this is not limited to docker compose. 

Patch:
diff --git a/libcontainer/specconv/spec_linux.go b/libcontainer/specconv/spec_linux.go
index e44e04c5..79a9a790 100644
--- a/libcontainer/specconv/spec_linux.go
+++ b/libcontainer/specconv/spec_linux.go
@@ -315,6 +315,23 @@ var AllowedDevices = []*devices.Device{
 			Allow:       true,
 		},
 	},
+	// The following entry for /dev/net/tun device was there from the
+	// very early days of Docker, but got removed in runc 1.2.0-rc1,
+	// causing a number of regressions for users (see
+	// https://github.com/opencontainers/runc/pull/3468).
+	//
+	// Some upper-level orcherstration tools makes it either impossible
+	// or cumbersome to supply additional device rules, so we have to
+	// keep this for the sake of backward compatibility.
+	{
+		Rule: devices.Rule{
+			Type:        devices.CharDevice,
+			Major:       10,
+			Minor:       200,
+			Permissions: "rwm",
+			Allow:       true,
+		},
+	},
 }
 
 type CreateOpts struct {


Test patch:
diff --git a/libcontainer/cgroups/devices/devicefilter_test.go b/libcontainer/cgroups/devices/devicefilter_test.go
index 3a415a71..23ad92ea 100644
--- a/libcontainer/cgroups/devices/devicefilter_test.go
+++ b/libcontainer/cgroups/devices/devicefilter_test.go
@@ -120,14 +120,21 @@ block-8:
         51: MovImm32 dst: r0 imm: 1
         52: Exit
 block-9:
-// /dev/pts (c, 136, wildcard, rwm, true)
+// tuntap (c, 10, 200, rwm, true)
         53: JNEImm dst: r2 off: -1 imm: 2 <block-10>
-        54: JNEImm dst: r4 off: -1 imm: 136 <block-10>
-        55: MovImm32 dst: r0 imm: 1
-        56: Exit
+        54: JNEImm dst: r4 off: -1 imm: 10 <block-10>
+        55: JNEImm dst: r5 off: -1 imm: 200 <block-10>
+        56: MovImm32 dst: r0 imm: 1
+        57: Exit
 block-10:
-        57: MovImm32 dst: r0 imm: 0
-        58: Exit
+// /dev/pts (c, 136, wildcard, rwm, true)
+	58: JNEImm dst: r2 off: -1 imm: 2 <block-11>
+        59: JNEImm dst: r4 off: -1 imm: 136 <block-11>
+        60: MovImm32 dst: r0 imm: 1
+        61: Exit
+block-11:
+        62: MovImm32 dst: r0 imm: 0
+        63: Exit
 `
 	var devices []*devices.Rule
 	for _, device := range specconv.AllowedDevices {