mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add support for mount flags
Plumbs MS_NOEXEC and MS_RDONLY. Others are TODO. Updates #1623 #1193 PiperOrigin-RevId: 300764669
This commit is contained in:
committed by
gVisor bot
parent
f693e1334b
commit
8f8f16efaf
@@ -115,8 +115,6 @@ func NewVFSLookup(mntns *vfs.MountNamespace, root, workingDir vfs.VirtualDentry)
|
||||
//
|
||||
// remainingTraversals is not configurable in VFS2, all callers are using the
|
||||
// default anyways.
|
||||
//
|
||||
// TODO(gvisor.dev/issue/1623): Check mount has read and exec permission.
|
||||
func (l *vfsLookup) OpenPath(ctx context.Context, pathname string, opts vfs.OpenOptions, _ *uint, resolveFinal bool) (File, error) {
|
||||
vfsObj := l.mntns.Root().Mount().Filesystem().VirtualFilesystem()
|
||||
creds := auth.CredentialsFromContext(ctx)
|
||||
|
||||
+22
-20
@@ -74,6 +74,10 @@ type Mount struct {
|
||||
// umounted is true. umounted is protected by VirtualFilesystem.mountMu.
|
||||
umounted bool
|
||||
|
||||
// flags contains settings as specified for mount(2), e.g. MS_NOEXEC, except
|
||||
// for MS_RDONLY which is tracked in "writers".
|
||||
flags MountFlags
|
||||
|
||||
// The lower 63 bits of writers is the number of calls to
|
||||
// Mount.CheckBeginWrite() that have not yet been paired with a call to
|
||||
// Mount.EndWrite(). The MSB of writers is set if MS_RDONLY is in effect.
|
||||
@@ -81,6 +85,21 @@ type Mount struct {
|
||||
writers int64
|
||||
}
|
||||
|
||||
func newMount(vfs *VirtualFilesystem, fs *Filesystem, root *Dentry, mntns *MountNamespace, opts *MountOptions) *Mount {
|
||||
mnt := &Mount{
|
||||
vfs: vfs,
|
||||
fs: fs,
|
||||
root: root,
|
||||
flags: opts.Flags,
|
||||
ns: mntns,
|
||||
refs: 1,
|
||||
}
|
||||
if opts.ReadOnly {
|
||||
mnt.setReadOnlyLocked(true)
|
||||
}
|
||||
return mnt
|
||||
}
|
||||
|
||||
// A MountNamespace is a collection of Mounts.
|
||||
//
|
||||
// MountNamespaces are reference-counted. Unless otherwise specified, all
|
||||
@@ -129,13 +148,7 @@ func (vfs *VirtualFilesystem) NewMountNamespace(ctx context.Context, creds *auth
|
||||
refs: 1,
|
||||
mountpoints: make(map[*Dentry]uint32),
|
||||
}
|
||||
mntns.root = &Mount{
|
||||
vfs: vfs,
|
||||
fs: fs,
|
||||
root: root,
|
||||
ns: mntns,
|
||||
refs: 1,
|
||||
}
|
||||
mntns.root = newMount(vfs, fs, root, mntns, &MountOptions{})
|
||||
return mntns, nil
|
||||
}
|
||||
|
||||
@@ -148,12 +161,7 @@ func (vfs *VirtualFilesystem) NewDisconnectedMount(fs *Filesystem, root *Dentry,
|
||||
if root != nil {
|
||||
root.IncRef()
|
||||
}
|
||||
return &Mount{
|
||||
vfs: vfs,
|
||||
fs: fs,
|
||||
root: root,
|
||||
refs: 1,
|
||||
}, nil
|
||||
return newMount(vfs, fs, root, nil /* mntns */, opts), nil
|
||||
}
|
||||
|
||||
// MountAt creates and mounts a Filesystem configured by the given arguments.
|
||||
@@ -218,13 +226,7 @@ func (vfs *VirtualFilesystem) MountAt(ctx context.Context, creds *auth.Credentia
|
||||
// are directories, or neither are, and returns ENOTDIR if this is not the
|
||||
// case.
|
||||
mntns := vd.mount.ns
|
||||
mnt := &Mount{
|
||||
vfs: vfs,
|
||||
fs: fs,
|
||||
root: root,
|
||||
ns: mntns,
|
||||
refs: 1,
|
||||
}
|
||||
mnt := newMount(vfs, fs, root, mntns, opts)
|
||||
vfs.mounts.seq.BeginWrite()
|
||||
vfs.connectLocked(mnt, vd, mntns)
|
||||
vfs.mounts.seq.EndWrite()
|
||||
|
||||
@@ -46,8 +46,21 @@ type MknodOptions struct {
|
||||
DevMinor uint32
|
||||
}
|
||||
|
||||
// MountFlags contains flags as specified for mount(2), e.g. MS_NOEXEC.
|
||||
// MS_RDONLY is not part of MountFlags because it's tracked in Mount.writers.
|
||||
type MountFlags struct {
|
||||
// NoExec is equivalent to MS_NOEXEC.
|
||||
NoExec bool
|
||||
}
|
||||
|
||||
// MountOptions contains options to VirtualFilesystem.MountAt().
|
||||
type MountOptions struct {
|
||||
// Flags contains flags as specified for mount(2), e.g. MS_NOEXEC.
|
||||
Flags MountFlags
|
||||
|
||||
// ReadOnly is equivalent to MS_RDONLY.
|
||||
ReadOnly bool
|
||||
|
||||
// GetFilesystemOptions contains options to FilesystemType.GetFilesystem().
|
||||
GetFilesystemOptions GetFilesystemOptions
|
||||
|
||||
@@ -75,7 +88,8 @@ type OpenOptions struct {
|
||||
|
||||
// FileExec is set when the file is being opened to be executed.
|
||||
// VirtualFilesystem.OpenAt() checks that the caller has execute permissions
|
||||
// on the file, and that the file is a regular file.
|
||||
// on the file, that the file is a regular file, and that the mount doesn't
|
||||
// have MS_NOEXEC set.
|
||||
FileExec bool
|
||||
}
|
||||
|
||||
|
||||
@@ -388,6 +388,11 @@ func (vfs *VirtualFilesystem) OpenAt(ctx context.Context, creds *auth.Credential
|
||||
// TODO(gvisor.dev/issue/1193): Move inside fsimpl to avoid another call
|
||||
// to FileDescription.Stat().
|
||||
if opts.FileExec {
|
||||
if fd.Mount().flags.NoExec {
|
||||
fd.DecRef()
|
||||
return nil, syserror.EACCES
|
||||
}
|
||||
|
||||
// Only a regular file can be executed.
|
||||
stat, err := fd.Stat(ctx, StatOptions{Mask: linux.STATX_TYPE})
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user