-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Fix data loss in rootfs overlayfs when unmount of tmp dirs fail with idmap mounts #10721
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -251,12 +251,22 @@ func doPrepareIDMappedOverlay(lowerDirs []string, usernsFd int) (tmpLowerDirs [] | |
| } | ||
| cleanUp := func() { | ||
| for _, lowerDir := range tmpLowerDirs { | ||
| if err := unix.Unmount(lowerDir, 0); err != nil { | ||
| // Do a detached unmount so even if the resource is busy, the mount will be | ||
| // gone (eventually) and we can safely delete the directory too. | ||
| if err := unix.Unmount(lowerDir, unix.MNT_DETACH); err != nil { | ||
| log.L.WithError(err).Warnf("failed to unmount temp lowerdir %s", lowerDir) | ||
| continue | ||
| } | ||
| // Using os.Remove() so if it's not empty, we don't delete files in the | ||
| // rootfs. | ||
| if err := os.Remove(lowerDir); err != nil { | ||
| log.L.WithError(err).Warnf("failed to remove temporary overlay lowerdir's") | ||
| } | ||
| } | ||
| if terr := os.RemoveAll(filepath.Clean(filepath.Join(tmpLowerDirs[0], ".."))); terr != nil { | ||
| log.L.WithError(terr).Warnf("failed to remove temporary overlay lowerdir's") | ||
|
|
||
| // This dir should be empty now. Otherwise, we don't do anything. | ||
| if err := os.Remove(filepath.Join(tmpLowerDirs[0], "..")); err != nil { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can't we just use filepath.Dir? (And validate the path)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I'm preparing a follow-up PR with more improvements. This is how it was written before, I'd improve it (that and other things, hopefully including tests :)) This PR is just about fixing the data loss, if that is fine, to land ASAP.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the follow-up PR this thing is removed and handled differently (IMHO, it is clearer). So I'd avoid improving lines that we will remove anyways :) |
||
| log.L.WithError(err).Infof("failed to remove temporary overlay dir") | ||
| } | ||
| } | ||
| for i, lowerDir := range lowerDirs { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
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.
MNT_DETACH isn't a best option :p
The cleanup is defer callback. It's hard to notify that caller to retry.
Based on this fact, the change is acceptable to me.
However, I think we can handle this issue in other way.
Based on
mount_setattrmanpage, theMOUNT_ATTR_RDONLYcan force the temporary mount in read-only. And no one can delete the content.It's kind of enhancement and it needs to change
IdMapMountinterface.It should be handled in the follow-up.
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.
@mbaynton are you interested in tackling this?
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.
Hmm, potentially. I'm most interested in investigating a new code path for Linux 6.13+ using the new file descriptor based layer setup and the new mount API. I think this will keep the idmap temp mounts off the host filesystem tree at all times, so the one and only accessor of them will be the desired overlayfs, so (I hypothesize) there will be no possibility of EBUSY failures / no need to use MNT_DETACH / no possibility of leaky mountpoints.
But an alternative implementation that removes
MNT_DETACH, instead makes these read-only as another safeguard, and accepts the possibility that the unmount may fail withoutMNT_DETACHseems pretty easy to put together too.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.
@rata it sounds like you already started a follow-up?
I don't see one pushed to
rata/containerdbut are there improvements you've got?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 should have something for this to address @fuweid's request in a week.
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.
#10955