@@ -63,6 +63,8 @@ var generateFlags = []cli.Flag{
63
63
cli.StringSliceFlag {Name : "linux-readonly-paths" , Usage : "specifies paths readonly inside container" },
64
64
cli.Int64Flag {Name : "linux-realtime-period" , Usage : "CPU period to be used for realtime scheduling (in usecs)" },
65
65
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" },
66
68
cli.StringFlag {Name : "linux-rootfs-propagation" , Usage : "mount propagation for rootfs" },
67
69
cli.StringFlag {Name : "linux-seccomp-allow" , Usage : "specifies syscalls to respond with allow" },
68
70
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 {
241
243
}
242
244
}
243
245
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
+
244
268
if context .IsSet ("linux-readonly-paths" ) {
245
269
paths := context .StringSlice ("linux-readonly-paths" )
246
270
for _ , path := range paths {
@@ -811,6 +835,7 @@ func parseRlimit(rlimit string) (string, uint64, uint64, error) {
811
835
return parts [0 ], uint64 (hard ), uint64 (soft ), nil
812
836
}
813
837
838
+ << << << < 9e0 e42dbf918070406a2a4a2e1476e7350ba9129
814
839
func parseNamespace (ns string ) (string , string , error ) {
815
840
parts := strings .SplitN (ns , ":" , 2 )
816
841
if len (parts ) == 0 || parts [0 ] == "" {
@@ -906,6 +931,82 @@ func parseDevice(device string, g *generate.Generator) (rspec.LinuxDevice, error
906
931
return dev , nil
907
932
}
908
933
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
+
909
1010
func addSeccomp (context * cli.Context , g * generate.Generator ) error {
910
1011
911
1012
// Set the DefaultAction of seccomp
0 commit comments