-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Disable redirect_dir for avoiding incorrect diff #2491
Conversation
2b90042
to
9eeb8f9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familiar with this but on my system(Docker Desktop) I have /sys/module/overlay/parameters/redirect_dir=N
, when I mv
a directory I get no error and regular whiteout without xattrs for the source dir. What is the case where error should appear.
If no error appears then I'd rather use a mount option that always disables this and overwrites global default until differ can handle it.
util/overlay/overlay_linux.go
Outdated
return diffSupported | ||
} | ||
|
||
func isDiffSupported() error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we use /sys/module/overlay/parameters/redirect_dir
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And check user namespace: torvalds/linux@2d2f2d7
Disable redirect_dir and metacopy options, because these would allow
privilege escalation through direct manipulation of the
"user.overlay.redirect" or "user.overlay.metacopy" xattrs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we should always append redirect_dir=off
to the overlayfs mount option (if kernel supports redirect_dir)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we should always append
redirect_dir=off
to the overlayfs mount option (if kernel supports redirect_dir)?
s/always/when in UserNS/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The behavior with userxattr
is really weird. The kernel forces redirect_dir
off when userxattr
is provided, but it also throws an error if you specify any options for redirect_dir
, even setting it to off
: https://github.com/torvalds/linux/blob/cb690f5238d71f543f4ce874aa59237cf53a877c/fs/overlayfs/super.c#L726-L745
So I think we should skip appending any redirect_dir
option when in a user ns to get the behavior we want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using nofollow
(redirects are not created and not followed) didn't return errors.
Based on the discussion with @tonistiigi (#2491 (review)), we should always append redirect_dir=nofollow
when /sys/module/overlay/parameters/redirect_dir
exists?
If no error appears then I'd rather use a mount option that always disables this and overwrites global default until differ can handle it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using nofollow (redirects are not created and not followed) didn't return errors.
Oh cool, good catch. The only downside to nofollow
is that pre-existing snapshots created while the kernel was defaulting redirect_dir=on
will no longer appear correctly (I don't think so anyways, haven't tested). This is only an issue if a user is already running on a kernel with that default and then upgrades to a commit from the master branch, so it's probably not a huge deal until the next release. But if it's easy to skip appending any redirect_dir=
option at all when userxattr
is present that might be slightly safer imo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But if it's easy to skip appending any redirect_dir= option at all when userxattr is present that might be slightly safer imo.
@AkihiroSuda SGTY?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the review. Fixed the PR based on the comments:
- Disable redirect_dir using the mount option
redirect_dir=off
when/sys/module/overlay/parameters/redirect_dir
exists. - if buildkit is in an user namespace, we disable redirect_dir using
redirect_dir=nofollow
(usingoff
results in an error).
'mv' is most likely getting EXDEV and then falling back to doing a recursive copy, same as it would if you tried to mv between separate filesystems. This was causing me a ton of confusion for a while too. |
Ah, indeed. But given that most systems have edit: also, the optimized rename doesn't matter for the layer blobs anyway. When we switch to walking differ we still get the same file duplication as we would get with the recursive directory mv. |
cache/blobs.go
Outdated
@@ -142,6 +142,11 @@ func computeBlobChain(ctx context.Context, sr *immutableRef, createIfNeeded bool | |||
// TODO: add support for fuse-overlayfs | |||
enableOverlay = false | |||
} | |||
if enableOverlay { | |||
if isOverlayDiffSupported() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this supposed to be !isOverlayDiffSupported ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
9eeb8f9
to
166008f
Compare
This is true for However this is not exactly a common case. Also, we can fix it by updating the differ to compare file content when it sees that either timestamp is truncated (right now it only does that when both are) or when it sees that the upper timestamp is older than the lower one. That would only fix this particular case though, not necessarily all possible ones, but that's probably good enough. |
that looks like busybox bug, right? coreutils is correct? |
Yeah based on quick test it looks like coreutils does the right thing (at least in version 8.32). |
166008f
to
a67cb3c
Compare
snapshot/snapshotter.go
Outdated
} | ||
|
||
type fromContainerd struct { | ||
name string | ||
snapshots.Snapshotter | ||
idmap *idtools.IdentityMapping | ||
idmap *idtools.IdentityMapping | ||
redirectDirOption string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite the need for this property. Why not just put a public method for this is overlay package, with sync.Once
ensuring proc read happens only once. And the places (2 I think) that need to overwrite the mounts call into these functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the review. Fixed to avoid adding the property.
a67cb3c
to
0a286c8
Compare
snapshot/snapshotter.go
Outdated
return redirectDirOption | ||
} | ||
|
||
func mountsRedirectDirOption(mounts []mount.Mount, redirectDirOption string) (ret []mount.Mount) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setRedirectDir
might be better name.
Or maybe even setMountOption(mounts, k, v)
0a286c8
to
f690f66
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
ping @AkihiroSuda |
@AkihiroSuda ping @ktock Needs rebase |
f690f66
to
87d93bb
Compare
snapshot/snapshotter.go
Outdated
return | ||
} | ||
if userns.RunningInUserNS() { | ||
redirectDirOption = "nofollow" // follow is not allowed in user ns |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kernel before 4.15 seemed to lack this: torvalds/linux@438c84c
While the upstream kernel didn't support overlayfs with userns at that time, Ubuntu XX.XX had supported it, so maybe we should just set redirectDirOption=""
Signed-off-by: Kohei Tokunaga <[email protected]>
87d93bb
to
bc5cfe9
Compare
Fixed the patch according to the review comments.
PTAL 🙏 |
@ktock We have a failure that looks related in buildx repo via master buildkit image.
https://github.com/docker/buildx/runs/4777886890?check_suite_focus=true#step:7:135 PTAL |
#2562 will fix #2491 (comment) |
#2490
Overlayfs differ cannot calculate diff correctly if redirect_dir is enabled.
This commit fixes this issue by falling back to walking differ if redirect_dir is enabled as done in moby (moby/moby#34342).This commit fixes this issue by disabling redirect_dir if it's supported by kernel.This'll cause performance drawback on such kernels so we should fix overlayfs differ to handle redirect_dir correctly on these kernels.
cc @sipsma