mirror of
https://github.com/openglow-org/forgefirm.git
synced 2026-10-19 11:01:43 -07:00
forgefirm-image: pack-licenses.sh refuses a license text tar cannot read
pack-licenses.sh packs the image's license tree into one tar.gz and removes the tree. It piped tar into gzip under /bin/sh (dash, no pipefail): the pipeline's status is gzip's, and tar's is lost. The check that follows proves only that the bundle holds license.manifest. So a member tar cannot read leaves a bundle without that text, the build green, and the tree removed, the only copy of the text with it. tar now runs the compressor itself (-I 'gzip -9 -n'), so its exit status covers the read and the write. A failed pack removes the partial bundle and the script refuses, with the tree left for the build log; pack_licenses in forgefirm-image.bb fails do_rootfs on the refusal. The bundle's bytes do not change: tar feeds the same stream to the same gzip, and a tree packed by both forms gives one sha256. Proof: forgetest-ci "Unit tests" (`python -B -m unittest discover -s tests -v` in forgetest), on Ubuntu 24.04 with python 3.12 as an unprivileged user: test_image.py's PackLicensesTests gain test_a_license_text_tar_cannot_read_is_refused_and_the_tree_left (a text under zlib/ with mode 0: a nonzero exit, a message on stderr, no bundle, the manifest left); the class's 5 tests OK. Negative control on a scratch copy: the new case against the script without this change fails at assertRefused with an exit status of 0. At the shell, on a fixture tree with the unreadable member, the script without this change exits 0, leaves the bundle without the text and removes the tree; with it, the script exits 1, leaves no bundle and leaves the tree. On a readable tree both forms write byte-identical bundles (one sha256 for both). pyflakes reports no undefined name. Acceptance: every catalog test. pack-licenses.sh is under meta-forgefirm, whose content hash is part of the platform in every fingerprint, so the image that carries this change needs the whole catalog on the bench.
This commit is contained in:
@@ -316,6 +316,21 @@ class PackLicensesTests(unittest.TestCase):
|
|||||||
self.assertIn("common-licenses/license.manifest", t.getnames())
|
self.assertIn("common-licenses/license.manifest", t.getnames())
|
||||||
self.assertFalse(os.path.exists(self.tree))
|
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):
|
class RootfsLintTests(unittest.TestCase):
|
||||||
"""rootfs-lint.sh, the image's last rootfs step, on a fixture tree: a
|
"""rootfs-lint.sh, the image's last rootfs step, on a fixture tree: a
|
||||||
|
|||||||
@@ -31,8 +31,11 @@ done
|
|||||||
|
|
||||||
base=$(basename "$dir")
|
base=$(basename "$dir")
|
||||||
mkdir -p "$(dirname "$out")" || fail "cannot make the directory of $out"
|
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 \
|
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
|
# the tree goes only once the bundle holds its manifest
|
||||||
tar -tzf "$out" "$base/license.manifest" > /dev/null 2>&1 \
|
tar -tzf "$out" "$base/license.manifest" > /dev/null 2>&1 \
|
||||||
|| fail "$out holds no $base/license.manifest"
|
|| fail "$out holds no $base/license.manifest"
|
||||||
|
|||||||
Reference in New Issue
Block a user