mirror of
https://github.com/systemd/systemd.git
synced 2026-08-09 09:32:04 +00:00
60-ukify: skip /proc/cmdline in containers
When running inside a container (during image builds or such), `/proc/cmdline` belongs to the host and would leak the host's root= (or a faked placeholder like root=/dev/osbuild) into the UKI. Mirror the same guard that `90-loaderentry.install` has: check `systemd-detect-virt --container` before falling back to `/proc/cmdline`, and return an empty cmdline if we are in a container to ensure both modes (`uki` and `bls`) work the same. Signed-off-by: Simon de Vlieger <cmdr@supakeen.com>
This commit is contained in:
committed by
Yu Watanabe
parent
7314e1cf76
commit
bdb5d53d4f
@@ -22,6 +22,7 @@
|
||||
import argparse
|
||||
import os
|
||||
import shlex
|
||||
import subprocess
|
||||
import types
|
||||
from shutil import which
|
||||
from pathlib import Path
|
||||
@@ -195,6 +196,18 @@ def kernel_cmdline_base() -> list[str]:
|
||||
if os.getenv('KERNEL_INSTALL_CONF_ROOT'):
|
||||
return []
|
||||
|
||||
# Don't read /proc/cmdline in containers it belongs to the host and would
|
||||
# leak the host's root= (or a faked value) into the UKI. Mirrors
|
||||
# the same guard in 90-loaderentry.install.
|
||||
try:
|
||||
result = subprocess.run(
|
||||
['systemd-detect-virt', '--container', '--quiet'],
|
||||
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
if result.returncode == 0:
|
||||
return []
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
# If we read /proc/cmdline, we need to do some additional filtering.
|
||||
options = Path('/proc/cmdline').read_text().split()
|
||||
return [opt for opt in options
|
||||
|
||||
@@ -146,7 +146,9 @@ if [ -f "$ukify" ]; then
|
||||
python3 - "$ukify_install" <<'PY'
|
||||
import os
|
||||
import runpy
|
||||
import subprocess
|
||||
import sys
|
||||
import unittest.mock
|
||||
|
||||
ns = runpy.run_path(sys.argv[1], run_name='not_main')
|
||||
|
||||
@@ -171,14 +173,22 @@ class FakePath:
|
||||
module_globals = ns['kernel_cmdline_base'].__globals__
|
||||
module_globals['Path'] = FakePath
|
||||
|
||||
# Mock subprocess.run to simulate not being in a container, so the test
|
||||
# works regardless of the environment (including container-based CI).
|
||||
os.environ.pop('KERNEL_INSTALL_CONF_ROOT', None)
|
||||
assert ns['kernel_cmdline_base']() == ['root=fake', 'quiet']
|
||||
with unittest.mock.patch.object(subprocess, 'run', return_value=subprocess.CompletedProcess([], 1)):
|
||||
assert ns['kernel_cmdline_base']() == ['root=fake', 'quiet']
|
||||
|
||||
os.environ['KERNEL_INSTALL_CONF_ROOT'] = '/conf-root'
|
||||
assert ns['kernel_cmdline_base']() == ['root=conf', 'quiet', 'splash']
|
||||
|
||||
os.environ['KERNEL_INSTALL_CONF_ROOT'] = '/empty-conf-root'
|
||||
assert ns['kernel_cmdline_base']() == []
|
||||
|
||||
# Test that /proc/cmdline is skipped in containers
|
||||
os.environ.pop('KERNEL_INSTALL_CONF_ROOT', None)
|
||||
with unittest.mock.patch.object(subprocess, 'run', return_value=subprocess.CompletedProcess([], 0)):
|
||||
assert ns['kernel_cmdline_base']() == [], 'should return empty in container'
|
||||
PY
|
||||
|
||||
mkdir "$D/sources/install.conf.d"
|
||||
|
||||
Reference in New Issue
Block a user