Check mount writability in VFS2 [f]access[at][2] implementations.

Linux exempts special files (sockets, named pipes, and character/block device
special files) from mount writability checks in both open
(fs/open.c:do_dentry_open()) and access (fs/open.c:do_faccessat()) paths. We
don't currently do so in open (in VFS1 or VFS2) or access (in VFS1), so we
don't do so in VFS2 access either.

PiperOrigin-RevId: 439398002
This commit is contained in:
Jamie Liu
2022-04-04 13:33:02 -07:00
committed by gVisor bot
parent 47fbf57a83
commit fa8f71f2ec
5 changed files with 30 additions and 4 deletions
+7 -1
View File
@@ -763,7 +763,13 @@ func (fs *filesystem) AccessAt(ctx context.Context, rp *vfs.ResolvingPath, creds
if err != nil {
return err
}
return d.checkPermissions(creds, ats)
if err := d.checkPermissions(creds, ats); err != nil {
return err
}
if ats.MayWrite() && rp.Mount().ReadOnly() {
return linuxerr.EROFS
}
return nil
}
// GetDentryAt implements vfs.FilesystemImpl.GetDentryAt.
+7 -1
View File
@@ -311,7 +311,13 @@ func (fs *Filesystem) AccessAt(ctx context.Context, rp *vfs.ResolvingPath, creds
if err != nil {
return err
}
return d.inode.CheckPermissions(ctx, creds, ats)
if err := d.inode.CheckPermissions(ctx, creds, ats); err != nil {
return err
}
if ats.MayWrite() && rp.Mount().ReadOnly() {
return linuxerr.EROFS
}
return nil
}
// GetDentryAt implements vfs.FilesystemImpl.GetDentryAt.
+7 -1
View File
@@ -567,7 +567,13 @@ func (fs *filesystem) AccessAt(ctx context.Context, rp *vfs.ResolvingPath, creds
if err != nil {
return err
}
return d.checkPermissions(creds, ats)
if err := d.checkPermissions(creds, ats); err != nil {
return err
}
if ats.MayWrite() && rp.Mount().ReadOnly() {
return linuxerr.EROFS
}
return nil
}
// BoundEndpointAt implements vfs.FilesystemImpl.BoundEndpointAt.
+7 -1
View File
@@ -207,7 +207,13 @@ func (fs *filesystem) AccessAt(ctx context.Context, rp *vfs.ResolvingPath, creds
if err != nil {
return err
}
return d.inode.checkPermissions(creds, ats)
if err := d.inode.checkPermissions(creds, ats); err != nil {
return err
}
if ats.MayWrite() && rp.Mount().ReadOnly() {
return linuxerr.EROFS
}
return nil
}
// GetDentryAt implements vfs.FilesystemImpl.GetDentryAt.
+2
View File
@@ -337,6 +337,8 @@ TEST(MountTest, MountReadonly) {
const struct stat s = ASSERT_NO_ERRNO_AND_VALUE(Stat(dir.path()));
EXPECT_EQ(s.st_mode, S_IFDIR | 0777);
EXPECT_THAT(access(dir.path().c_str(), W_OK), SyscallFailsWithErrno(EROFS));
std::string const filename = JoinPath(dir.path(), "foo");
EXPECT_THAT(open(filename.c_str(), O_RDWR | O_CREAT, 0777),
SyscallFailsWithErrno(EROFS));