diff --git a/0001-Add-device-access-option.patch b/0001-Add-device-access-option.patch new file mode 100644 index 0000000..0770609 --- /dev/null +++ b/0001-Add-device-access-option.patch @@ -0,0 +1,49 @@ +From a72b8fffc82657de85d20b3c9191d24a0b41e612 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Martin=20Sk=C3=B8tt?= +Date: Thu, 11 Aug 2022 14:20:14 +0200 +Subject: [PATCH 1/4] Add ---device--access option +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Martin Skøtt +--- + udica/__main__.py | 8 ++++++++ + udica/policy.py | 2 ++ + 2 files changed, 10 insertions(+) + +diff --git a/udica/__main__.py b/udica/__main__.py +index d72a4b4..9cb276d 100644 +--- a/udica/__main__.py ++++ b/udica/__main__.py +@@ -127,6 +127,14 @@ def get_args(): + required=False, + default="-", + ) ++ parser.add_argument( ++ "--device-access", ++ help='List of devices the container should have access to, e.g "--device-access /dev/dri/card0,/dev/dri/renderD128"', ++ required=False, ++ default=None, ++ type=str, ++ dest='DeviceAccess' ++ ) + args = parser.parse_args() + return vars(args) + +diff --git a/udica/policy.py b/udica/policy.py +index ec6ce20..0f1145a 100644 +--- a/udica/policy.py ++++ b/udica/policy.py +@@ -173,6 +173,8 @@ def create_policy( + # devices + # Not applicable for CRI-O container engine + if inspect_format != "CRI-0": ++ if (not devices and opts["DeviceAccess"]): ++ devices = [{"PathOnHost": device} for device in opts["DeviceAccess"].split(',')] + write_policy_for_podman_devices(devices, policy) + + # mounts +-- +2.37.3 + diff --git a/0002-Syntax-changes-after-running-black.patch b/0002-Syntax-changes-after-running-black.patch new file mode 100644 index 0000000..9571da0 --- /dev/null +++ b/0002-Syntax-changes-after-running-black.patch @@ -0,0 +1,47 @@ +From a2f0e4588e010e9df9da7bbd46fa4304335f9b25 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Martin=20Sk=C3=B8tt?= +Date: Thu, 11 Aug 2022 20:29:18 +0200 +Subject: [PATCH 2/4] Syntax changes after running black +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Martin Skøtt +--- + udica/__main__.py | 2 +- + udica/policy.py | 6 ++++-- + 2 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/udica/__main__.py b/udica/__main__.py +index 9cb276d..84e0ba4 100644 +--- a/udica/__main__.py ++++ b/udica/__main__.py +@@ -133,7 +133,7 @@ def get_args(): + required=False, + default=None, + type=str, +- dest='DeviceAccess' ++ dest="DeviceAccess", + ) + args = parser.parse_args() + return vars(args) +diff --git a/udica/policy.py b/udica/policy.py +index 0f1145a..9b7a14f 100644 +--- a/udica/policy.py ++++ b/udica/policy.py +@@ -173,8 +173,10 @@ def create_policy( + # devices + # Not applicable for CRI-O container engine + if inspect_format != "CRI-0": +- if (not devices and opts["DeviceAccess"]): +- devices = [{"PathOnHost": device} for device in opts["DeviceAccess"].split(',')] ++ if not devices and opts["DeviceAccess"]: ++ devices = [ ++ {"PathOnHost": device} for device in opts["DeviceAccess"].split(",") ++ ] + write_policy_for_podman_devices(devices, policy) + + # mounts +-- +2.37.3 + diff --git a/0003-Add-unit-test-for-device-access.patch b/0003-Add-unit-test-for-device-access.patch new file mode 100644 index 0000000..321a9b8 --- /dev/null +++ b/0003-Add-unit-test-for-device-access.patch @@ -0,0 +1,294 @@ +From 0d3e3194e26a21c531d13bde5e45c0bce9717a99 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Martin=20Sk=C3=B8tt?= +Date: Thu, 11 Aug 2022 21:50:57 +0200 +Subject: [PATCH 3/4] Add unit test for --device-access +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Martin Skøtt +--- + tests/test_device_access.podman.json | 244 +++++++++++++++++++++++++++ + tests/test_main.py | 15 ++ + 2 files changed, 259 insertions(+) + create mode 100644 tests/test_device_access.podman.json + +diff --git a/tests/test_device_access.podman.json b/tests/test_device_access.podman.json +new file mode 100644 +index 0000000..9a806a2 +--- /dev/null ++++ b/tests/test_device_access.podman.json +@@ -0,0 +1,244 @@ ++[ ++ { ++ "Id": "68485406c4bbfd2b379beac7d80834a4ca94d7e74ada5019c7499afed62e1744", ++ "Created": "2022-08-11T20:54:51.026287311+02:00", ++ "Path": "/bin/bash", ++ "Args": [ ++ "/bin/bash" ++ ], ++ "State": { ++ "OciVersion": "1.0.2-dev", ++ "Status": "exited", ++ "Running": false, ++ "Paused": false, ++ "Restarting": false, ++ "OOMKilled": false, ++ "Dead": false, ++ "Pid": 0, ++ "ExitCode": 0, ++ "Error": "", ++ "StartedAt": "2022-08-11T20:54:51.116938836+02:00", ++ "FinishedAt": "2022-08-11T20:54:51.1327839+02:00", ++ "Health": { ++ "Status": "", ++ "FailingStreak": 0, ++ "Log": null ++ }, ++ "CheckpointedAt": "0001-01-01T00:00:00Z", ++ "RestoredAt": "0001-01-01T00:00:00Z" ++ }, ++ "Image": "2ecb6df959942dd2fdeb65606ca2e42a54f8c06af10eeb594fdfc3e2656c53d1", ++ "ImageName": "registry.fedoraproject.org/fedora:latest", ++ "Rootfs": "", ++ "Pod": "", ++ "ResolvConfPath": "/run/user/1000/overlay-containers/68485406c4bbfd2b379beac7d80834a4ca94d7e74ada5019c7499afed62e1744/userdata/resolv.conf", ++ "HostnamePath": "/run/user/1000/overlay-containers/68485406c4bbfd2b379beac7d80834a4ca94d7e74ada5019c7499afed62e1744/userdata/hostname", ++ "HostsPath": "/run/user/1000/overlay-containers/68485406c4bbfd2b379beac7d80834a4ca94d7e74ada5019c7499afed62e1744/userdata/hosts", ++ "StaticDir": "/home/martin/.local/share/containers/storage/overlay-containers/68485406c4bbfd2b379beac7d80834a4ca94d7e74ada5019c7499afed62e1744/userdata", ++ "OCIConfigPath": "/home/martin/.local/share/containers/storage/overlay-containers/68485406c4bbfd2b379beac7d80834a4ca94d7e74ada5019c7499afed62e1744/userdata/config.json", ++ "OCIRuntime": "crun", ++ "ConmonPidFile": "/run/user/1000/overlay-containers/68485406c4bbfd2b379beac7d80834a4ca94d7e74ada5019c7499afed62e1744/userdata/conmon.pid", ++ "PidFile": "/run/user/1000/overlay-containers/68485406c4bbfd2b379beac7d80834a4ca94d7e74ada5019c7499afed62e1744/userdata/pidfile", ++ "Name": "charming_khorana", ++ "RestartCount": 0, ++ "Driver": "overlay", ++ "MountLabel": "system_u:object_r:container_file_t:s0:c8,c574", ++ "ProcessLabel": "system_u:system_r:container_t:s0:c8,c574", ++ "AppArmorProfile": "", ++ "EffectiveCaps": [ ++ "CAP_CHOWN", ++ "CAP_DAC_OVERRIDE", ++ "CAP_FOWNER", ++ "CAP_FSETID", ++ "CAP_KILL", ++ "CAP_NET_BIND_SERVICE", ++ "CAP_SETFCAP", ++ "CAP_SETGID", ++ "CAP_SETPCAP", ++ "CAP_SETUID", ++ "CAP_SYS_CHROOT" ++ ], ++ "BoundingCaps": [ ++ "CAP_CHOWN", ++ "CAP_DAC_OVERRIDE", ++ "CAP_FOWNER", ++ "CAP_FSETID", ++ "CAP_KILL", ++ "CAP_NET_BIND_SERVICE", ++ "CAP_SETFCAP", ++ "CAP_SETGID", ++ "CAP_SETPCAP", ++ "CAP_SETUID", ++ "CAP_SYS_CHROOT" ++ ], ++ "ExecIDs": [], ++ "GraphDriver": { ++ "Name": "overlay", ++ "Data": { ++ "LowerDir": "/home/martin/.local/share/containers/storage/overlay/1da06ca5080c2ce2499e2f9802259209c7dd85c92d64852c3165425cdc18c443/diff", ++ "UpperDir": "/home/martin/.local/share/containers/storage/overlay/98294044df8fadc428b8a41befc0c83d574601b56076c62ce7fa93df6c48f8dc/diff", ++ "WorkDir": "/home/martin/.local/share/containers/storage/overlay/98294044df8fadc428b8a41befc0c83d574601b56076c62ce7fa93df6c48f8dc/work" ++ } ++ }, ++ "Mounts": [], ++ "Dependencies": [], ++ "NetworkSettings": { ++ "EndpointID": "", ++ "Gateway": "", ++ "IPAddress": "", ++ "IPPrefixLen": 0, ++ "IPv6Gateway": "", ++ "GlobalIPv6Address": "", ++ "GlobalIPv6PrefixLen": 0, ++ "MacAddress": "", ++ "Bridge": "", ++ "SandboxID": "", ++ "HairpinMode": false, ++ "LinkLocalIPv6Address": "", ++ "LinkLocalIPv6PrefixLen": 0, ++ "Ports": {}, ++ "SandboxKey": "" ++ }, ++ "Namespace": "", ++ "IsInfra": false, ++ "Config": { ++ "Hostname": "68485406c4bb", ++ "Domainname": "", ++ "User": "", ++ "AttachStdin": false, ++ "AttachStdout": false, ++ "AttachStderr": false, ++ "Tty": false, ++ "OpenStdin": false, ++ "StdinOnce": false, ++ "Env": [ ++ "FGC=f36", ++ "DISTTAG=f36container", ++ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", ++ "TERM=xterm", ++ "container=oci", ++ "HOME=/root", ++ "HOSTNAME=68485406c4bb" ++ ], ++ "Cmd": [ ++ "/bin/bash" ++ ], ++ "Image": "registry.fedoraproject.org/fedora:latest", ++ "Volumes": null, ++ "WorkingDir": "/", ++ "Entrypoint": "", ++ "OnBuild": null, ++ "Labels": { ++ "license": "MIT", ++ "name": "fedora", ++ "vendor": "Fedora Project", ++ "version": "36" ++ }, ++ "Annotations": { ++ "io.container.manager": "libpod", ++ "io.kubernetes.cri-o.Created": "2022-08-11T20:54:51.026287311+02:00", ++ "io.kubernetes.cri-o.TTY": "false", ++ "io.podman.annotations.autoremove": "FALSE", ++ "io.podman.annotations.init": "FALSE", ++ "io.podman.annotations.privileged": "FALSE", ++ "io.podman.annotations.publish-all": "FALSE", ++ "org.opencontainers.image.stopSignal": "15" ++ }, ++ "StopSignal": 15, ++ "CreateCommand": [ ++ "podman", ++ "run", ++ "--device", ++ "/dev/fb0", ++ "fedora" ++ ], ++ "Umask": "0022", ++ "Timeout": 0, ++ "StopTimeout": 10, ++ "Passwd": true ++ }, ++ "HostConfig": { ++ "Binds": [], ++ "CgroupManager": "systemd", ++ "CgroupMode": "private", ++ "ContainerIDFile": "", ++ "LogConfig": { ++ "Type": "journald", ++ "Config": null, ++ "Path": "", ++ "Tag": "", ++ "Size": "0B" ++ }, ++ "NetworkMode": "slirp4netns", ++ "PortBindings": {}, ++ "RestartPolicy": { ++ "Name": "", ++ "MaximumRetryCount": 0 ++ }, ++ "AutoRemove": false, ++ "VolumeDriver": "", ++ "VolumesFrom": null, ++ "CapAdd": [], ++ "CapDrop": [ ++ "CAP_AUDIT_WRITE", ++ "CAP_MKNOD", ++ "CAP_NET_RAW" ++ ], ++ "Dns": [], ++ "DnsOptions": [], ++ "DnsSearch": [], ++ "ExtraHosts": [], ++ "GroupAdd": [], ++ "IpcMode": "shareable", ++ "Cgroup": "", ++ "Cgroups": "default", ++ "Links": null, ++ "OomScoreAdj": 0, ++ "PidMode": "private", ++ "Privileged": false, ++ "PublishAllPorts": false, ++ "ReadonlyRootfs": false, ++ "SecurityOpt": [], ++ "Tmpfs": {}, ++ "UTSMode": "private", ++ "UsernsMode": "", ++ "ShmSize": 65536000, ++ "Runtime": "oci", ++ "ConsoleSize": [ ++ 0, ++ 0 ++ ], ++ "Isolation": "", ++ "CpuShares": 0, ++ "Memory": 0, ++ "NanoCpus": 0, ++ "CgroupParent": "user.slice", ++ "BlkioWeight": 0, ++ "BlkioWeightDevice": null, ++ "BlkioDeviceReadBps": null, ++ "BlkioDeviceWriteBps": null, ++ "BlkioDeviceReadIOps": null, ++ "BlkioDeviceWriteIOps": null, ++ "CpuPeriod": 0, ++ "CpuQuota": 0, ++ "CpuRealtimePeriod": 0, ++ "CpuRealtimeRuntime": 0, ++ "CpusetCpus": "", ++ "CpusetMems": "", ++ "Devices": [], ++ "DiskQuota": 0, ++ "KernelMemory": 0, ++ "MemoryReservation": 0, ++ "MemorySwap": 0, ++ "MemorySwappiness": 0, ++ "OomKillDisable": false, ++ "PidsLimit": 2048, ++ "Ulimits": [], ++ "CpuCount": 0, ++ "CpuPercent": 0, ++ "IOMaximumIOps": 0, ++ "IOMaximumBandwidth": 0, ++ "CgroupConf": null ++ } ++ } ++] +diff --git a/tests/test_main.py b/tests/test_main.py +index 6b30dc4..bc17cc2 100644 +--- a/tests/test_main.py ++++ b/tests/test_main.py +@@ -354,6 +354,21 @@ class TestBase(unittest.TestCase): + self.assert_templates(output, ["base_container"]) + self.assert_policy(test_file("test_devices.podman.cil")) + ++ def test_device_access_podman(self): ++ """podman run --device /dev/fb0 fedora""" ++ output = self.run_udica( ++ [ ++ "udica", ++ "-j", ++ "tests/test_devices.podman.json", ++ "--device-access", ++ "/dev/fd0", ++ "my_container", ++ ] ++ ) ++ self.assert_templates(output, ["base_container"]) ++ self.assert_policy(test_file("test_devices.podman.cil")) ++ + def run_udica(self, args): + with patch("sys.argv", args): + with patch("sys.stderr.write") as mock_err, patch( +-- +2.37.3 + diff --git a/0004-Rename-device-access-to-devices.patch b/0004-Rename-device-access-to-devices.patch new file mode 100644 index 0000000..e4d6e8a --- /dev/null +++ b/0004-Rename-device-access-to-devices.patch @@ -0,0 +1,101 @@ +From 34c0f137583001c5b7b0f8bf681b027aeff109cb Mon Sep 17 00:00:00 2001 +From: Vit Mojzis +Date: Wed, 19 Oct 2022 16:34:46 +0200 +Subject: [PATCH 4/4] Rename --device-access to --devices + +This makes parameters more consistent. +Also, describe the new parameter in man page. + +Signed-off-by: Vit Mojzis +--- + tests/test_main.py | 4 ++-- + udica/__main__.py | 16 ++++++++-------- + udica/man/man8/udica.8 | 5 +++++ + udica/policy.py | 6 ++---- + 4 files changed, 17 insertions(+), 14 deletions(-) + +diff --git a/tests/test_main.py b/tests/test_main.py +index bc17cc2..f32588b 100644 +--- a/tests/test_main.py ++++ b/tests/test_main.py +@@ -361,8 +361,8 @@ class TestBase(unittest.TestCase): + "udica", + "-j", + "tests/test_devices.podman.json", +- "--device-access", +- "/dev/fd0", ++ "--devices", ++ "/dev/fb0", + "my_container", + ] + ) +diff --git a/udica/__main__.py b/udica/__main__.py +index 84e0ba4..103ddc2 100644 +--- a/udica/__main__.py ++++ b/udica/__main__.py +@@ -99,6 +99,14 @@ def get_args(): + dest="Caps", + default=None, + ) ++ parser.add_argument( ++ "--devices", ++ type=str, ++ help='List of devices the container should have access to, e.g "--devices /dev/dri/card0,/dev/dri/renderD128"', ++ dest="Devices", ++ required=False, ++ default=None, ++ ) + parser.add_argument( + "-d", + "--ansible", +@@ -127,14 +135,6 @@ def get_args(): + required=False, + default="-", + ) +- parser.add_argument( +- "--device-access", +- help='List of devices the container should have access to, e.g "--device-access /dev/dri/card0,/dev/dri/renderD128"', +- required=False, +- default=None, +- type=str, +- dest="DeviceAccess", +- ) + args = parser.parse_args() + return vars(args) + +diff --git a/udica/man/man8/udica.8 b/udica/man/man8/udica.8 +index 8c3a48e..c7158ff 100644 +--- a/udica/man/man8/udica.8 ++++ b/udica/man/man8/udica.8 +@@ -53,6 +53,11 @@ Load templates and module created by this tool + List of capabilities, for example: "\-c AUDIT\_WRITE,CHOWN,DAC\_OVERRIDE,FOWNER,FSETID,KILL" + (mandatory to use for Docker Engine, see the BUGS section) + ++.TP ++.I \-\-devices DEVS ++List of devices the container should have access to, e.g "\-\-devices /dev/dri/card0,/dev/dri/renderD128" ++(overrides devices specified in the conatiner JSON) ++ + .TP + .I \-a, \-\-append-rules FILE + Append more SELinux allow rules generated from SELinux denials in audit daemon. +diff --git a/udica/policy.py b/udica/policy.py +index 9b7a14f..9069c97 100644 +--- a/udica/policy.py ++++ b/udica/policy.py +@@ -173,10 +173,8 @@ def create_policy( + # devices + # Not applicable for CRI-O container engine + if inspect_format != "CRI-0": +- if not devices and opts["DeviceAccess"]: +- devices = [ +- {"PathOnHost": device} for device in opts["DeviceAccess"].split(",") +- ] ++ if opts["Devices"]: ++ devices = [{"PathOnHost": device} for device in opts["Devices"].split(",")] + write_policy_for_podman_devices(devices, policy) + + # mounts +-- +2.37.3 + diff --git a/udica.spec b/udica.spec index 53b2b86..5124cef 100644 --- a/udica.spec +++ b/udica.spec @@ -1,8 +1,12 @@ Summary: A tool for generating SELinux security policies for containers Name: udica Version: 0.2.7 -Release: 2%{?dist} +Release: 3%{?dist} Source0: https://github.com/containers/udica/archive/v%{version}.tar.gz +Patch001: 0001-Add-device-access-option.patch +Patch002: 0002-Syntax-changes-after-running-black.patch +Patch003: 0003-Add-unit-test-for-device-access.patch +Patch004: 0004-Rename-device-access-to-devices.patch License: GPLv3+ BuildArch: noarch Url: https://github.com/containers/udica @@ -58,6 +62,9 @@ install -m 0644 udica/man/man8/udica.8 %{buildroot}%{_mandir}/man8/udica.8 %endif %changelog +* Fri Oct 21 2022 Vit Mojzis - 0.2.7-3 +- Add --devices option + * Sat Jul 23 2022 Fedora Release Engineering - 0.2.7-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild