diff options
author | Nicolas Lacasse <nlacasse@google.com> | 2019-04-03 17:52:53 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2019-04-03 17:53:56 -0700 |
commit | 61d8c361c6639ecbc262076be9f1214dd82065d1 (patch) | |
tree | 977c594b2ac67396fd7e4f9bf229c21a81f8b5b0 /pkg/sentry/fs/dirent_cache.go | |
parent | 4968dd1341a04e93557bdd9f4b4b83eb508e026d (diff) |
Don't release d.mu in checks for child-existence.
Dirent.exists() is called in Create to check whether a child with the given
name already exists.
Dirent.exists() calls walk(), and before this CL allowed walk() to drop d.mu
while calling d.Inode.Lookup. During this existence check, a racing Rename()
can acquire d.mu and create a new child of the dirent with the same name.
(Note that the source and destination of the rename must be in the same
directory, otherwise renameMu will be taken preventing the race.) In this
case, d.exists() can return false, even though a child with the same name
actually does exist.
This CL changes d.exists() so that it does not release d.mu while walking, thus
preventing the race with Rename.
It also adds comments noting that lockForRename may not take renameMu if the
source and destination are in the same directory, as this is a bit surprising
(at least it was to me).
PiperOrigin-RevId: 241842579
Change-Id: I56524870e39dfcd18cab82054eb3088846c34813
Diffstat (limited to 'pkg/sentry/fs/dirent_cache.go')
0 files changed, 0 insertions, 0 deletions