diff --git a/forgetest/tests/test_image.py b/forgetest/tests/test_image.py index 3a89d42..100b42e 100644 --- a/forgetest/tests/test_image.py +++ b/forgetest/tests/test_image.py @@ -316,6 +316,21 @@ class PackLicensesTests(unittest.TestCase): self.assertIn("common-licenses/license.manifest", t.getnames()) self.assertFalse(os.path.exists(self.tree)) + def test_a_license_text_tar_cannot_read_is_refused_and_the_tree_left(self): + """A member tar cannot read fails the pack, bundle removed and tree + left: the manifest check alone passes a bundle truncated after it.""" + if os.geteuid() == 0: + self.skipTest("root reads every file") + self.make_tree(self.RECIPES) + d = os.path.join(self.tree, "zlib") # sorts after license.manifest + os.makedirs(d) + locked = os.path.join(d, "generic_Zlib") + with open(locked, "w") as f: + f.write("zlib license\n") + os.chmod(locked, 0) # rmtree still unlinks it + self.assertRefused(self.pack()) + self.assertTrue(os.path.isfile(self.manifest)) + class RootfsLintTests(unittest.TestCase): """rootfs-lint.sh, the image's last rootfs step, on a fixture tree: a diff --git a/meta-forgefirm/recipes-forgefirm/images/pack-licenses.sh b/meta-forgefirm/recipes-forgefirm/images/pack-licenses.sh index e9acf4b..782c015 100755 --- a/meta-forgefirm/recipes-forgefirm/images/pack-licenses.sh +++ b/meta-forgefirm/recipes-forgefirm/images/pack-licenses.sh @@ -31,8 +31,11 @@ done base=$(basename "$dir") mkdir -p "$(dirname "$out")" || fail "cannot make the directory of $out" +# tar runs the compressor itself, so its exit status covers both: a +# member it cannot read fails the pack, and a failed pack leaves no bundle. tar -C "$(dirname "$dir")" --sort=name --mtime=@0 --owner=0 --group=0 \ - --numeric-owner -cf - "$base" | gzip -9 -n > "$out" || fail "cannot write $out" + --numeric-owner -I 'gzip -9 -n' -cf "$out" "$base" \ + || { rm -f "$out"; fail "cannot pack $dir into $out"; } # the tree goes only once the bundle holds its manifest tar -tzf "$out" "$base/license.manifest" > /dev/null 2>&1 \ || fail "$out holds no $base/license.manifest"