mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-19 23:26:29 +00:00
Allow dynamic lookup cgroup rules based on Host udev (#2652)
This commit is contained in:
parent
bee55d08fb
commit
b288554d9c
@ -23,8 +23,11 @@ class UdevSubsystem(str, Enum):
|
|||||||
GPIOMEM = "gpiomem"
|
GPIOMEM = "gpiomem"
|
||||||
VCHIQ = "vchiq"
|
VCHIQ = "vchiq"
|
||||||
GRAPHICS = "graphics"
|
GRAPHICS = "graphics"
|
||||||
CEC = "CEC"
|
CEC = "cec"
|
||||||
DRM = "drm"
|
DRM = "drm"
|
||||||
|
HIDRAW = "hidraw"
|
||||||
|
RPI_HEVCMEM = "rpivid-hevcmem"
|
||||||
|
RPI_H264MEM = "rpivid-h264mem"
|
||||||
|
|
||||||
|
|
||||||
class PolicyGroup(str, Enum):
|
class PolicyGroup(str, Enum):
|
||||||
|
@ -16,19 +16,13 @@ _CGROUPS: Dict[PolicyGroup, List[int]] = {
|
|||||||
PolicyGroup.UART: [
|
PolicyGroup.UART: [
|
||||||
204, # ttyAMA / ttySAC (tty)
|
204, # ttyAMA / ttySAC (tty)
|
||||||
188, # ttyUSB (tty)
|
188, # ttyUSB (tty)
|
||||||
166, # ttyACM (tty)
|
166 # ttyACM (tty)
|
||||||
244 # ttyAML (tty)
|
|
||||||
],
|
],
|
||||||
PolicyGroup.GPIO: [
|
PolicyGroup.GPIO: [
|
||||||
254, # gpiochip (gpio)
|
|
||||||
245 # gpiomem (gpiomem)
|
|
||||||
],
|
],
|
||||||
PolicyGroup.VIDEO: [
|
PolicyGroup.VIDEO: [
|
||||||
239,
|
29, # /dev/fb (graphics)
|
||||||
29,
|
|
||||||
81,
|
81,
|
||||||
251,
|
|
||||||
242, # vchiq (vchiq)
|
|
||||||
226
|
226
|
||||||
],
|
],
|
||||||
PolicyGroup.AUDIO: [
|
PolicyGroup.AUDIO: [
|
||||||
@ -37,13 +31,35 @@ _CGROUPS: Dict[PolicyGroup, List[int]] = {
|
|||||||
PolicyGroup.USB: [
|
PolicyGroup.USB: [
|
||||||
189, # /dev/bus/usb (usb)
|
189, # /dev/bus/usb (usb)
|
||||||
180, # hiddev (usbmisc)
|
180, # hiddev (usbmisc)
|
||||||
243 # hidraw (hidraw)
|
|
||||||
],
|
],
|
||||||
PolicyGroup.BLUETOOTH: [
|
PolicyGroup.BLUETOOTH: [
|
||||||
13 # /dev/input (input)
|
13 # /dev/input (input)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_CGROUPS_DYNAMIC_MAJOR: Dict[PolicyGroup, List[UdevSubsystem]] = {
|
||||||
|
PolicyGroup.USB: [
|
||||||
|
UdevSubsystem.HIDRAW
|
||||||
|
],
|
||||||
|
PolicyGroup.GPIO: [
|
||||||
|
UdevSubsystem.GPIO,
|
||||||
|
UdevSubsystem.GPIOMEM
|
||||||
|
],
|
||||||
|
PolicyGroup.VIDEO: [
|
||||||
|
UdevSubsystem.VCHIQ,
|
||||||
|
UdevSubsystem.MEDIA,
|
||||||
|
UdevSubsystem.CEC,
|
||||||
|
UdevSubsystem.RPI_H264MEM,
|
||||||
|
UdevSubsystem.RPI_HEVCMEM
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
_CGROUPS_DYNAMIC_MINOR: Dict[PolicyGroup, List[UdevSubsystem]] = {
|
||||||
|
PolicyGroup.UART: [
|
||||||
|
UdevSubsystem.SERIAL
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
||||||
|
|
||||||
@ -60,12 +76,33 @@ class HwPolicy(CoreSysAttributes):
|
|||||||
|
|
||||||
def get_cgroups_rules(self, group: PolicyGroup) -> List[str]:
|
def get_cgroups_rules(self, group: PolicyGroup) -> List[str]:
|
||||||
"""Generate cgroups rules for a policy group."""
|
"""Generate cgroups rules for a policy group."""
|
||||||
return [f"c {dev}:* rwm" for dev in _CGROUPS.get(group, [])]
|
cgroups: List[str] = [f"c {dev}:* rwm" for dev in _CGROUPS[group]]
|
||||||
|
|
||||||
|
# Lookup dynamic device groups from host
|
||||||
|
if group in _CGROUPS_DYNAMIC_MAJOR:
|
||||||
|
majors = {
|
||||||
|
device.cgroups_major
|
||||||
|
for device in self.sys_hardware.devices
|
||||||
|
if device.subsystem in _CGROUPS_DYNAMIC_MAJOR[group]
|
||||||
|
and device.cgroups_major not in _CGROUPS[group]
|
||||||
|
}
|
||||||
|
cgroups.extend([f"c {dev}:* rwm" for dev in majors])
|
||||||
|
|
||||||
|
# Lookup dynamic devices from host
|
||||||
|
if group in _CGROUPS_DYNAMIC_MINOR:
|
||||||
|
for device in self.sys_hardware.devices:
|
||||||
|
if (
|
||||||
|
device.subsystem not in _CGROUPS_DYNAMIC_MINOR[group]
|
||||||
|
or device.cgroups_major in _CGROUPS[group]
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
cgroups.append(self.get_cgroups_rule(device))
|
||||||
|
|
||||||
|
return cgroups
|
||||||
|
|
||||||
def get_cgroups_rule(self, device: Device) -> str:
|
def get_cgroups_rule(self, device: Device) -> str:
|
||||||
"""Generate a cgroups rule for given device."""
|
"""Generate a cgroups rule for given device."""
|
||||||
cgroup_type = "c" if device.subsystem != UdevSubsystem.DISK else "b"
|
cgroup_type = "c" if device.subsystem != UdevSubsystem.DISK else "b"
|
||||||
|
|
||||||
return f"{cgroup_type} {device.cgroups_major}:{device.cgroups_minor} rwm"
|
return f"{cgroup_type} {device.cgroups_major}:{device.cgroups_minor} rwm"
|
||||||
|
|
||||||
def get_full_access(self) -> str:
|
def get_full_access(self) -> str:
|
||||||
|
@ -35,11 +35,8 @@ def test_device_policy(coresys):
|
|||||||
def test_policy_group(coresys):
|
def test_policy_group(coresys):
|
||||||
"""Test policy group generator."""
|
"""Test policy group generator."""
|
||||||
assert coresys.hardware.policy.get_cgroups_rules(PolicyGroup.VIDEO) == [
|
assert coresys.hardware.policy.get_cgroups_rules(PolicyGroup.VIDEO) == [
|
||||||
"c 239:* rwm",
|
|
||||||
"c 29:* rwm",
|
"c 29:* rwm",
|
||||||
"c 81:* rwm",
|
"c 81:* rwm",
|
||||||
"c 251:* rwm",
|
|
||||||
"c 242:* rwm",
|
|
||||||
"c 226:* rwm",
|
"c 226:* rwm",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -83,3 +80,93 @@ def test_allowed_access(coresys):
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert coresys.hardware.policy.allowed_for_access(device)
|
assert coresys.hardware.policy.allowed_for_access(device)
|
||||||
|
|
||||||
|
|
||||||
|
def test_dynamic_group_alloc_minor(coresys):
|
||||||
|
"""Test dynamic cgroup generation based on minor."""
|
||||||
|
for device in (
|
||||||
|
Device(
|
||||||
|
"ttyACM0",
|
||||||
|
Path("/dev/ttyACM0"),
|
||||||
|
Path("/sys/bus/usb/001"),
|
||||||
|
"tty",
|
||||||
|
[],
|
||||||
|
{"MAJOR": "204", "MINOR": "10"},
|
||||||
|
),
|
||||||
|
Device(
|
||||||
|
"ttyUSB0",
|
||||||
|
Path("/dev/ttyUSB0"),
|
||||||
|
Path("/sys/bus/usb/000"),
|
||||||
|
"tty",
|
||||||
|
[Path("/dev/ttyS1"), Path("/dev/serial/by-id/xyx")],
|
||||||
|
{"MAJOR": "188", "MINOR": "10"},
|
||||||
|
),
|
||||||
|
Device(
|
||||||
|
"ttyS0",
|
||||||
|
Path("/dev/ttyS0"),
|
||||||
|
Path("/sys/bus/usb/002"),
|
||||||
|
"tty",
|
||||||
|
[],
|
||||||
|
{"MAJOR": "4", "MINOR": "65"},
|
||||||
|
),
|
||||||
|
Device(
|
||||||
|
"video1",
|
||||||
|
Path("/dev/video1"),
|
||||||
|
Path("/sys/bus/usb/003"),
|
||||||
|
"misc",
|
||||||
|
[],
|
||||||
|
{"MAJOR": "38", "MINOR": "10"},
|
||||||
|
),
|
||||||
|
):
|
||||||
|
coresys.hardware.update_device(device)
|
||||||
|
|
||||||
|
assert coresys.hardware.policy.get_cgroups_rules(PolicyGroup.UART) == [
|
||||||
|
"c 204:* rwm",
|
||||||
|
"c 188:* rwm",
|
||||||
|
"c 166:* rwm",
|
||||||
|
"c 4:65 rwm",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def test_dynamic_group_alloc_major(coresys):
|
||||||
|
"""Test dynamic cgroup generation based on minor."""
|
||||||
|
for device in (
|
||||||
|
Device(
|
||||||
|
"gpio16",
|
||||||
|
Path("/dev/gpio16"),
|
||||||
|
Path("/sys/bus/usb/001"),
|
||||||
|
"gpio",
|
||||||
|
[],
|
||||||
|
{"MAJOR": "254", "MINOR": "10"},
|
||||||
|
),
|
||||||
|
Device(
|
||||||
|
"gpiomem",
|
||||||
|
Path("/dev/gpiomem"),
|
||||||
|
Path("/sys/bus/usb/000"),
|
||||||
|
"gpiomem",
|
||||||
|
[Path("/dev/ttyS1"), Path("/dev/serial/by-id/xyx")],
|
||||||
|
{"MAJOR": "239", "MINOR": "10"},
|
||||||
|
),
|
||||||
|
Device(
|
||||||
|
"ttyS0",
|
||||||
|
Path("/dev/ttyS0"),
|
||||||
|
Path("/sys/bus/usb/002"),
|
||||||
|
"tty",
|
||||||
|
[],
|
||||||
|
{"MAJOR": "4", "MINOR": "65"},
|
||||||
|
),
|
||||||
|
Device(
|
||||||
|
"video1",
|
||||||
|
Path("/dev/video1"),
|
||||||
|
Path("/sys/bus/usb/003"),
|
||||||
|
"misc",
|
||||||
|
[],
|
||||||
|
{"MAJOR": "38", "MINOR": "10"},
|
||||||
|
),
|
||||||
|
):
|
||||||
|
coresys.hardware.update_device(device)
|
||||||
|
|
||||||
|
assert coresys.hardware.policy.get_cgroups_rules(PolicyGroup.GPIO) == [
|
||||||
|
"c 254:* rwm",
|
||||||
|
"c 239:* rwm",
|
||||||
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user