2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-10-21 07:08:12 +00:00

Merge pull request #7938 from VersatusHPC/fix/packimage-image-dir-glob

fix(packimage): refuse an image directory that the shell would split
This commit is contained in:
Daniel Hilst
2026-10-14 11:46:58 -03:00
committed by GitHub
2 changed files with 31 additions and 3 deletions
@@ -196,6 +196,13 @@ sub process_request {
}
$rootimg_dir = "$destdir/rootimg";
# packimage passes the image directory through the shell, which splits a path at a space and expands other
# characters, so a command such as rm -rf would act on another path.
if ($destdir =~ /[\s'"`\$;&|<>()\\*?\[\]{}]/x) {
$callback->({ error => ["Cannot pack the image in $destdir: its path has a space or a shell character"], errorcode => [1] });
return 1;
}
my $is_openeuler = $osver =~ /^openeuler/;
if ($is_openeuler) {
unless (defined(xCAT::Utils::normalize_openeuler_version(substr($osver, 9)))
+24 -3
View File
@@ -60,11 +60,12 @@ our @LITEFILES;
my ($unsquashfs, $mksquashfs) = (tool('unsquashfs'), tool('mksquashfs'));
my $sequence = 0;
# The wrapper records what nodes would download while the pack runs, then runs or fails the real tool.
# The wrapper records what nodes would download while the pack runs, then runs or fails the real tool. $parent
# is the directory of the image directory.
sub image {
my ($method, $compress, $wrapped, $mode) = @_;
my ($method, $compress, $wrapped, $mode, $parent) = @_;
my $name = 'atomic-' . ++$sequence;
my $dest = "$fixture/images/$name";
my $dest = ($parent // "$fixture/images") . "/$name";
my $root = "$dest/rootimg";
make_path("$root/etc", "$root/opt/xcat", "$root/usr/bin", "$root/usr/lib/dracut/modules.d/97xcat", "$dest/bin");
write_text("$root/etc/shadow", "root:*:1:0:99999:7:::\n");
@@ -364,4 +365,24 @@ SCRIPT
is_deeply([ glob("$dest/.packimage-$host+*") ], [], "$label: no temporary file is left");
}
for my $kind (qw(directory file)) {
# The shell splits an image directory with a space, and the first word of its path names another path.
my $word = "$fixture/word-$kind";
if ($kind eq 'directory') {
make_path("$word/keep");
} else {
write_text($word, "file that the first word of the image directory names\n");
}
my ($name, $dest, $archive) = image('cpio', 'gzip', 'gzip', 'pass', "$word images");
make_path("$dest/rootimg/xcatpost");
write_text("$dest/rootimg/xcatpost/previous", "postscript of the previous pack\n");
my ($result, $errors) = packimage($dest, '-m', 'cpio', '-c', 'gzip', $name);
my $label = "image directory with a space after the path of a $kind";
like($errors, qr/Cannot pack the image in \Q$dest\E: its path has a space or a shell character/, "$label: the pack is refused");
ok($kind eq 'directory' ? -d "$word/keep" : -f $word, "$label: the $kind that the first word of the path names stays");
is(content($archive), "previous archive\n", "$label: the previous archive stays");
is(content("$dest/rootimg.previous"), "previous format\n", "$label: other formats stay");
is(content("$dest/rootimg/xcatpost/previous"), "postscript of the previous pack\n", "$label: the image stays as it was");
}
done_testing();