diff options
author | Dean Deng <deandeng@google.com> | 2020-07-23 18:46:10 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-07-23 18:52:44 -0700 |
commit | d9a3f5d0c7d675b3cb4519eccca341bac33456af (patch) | |
tree | 84a79ce511fed0dd4faf362896bc6d2be1c0cc82 /pkg/sentry/fsimpl/host | |
parent | bac4ebaabfac95f7b467b9c777a890fcf31a42ae (diff) |
Add permission checks to vfs2 truncate.
- Check write permission on truncate(2). Unlike ftruncate(2),
truncate(2) fails if the user does not have write permissions
on the file.
- For gofers under InteropModeShared, check file type before
making a truncate request. We should fail early and avoid
making an rpc when possible. Furthermore, depending on the
remote host's failure may give us unexpected behavior--if the
host converts the truncate request to an ftruncate syscall on
an open fd, we will get EINVAL instead of EISDIR.
Updates #2923.
PiperOrigin-RevId: 322913569
Diffstat (limited to 'pkg/sentry/fsimpl/host')
-rw-r--r-- | pkg/sentry/fsimpl/host/host.go | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/pkg/sentry/fsimpl/host/host.go b/pkg/sentry/fsimpl/host/host.go index 1a88cb657..c894f2ca0 100644 --- a/pkg/sentry/fsimpl/host/host.go +++ b/pkg/sentry/fsimpl/host/host.go @@ -373,7 +373,7 @@ func (i *inode) fstat(fs *filesystem) (linux.Statx, error) { // SetStat implements kernfs.Inode. func (i *inode) SetStat(ctx context.Context, fs *vfs.Filesystem, creds *auth.Credentials, opts vfs.SetStatOptions) error { - s := opts.Stat + s := &opts.Stat m := s.Mask if m == 0 { @@ -386,7 +386,7 @@ func (i *inode) SetStat(ctx context.Context, fs *vfs.Filesystem, creds *auth.Cre if err := syscall.Fstat(i.hostFD, &hostStat); err != nil { return err } - if err := vfs.CheckSetStat(ctx, creds, &s, linux.FileMode(hostStat.Mode&linux.PermissionsMask), auth.KUID(hostStat.Uid), auth.KGID(hostStat.Gid)); err != nil { + if err := vfs.CheckSetStat(ctx, creds, &opts, linux.FileMode(hostStat.Mode), auth.KUID(hostStat.Uid), auth.KGID(hostStat.Gid)); err != nil { return err } @@ -396,6 +396,9 @@ func (i *inode) SetStat(ctx context.Context, fs *vfs.Filesystem, creds *auth.Cre } } if m&linux.STATX_SIZE != 0 { + if hostStat.Mode&linux.S_IFMT != linux.S_IFREG { + return syserror.EINVAL + } if err := syscall.Ftruncate(i.hostFD, int64(s.Size)); err != nil { return err } |