Skip to content

Commit 7f09e1b

Browse files
Zhai Zhaoxuanzhouhao
Zhai Zhaoxuan
authored and
zhouhao
committed
generate: add --device-access-add and --device-access-remove option
These options allow user to configures the device whitelist. Signed-off-by: Zhai Zhaoxuan <[email protected]>
1 parent 9e0e42d commit 7f09e1b

File tree

2 files changed

+134
-0
lines changed

2 files changed

+134
-0
lines changed

Diff for: cmd/oci-runtime-tool/generate.go

+101
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ var generateFlags = []cli.Flag{
6363
cli.StringSliceFlag{Name: "linux-readonly-paths", Usage: "specifies paths readonly inside container"},
6464
cli.Int64Flag{Name: "linux-realtime-period", Usage: "CPU period to be used for realtime scheduling (in usecs)"},
6565
cli.Int64Flag{Name: "linux-realtime-runtime", Usage: "the time realtime scheduling may use (in usecs)"},
66+
cli.StringSliceFlag{Name: "linux-resources-device-add", Usage: "add a device access rule"},
67+
cli.StringSliceFlag{Name: "linux-resources-device-remove", Usage: "remove a device access rule"},
6668
cli.StringFlag{Name: "linux-rootfs-propagation", Usage: "mount propagation for rootfs"},
6769
cli.StringFlag{Name: "linux-seccomp-allow", Usage: "specifies syscalls to respond with allow"},
6870
cli.StringFlag{Name: "linux-seccomp-arch", Usage: "specifies additional architectures permitted to be used for system calls"},
@@ -241,6 +243,28 @@ func setupSpec(g *generate.Generator, context *cli.Context) error {
241243
}
242244
}
243245

246+
if context.IsSet("linux-resources-device-add") {
247+
devices := context.StringSlice("linux-resources-device-add")
248+
for _, device := range devices {
249+
dev, err := parseLinuxResourcesDeviceAccess(device, g)
250+
if err != nil {
251+
return err
252+
}
253+
g.AddLinuxResourcesDevice(dev.Allow, dev.Type, dev.Major, dev.Minor, dev.Access)
254+
}
255+
}
256+
257+
if context.IsSet("linux-resources-device-remove") {
258+
devices := context.StringSlice("linux-resources-device-remove")
259+
for _, device := range devices {
260+
dev, err := parseLinuxResourcesDeviceAccess(device, g)
261+
if err != nil {
262+
return err
263+
}
264+
g.RemoveLinuxResourcesDevice(dev.Allow, dev.Type, dev.Major, dev.Minor, dev.Access)
265+
}
266+
}
267+
244268
if context.IsSet("linux-readonly-paths") {
245269
paths := context.StringSlice("linux-readonly-paths")
246270
for _, path := range paths {
@@ -811,6 +835,7 @@ func parseRlimit(rlimit string) (string, uint64, uint64, error) {
811835
return parts[0], uint64(hard), uint64(soft), nil
812836
}
813837

838+
<<<<<<< 9e0e42dbf918070406a2a4a2e1476e7350ba9129
814839
func parseNamespace(ns string) (string, string, error) {
815840
parts := strings.SplitN(ns, ":", 2)
816841
if len(parts) == 0 || parts[0] == "" {
@@ -906,6 +931,82 @@ func parseDevice(device string, g *generate.Generator) (rspec.LinuxDevice, error
906931
return dev, nil
907932
}
908933

934+
var cgroupDeviceType = map[string]bool{
935+
"a": true, // all
936+
"b": true, // block device
937+
"c": true, // character device
938+
}
939+
var cgroupDeviceAccess = map[string]bool{
940+
"r": true, //read
941+
"w": true, //write
942+
"m": true, //mknod
943+
}
944+
945+
// parseLinuxResourcesDeviceAccess parses the raw string passed with the --device-access-add flag
946+
func parseLinuxResourcesDeviceAccess(device string, g *generate.Generator) (rspec.DeviceCgroup, error) {
947+
var allow bool
948+
var devType, access string
949+
var major, minor *int64
950+
951+
argsParts := strings.Split(device, ",")
952+
953+
switch argsParts[0] {
954+
case "allow":
955+
allow = true
956+
case "deny":
957+
allow = false
958+
default:
959+
return rspec.DeviceCgroup{},
960+
fmt.Errorf("Only 'allow' and 'deny' are allowed in the first field of device-access-add: %s", device)
961+
}
962+
963+
for _, s := range argsParts[1:] {
964+
s = strings.TrimSpace(s)
965+
if s == "" {
966+
continue
967+
}
968+
parts := strings.SplitN(s, "=", 2)
969+
if len(parts) != 2 {
970+
return rspec.DeviceCgroup{}, fmt.Errorf("Incomplete device-access-add arguments: %s", s)
971+
}
972+
name, value := parts[0], parts[1]
973+
974+
switch name {
975+
case "type":
976+
if !cgroupDeviceType[value] {
977+
return rspec.DeviceCgroup{}, fmt.Errorf("Invalid device type in device-access-add: %s", value)
978+
}
979+
devType = &value
980+
case "major":
981+
i, err := strconv.ParseInt(value, 10, 64)
982+
if err != nil {
983+
return rspec.DeviceCgroup{}, err
984+
}
985+
major = &i
986+
case "minor":
987+
i, err := strconv.ParseInt(value, 10, 64)
988+
if err != nil {
989+
return rspec.DeviceCgroup{}, err
990+
}
991+
minor = &i
992+
case "access":
993+
for _, c := range strings.Split(value, "") {
994+
if !cgroupDeviceAccess[c] {
995+
return rspec.DeviceCgroup{}, fmt.Errorf("Invalid device access in device-access-add: %s", c)
996+
}
997+
}
998+
access = &value
999+
}
1000+
}
1001+
return rspec.DeviceCgroup{
1002+
Allow: allow,
1003+
Type: devType,
1004+
Major: major,
1005+
Minor: minor,
1006+
Access: access,
1007+
}, nil
1008+
}
1009+
9091010
func addSeccomp(context *cli.Context, g *generate.Generator) error {
9101011

9111012
// Set the DefaultAction of seccomp

Diff for: generate/generate.go

+33
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,39 @@ func (g *Generator) ClearLinuxDevices() {
11761176
g.spec.Linux.Devices = []rspec.LinuxDevice{}
11771177
}
11781178

1179+
// AddLinuxResourcesDevice - add a device into g.spec.Linux.Resources.Devices
1180+
func (g *Generator) AddLinuxResourcesDevice(allow bool, devType string, major, minor *int64, access *string) {
1181+
g.initSpecLinuxResources()
1182+
1183+
device := rspec.DeviceCgroup{
1184+
Allow: allow,
1185+
Type: devType,
1186+
Access: access,
1187+
Major: major,
1188+
Minor: minor,
1189+
}
1190+
g.spec.Linux.Resources.Devices = append(g.spec.Linux.Resources.Devices, device)
1191+
}
1192+
1193+
// RemoveLinuxResourcesDevice - remove a device from g.spec.Linux.Resources.Devices
1194+
func (g *Generator) RemoveLinuxResourcesDevice(allow bool, devType string, major, minor *int64, access *string) {
1195+
if g.spec == nil || g.spec.Linux == nil || g.spec.Linux.Resources == nil {
1196+
return
1197+
}
1198+
for i, device := range g.spec.Linux.Resources.Devices {
1199+
if device.Allow == allow &&
1200+
(devType == device.Type || (devType != "" && device.Type != "" && devType == device.Type)) &&
1201+
(access == device.Access || (access != "" && device.Access != "" && access == device.Access)) &&
1202+
(major == device.Major || (major != nil && device.Major != nil && *major == *device.Major)) &&
1203+
(minor == device.Minor || (minor != nil && device.Minor != nil && *minor == *device.Minor)) {
1204+
1205+
g.spec.Linux.Resources.Devices = append(g.spec.Linux.Resources.Devices[:i], g.spec.Linux.Resources.Devices[i+1:]...)
1206+
return
1207+
}
1208+
}
1209+
return
1210+
}
1211+
11791212
// strPtr returns the pointer pointing to the string s.
11801213
func strPtr(s string) *string { return &s }
11811214

0 commit comments

Comments
 (0)