mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
fuse: Error out in case of unsupported file type instead of panicking.
Linux has the same behavior; see callers of fs/fuse/dir.c:fuse_invalid_attr(). Reported-by: syzbot+7e65f2f0bdf121c71bcf@syzkaller.appspotmail.com PiperOrigin-RevId: 663853750
This commit is contained in:
@@ -301,8 +301,11 @@ func (fs *filesystem) newRoot(ctx context.Context, creds *auth.Credentials, mode
|
||||
return &d
|
||||
}
|
||||
|
||||
func (fs *filesystem) newInode(ctx context.Context, out linux.FUSEEntryOut) kernfs.Inode {
|
||||
func (fs *filesystem) newInode(ctx context.Context, out linux.FUSEEntryOut) (kernfs.Inode, error) {
|
||||
attr := out.Attr
|
||||
if !isValidType(attr.Mode) {
|
||||
return nil, linuxerr.EIO
|
||||
}
|
||||
i := &inode{fs: fs, nodeID: out.NodeID, generation: out.Generation}
|
||||
i.attrMu.Lock()
|
||||
defer i.attrMu.Unlock()
|
||||
@@ -314,5 +317,15 @@ func (fs *filesystem) newInode(ctx context.Context, out linux.FUSEEntryOut) kern
|
||||
|
||||
i.OrderedChildren.Init(kernfs.OrderedChildrenOptions{})
|
||||
i.InitRefs()
|
||||
return i
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// isValidType is analogous to fs/fuse/dir.c:fuse_valid_type().
|
||||
func isValidType(mode uint32) bool {
|
||||
switch mode & linux.S_IFMT {
|
||||
case linux.S_IFREG, linux.S_IFDIR, linux.S_IFLNK, linux.S_IFCHR, linux.S_IFBLK, linux.S_IFIFO, linux.S_IFSOCK:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
package fuse
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
gotime "time"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
@@ -171,12 +170,9 @@ func (i *inode) touchAtime() {
|
||||
i.atime.Store(i.fs.clock.Now().Nanoseconds())
|
||||
}
|
||||
|
||||
// Precondition: isValidType(mode) == true.
|
||||
// +checklocks:i.attrMu
|
||||
func (i *inode) init(creds *auth.Credentials, devMajor, devMinor uint32, nodeid uint64, mode linux.FileMode, nlink uint32) {
|
||||
if mode.FileType() == 0 {
|
||||
panic(fmt.Sprintf("No file type specified in 'mode' for InodeAttrs.Init(): mode=0%o", mode))
|
||||
}
|
||||
|
||||
i.nodeID = nodeid
|
||||
i.ino.Store(nodeid)
|
||||
i.mode.Store(uint32(mode))
|
||||
@@ -560,7 +556,10 @@ func (i *inode) newEntry(ctx context.Context, name string, fileType linux.FileMo
|
||||
if opcode != linux.FUSE_LOOKUP && ((out.Attr.Mode&linux.S_IFMT)^uint32(fileType) != 0 || out.NodeID == 0 || out.NodeID == linux.FUSE_ROOT_ID) {
|
||||
return nil, linuxerr.EIO
|
||||
}
|
||||
child := i.fs.newInode(ctx, out.FUSEEntryOut)
|
||||
child, err := i.fs.newInode(ctx, out.FUSEEntryOut)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if opcode == linux.FUSE_CREATE {
|
||||
// File handler is returned by fuse server at a time of file create.
|
||||
// Save it temporary in a created child, so Open could return it when invoked
|
||||
|
||||
Reference in New Issue
Block a user