2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-09-04 20:17:55 +00:00

test(subiquity): the resolv.conf sandbox fails open, as root

ubuntu_resolvconf_ip.t sandboxes the fragment by rewriting /etc/resolv.conf to
a path inside a tempdir. The fragment contains `rm -f /etc/resolv.conf` and the
unit suite runs as root in CI, so if that substitution ever stops matching the
test deletes the runner's resolver configuration instead of failing.

It matches today. It is one respelling away from not: writing the path in the
template as `etcdir=/etc; rm -f "$etcdir/resolv.conf"` slips straight past it,
and the existing BAIL_OUT does not catch that -- it guards only the fragment
extraction, not the rewrite.

Check the rewritten script for any /etc path outside the scratch tree and
BAIL_OUT rather than execute it. AGENTS.md asks that a test never escape its
scratch tree and notes that rewriting paths in the source under test is the
fragile way to arrange it; this makes the fragile part fail closed.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
This commit is contained in:
Daniel Hilst
2026-09-01 18:51:05 -03:00
parent 7082fabe0b
commit 1cebb4d9e8
+9
View File
@@ -32,6 +32,15 @@ sub write_resolv_conf {
$script =~ s/\#TABLE:noderes:\$NODE:xcatmaster\#/$opt{xcatmaster}/;
$script =~ s{/etc/resolv\.conf}{$root/resolv.conf}g;
# The fragment contains `rm -f /etc/resolv.conf` and this suite runs as root in CI, so a
# rewrite that stops matching would delete the runner's resolver configuration rather than
# fail a test. Sandboxing by rewriting paths is fragile by nature -- respelling the path in
# the template as, say, `etcdir=/etc; rm -f "$etcdir/resolv.conf"` slips straight past the
# substitution above. Refuse to execute anything that still points outside the scratch tree.
if ($script =~ m{(?<!\Q$root\E)/etc/}) {
BAIL_OUT('the /etc rewrite no longer covers the fragment; refusing to run it as root');
}
# getent is the resolver the fragment uses; make it answer as the test wants.
my $getent = $opt{resolves}
? "getent() { printf '%s\\n' '$opt{resolves} $opt{xcatmaster}'; }\n"