diff options
author | Jamie Liu <jamieliu@google.com> | 2020-10-27 12:08:20 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-10-27 12:10:24 -0700 |
commit | 6d50185e7c1b551168f9318d0f26a25ee37d6ef9 (patch) | |
tree | cc3d3700b5ead48340e107d9bf4ac0ba16405440 /pkg/sentry/fsimpl/overlay/filesystem.go | |
parent | 59e2c9f16a9a4cce2ecf8b6449a47316fdf76ca2 (diff) |
Assign VFS2 overlay device numbers based on layer device numbers.
In VFS1's overlayfs, files use the device and inode number of the lower layer
inode if one exists, and the upper layer inode otherwise. The former behavior
is inefficient (requiring lower layer lookups even if the file exists and is
otherwise wholly determined by the upper layer), and somewhat dangerous if the
lower layer is also observable (since both the overlay and lower layer file
will have the same device and inode numbers and thus appear to be the same
file, despite being behaviorally different). VFS2 overlayfs imitates Linux
overlayfs (in its default configuration) instead; it always uses the inode
number from the originating layer, but synthesizes a unique device number for
directories and another device number for non-directory files that have not
been copied-up.
As it turns out, the latter is insufficient (in VFS2, and possibly Linux as
well), because a given layer may include files with different device numbers.
If two distinct files on such a layer have device number X and Y respectively,
but share inode number Z, then the overlay will map both files to some private
device number X' and inode number Z, potentially confusing applications. Fix
this by assigning synthetic device numbers based on the lower layer's device
number, rather than the lower layer's vfs.Filesystem.
PiperOrigin-RevId: 339300341
Diffstat (limited to 'pkg/sentry/fsimpl/overlay/filesystem.go')
-rw-r--r-- | pkg/sentry/fsimpl/overlay/filesystem.go | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/pkg/sentry/fsimpl/overlay/filesystem.go b/pkg/sentry/fsimpl/overlay/filesystem.go index 78a01bbb7..10161a08d 100644 --- a/pkg/sentry/fsimpl/overlay/filesystem.go +++ b/pkg/sentry/fsimpl/overlay/filesystem.go @@ -302,8 +302,14 @@ func (fs *filesystem) lookupLocked(ctx context.Context, parent *dentry, name str child.devMinor = fs.dirDevMinor child.ino = fs.newDirIno() } else if !child.upperVD.Ok() { + childDevMinor, err := fs.getLowerDevMinor(child.devMajor, child.devMinor) + if err != nil { + ctx.Infof("overlay.filesystem.lookupLocked: failed to map lower layer device number (%d, %d) to an overlay-specific device number: %v", child.devMajor, child.devMinor, err) + child.destroyLocked(ctx) + return nil, err + } child.devMajor = linux.UNNAMED_MAJOR - child.devMinor = fs.lowerDevMinors[child.lowerVDs[0].Mount().Filesystem()] + child.devMinor = childDevMinor } parent.IncRef() |