From 4784f4f6f50d7ddf958ddbb717bb2a0cb3e397a9 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Thu, 19 Nov 2015 17:16:36 +0100 Subject: add fuse support --- executor/executor.cc | 73 +++++++++++++++++++++++--- executor/syscalls.h | 16 ++++++ prog/consts.go | 3 ++ sys/decl.go | 3 +- sys/sys.go | 14 +++++ sys/sys.txt | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++ sysgen/sysgen.go | 4 ++ 7 files changed, 251 insertions(+), 8 deletions(-) diff --git a/executor/executor.cc b/executor/executor.cc index c0cdf72f1..7f0e82ba9 100644 --- a/executor/executor.cc +++ b/executor/executor.cc @@ -33,7 +33,7 @@ const int kOutPipeFd = 6; const int kCoverFd = 5; const int kMaxInput = 1 << 20; const int kMaxOutput = 16 << 20; -const int kMaxArgs = 6; +const int kMaxArgs = 9; const int kMaxThreads = 16; const int kMaxCommands = 4 << 10; @@ -160,6 +160,7 @@ int main() fail("fork failed"); if (pid == 0) { setpgid(0, 0); + unshare(CLONE_NEWNS); if (flag_drop_privs) { // Pre-create one thread with root privileges for execution of special syscalls (e.g. mount). if (flag_threaded) @@ -167,9 +168,11 @@ int main() // TODO: 65534 is meant to be nobody if (setgroups(0, NULL)) fail("failed to setgroups"); - if (setresgid(65534, 65534, 65534)) + // glibc versions do not we want -- they force all threads to setuid. + // We want to preserve the thread above as root. + if (syscall(SYS_setresgid, 65534, 65534, 65534)) fail("failed to setresgid"); - if (setresuid(65534, 65534, 65534)) + if (syscall(SYS_setresuid, 65534, 65534, 65534)) fail("failed to setresuid"); } // Don't need that SIGCANCEL/SIGSETXID glibc stuff. @@ -336,7 +339,8 @@ thread_t* schedule_call(int n, int call_index, int call_num, uint64_t num_args, // Figure out whether we need root privs for this call. bool root = false; switch (syscalls[call_num].sys_nr) { - case __NR_syz_dri_open: + case __NR_syz_fuse_mount: + case __NR_syz_fuseblk_mount: root = true; } // Find a spare thread to execute the call. @@ -447,16 +451,16 @@ void execute_call(thread_t* th) } debug(")\n"); - if (kMaxArgs != 6) - fail("inconsistent number of arguments"); - cover_reset(th); switch (call->sys_nr) { default: { + if (th->num_args > 6) + fail("bad number of arguments"); th->res = syscall(call->sys_nr, th->args[0], th->args[1], th->args[2], th->args[3], th->args[4], th->args[5]); break; } case __NR_syz_openpts: { + // syz_openpts(fd fd[tty], flags flags[open_flags]) fd[tty] int ptyno = 0; if (ioctl(th->args[0], TIOCGPTN, &ptyno) == 0) { char buf[128]; @@ -468,10 +472,65 @@ void execute_call(thread_t* th) } } case __NR_syz_dri_open: { + // syz_dri_open(card_id intptr, flags flags[open_flags]) fd[dri] char buf[128]; sprintf(buf, "/dev/dri/card%lu", th->args[0]); th->res = open(buf, th->args[1], 0); } + case __NR_syz_fuse_mount: { + // syz_fuse_mount(target filename, mode flags[fuse_mode], uid uid, gid gid, maxread intptr, flags flags[mount_flags]) fd[fuse] + uint64_t target = th->args[0]; + uint64_t mode = th->args[1]; + uint64_t uid = th->args[2]; + uint64_t gid = th->args[3]; + uint64_t maxread = th->args[4]; + uint64_t flags = th->args[5]; + + int fd = open("/dev/fuse", O_RDWR); + if (fd != -1) { + char buf[256]; + sprintf(buf, "fd=%d,user_id=%lu,group_id=%lu,rootmode=0%o", fd, uid, gid, (unsigned)mode & ~3u); + if (maxread != 0) + sprintf(buf + strlen(buf), ",max_read=%lu", maxread); + if (mode & 1) + strcat(buf, ",default_permissions"); + if (mode & 2) + strcat(buf, ",allow_other"); + syscall(SYS_mount, "", target, "fuse", flags, buf); + // Ignore errors, maybe fuzzer can do something useful with fd alone. + } + th->res = fd; + } + case __NR_syz_fuseblk_mount: { + // syz_fuseblk_mount(target filename, blkdev filename, mode flags[fuse_mode], uid uid, gid gid, maxread intptr, blksize intptr, flags flags[mount_flags]) fd[fuse] + uint64_t target = th->args[0]; + uint64_t blkdev = th->args[1]; + uint64_t mode = th->args[2]; + uint64_t uid = th->args[3]; + uint64_t gid = th->args[4]; + uint64_t maxread = th->args[5]; + uint64_t blksize = th->args[6]; + uint64_t flags = th->args[7]; + + int fd = open("/dev/fuse", O_RDWR); + if (fd != -1) { + if (syscall(SYS_mknod, blkdev, S_IFBLK, makedev(7, 199)) == 0) { + char buf[256]; + sprintf(buf, "fd=%d,user_id=%lu,group_id=%lu,rootmode=0%o", fd, uid, gid, (unsigned)mode & ~3u); + if (maxread != 0) + sprintf(buf + strlen(buf), ",max_read=%lu", maxread); + if (blksize != 0) + sprintf(buf + strlen(buf), ",blksize=%lu", blksize); + if (mode & 1) + strcat(buf, ",default_permissions"); + if (mode & 2) + strcat(buf, ",allow_other"); + syscall(SYS_mount, blkdev, target, "fuseblk", flags, buf); + // Ignore errors, maybe fuzzer can do something useful with fd alone. + } + } + th->res = fd; + } } int errno0 = errno; th->cover_size = cover_read(th); diff --git a/executor/syscalls.h b/executor/syscalls.h index 560b9786b..e77958674 100644 --- a/executor/syscalls.h +++ b/executor/syscalls.h @@ -12,6 +12,8 @@ struct call_t { #define __NR_syz_openpts 1000001 #define __NR_syz_dri_open 1000002 +#define __NR_syz_fuse_mount 1000003 +#define __NR_syz_fuseblk_mount 1000004 call_t syscalls[] = { {"open", __NR_open}, @@ -518,4 +520,18 @@ call_t syscalls[] = { {"ioctl$DRM_IOCTL_GET_CAP", __NR_ioctl}, {"ioctl$DRM_IOCTL_SET_CLIENT_CAP", __NR_ioctl}, {"ioctl$DRM_IOCTL_SET_VERSION", __NR_ioctl}, + {"syz_fuse_mount", __NR_syz_fuse_mount}, + {"syz_fuseblk_mount", __NR_syz_fuseblk_mount}, + {"ioctl$FUSE_DEV_IOC_CLONE", __NR_ioctl}, + {"write$fuse_init", __NR_write}, + {"write$fuse_interrupt", __NR_write}, + {"write$fuse_bmap", __NR_write}, + {"write$fuse_ioctl", __NR_write}, + {"write$fuse_poll", __NR_write}, + {"write$fuse_notify_poll_wakeup", __NR_write}, + {"write$fuse_notify_inval_inode", __NR_write}, + {"write$fuse_notify_inval_entry", __NR_write}, + {"write$fuse_notify_delete", __NR_write}, + {"write$fuse_notify_store", __NR_write}, + {"write$fuse_notify_retrieve", __NR_write}, }; diff --git a/prog/consts.go b/prog/consts.go index cb1683497..fa1a2d1c9 100644 --- a/prog/consts.go +++ b/prog/consts.go @@ -137,6 +137,7 @@ const ( FIOQSIZE = 21600 FITHAW = 3221510264 FS_IOC_FIEMAP = 3223348747 + FUSE_DEV_IOC_CLONE = 2147804416 FUTEX_CMP_REQUEUE = 4 FUTEX_REQUEUE = 3 FUTEX_WAIT = 0 @@ -866,7 +867,9 @@ const ( SYZ_PER_XENIX = 7 S_IFBLK = 24576 S_IFCHR = 8192 + S_IFDIR = 16384 S_IFIFO = 4096 + S_IFLNK = 40960 S_IFREG = 32768 S_IFSOCK = 49152 S_IRGRP = 32 diff --git a/sys/decl.go b/sys/decl.go index cf64a55d8..20aff9433 100644 --- a/sys/decl.go +++ b/sys/decl.go @@ -71,6 +71,7 @@ const ( FdFanotify FdTty FdDRI + FdFuse IPCMsq IPCSem @@ -167,7 +168,7 @@ func (t ResourceType) Size() uintptr { func (t ResourceType) SubKinds() []ResourceSubkind { switch t.Kind { case ResFD: - return []ResourceSubkind{FdFile, FdSock, FdPipe, FdSignal, FdEvent, FdTimer, FdEpoll, FdDir, FdMq, FdInotify, FdFanotify, FdTty, FdDRI} + return []ResourceSubkind{FdFile, FdSock, FdPipe, FdSignal, FdEvent, FdTimer, FdEpoll, FdDir, FdMq, FdInotify, FdFanotify, FdTty, FdDRI, FdFuse} case ResIPC: return []ResourceSubkind{IPCMsq, IPCSem, IPCShm} case ResIOCtx, ResKey, ResInotifyDesc, ResPid, ResUid, ResGid, ResTimerid: diff --git a/sys/sys.go b/sys/sys.go index 6d9f2efbe..9659a10f6 100644 --- a/sys/sys.go +++ b/sys/sys.go @@ -506,4 +506,18 @@ var Calls = []*Call{ &Call{ID: 501, Name: "ioctl$DRM_IOCTL_GET_CAP", CallName: "ioctl", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdDRI}, ConstType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Val: uintptr(3222299660)}, PtrType{TypeCommon: TypeCommon{TypeName: "arg", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "drm_get_cap", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "cap", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "val", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}}}, &Call{ID: 502, Name: "ioctl$DRM_IOCTL_SET_CLIENT_CAP", CallName: "ioctl", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdDRI}, ConstType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Val: uintptr(1074816013)}, PtrType{TypeCommon: TypeCommon{TypeName: "arg", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "drm_get_cap", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "cap", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "val", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}}}, &Call{ID: 503, Name: "ioctl$DRM_IOCTL_SET_VERSION", CallName: "ioctl", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdDRI}, ConstType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Val: uintptr(3222299655)}, PtrType{TypeCommon: TypeCommon{TypeName: "arg", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "drm_set_version", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "di_maj", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "di_min", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "dd_maj", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "dd_min", IsOptional: false}, TypeSize: 4}}}, Dir: DirIn}}}, + &Call{ID: 504, Name: "syz_fuse_mount", CallName: "syz_fuse_mount", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: FdFuse}, Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "target", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "target", IsOptional: false}}}, FlagsType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 32768, 8192, 24576, 4096, 49152, 40960, 16384}}, ResourceType{TypeCommon: TypeCommon{TypeName: "uid", IsOptional: false}, Kind: ResUid}, ResourceType{TypeCommon: TypeCommon{TypeName: "gid", IsOptional: false}, Kind: ResGid}, IntType{TypeCommon: TypeCommon{TypeName: "maxread", IsOptional: false}, TypeSize: 8}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{4096, 128, 64, 8192, 1024, 4, 2048, 8, 2, 1, 2097152, 32, 32768, 16777216, 16}}}}, + &Call{ID: 505, Name: "syz_fuseblk_mount", CallName: "syz_fuseblk_mount", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: FdFuse}, Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "target", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "target", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "blkdev", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "blkdev", IsOptional: false}}}, FlagsType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 32768, 8192, 24576, 4096, 49152, 40960, 16384}}, ResourceType{TypeCommon: TypeCommon{TypeName: "uid", IsOptional: false}, Kind: ResUid}, ResourceType{TypeCommon: TypeCommon{TypeName: "gid", IsOptional: false}, Kind: ResGid}, IntType{TypeCommon: TypeCommon{TypeName: "maxread", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "blksize", IsOptional: false}, TypeSize: 8}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{4096, 128, 64, 8192, 1024, 4, 2048, 8, 2, 1, 2097152, 32, 32768, 16777216, 16}}}}, + &Call{ID: 506, Name: "ioctl$FUSE_DEV_IOC_CLONE", CallName: "ioctl", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdFuse}, ConstType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Val: uintptr(2147804416)}, PtrType{TypeCommon: TypeCommon{TypeName: "arg", IsOptional: false}, Type: ResourceType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: ResFD, Subkind: FdFuse}, Dir: DirIn}}}, + &Call{ID: 507, Name: "write$fuse_init", CallName: "write", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdFuse}, PtrType{TypeCommon: TypeCommon{TypeName: "arg", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "fuse_init_out", IsOptional: false}, Fields: []Type{LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "parent", TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "err", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "unique", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "maj", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "min", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "readah", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "backg", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "congest", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "maxwr", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "timegr", IsOptional: false}, TypeSize: 4}, ConstType{TypeCommon: TypeCommon{TypeName: "unused0", IsOptional: false}, TypeSize: 4, Val: uintptr(0)}, ConstType{TypeCommon: TypeCommon{TypeName: "unused1", IsOptional: false}, TypeSize: 4, Val: uintptr(0)}, ConstType{TypeCommon: TypeCommon{TypeName: "unused2", IsOptional: false}, TypeSize: 4, Val: uintptr(0)}, ConstType{TypeCommon: TypeCommon{TypeName: "unused3", IsOptional: false}, TypeSize: 4, Val: uintptr(0)}, ConstType{TypeCommon: TypeCommon{TypeName: "unused4", IsOptional: false}, TypeSize: 4, Val: uintptr(0)}, ConstType{TypeCommon: TypeCommon{TypeName: "unused5", IsOptional: false}, TypeSize: 4, Val: uintptr(0)}, ConstType{TypeCommon: TypeCommon{TypeName: "unused6", IsOptional: false}, TypeSize: 4, Val: uintptr(0)}, ConstType{TypeCommon: TypeCommon{TypeName: "unused7", IsOptional: false}, TypeSize: 4, Val: uintptr(0)}, ConstType{TypeCommon: TypeCommon{TypeName: "unused8", IsOptional: false}, TypeSize: 4, Val: uintptr(0)}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "arg", TypeSize: 0}}}, + &Call{ID: 508, Name: "write$fuse_interrupt", CallName: "write", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdFuse}, PtrType{TypeCommon: TypeCommon{TypeName: "arg", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "fuse_interrupt_out", IsOptional: false}, Fields: []Type{LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "parent", TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "err", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "unique", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "arg", TypeSize: 0}}}, + &Call{ID: 509, Name: "write$fuse_bmap", CallName: "write", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdFuse}, PtrType{TypeCommon: TypeCommon{TypeName: "arg", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "fuse_bmap_out", IsOptional: false}, Fields: []Type{LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "parent", TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "err", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "unique", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "block", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "arg", TypeSize: 0}}}, + &Call{ID: 510, Name: "write$fuse_ioctl", CallName: "write", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdFuse}, PtrType{TypeCommon: TypeCommon{TypeName: "arg", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "fuse_ioctl_out", IsOptional: false}, Fields: []Type{LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "parent", TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "err", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "unique", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "res", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "iniovs", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "outiovs", IsOptional: false}, TypeSize: 4}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "arg", TypeSize: 0}}}, + &Call{ID: 511, Name: "write$fuse_poll", CallName: "write", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdFuse}, PtrType{TypeCommon: TypeCommon{TypeName: "arg", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "fuse_poll_out", IsOptional: false}, Fields: []Type{LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "parent", TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "err", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "unique", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "revents", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false}, TypeSize: 4}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "arg", TypeSize: 0}}}, + &Call{ID: 512, Name: "write$fuse_notify_poll_wakeup", CallName: "write", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdFuse}, PtrType{TypeCommon: TypeCommon{TypeName: "arg", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "fuse_notify_poll_wakeup_out", IsOptional: false}, Fields: []Type{LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "parent", TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "err", IsOptional: false}, TypeSize: 4}, ConstType{TypeCommon: TypeCommon{TypeName: "unique", IsOptional: false}, TypeSize: 8, Val: uintptr(0)}, IntType{TypeCommon: TypeCommon{TypeName: "kh", IsOptional: false}, TypeSize: 2}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "arg", TypeSize: 0}}}, + &Call{ID: 513, Name: "write$fuse_notify_inval_inode", CallName: "write", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdFuse}, PtrType{TypeCommon: TypeCommon{TypeName: "arg", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "fuse_notify_inval_inode_out", IsOptional: false}, Fields: []Type{LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "parent", TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "err", IsOptional: false}, TypeSize: 4}, ConstType{TypeCommon: TypeCommon{TypeName: "unique", IsOptional: false}, TypeSize: 8, Val: uintptr(0)}, IntType{TypeCommon: TypeCommon{TypeName: "ino", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "off", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, TypeSize: 2}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "arg", TypeSize: 0}}}, + &Call{ID: 514, Name: "write$fuse_notify_inval_entry", CallName: "write", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdFuse}, PtrType{TypeCommon: TypeCommon{TypeName: "arg", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "fuse_notify_inval_entry_out", IsOptional: false}, Fields: []Type{LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "parent", TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "err", IsOptional: false}, TypeSize: 4}, ConstType{TypeCommon: TypeCommon{TypeName: "unique", IsOptional: false}, TypeSize: 8, Val: uintptr(0)}, IntType{TypeCommon: TypeCommon{TypeName: "parent", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "namelen", IsOptional: false}, TypeSize: 4}, ConstType{TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false}, TypeSize: 4, Val: uintptr(0)}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "arg", TypeSize: 0}}}, + &Call{ID: 515, Name: "write$fuse_notify_delete", CallName: "write", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdFuse}, PtrType{TypeCommon: TypeCommon{TypeName: "arg", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "fuse_notify_delete_out", IsOptional: false}, Fields: []Type{LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "parent", TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "err", IsOptional: false}, TypeSize: 4}, ConstType{TypeCommon: TypeCommon{TypeName: "unique", IsOptional: false}, TypeSize: 8, Val: uintptr(0)}, IntType{TypeCommon: TypeCommon{TypeName: "parent", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "child", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "namelen", IsOptional: false}, TypeSize: 4}, ConstType{TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false}, TypeSize: 4, Val: uintptr(0)}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "arg", TypeSize: 0}}}, + &Call{ID: 516, Name: "write$fuse_notify_store", CallName: "write", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdFuse}, PtrType{TypeCommon: TypeCommon{TypeName: "arg", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "fuse_notify_store_out", IsOptional: false}, Fields: []Type{LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "parent", TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "err", IsOptional: false}, TypeSize: 4}, ConstType{TypeCommon: TypeCommon{TypeName: "unique", IsOptional: false}, TypeSize: 8, Val: uintptr(0)}, IntType{TypeCommon: TypeCommon{TypeName: "nodeid", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "off", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, TypeSize: 4}, ConstType{TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false}, TypeSize: 4, Val: uintptr(0)}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "arg", TypeSize: 0}}}, + &Call{ID: 517, Name: "write$fuse_notify_retrieve", CallName: "write", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdFuse}, PtrType{TypeCommon: TypeCommon{TypeName: "arg", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "fuse_notify_retrieve_out", IsOptional: false}, Fields: []Type{LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "parent", TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "err", IsOptional: false}, TypeSize: 4}, ConstType{TypeCommon: TypeCommon{TypeName: "unique", IsOptional: false}, TypeSize: 8, Val: uintptr(0)}, IntType{TypeCommon: TypeCommon{TypeName: "unique", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nodeid", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "off", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, TypeSize: 4}, ConstType{TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false}, TypeSize: 4, Val: uintptr(0)}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "arg", TypeSize: 0}}}, } diff --git a/sys/sys.txt b/sys/sys.txt index 6010c6c5f..e2c53329a 100644 --- a/sys/sys.txt +++ b/sys/sys.txt @@ -65,6 +65,7 @@ include include include include +include include @@ -2172,3 +2173,148 @@ drm_set_version { drm_map_type = _DRM_FRAME_BUFFER, _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, _DRM_SCATTER_GATHER, _DRM_CONSISTENT drm_map_flags = _DRM_RESTRICTED, _DRM_READ_ONLY, _DRM_LOCKED, _DRM_KERNEL, _DRM_WRITE_COMBINING, _DRM_CONTAINS_LOCK, _DRM_REMOVABLE, _DRM_DRIVER + + + + +# FUSE support + +syz_fuse_mount(target filename, mode flags[fuse_mode], uid uid, gid gid, maxread intptr, flags flags[mount_flags]) fd[fuse] +syz_fuseblk_mount(target filename, blkdev filename, mode flags[fuse_mode], uid uid, gid gid, maxread intptr, blksize intptr, flags flags[mount_flags]) fd[fuse] +ioctl$FUSE_DEV_IOC_CLONE(fd fd[fuse], cmd const[FUSE_DEV_IOC_CLONE], arg ptr[in, fd[fuse]]) +write$fuse_init(fd fd[fuse], arg ptr[in, fuse_init_out], len len[arg]) +write$fuse_interrupt(fd fd[fuse], arg ptr[in, fuse_interrupt_out], len len[arg]) +write$fuse_bmap(fd fd[fuse], arg ptr[in, fuse_bmap_out], len len[arg]) +write$fuse_ioctl(fd fd[fuse], arg ptr[in, fuse_ioctl_out], len len[arg]) +write$fuse_poll(fd fd[fuse], arg ptr[in, fuse_poll_out], len len[arg]) +write$fuse_notify_poll_wakeup(fd fd[fuse], arg ptr[in, fuse_notify_poll_wakeup_out], len len[arg]) +write$fuse_notify_inval_inode(fd fd[fuse], arg ptr[in, fuse_notify_inval_inode_out], len len[arg]) +write$fuse_notify_inval_entry(fd fd[fuse], arg ptr[in, fuse_notify_inval_entry_out], len len[arg]) +write$fuse_notify_delete(fd fd[fuse], arg ptr[in, fuse_notify_delete_out], len len[arg]) +write$fuse_notify_store(fd fd[fuse], arg ptr[in, fuse_notify_store_out], len len[arg]) +write$fuse_notify_retrieve(fd fd[fuse], arg ptr[in, fuse_notify_retrieve_out], len len[arg]) + +# 1 stands for default_permissions, 2 - allow_other +fuse_mode = 1, 2, S_IFREG, S_IFCHR, S_IFBLK, S_IFIFO, S_IFSOCK, S_IFLNK, S_IFDIR + +define FUSE_DEV_IOC_CLONE _IOR(229, 0, uint32_t) + +fuse_init_out { + len len[parent, int32] + err int32 + unique int64 + + maj int32 + min int32 + readah int32 + flags int32 + backg int16 + congest int16 + maxwr int32 + timegr int32 + unused0 const[0, int32] + unused1 const[0, int32] + unused2 const[0, int32] + unused3 const[0, int32] + unused4 const[0, int32] + unused5 const[0, int32] + unused6 const[0, int32] + unused7 const[0, int32] + unused8 const[0, int32] +} + +fuse_interrupt_out { + len len[parent, int32] + err int32 + unique int64 +} + +fuse_bmap_out { + len len[parent, int32] + err int32 + unique int64 + + block int64 +} + +fuse_ioctl_out { + len len[parent, int32] + err int32 + unique int64 + + res int32 + flags int32 + iniovs int32 + outiovs int32 +} + +fuse_poll_out { + len len[parent, int32] + err int32 + unique int64 + + revents int32 + pad int32 +} + +fuse_notify_poll_wakeup_out { + len len[parent, int32] + err int32 + unique const[0, int64] + + kh int16 +} + +fuse_notify_inval_inode_out { + len len[parent, int32] + err int32 + unique const[0, int64] + + ino int64 + off int64 + len int16 +} + +fuse_notify_inval_entry_out { + len len[parent, int32] + err int32 + unique const[0, int64] + + parent int64 + namelen int32 + pad const[0, int32] +} + +fuse_notify_delete_out { + len len[parent, int32] + err int32 + unique const[0, int64] + + parent int64 + child int64 + namelen int32 + pad const[0, int32] +} + +fuse_notify_store_out { + len len[parent, int32] + err int32 + unique const[0, int64] + + nodeid int64 + off int64 + size int32 + pad const[0, int32] +} + +fuse_notify_retrieve_out { + len len[parent, int32] + err int32 + unique const[0, int64] + + unique int64 + nodeid int64 + off int64 + size int32 + pad const[0, int32] +} diff --git a/sysgen/sysgen.go b/sysgen/sysgen.go index b4d6f5751..74639a7f0 100644 --- a/sysgen/sysgen.go +++ b/sysgen/sysgen.go @@ -328,6 +328,8 @@ func fmtFdKind(s string) string { return "FdTty" case "dri": return "FdDRI" + case "fuse": + return "FdFuse" default: failf("bad fd type %v", s) return "" @@ -417,6 +419,8 @@ struct call_t { #define __NR_syz_openpts 1000001 #define __NR_syz_dri_open 1000002 +#define __NR_syz_fuse_mount 1000003 +#define __NR_syz_fuseblk_mount 1000004 call_t syscalls[] = { `) -- cgit mrf-deployment