Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid nil pointer dereference when copying from image with no layers #2197

Merged
merged 5 commits into from Jun 28, 2021

Conversation

aaronlehmann
Copy link
Collaborator

Fix this panic when copying from an image with no layers:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x50 pc=0xdd8c17]

goroutine 326 [running]:
github.com/moby/buildkit/cache/contenthash.(*cacheManager).Checksum(0xc0005ec030, 0x1682c00, 0xc000842140, 0x0, 0x0, 0xc0005d4023, 0x1, 0x0, 0x0, 0x0, ...)
	/src/cache/contenthash/checksum.go:95 +0x37
github.com/moby/buildkit/cache/contenthash.Checksum(0x1682c00, 0xc000842140, 0x0, 0x0, 0xc0005d4023, 0x1, 0x0, 0x0, 0x0, 0x0, ...)
	/src/cache/contenthash/checksum.go:59 +0xd5
github.com/moby/buildkit/solver/llbsolver.NewContentHashFunc.func1.1(0x0, 0x4425d6)
	/src/solver/llbsolver/result.go:59 +0x20a
golang.org/x/sync/errgroup.(*Group).Go.func1(0xc00056a360, 0xc000594510)
	/src/vendor/golang.org/x/sync/errgroup/errgroup.go:57 +0x59
created by golang.org/x/sync/errgroup.(*Group).Go
	/src/vendor/golang.org/x/sync/errgroup/errgroup.go:54 +0x66

When the path is "/", we allow it because it's a noop.

Based on #2185

Signed-off-by: Aaron Lehmann alehmann@netflix.com

Fix this panic when copying from an image with no layers:

```
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x50 pc=0xdd8c17]

goroutine 326 [running]:
github.com/moby/buildkit/cache/contenthash.(*cacheManager).Checksum(0xc0005ec030, 0x1682c00, 0xc000842140, 0x0, 0x0, 0xc0005d4023, 0x1, 0x0, 0x0, 0x0, ...)
	/src/cache/contenthash/checksum.go:95 +0x37
github.com/moby/buildkit/cache/contenthash.Checksum(0x1682c00, 0xc000842140, 0x0, 0x0, 0xc0005d4023, 0x1, 0x0, 0x0, 0x0, 0x0, ...)
	/src/cache/contenthash/checksum.go:59 +0xd5
github.com/moby/buildkit/solver/llbsolver.NewContentHashFunc.func1.1(0x0, 0x4425d6)
	/src/solver/llbsolver/result.go:59 +0x20a
golang.org/x/sync/errgroup.(*Group).Go.func1(0xc00056a360, 0xc000594510)
	/src/vendor/golang.org/x/sync/errgroup/errgroup.go:57 +0x59
created by golang.org/x/sync/errgroup.(*Group).Go
	/src/vendor/golang.org/x/sync/errgroup/errgroup.go:54 +0x66
```

When the path is "/", we allow it because it's a noop.

Based on moby#2185

Signed-off-by: Aaron Lehmann <alehmann@netflix.com>
@tonistiigi
Copy link
Member

We should add tests for copying from scratch/image with no layers and probably also the same for the mount sources.

@aaronlehmann
Copy link
Collaborator Author

I don't understand the part about mount sources.

Signed-off-by: Aaron Lehmann <alehmann@netflix.com>
@tonistiigi
Copy link
Member

I don't understand the part about mount sources.

llbstate.AddMount("/foo", llb.Scratch(), llb.Readonly) should have the same behavior and mount empty directory.

Signed-off-by: Aaron Lehmann <alehmann@netflix.com>
@aaronlehmann
Copy link
Collaborator Author

llbstate.AddMount("/foo", llb.Scratch(), llb.Readonly) should have the same behavior and mount empty directory.

Added

if p == "/" {
return digest.FromBytes(nil), nil
}
return "", errors.Errorf("cannot checksum empty reference")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: probably better to return the same "not found" error that would happen if p does not exist. "empty reference" is an internal concept, users of build don't know what it means


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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

regarding errors, if I change llb.Scratch() to llb.Image("tonistiigi/test:nolayers") I get "failed to solve: rpc error: code = Unknown desc = failed to compute cache key: cannot checksum empty reference" here.

Signed-off-by: Aaron Lehmann <alehmann@netflix.com>
@aaronlehmann
Copy link
Collaborator Author

Updated the error message.

Do you think I should add a test using tonistiigi/test:nolayers, or is it better to avoid adding new images to the set needed for tests?

@tonistiigi
Copy link
Member

Do you think I should add a test using tonistiigi/test:nolayers, or is it better to avoid adding new images to the set needed for tests?

We could test these cases with that image indeed as the codepath they invoke is different than scratch that can be determined directly from llb. Add the image into mirrored images list https://github.com/moby/buildkit/blob/master/client/client_test.go#L69 that makes sure it is pulled only once (and can be cached between test invocations).

Another way would be to build such an image inside the test and push it to the local registry https://github.com/moby/buildkit/blob/master/client/client_test.go#L559 . Either solution is ok by me.

Signed-off-by: Aaron Lehmann <alehmann@netflix.com>
@tonistiigi tonistiigi merged commit 6eab36d into moby:master Jun 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants