From 63cf9aa92c17025a684a922c3bd18ae3a4007525 Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Wed, 2 Sep 2026 15:16:06 -0400 Subject: [PATCH 1/2] tarfs: keep dir mode bits and ownership from tar headers WriteHeader's TypeDir branch created the directory with hdr.FileInfo().Mode().Perm(), which masks to 0o777 and so dropped setuid/setgid/sticky, and it never applied hdr.Uid/hdr.Gid at all. Every package-owned directory landed as root:root with its special bits gone. The loss is format-neutral, because both writers read the same node: pkg/build/tarball.go builds output headers with tar.FileInfoHeader, which takes the special bits from FileInfo.Mode() and Uid/Gid from FileInfo.Sys(), and pkg/build/erofs.go reads that same Sys() header. Wolfi's postfix is a live example. Its apk ships 15 directories under /var/spool/postfix and /var/lib/postfix owned by uid 100, four of them also gid 100 or 101; an `apko build` of it emitted all 15 as 0:0. MkdirAll carries only permission bits, so the special bits need a separate Chmod. Both the Chmod and the Chown are restricted to directories this header actually created: - Ancestors MkdirAll had to invent are not described by this header, so they must not inherit its ownership. - InitDB creates /tmp as 1777 before any package installs, and packages ship a tmp directory header with no sticky bit (wolfi-baselayout intends 1777 but the apk records 0777), so applying dir modes unconditionally would take the sticky bit off /tmp in every wolfi-based image. Reported by mattmoor in #2418. --- pkg/tarfs/fs.go | 20 ++++++++- pkg/tarfs/fs_test.go | 102 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 1 deletion(-) diff --git a/pkg/tarfs/fs.go b/pkg/tarfs/fs.go index c37756b54..8d9588c4c 100644 --- a/pkg/tarfs/fs.go +++ b/pkg/tarfs/fs.go @@ -116,9 +116,27 @@ func (m *memFS) WriteHeader(hdr tar.Header, tfs fs.FS, pkg *apk.Package) (bool, } } } - if err := m.MkdirAll(hdr.Name, hdr.FileInfo().Mode().Perm()); err != nil { + // Whether the directory is already here decides if we get to set its + // metadata below, so check before MkdirAll makes it exist. + _, statErr := m.getNode(hdr.Name) + created := statErr != nil + + mode := hdr.FileInfo().Mode() + if err := m.MkdirAll(hdr.Name, mode.Perm()); err != nil { return false, fmt.Errorf("error creating directory %s: %w", hdr.Name, err) } + if created { + // MkdirAll carries only permission bits, so setuid/setgid/sticky + // need a separate Chmod. Restrict both of these to directories we + // just created: InitDB creates /tmp as 1777 before any package + // installs, and packages ship a tmp header without the sticky bit. + if err := m.Chmod(hdr.Name, mode&^os.ModeType); err != nil { + return false, fmt.Errorf("error setting mode on directory %s: %w", hdr.Name, err) + } + if err := m.Chown(hdr.Name, hdr.Uid, hdr.Gid); err != nil { + return false, fmt.Errorf("error setting owner on directory %s: %w", hdr.Name, err) + } + } if err := m.Chtimes(hdr.Name, hdr.AccessTime, hdr.ModTime); err != nil { return false, fmt.Errorf("error chtime on directory %s: %w", hdr.Name, err) } diff --git a/pkg/tarfs/fs_test.go b/pkg/tarfs/fs_test.go index 5e3403676..ea6b1ff14 100644 --- a/pkg/tarfs/fs_test.go +++ b/pkg/tarfs/fs_test.go @@ -20,6 +20,7 @@ import ( "crypto/sha1" "encoding/hex" "io/fs" + "path" "path/filepath" "testing" @@ -172,3 +173,104 @@ func TestTarFSCreate(t *testing.T) { require.NoError(t, err) require.Equal(t, fileInfo.Mode(), fs.FileMode(0o644)) } + +// dirReader is implemented by the (unexported) tarfs type returned by New(). +type dirReader interface { + ReadDir(string) ([]fs.DirEntry, error) + Readlink(string) (string, error) +} + +// outHeader returns the tar.Header that pkg/build/tarball.go would write for +// name. It reaches the entry the way that writer does -- a directory walk, +// then tar.FileInfoHeader -- because that is how a node's metadata reaches +// both the tar and the erofs writer. +func outHeader(t *testing.T, tfs dirReader, name string) *tar.Header { + t.Helper() + entries, err := tfs.ReadDir(path.Dir(name)) + require.NoError(t, err) + for _, d := range entries { + if d.Name() != path.Base(name) { + continue + } + info, err := d.Info() + require.NoError(t, err) + var link string + if info.Mode()&fs.ModeSymlink != 0 { + // tarball.go passes the link target for symlinks. + link, err = tfs.Readlink(name) + require.NoError(t, err) + } + hdr, err := tar.FileInfoHeader(info, link) + require.NoError(t, err) + return hdr + } + t.Fatalf("no entry for %q", name) + return nil +} + +// TestWriteHeaderDirMetadata covers a directory header's setuid/setgid/sticky +// bits and ownership, which MkdirAll alone does not carry. +func TestWriteHeaderDirMetadata(t *testing.T) { + tfs := tarfs.New() + pkg := &apk.Package{Name: "postfix", Origin: "postfix"} + + // Mode as apk-tools would record 2755 with the sticky bit also set. + dir := tar.Header{ + Typeflag: tar.TypeDir, + Name: "var/spool/postfix/maildrop", + Mode: 0o2755 | 0o1000, + Uid: 100, + Gid: 101, + } + if _, err := tfs.WriteHeader(dir, tfs, pkg); err != nil { + t.Fatal(err) + } + + fi, err := tfs.Lstat(dir.Name) + require.NoError(t, err) + require.Equal(t, fs.ModeDir|fs.ModeSetgid|fs.ModeSticky|0o755, fi.Mode()) + + hdr := outHeader(t, tfs, dir.Name) + require.Equal(t, dir.Mode, hdr.Mode) + require.Equal(t, 100, hdr.Uid) + require.Equal(t, 101, hdr.Gid) + + // Ancestors MkdirAll had to invent are not owned by the header, so they + // must not pick up its ownership. + for _, ancestor := range []string{"var", "var/spool", "var/spool/postfix"} { + hdr := outHeader(t, tfs, ancestor) + require.Zerof(t, hdr.Uid, "uid of implicit ancestor %q", ancestor) + require.Zerof(t, hdr.Gid, "gid of implicit ancestor %q", ancestor) + } +} + +// TestWriteHeaderDirExisting guards the /tmp case: apk's InitDB creates /tmp +// as 1777 before any package installs, and packages ship a tmp header with no +// sticky bit, so a header for a directory that is already there must not +// downgrade it. +func TestWriteHeaderDirExisting(t *testing.T) { + tfs := tarfs.New() + pkg := &apk.Package{Name: "wolfi-baselayout", Origin: "wolfi-baselayout"} + + require.NoError(t, tfs.Mkdir("tmp", fs.ModeSticky|0o777)) + + dir := tar.Header{ + Typeflag: tar.TypeDir, + Name: "tmp", + Mode: 0o777, + Uid: 100, + Gid: 100, + } + if _, err := tfs.WriteHeader(dir, tfs, pkg); err != nil { + t.Fatal(err) + } + + fi, err := tfs.Lstat("tmp") + require.NoError(t, err) + require.Equal(t, fs.ModeDir|fs.ModeSticky|0o777, fi.Mode()) + + hdr := outHeader(t, tfs, "tmp") + require.Equal(t, int64(0o1777), hdr.Mode) + require.Zero(t, hdr.Uid) + require.Zero(t, hdr.Gid) +} From a45a6a465fec8a1138456bff0b06627deae229a6 Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Wed, 2 Sep 2026 15:19:21 -0400 Subject: [PATCH 2/2] tarfs: keep file and symlink ownership from tar headers The same gap the previous commit fixed for directories applies to everything writeHeader creates: the node was built from the tar header's mode but never its Uid/Gid, so every packaged file and symlink was serialized as root:root. For a setgid binary that is a privilege change, not just cosmetics. Wolfi's postfix ships /usr/bin/postdrop and /usr/bin/postqueue as mode 0o2755 gid 101, i.e. setgid to the unprivileged "postdrop" group. An `apko build` of it emitted mode 0o2755 gid 0 -- setgid to root. The golden fixtures move because of this. The apks under internal/cli/testdata/packages declare their files as uid 501 gid 20, the account on the machine that built them, and apko now reproduces that faithfully; /etc/os-release is the only entry whose metadata changes in either golden image. testdata/golden was rebuilt with the same options TestBuild passes (verified byte-identical to the committed copy when built against the unfixed code), and testdata/top_image with internal/cli/testdata/regenerate_golden_top_image.sh. --- internal/cli/publish_test.go | 4 +- ...457a9651a68c4fb9733d4462ae6288b98011277858 | 1 - ...73f0756da04eccfd12f53e1c5267e3231a4ffbe41} | 2 +- ...6e971100e996fa8bca0fb4482c26911ee00cbfd640 | 1 + ...510e43d476a75b6985cc11e0bae09b7ddcf887c0ec | Bin 0 -> 3077 bytes ...bf1d6870c870c4ec323e39d3a6da59596632d0f2f4 | 1 - ...5f17d03f20ffb776881f1f46258efd9458f7cdaf08 | Bin 3079 -> 0 bytes ...d1ac6dcf7e3a2439732aa5981270b4f3a02454b738 | Bin 3072 -> 0 bytes ...6efcf135aabe7f053efc515434bc65b5d9891fc9c} | 2 +- ...39c5c59a6b651f44fc083ae91b4cca8586b7374e58 | 1 + ...a93714c16e45aa7c806cf4fa3662d4725d18425fad | Bin 0 -> 3085 bytes internal/cli/testdata/golden/index.json | 2 +- .../golden/sboms/sbom-aarch64.spdx.json | 28 +++---- .../golden/sboms/sbom-index.spdx.json | 42 +++++----- .../golden/sboms/sbom-x86_64.spdx.json | 28 +++---- ...e158a2ab71f52ac10a00424d9822adf985ee1cb643 | Bin 0 -> 2961 bytes ...60533dd8de171620c83ed8b917970e95c23fcadb7} | 2 +- ...d75acb8dec66012cf2d044a457f4d4243128a60464 | Bin 0 -> 2952 bytes ...4e0d7cd95e09d575793ff017e2a9fe6f800cb7091} | 2 +- ...f59afc38a82175a70e02a10b26ffe3fcfdf8af2e0} | 2 +- ...6814bdfd629ef6da668805945c414cb074ddb7f0ed | Bin 2955 -> 0 bytes ...706d3d45ccc6ea532cdac5289e84ddfa399d56e97} | 2 +- ...53a7f451c4f6116ec6fac9c22ef41ebaf27704a566 | Bin 2945 -> 0 bytes internal/cli/testdata/top_image/index.json | 2 +- pkg/tarfs/fs.go | 4 + pkg/tarfs/fs_test.go | 79 ++++++++++++++++++ 26 files changed, 144 insertions(+), 61 deletions(-) delete mode 100644 internal/cli/testdata/golden/blobs/sha256/124c885f834cfaf1329987457a9651a68c4fb9733d4462ae6288b98011277858 rename internal/cli/testdata/golden/blobs/sha256/{fbb854f9d5a601a36c4dc8cc82e5b21e91b11cdd4aab5035340e4f517c5a8eb1 => 270f5467dc529c2edaa0d5173f0756da04eccfd12f53e1c5267e3231a4ffbe41} (80%) create mode 100644 internal/cli/testdata/golden/blobs/sha256/32e7835adc3cd8ed7a86746e971100e996fa8bca0fb4482c26911ee00cbfd640 create mode 100644 internal/cli/testdata/golden/blobs/sha256/36f58cd88d06783d4b3adb510e43d476a75b6985cc11e0bae09b7ddcf887c0ec delete mode 100644 internal/cli/testdata/golden/blobs/sha256/69f0237c7f8cf0b8a329d1bf1d6870c870c4ec323e39d3a6da59596632d0f2f4 delete mode 100644 internal/cli/testdata/golden/blobs/sha256/7e0f9d62f6cab4785e18a55f17d03f20ffb776881f1f46258efd9458f7cdaf08 delete mode 100644 internal/cli/testdata/golden/blobs/sha256/c7557730da0e2d7fb242d8d1ac6dcf7e3a2439732aa5981270b4f3a02454b738 rename internal/cli/testdata/golden/blobs/sha256/{6c815259150f37d000417f9a93f41bddf74dff905c745986069d4b03e954ac1d => da5813653efaae5464c67846efcf135aabe7f053efc515434bc65b5d9891fc9c} (80%) create mode 100644 internal/cli/testdata/golden/blobs/sha256/ea8cf97bc59cac73cfb94539c5c59a6b651f44fc083ae91b4cca8586b7374e58 create mode 100644 internal/cli/testdata/golden/blobs/sha256/eb39d585629f6f13753cffa93714c16e45aa7c806cf4fa3662d4725d18425fad create mode 100644 internal/cli/testdata/top_image/blobs/sha256/015f772c76385839f8c653e158a2ab71f52ac10a00424d9822adf985ee1cb643 rename internal/cli/testdata/top_image/blobs/sha256/{9743477d70b66d27d627eb7dc1a548dee98ad742b195e24545b73a1c7113aea8 => 01966bcd4c12b0984abfbab60533dd8de171620c83ed8b917970e95c23fcadb7} (59%) create mode 100644 internal/cli/testdata/top_image/blobs/sha256/3887ee57051bb0dea45b02d75acb8dec66012cf2d044a457f4d4243128a60464 rename internal/cli/testdata/top_image/blobs/sha256/{3c6b4bb5b39be26700e6baff9d83a53bba4a0d994e22638d11a4c104bc9e39c9 => 4b8ece5ce1b8f904e7799114e0d7cd95e09d575793ff017e2a9fe6f800cb7091} (59%) rename internal/cli/testdata/top_image/blobs/sha256/{e83f38a3553148f2189193b4908cce3576907dacddc14617d0e8d22370c80cce => 6f80449398e607e42aae9bef59afc38a82175a70e02a10b26ffe3fcfdf8af2e0} (83%) delete mode 100644 internal/cli/testdata/top_image/blobs/sha256/7bd766d91d366d79c001436814bdfd629ef6da668805945c414cb074ddb7f0ed rename internal/cli/testdata/top_image/blobs/sha256/{52a254489d2b6d123a52b293b7032cca79834ce9f0176151c52754a0c7b1d1ea => b499426d6dc90675e0b6629706d3d45ccc6ea532cdac5289e84ddfa399d56e97} (83%) delete mode 100644 internal/cli/testdata/top_image/blobs/sha256/ff58773a945b386b75663553a7f451c4f6116ec6fac9c22ef41ebaf27704a566 diff --git a/internal/cli/publish_test.go b/internal/cli/publish_test.go index c9b1a0ced..4416100f7 100644 --- a/internal/cli/publish_test.go +++ b/internal/cli/publish_test.go @@ -101,7 +101,7 @@ func TestPublish(t *testing.T) { // This test will fail if we ever make a change in apko that changes the image. // Sometimes, this is intentional, and we need to change this and bump the version. - want := "sha256:1cc2a29f39af74ad432a283ee466dd43130dd9292e49f18baaaa3d890a857347" + want := "sha256:209d938840c9ecea442fc15db054aec5e6677c13393f7389e0069913151536f6" require.Equal(t, want, digest.String()) // Check that the sbomPath is not empty. @@ -177,7 +177,7 @@ func TestPublishLayering(t *testing.T) { // This test will fail if we ever make a change in apko that changes the image. // Sometimes, this is intentional, and we need to change this and bump the version. - want := "sha256:f5dc65ebea1afb5693ec323d6fdfa4b899a0c73af634d776a88bd44852d4216c" + want := "sha256:2c0fb0050fb586711d10d3d0b2b3858e02c45e6c894da5348cf7be87de3a4eb1" require.Equal(t, want, digest.String()) im, err := idx.IndexManifest() diff --git a/internal/cli/testdata/golden/blobs/sha256/124c885f834cfaf1329987457a9651a68c4fb9733d4462ae6288b98011277858 b/internal/cli/testdata/golden/blobs/sha256/124c885f834cfaf1329987457a9651a68c4fb9733d4462ae6288b98011277858 deleted file mode 100644 index 3e131dfbc..000000000 --- a/internal/cli/testdata/golden/blobs/sha256/124c885f834cfaf1329987457a9651a68c4fb9733d4462ae6288b98011277858 +++ /dev/null @@ -1 +0,0 @@ -{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","size":658,"digest":"sha256:fbb854f9d5a601a36c4dc8cc82e5b21e91b11cdd4aab5035340e4f517c5a8eb1"},"layers":[{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","size":3079,"digest":"sha256:7e0f9d62f6cab4785e18a55f17d03f20ffb776881f1f46258efd9458f7cdaf08"}],"annotations":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z","org.opencontainers.image.title":"Title","org.opencontainers.image.vendor":"Vendor"}} \ No newline at end of file diff --git a/internal/cli/testdata/golden/blobs/sha256/fbb854f9d5a601a36c4dc8cc82e5b21e91b11cdd4aab5035340e4f517c5a8eb1 b/internal/cli/testdata/golden/blobs/sha256/270f5467dc529c2edaa0d5173f0756da04eccfd12f53e1c5267e3231a4ffbe41 similarity index 80% rename from internal/cli/testdata/golden/blobs/sha256/fbb854f9d5a601a36c4dc8cc82e5b21e91b11cdd4aab5035340e4f517c5a8eb1 rename to internal/cli/testdata/golden/blobs/sha256/270f5467dc529c2edaa0d5173f0756da04eccfd12f53e1c5267e3231a4ffbe41 index cafd71a39..29a4156c9 100644 --- a/internal/cli/testdata/golden/blobs/sha256/fbb854f9d5a601a36c4dc8cc82e5b21e91b11cdd4aab5035340e4f517c5a8eb1 +++ b/internal/cli/testdata/golden/blobs/sha256/270f5467dc529c2edaa0d5173f0756da04eccfd12f53e1c5267e3231a4ffbe41 @@ -1 +1 @@ -{"architecture":"arm64","author":"github.com/chainguard-dev/apko","created":"1970-01-01T00:00:00Z","history":[{"author":"apko","created":"1970-01-01T00:00:00Z","created_by":"apko","comment":"Title by Vendor"}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:ca5e16c7c944d764863cb1a4286e668e72d6d87ef9ddd82337b19d87715bae7e"]},"config":{"Entrypoint":["/bin/sh","-l"],"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin","SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt"],"Labels":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z","org.opencontainers.image.title":"Title","org.opencontainers.image.vendor":"Vendor"}}} \ No newline at end of file +{"architecture":"arm64","author":"github.com/chainguard-dev/apko","created":"1970-01-01T00:00:00Z","history":[{"author":"apko","created":"1970-01-01T00:00:00Z","created_by":"apko","comment":"Title by Vendor"}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:c11431cd0f01e2f3046c0e43371e8c9abd2dcb2be0152e28484c1af133834bd3"]},"config":{"Entrypoint":["/bin/sh","-l"],"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin","SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt"],"Labels":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z","org.opencontainers.image.title":"Title","org.opencontainers.image.vendor":"Vendor"}}} \ No newline at end of file diff --git a/internal/cli/testdata/golden/blobs/sha256/32e7835adc3cd8ed7a86746e971100e996fa8bca0fb4482c26911ee00cbfd640 b/internal/cli/testdata/golden/blobs/sha256/32e7835adc3cd8ed7a86746e971100e996fa8bca0fb4482c26911ee00cbfd640 new file mode 100644 index 000000000..adb8921ca --- /dev/null +++ b/internal/cli/testdata/golden/blobs/sha256/32e7835adc3cd8ed7a86746e971100e996fa8bca0fb4482c26911ee00cbfd640 @@ -0,0 +1 @@ +{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","size":658,"digest":"sha256:270f5467dc529c2edaa0d5173f0756da04eccfd12f53e1c5267e3231a4ffbe41"},"layers":[{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","size":3085,"digest":"sha256:eb39d585629f6f13753cffa93714c16e45aa7c806cf4fa3662d4725d18425fad"}],"annotations":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z","org.opencontainers.image.title":"Title","org.opencontainers.image.vendor":"Vendor"}} \ No newline at end of file diff --git a/internal/cli/testdata/golden/blobs/sha256/36f58cd88d06783d4b3adb510e43d476a75b6985cc11e0bae09b7ddcf887c0ec b/internal/cli/testdata/golden/blobs/sha256/36f58cd88d06783d4b3adb510e43d476a75b6985cc11e0bae09b7ddcf887c0ec new file mode 100644 index 0000000000000000000000000000000000000000..e4739d60cdde69bce85cb7be7a8549578eeaa29d GIT binary patch literal 3077 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 T{|^8F|NjF3L(~ur0Du4hSs_HK literal 0 HcmV?d00001 diff --git a/internal/cli/testdata/golden/blobs/sha256/69f0237c7f8cf0b8a329d1bf1d6870c870c4ec323e39d3a6da59596632d0f2f4 b/internal/cli/testdata/golden/blobs/sha256/69f0237c7f8cf0b8a329d1bf1d6870c870c4ec323e39d3a6da59596632d0f2f4 deleted file mode 100644 index b08eaa114..000000000 --- a/internal/cli/testdata/golden/blobs/sha256/69f0237c7f8cf0b8a329d1bf1d6870c870c4ec323e39d3a6da59596632d0f2f4 +++ /dev/null @@ -1 +0,0 @@ -{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","size":658,"digest":"sha256:6c815259150f37d000417f9a93f41bddf74dff905c745986069d4b03e954ac1d"},"layers":[{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","size":3072,"digest":"sha256:c7557730da0e2d7fb242d8d1ac6dcf7e3a2439732aa5981270b4f3a02454b738"}],"annotations":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z","org.opencontainers.image.title":"Title","org.opencontainers.image.vendor":"Vendor"}} \ No newline at end of file diff --git a/internal/cli/testdata/golden/blobs/sha256/7e0f9d62f6cab4785e18a55f17d03f20ffb776881f1f46258efd9458f7cdaf08 b/internal/cli/testdata/golden/blobs/sha256/7e0f9d62f6cab4785e18a55f17d03f20ffb776881f1f46258efd9458f7cdaf08 deleted file mode 100644 index 493f79b37b3f2ef84ac0f99dcd6d03adb7aa6d5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3079 zcmV+i4EXaOiwFP!32ul0|Lk0AbE3?bpVxc}i> z5oyw3yiCn^-@nMT>e)|&TbC;-U#`3$BwgIc5H+aktAuC_n+_&Ba&u83G}Ad(8tl`68XkTR~;6knEFIBawsa8e}k84&@Q?0x@&S&BEqj!Okd|h#GrUQ@j zsA=;0>b_SS%xgfK)w|_N*|@$pWvOkz+T^Cv>O2(mOrhN3#xggm`T1K#GtI@pg<;# zuKPgxl+PDXmYLX@3ubb~`g6G^OsZELZ{AP6Y9r^D^{h6#8@Ot*U$L0+!|0Onr};^> zBwWJWUD=`l#&U7WU)~1~55-m|GrsI;IlndS@LB_SBmSmf-ey~s{{3y~w(oIJs^_{x zwt%}%GTCll7pbId&&#(2OH->WS8J{0rI2B|mF~3381{7*F<`>*Lhl9K8=EI;m zEOdl6>1xG`>#itLxA$HS$w_xKxrGm%nd)dw$;&-lqi(zHbz7eMDD<+uo*!f@LATcE zW^Mqe8lvX&Me`bUB&ziAc&%PdDy_S@{g`FjEzbsna-Wm+WVr-yr^)-u%}Bf#08HM^ z{7FfzH%oeQ%$KJ9nsaSJ${BdDK1pi0%#V%REHT^yys+@()^KvF`q-%G_j0~axe@(g zl5h6BQL&gClANqLfRvlWq*&9Q=I-ulb2ZZrCIeJyjXFs^2?#r^myJr-xX9S;qK|KM z4~_}YF0{!6a5t@MuUar{I0u?K$*XGp{G3XqQmItF zl6zqUU;c2cp8o`S*tY{rY;^Q-z?&vPL5|B?9rG!q~{Fkt{04;n*gAwP}< z{-Ri5W&aaQ9CNGun0V9vMR~{mSqaFo{YPQ{9zg+e%~TKi$bmCF4$j#$NP`ps6hYo@ z(bkzU{sb)TAE)nq>~57G6QMl_Ke2z2U8T)e@gFMz5Ziwg_WzwWup1yZ@M+~cy*&z~ zm4E0xqXYWu89hWZV!PH(jh(j#Va4@H%0Ki^JPmzDzw|Zq*B@szasx8+ug^dJa4Utt(Dg(J^FX#=tP`3al;-CA9U;E#VklO!ul%F37DY-| zcs>i(vK~v^1O_*Dqgl5)fvS%?<1WrsVW%prWZh6Uc|-~-B48B`D52pmu677pZTEuGisu|_S-s8?=qY5P4~x@lLfN=F*r%!>JQD$Yl( z^HDqg-@(T5*8+zAPy*nEi(Kw+KNFVzp9^0X#r{76|G&e(ZxGuH{B-zCJR073{&O$+ z7g#pV|3{Mlj}arr--{jp9}wHJ5IOD=kT?84csP!e>6oW$ps$%{)gk@ z@Bc;f{lCX!4)l)2KagcsiusR-f5w2u;B;Sq{D}PnS&F~^6Up~~*8HC^19Uk5tjNdy zKPvyfq8EJ_jyx`nZ$B$n%s6aVuF z7AboUa1!7+ffaznvMJE-@mx>LKuOI0@3OT-g02z^y7qk0DdNc6BRf@z6Xs( zjn#t5P;6;Tti^_j4WBXAeOWE7W_rC$ADS5xWO|~&%cg+1tSE6=i8o}E7ue_5$)PZv z*Fzgwt@*7zEzC~6#VEDB`>mDSOR;}n3Gk)zR6RssV7pdx<_BoBk@ZTCmh%}l2l}>y zeAR`{Y`#!~K6HGvKDv~aTx@u$MVSgdQ zYAxSTTYBXx)$BG~`EtnAQU`y^&3lP|!P!f@-_&`0vWBHm(`)UCfZwv-`i&ugP;fQSp72I_CDZ=2;1G(mktkZT|f2FSu>7PePYwW4~J zPnFe*dX;a`XM4|BNGtrBL4x*%mIA#Yvoz2>qk;dd$o;=?BGdVDI@2pHw`Sgx?u>~; zuWS5RZhbvaWy??geUI9vm;Nz5gCi&P-Z@Y2(eY<3zpC(uUomQj_uKk0z0z!{rP9Br z?v@=4#yw{F82)eWa;f|Kw*K>8qW|j+9i`9q+U~pTW&KDd$XU27e_(rip3C7lBJV6_ z7V73NJp#5bwCZ9m-_#oVMLzfKqPrn)Q4^WX&7~tT%JT-lH1?lt6F{dh2jA2&ko?;P@v~Miau^zcW<4YIeoacUnFsq7D1F2BSwrE V$H)Hz009600|4A7vvB}`003iqJ^lay diff --git a/internal/cli/testdata/golden/blobs/sha256/c7557730da0e2d7fb242d8d1ac6dcf7e3a2439732aa5981270b4f3a02454b738 b/internal/cli/testdata/golden/blobs/sha256/c7557730da0e2d7fb242d8d1ac6dcf7e3a2439732aa5981270b4f3a02454b738 deleted file mode 100644 index 4d94d7bbbc7fede26ee04f6c285aae026ea7044e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3072 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 O{{sN3`!%EhfB*pY@mGuh diff --git a/internal/cli/testdata/golden/blobs/sha256/6c815259150f37d000417f9a93f41bddf74dff905c745986069d4b03e954ac1d b/internal/cli/testdata/golden/blobs/sha256/da5813653efaae5464c67846efcf135aabe7f053efc515434bc65b5d9891fc9c similarity index 80% rename from internal/cli/testdata/golden/blobs/sha256/6c815259150f37d000417f9a93f41bddf74dff905c745986069d4b03e954ac1d rename to internal/cli/testdata/golden/blobs/sha256/da5813653efaae5464c67846efcf135aabe7f053efc515434bc65b5d9891fc9c index e850efd3a..ef0cc67e0 100644 --- a/internal/cli/testdata/golden/blobs/sha256/6c815259150f37d000417f9a93f41bddf74dff905c745986069d4b03e954ac1d +++ b/internal/cli/testdata/golden/blobs/sha256/da5813653efaae5464c67846efcf135aabe7f053efc515434bc65b5d9891fc9c @@ -1 +1 @@ -{"architecture":"amd64","author":"github.com/chainguard-dev/apko","created":"1970-01-01T00:00:00Z","history":[{"author":"apko","created":"1970-01-01T00:00:00Z","created_by":"apko","comment":"Title by Vendor"}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:20f698463c2755b6dc42b7d07e959ed7455a06e7367d507e829a315898f21a01"]},"config":{"Entrypoint":["/bin/sh","-l"],"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin","SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt"],"Labels":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z","org.opencontainers.image.title":"Title","org.opencontainers.image.vendor":"Vendor"}}} \ No newline at end of file +{"architecture":"amd64","author":"github.com/chainguard-dev/apko","created":"1970-01-01T00:00:00Z","history":[{"author":"apko","created":"1970-01-01T00:00:00Z","created_by":"apko","comment":"Title by Vendor"}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:b1499bfee6eb2f1f4ace628e58ee5dc91d9de4b1fb0e175266b4473e04030c93"]},"config":{"Entrypoint":["/bin/sh","-l"],"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin","SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt"],"Labels":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z","org.opencontainers.image.title":"Title","org.opencontainers.image.vendor":"Vendor"}}} \ No newline at end of file diff --git a/internal/cli/testdata/golden/blobs/sha256/ea8cf97bc59cac73cfb94539c5c59a6b651f44fc083ae91b4cca8586b7374e58 b/internal/cli/testdata/golden/blobs/sha256/ea8cf97bc59cac73cfb94539c5c59a6b651f44fc083ae91b4cca8586b7374e58 new file mode 100644 index 000000000..a866838c9 --- /dev/null +++ b/internal/cli/testdata/golden/blobs/sha256/ea8cf97bc59cac73cfb94539c5c59a6b651f44fc083ae91b4cca8586b7374e58 @@ -0,0 +1 @@ +{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","size":658,"digest":"sha256:da5813653efaae5464c67846efcf135aabe7f053efc515434bc65b5d9891fc9c"},"layers":[{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","size":3077,"digest":"sha256:36f58cd88d06783d4b3adb510e43d476a75b6985cc11e0bae09b7ddcf887c0ec"}],"annotations":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z","org.opencontainers.image.title":"Title","org.opencontainers.image.vendor":"Vendor"}} \ No newline at end of file diff --git a/internal/cli/testdata/golden/blobs/sha256/eb39d585629f6f13753cffa93714c16e45aa7c806cf4fa3662d4725d18425fad b/internal/cli/testdata/golden/blobs/sha256/eb39d585629f6f13753cffa93714c16e45aa7c806cf4fa3662d4725d18425fad new file mode 100644 index 0000000000000000000000000000000000000000..84d76035a9950e5df5cabf7fd67a494a2325463e GIT binary patch literal 3085 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 blolgKj2MT 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 literal 0 HcmV?d00001 diff --git a/internal/cli/testdata/top_image/blobs/sha256/3c6b4bb5b39be26700e6baff9d83a53bba4a0d994e22638d11a4c104bc9e39c9 b/internal/cli/testdata/top_image/blobs/sha256/4b8ece5ce1b8f904e7799114e0d7cd95e09d575793ff017e2a9fe6f800cb7091 similarity index 59% rename from internal/cli/testdata/top_image/blobs/sha256/3c6b4bb5b39be26700e6baff9d83a53bba4a0d994e22638d11a4c104bc9e39c9 rename to internal/cli/testdata/top_image/blobs/sha256/4b8ece5ce1b8f904e7799114e0d7cd95e09d575793ff017e2a9fe6f800cb7091 index 0ede92a2a..d1fbf3361 100644 --- a/internal/cli/testdata/top_image/blobs/sha256/3c6b4bb5b39be26700e6baff9d83a53bba4a0d994e22638d11a4c104bc9e39c9 +++ b/internal/cli/testdata/top_image/blobs/sha256/4b8ece5ce1b8f904e7799114e0d7cd95e09d575793ff017e2a9fe6f800cb7091 @@ -1 +1 @@ -{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","size":785,"digest":"sha256:e83f38a3553148f2189193b4908cce3576907dacddc14617d0e8d22370c80cce"},"layers":[{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","size":4126,"digest":"sha256:bf74ddaf55d32ec9672a0a40efc6cb1bf0a167763c18fc22586c8a301167822f"},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","size":2955,"digest":"sha256:7bd766d91d366d79c001436814bdfd629ef6da668805945c414cb074ddb7f0ed"}],"annotations":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}} \ No newline at end of file +{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","size":785,"digest":"sha256:6f80449398e607e42aae9bef59afc38a82175a70e02a10b26ffe3fcfdf8af2e0"},"layers":[{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","size":4126,"digest":"sha256:bf74ddaf55d32ec9672a0a40efc6cb1bf0a167763c18fc22586c8a301167822f"},{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","size":2961,"digest":"sha256:015f772c76385839f8c653e158a2ab71f52ac10a00424d9822adf985ee1cb643"}],"annotations":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}} \ No newline at end of file diff --git a/internal/cli/testdata/top_image/blobs/sha256/e83f38a3553148f2189193b4908cce3576907dacddc14617d0e8d22370c80cce b/internal/cli/testdata/top_image/blobs/sha256/6f80449398e607e42aae9bef59afc38a82175a70e02a10b26ffe3fcfdf8af2e0 similarity index 83% rename from internal/cli/testdata/top_image/blobs/sha256/e83f38a3553148f2189193b4908cce3576907dacddc14617d0e8d22370c80cce rename to internal/cli/testdata/top_image/blobs/sha256/6f80449398e607e42aae9bef59afc38a82175a70e02a10b26ffe3fcfdf8af2e0 index 10db8f89b..71f5091d8 100644 --- a/internal/cli/testdata/top_image/blobs/sha256/e83f38a3553148f2189193b4908cce3576907dacddc14617d0e8d22370c80cce +++ b/internal/cli/testdata/top_image/blobs/sha256/6f80449398e607e42aae9bef59afc38a82175a70e02a10b26ffe3fcfdf8af2e0 @@ -1 +1 @@ -{"architecture":"amd64","author":"github.com/chainguard-dev/apko","created":"1970-01-01T00:00:00Z","history":[{"author":"apko","created":"1970-01-01T00:00:00Z","created_by":"apko","comment":"This is an apko single-layer image"},{"author":"apko","created":"1970-01-01T00:00:00Z","created_by":"apko","comment":"This is an apko single-layer image"}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:783b8b05724ae7998917558527ef930f1442af2f071850913fc406992e44606c","sha256:79551ed211a0ca334ac3206473ff5f46a095fb4baf5ee4d13b804d8acca517bf"]},"config":{"Entrypoint":["/bin/sh","-l"],"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin","SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt"],"Labels":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}}} \ No newline at end of file +{"architecture":"amd64","author":"github.com/chainguard-dev/apko","created":"1970-01-01T00:00:00Z","history":[{"author":"apko","created":"1970-01-01T00:00:00Z","created_by":"apko","comment":"This is an apko single-layer image"},{"author":"apko","created":"1970-01-01T00:00:00Z","created_by":"apko","comment":"This is an apko single-layer image"}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:783b8b05724ae7998917558527ef930f1442af2f071850913fc406992e44606c","sha256:959a9d8c7ff73885cc696d9364b69c11fa555d3d6309937fc407c86461b0dbc5"]},"config":{"Entrypoint":["/bin/sh","-l"],"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin","SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt"],"Labels":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}}} \ No newline at end of file diff --git a/internal/cli/testdata/top_image/blobs/sha256/7bd766d91d366d79c001436814bdfd629ef6da668805945c414cb074ddb7f0ed b/internal/cli/testdata/top_image/blobs/sha256/7bd766d91d366d79c001436814bdfd629ef6da668805945c414cb074ddb7f0ed deleted file mode 100644 index 0e8b2d71b47569d65b6863d8ca943b2a7f061f58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2955 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 B1@iy^ diff --git a/internal/cli/testdata/top_image/blobs/sha256/52a254489d2b6d123a52b293b7032cca79834ce9f0176151c52754a0c7b1d1ea b/internal/cli/testdata/top_image/blobs/sha256/b499426d6dc90675e0b6629706d3d45ccc6ea532cdac5289e84ddfa399d56e97 similarity index 83% rename from internal/cli/testdata/top_image/blobs/sha256/52a254489d2b6d123a52b293b7032cca79834ce9f0176151c52754a0c7b1d1ea rename to internal/cli/testdata/top_image/blobs/sha256/b499426d6dc90675e0b6629706d3d45ccc6ea532cdac5289e84ddfa399d56e97 index edcba1609..9b66b47be 100644 --- a/internal/cli/testdata/top_image/blobs/sha256/52a254489d2b6d123a52b293b7032cca79834ce9f0176151c52754a0c7b1d1ea +++ b/internal/cli/testdata/top_image/blobs/sha256/b499426d6dc90675e0b6629706d3d45ccc6ea532cdac5289e84ddfa399d56e97 @@ -1 +1 @@ -{"architecture":"arm64","author":"github.com/chainguard-dev/apko","created":"1970-01-01T00:00:00Z","history":[{"author":"apko","created":"1970-01-01T00:00:00Z","created_by":"apko","comment":"This is an apko single-layer image"},{"author":"apko","created":"1970-01-01T00:00:00Z","created_by":"apko","comment":"This is an apko single-layer image"}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:2888aac57b90cf66093aa48092bf1f1f1b1bdb85bde8601a5f8cf0f06c814763","sha256:833080c5930b626e29628105bd42d7390dfdbc753f761d111d3ac92256bae9c3"]},"config":{"Entrypoint":["/bin/sh","-l"],"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin","SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt"],"Labels":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}}} \ No newline at end of file +{"architecture":"arm64","author":"github.com/chainguard-dev/apko","created":"1970-01-01T00:00:00Z","history":[{"author":"apko","created":"1970-01-01T00:00:00Z","created_by":"apko","comment":"This is an apko single-layer image"},{"author":"apko","created":"1970-01-01T00:00:00Z","created_by":"apko","comment":"This is an apko single-layer image"}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:2888aac57b90cf66093aa48092bf1f1f1b1bdb85bde8601a5f8cf0f06c814763","sha256:9b9e0d55d57bb37665ec46a2f4ed9e69dce98919466c4433dbd0a0e9b0eb8262"]},"config":{"Entrypoint":["/bin/sh","-l"],"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin","SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt"],"Labels":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}}} \ No newline at end of file diff --git a/internal/cli/testdata/top_image/blobs/sha256/ff58773a945b386b75663553a7f451c4f6116ec6fac9c22ef41ebaf27704a566 b/internal/cli/testdata/top_image/blobs/sha256/ff58773a945b386b75663553a7f451c4f6116ec6fac9c22ef41ebaf27704a566 deleted file mode 100644 index c8ca33564f6d37a8b219c4df8271bae0841907c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2945 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 diff --git a/internal/cli/testdata/top_image/index.json b/internal/cli/testdata/top_image/index.json index c9f45c7f5..5e76fa5ac 100755 --- a/internal/cli/testdata/top_image/index.json +++ b/internal/cli/testdata/top_image/index.json @@ -1 +1 @@ -{"schemaVersion":2,"mediaType":"application/vnd.oci.image.index.v1+json","manifests":[{"mediaType":"application/vnd.oci.image.manifest.v1+json","size":631,"digest":"sha256:3c6b4bb5b39be26700e6baff9d83a53bba4a0d994e22638d11a4c104bc9e39c9","platform":{"architecture":"amd64","os":"linux"},"artifactType":"application/vnd.oci.image.config.v1+json"},{"mediaType":"application/vnd.oci.image.manifest.v1+json","size":631,"digest":"sha256:9743477d70b66d27d627eb7dc1a548dee98ad742b195e24545b73a1c7113aea8","platform":{"architecture":"arm64","os":"linux"},"artifactType":"application/vnd.oci.image.config.v1+json"}],"annotations":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}} \ No newline at end of file +{"schemaVersion":2,"mediaType":"application/vnd.oci.image.index.v1+json","manifests":[{"mediaType":"application/vnd.oci.image.manifest.v1+json","size":631,"digest":"sha256:4b8ece5ce1b8f904e7799114e0d7cd95e09d575793ff017e2a9fe6f800cb7091","platform":{"architecture":"amd64","os":"linux"},"artifactType":"application/vnd.oci.image.config.v1+json"},{"mediaType":"application/vnd.oci.image.manifest.v1+json","size":631,"digest":"sha256:01966bcd4c12b0984abfbab60533dd8de171620c83ed8b917970e95c23fcadb7","platform":{"architecture":"arm64","os":"linux"},"artifactType":"application/vnd.oci.image.config.v1+json"}],"annotations":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}} \ No newline at end of file diff --git a/pkg/tarfs/fs.go b/pkg/tarfs/fs.go index 8d9588c4c..b27afdf94 100644 --- a/pkg/tarfs/fs.go +++ b/pkg/tarfs/fs.go @@ -474,6 +474,8 @@ func (m *memFS) writeHeader(name string, te tarEntry) (bool, error) { anode := &node{ name: base, mode: te.header.FileInfo().Mode(), + uid: te.header.Uid, + gid: te.header.Gid, dir: false, modTime: te.header.ModTime, linkTarget: te.header.Linkname, @@ -536,6 +538,8 @@ func (m *memFS) writeHeader(name string, te tarEntry) (bool, error) { anode := &node{ name: base, mode: te.header.FileInfo().Mode(), + uid: te.header.Uid, + gid: te.header.Gid, dir: false, modTime: te.header.ModTime, linkTarget: te.header.Linkname, diff --git a/pkg/tarfs/fs_test.go b/pkg/tarfs/fs_test.go index ea6b1ff14..b31eaf9fb 100644 --- a/pkg/tarfs/fs_test.go +++ b/pkg/tarfs/fs_test.go @@ -208,6 +208,23 @@ func outHeader(t *testing.T, tfs dirReader, name string) *tar.Header { return nil } +// regHeader builds a TypeReg header for body, including the checksum PAX +// record that WriteHeader requires. +func regHeader(name string, mode int64, uid, gid int, body []byte) tar.Header { + sum := sha1.Sum(body) //nolint:gosec // this is what apk tools is using + return tar.Header{ + Typeflag: tar.TypeReg, + Name: name, + Mode: mode, + Uid: uid, + Gid: gid, + Size: int64(len(body)), + PAXRecords: map[string]string{ + "APK-TOOLS.checksum.SHA1": hex.EncodeToString(sum[:]), + }, + } +} + // TestWriteHeaderDirMetadata covers a directory header's setuid/setgid/sticky // bits and ownership, which MkdirAll alone does not carry. func TestWriteHeaderDirMetadata(t *testing.T) { @@ -274,3 +291,65 @@ func TestWriteHeaderDirExisting(t *testing.T) { require.Zero(t, hdr.Uid) require.Zero(t, hdr.Gid) } + +// TestWriteHeaderFileOwnership covers ownership of regular files and symlinks. +// A setgid binary is the case that matters most: dropping its gid makes it +// setgid to root rather than to an unprivileged group. +func TestWriteHeaderFileOwnership(t *testing.T) { + tfs := tarfs.New() + pkg := &apk.Package{Name: "postfix", Origin: "postfix"} + + require.NoError(t, tfs.MkdirAll("usr/bin", 0o755)) + + // setgid to gid 101 (postfix's "postdrop" group), not to root. + reg := regHeader("usr/bin/postdrop", 0o2755, 0, 101, []byte("ELF")) + if _, err := tfs.WriteHeader(reg, tfs, pkg); err != nil { + t.Fatal(err) + } + + hdr := outHeader(t, tfs, reg.Name) + require.Equal(t, int64(0o2755), hdr.Mode) + require.Zero(t, hdr.Uid) + require.Equal(t, 101, hdr.Gid) + + link := tar.Header{ + Typeflag: tar.TypeSymlink, + Name: "usr/bin/sendmail", + Linkname: "postdrop", + Mode: 0o777, + Uid: 100, + Gid: 101, + } + linkDigest := sha1.Sum([]byte(link.Linkname)) //nolint:gosec + link.PAXRecords = map[string]string{ + "APK-TOOLS.checksum.SHA1": hex.EncodeToString(linkDigest[:]), + } + if _, err := tfs.WriteHeader(link, tfs, pkg); err != nil { + t.Fatal(err) + } + + hdr = outHeader(t, tfs, link.Name) + require.Equal(t, 100, hdr.Uid) + require.Equal(t, 101, hdr.Gid) +} + +// TestWriteHeaderFileOwnershipReplaced checks that a file installed over +// another package's copy also gets its own ownership. +func TestWriteHeaderFileOwnershipReplaced(t *testing.T) { + tfs := tarfs.New() + first := &apk.Package{Name: "first", Origin: "shared"} + second := &apk.Package{Name: "second", Origin: "shared"} + + require.NoError(t, tfs.MkdirAll("etc", 0o755)) + + if _, err := tfs.WriteHeader(regHeader("etc/conf", 0o644, 1, 1, []byte("a")), tfs, first); err != nil { + t.Fatal(err) + } + if _, err := tfs.WriteHeader(regHeader("etc/conf", 0o644, 100, 101, []byte("b")), tfs, second); err != nil { + t.Fatal(err) + } + + hdr := outHeader(t, tfs, "etc/conf") + require.Equal(t, 100, hdr.Uid) + require.Equal(t, 101, hdr.Gid) +}