Skip to content

Commit

Permalink
Merge pull request #2197 from aaronlehmann/hash-empty
Browse files Browse the repository at this point in the history
Avoid nil pointer dereference when copying from image with no layers
  • Loading branch information
tonistiigi committed Jun 28, 2021
2 parents 103ad93 + a018bf5 commit 6eab36d
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
6 changes: 6 additions & 0 deletions cache/contenthash/checksum.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ type cacheManager struct {
}

func (cm *cacheManager) Checksum(ctx context.Context, ref cache.ImmutableRef, p string, opts ChecksumOpts, s session.Group) (digest.Digest, error) {
if ref == nil {
if p == "/" {
return digest.FromBytes(nil), nil
}
return "", errors.Errorf("%s: no such file or directory", p)
}
cc, err := cm.GetCacheContext(ctx, ensureOriginMetadata(ref.Metadata()), ref.IdentityMapping())
if err != nil {
return "", nil
Expand Down
40 changes: 39 additions & 1 deletion client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ type nopWriteCloser struct {
func (nopWriteCloser) Close() error { return nil }

func TestIntegration(t *testing.T) {
mirrors := integration.WithMirroredImages(integration.OfficialImages("busybox:latest", "alpine:latest"))
mirroredImages := integration.OfficialImages("busybox:latest", "alpine:latest")
mirroredImages["tonistiigi/test:nolayers"] = "docker.io/tonistiigi/test:nolayers"
mirrors := integration.WithMirroredImages(mirroredImages)

integration.Run(t, []integration.Test{
testCacheExportCacheKeyLoop,
Expand All @@ -93,6 +95,7 @@ func TestIntegration(t *testing.T) {
testBasicRegistryCacheImportExport,
testBasicLocalCacheImportExport,
testCachedMounts,
testCopyFromEmptyImage,
testProxyEnv,
testLocalSymlinkEscape,
testTmpfsMounts,
Expand Down Expand Up @@ -2944,6 +2947,41 @@ func testCacheMountNoCache(t *testing.T, sb integration.Sandbox) {
require.NoError(t, err)
}

func testCopyFromEmptyImage(t *testing.T, sb integration.Sandbox) {
requiresLinux(t)
c, err := New(sb.Context(), sb.Address())
require.NoError(t, err)
defer c.Close()

for _, image := range []llb.State{llb.Scratch(), llb.Image("tonistiigi/test:nolayers")} {
st := llb.Scratch().File(llb.Copy(image, "/", "/"))
def, err := st.Marshal(sb.Context())
require.NoError(t, err)

_, err = c.Solve(sb.Context(), def, SolveOpt{}, nil)
require.NoError(t, err)

st = llb.Scratch().File(llb.Copy(image, "/foo", "/"))
def, err = st.Marshal(sb.Context())
require.NoError(t, err)

_, err = c.Solve(sb.Context(), def, SolveOpt{}, nil)
require.Error(t, err)
require.Contains(t, err.Error(), "/foo: no such file or directory")

busybox := llb.Image("busybox:latest")

out := busybox.Run(llb.Shlex(`sh -e -c '[ $(ls /scratch | wc -l) = '0' ]'`))
out.AddMount("/scratch", image, llb.Readonly)

def, err = out.Marshal(sb.Context())
require.NoError(t, err)

_, err = c.Solve(sb.Context(), def, SolveOpt{}, nil)
require.NoError(t, err)
}
}

// containerd/containerd#2119
func testDuplicateWhiteouts(t *testing.T, sb integration.Sandbox) {
skipDockerd(t, sb)
Expand Down

0 comments on commit 6eab36d

Please sign in to comment.