From 588a542b2a23ba477031bf20b4c46b0f40a04b7d Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Mon, 31 Oct 2016 15:15:13 -0600 Subject: sys: add string flags Allow to define string flags in txt descriptions. E.g.: filesystem = "ext2", "ext3", "ext4" and then use it in string type: ptr[in, string[filesystem]] --- host/host.go | 30 ++++++++------ prog/mutation.go | 12 +++--- prog/prio.go | 2 +- prog/prog.go | 2 +- prog/rand.go | 28 +++---------- sys/README.md | 10 +++-- sys/decl.go | 30 +++++--------- sys/dri.txt | 6 +-- sys/input.txt | 6 +-- sys/kdbus.txt | 2 +- sys/kvm.txt | 4 +- sys/random.txt | 4 +- sys/sndcontrol.txt | 2 +- sys/sndseq.txt | 2 +- sys/sndtimer.txt | 2 +- sys/sys.txt | 113 ++++++++++++++++++++++++++-------------------------- sys/tlk_device.txt | 2 +- sys/tty.txt | 2 +- sys/tun.txt | 2 +- sysgen/sysgen.go | 39 +++++++++--------- sysparser/lexer.go | 23 +++++++++-- sysparser/parser.go | 3 +- 22 files changed, 161 insertions(+), 165 deletions(-) diff --git a/host/host.go b/host/host.go index 49cf78e57..a58964e8c 100644 --- a/host/host.go +++ b/host/host.go @@ -60,11 +60,7 @@ func isSupportedSyzkall(c *sys.Call) bool { case "syz_test": return false case "syz_open_dev": - ptr, ok := c.Args[0].(*sys.PtrType) - if !ok { - return true - } - fname, ok := ptr.Type.(*sys.StrConstType) + fname, ok := extractStringConst(c.Args[0]) if !ok { panic("first open arg is not a pointer to string const") } @@ -84,7 +80,7 @@ func isSupportedSyzkall(c *sys.Call) bool { } return false } - return check(fname.Val[:len(fname.Val)-1]) + return check(fname) case "syz_open_pts": return true case "syz_fuse_mount": @@ -112,17 +108,27 @@ func isSupportedSocket(c *sys.Call) bool { } func isSupportedOpen(c *sys.Call) bool { - ptr, ok := c.Args[0].(*sys.PtrType) - if !ok { - panic("first open arg is not a pointer") - } - fname, ok := ptr.Type.(*sys.StrConstType) + fname, ok := extractStringConst(c.Args[0]) if !ok { return true } - fd, err := syscall.Open(fname.Val[:len(fname.Val)-1], syscall.O_RDONLY, 0) + fd, err := syscall.Open(fname, syscall.O_RDONLY, 0) if fd != -1 { syscall.Close(fd) } return err == nil } + +func extractStringConst(typ sys.Type) (string, bool) { + ptr, ok := typ.(*sys.PtrType) + if !ok { + panic("first open arg is not a pointer to string const") + } + str, ok := ptr.Type.(*sys.BufferType) + if !ok || str.Kind != sys.BufferString || len(str.Values) != 1 { + return "", false + } + v := str.Values[0] + v = v[:len(v)-1] // string terminating \x00 + return v, true +} diff --git a/prog/mutation.go b/prog/mutation.go index 72535f656..e861725c8 100644 --- a/prog/mutation.go +++ b/prog/mutation.go @@ -89,10 +89,8 @@ func (p *Prog) Mutate(rs rand.Source, ncalls int, ct *ChoiceTable) { if r.bin() { arg.Data = mutateData(r, append([]byte{}, arg.Data...), int(0), ^int(0)) } else { - arg.Data = r.randString(s) + arg.Data = r.randString(s, a.Values) } - case sys.BufferFilesystem: - arg.Data = r.filesystem(s) case sys.BufferFilename: arg.Data = []byte(r.filename(s)) case sys.BufferSockaddr: @@ -170,7 +168,7 @@ func (p *Prog) Mutate(rs rand.Source, ncalls int, ct *ChoiceTable) { p.replaceArg(c, arg, arg1, calls) case *sys.LenType: panic("bad arg returned by mutationArgs: LenType") - case *sys.ConstType, *sys.StrConstType: + case *sys.ConstType: panic("bad arg returned by mutationArgs: ConstType") default: panic(fmt.Sprintf("bad arg returned by mutationArgs: %#v, type=%#v", *arg, arg.Type)) @@ -322,9 +320,13 @@ func mutationArgs(c *Call) (args, bases []*Arg) { case *sys.LenType: // Size is updated when the size-of arg change. return - case *sys.ConstType, *sys.StrConstType: + case *sys.ConstType: // Well, this is const. return + case *sys.BufferType: + if typ.Kind == sys.BufferString && len(typ.Values) == 1 { + return // string const + } } if arg.Type.Dir() == sys.DirOut { return diff --git a/prog/prio.go b/prog/prio.go index 9b0ace782..a6919372d 100644 --- a/prog/prio.go +++ b/prog/prio.go @@ -80,7 +80,7 @@ func calcStaticPriorities() [][]float32 { } case *sys.BufferType: switch a.Kind { - case sys.BufferBlobRand, sys.BufferBlobRange, sys.BufferFilesystem, sys.BufferAlgType, sys.BufferAlgName: + case sys.BufferBlobRand, sys.BufferBlobRange, sys.BufferAlgType, sys.BufferAlgName: case sys.BufferString: noteUsage(0.2, "str") case sys.BufferSockaddr: diff --git a/prog/prog.go b/prog/prog.go index 4ffc3e6bf..e3a0febd2 100644 --- a/prog/prog.go +++ b/prog/prog.go @@ -101,7 +101,7 @@ func (a *Arg) Value() uintptr { func (a *Arg) Size() uintptr { switch typ := a.Type.(type) { - case *sys.IntType, *sys.LenType, *sys.FlagsType, *sys.ConstType, *sys.StrConstType, + case *sys.IntType, *sys.LenType, *sys.FlagsType, *sys.ConstType, *sys.ResourceType, *sys.VmaType, *sys.PtrType: return typ.Size() case *sys.BufferType: diff --git a/prog/rand.go b/prog/rand.go index 6415277eb..30d0ba4aa 100644 --- a/prog/rand.go +++ b/prog/rand.go @@ -258,7 +258,10 @@ func (r *randGen) sockaddr(s *state) []byte { return data } -func (r *randGen) randString(s *state) []byte { +func (r *randGen) randString(s *state, vals []string) []byte { + if len(vals) != 0 { + return []byte(vals[r.Intn(len(vals))]) + } if len(s.strings) != 0 && r.bin() { // Return an existing string. strings := make([]string, 0, len(s.strings)) @@ -288,20 +291,6 @@ func (r *randGen) randString(s *state) []byte { return buf.Bytes() } -func (r *randGen) filesystem(s *state) []byte { - dict := []string{"sysfs", "rootfs", "ramfs", "tmpfs", "devtmpfs", "debugfs", - "securityfs", "sockfs", "pipefs", "anon_inodefs", "devpts", "ext3", "ext2", "ext4", - "hugetlbfs", "vfat", "ecryptfs", "kdbusfs", "fuseblk", "fuse", "rpc_pipefs", - "nfs", "nfs4", "nfsd", "binfmt_misc", "autofs", "xfs", "jfs", "msdos", "ntfs", - "minix", "hfs", "hfsplus", "qnx4", "ufs", "btrfs", "configfs", "ncpfs", "qnx6", - "exofs", "befs", "vxfs", "gfs2", "gfs2meta", "fusectl", "bfs", "nsfs", "efs", - "cifs", "efivarfs", "affs", "tracefs", "bdev", "ocfs2", "ocfs2_dlmfs", "hpfs", - "proc", "afs", "reiserfs", "jffs2", "romfs", "aio", "sysv", "v7", "udf", - "ceph", "pstore", "adfs", "9p", "hostfs", "squashfs", "cramfs", "iso9660", - "coda", "nilfs2", "logfs", "overlay", "f2fs", "omfs", "ubifs", "openpromfs"} - return []byte(dict[r.Intn(len(dict))] + "\x00") -} - func (r *randGen) algType(s *state) []byte { dict := []string{"aead", "hash", "rng", "skcipher"} res := make([]byte, 14) @@ -662,7 +651,7 @@ func (r *randGen) generateArg(s *state, typ sys.Type) (arg *Arg, calls []*Call) // in subsequent calls. For the same reason we do generate pointer/array/struct // output arguments (their elements can be referenced in subsequent calls). switch typ.(type) { - case *sys.IntType, *sys.FlagsType, *sys.ConstType, *sys.StrConstType, + case *sys.IntType, *sys.FlagsType, *sys.ConstType, *sys.ResourceType, *sys.VmaType: return constArg(typ, 0), nil } @@ -718,10 +707,7 @@ func (r *randGen) generateArg(s *state, typ sys.Type) (arg *Arg, calls []*Call) } return dataArg(a, data), nil case sys.BufferString: - data := r.randString(s) - return dataArg(a, data), nil - case sys.BufferFilesystem: - data := r.filesystem(s) + data := r.randString(s, a.Values) return dataArg(a, data), nil case sys.BufferFilename: filename := r.filename(s) @@ -761,8 +747,6 @@ func (r *randGen) generateArg(s *state, typ sys.Type) (arg *Arg, calls []*Call) return constArg(a, r.flags(a.Vals)), nil case *sys.ConstType: return constArg(a, a.Val), nil - case *sys.StrConstType: - return dataArg(a, []byte(a.Val)), nil case *sys.IntType: v := r.randInt() switch a.Kind { diff --git a/sys/README.md b/sys/README.md index 89638aa12..161c1e73e 100644 --- a/sys/README.md +++ b/sys/README.md @@ -44,9 +44,9 @@ rest of the type-options are type-specific: type of the object; direction (in/out/inout) "buffer": a pointer to a memory buffer (like read/write buffer argument), type-options: direction (in/out/inout) - "string": a zero-terminated memory buffer (no pointer indirection implied) - "strconst": a pointer to a constant string, type-options: - the underlying string (for example "/dev/dsp") + "string": a zero-terminated memory buffer (no pointer indirection implied), type-options: + either a string value in quotes for constant strings (e.g. "foo"), + or a reference to string flags "filename": a file/link/dir name "fileoff": offset within a file "len": length of another field (for array it is number of elements), type-options: @@ -61,6 +61,10 @@ Flags are described as: ``` flagname = const ["," const]* ``` +or for string flags as: +``` + flagname = "\"" literal "\"" ["," "\"" literal "\""]* +``` ### Structs diff --git a/sys/decl.go b/sys/decl.go index d5ec9a547..2f86ea87c 100644 --- a/sys/decl.go +++ b/sys/decl.go @@ -105,7 +105,6 @@ const ( BufferString BufferFilename BufferSockaddr - BufferFilesystem BufferAlgType BufferAlgName ) @@ -115,6 +114,8 @@ type BufferType struct { Kind BufferKind RangeBegin uintptr // for BufferBlobRange kind RangeEnd uintptr // for BufferBlobRange kind + SubKind string + Values []string // possible values for BufferString kind } func (t *BufferType) Size() uintptr { @@ -123,14 +124,16 @@ func (t *BufferType) Size() uintptr { return 14 case BufferAlgName: return 64 + case BufferString: + if len(t.Values) == 1 { + return uintptr(len(t.Values[0])) + } case BufferBlobRange: if t.RangeBegin == t.RangeEnd { return t.RangeBegin } - fallthrough - default: - panic(fmt.Sprintf("buffer size is not statically known: %v", t.Name())) } + panic(fmt.Sprintf("buffer size is not statically known: %v", t.Name())) } func (t *BufferType) Align() uintptr { @@ -196,20 +199,6 @@ func (t *ConstType) Align() uintptr { return t.Size() } -type StrConstType struct { - TypeCommon - TypeSize uintptr - Val string -} - -func (t *StrConstType) Size() uintptr { - return uintptr(len(t.Val)) -} - -func (t *StrConstType) Align() uintptr { - return 1 -} - type IntKind int const ( @@ -486,9 +475,8 @@ func ForeachType(meta *Call, f func(Type)) { for _, opt := range a.Options { rec(opt) } - case *ResourceType, *BufferType, - *VmaType, *LenType, *FlagsType, *ConstType, - *StrConstType, *IntType: + case *ResourceType, *BufferType, *VmaType, *LenType, + *FlagsType, *ConstType, *IntType: default: panic("unknown type") } diff --git a/sys/dri.txt b/sys/dri.txt index 3c5753f23..bc35016e4 100644 --- a/sys/dri.txt +++ b/sys/dri.txt @@ -10,9 +10,9 @@ resource drm_agp_handle[intptr] resource drm_gem_handle[int32] resource drm_gem_name[int32] -syz_open_dev$dri(dev strconst["/dev/dri/card#"], id intptr, flags flags[open_flags]) fd_dri -syz_open_dev$dricontrol(dev strconst["/dev/dri/controlD#"], id intptr, flags flags[open_flags]) fd_dri -syz_open_dev$drirender(dev strconst["/dev/dri/renderD#"], id intptr, flags flags[open_flags]) fd_dri +syz_open_dev$dri(dev ptr[in, string["/dev/dri/card#"]], id intptr, flags flags[open_flags]) fd_dri +syz_open_dev$dricontrol(dev ptr[in, string["/dev/dri/controlD#"]], id intptr, flags flags[open_flags]) fd_dri +syz_open_dev$drirender(dev ptr[in, string["/dev/dri/renderD#"]], id intptr, flags flags[open_flags]) fd_dri ioctl$DRM_IOCTL_VERSION(fd fd_dri, cmd const[DRM_IOCTL_VERSION], arg ptr[in, drm_version]) ioctl$DRM_IOCTL_GET_UNIQUE(fd fd_dri, cmd const[DRM_IOCTL_GET_UNIQUE], arg ptr[in, drm_unique_out]) diff --git a/sys/input.txt b/sys/input.txt index 236d6c89c..4266c2b2b 100644 --- a/sys/input.txt +++ b/sys/input.txt @@ -6,10 +6,10 @@ include resource fd_evdev[fd] # There seems to be nothing special we can do with this fd. -syz_open_dev$mouse(dev strconst["/dev/input/mouse#"], id intptr, flags flags[open_flags]) fd -syz_open_dev$mice(dev strconst["/dev/input/mice"], id const[0], flags flags[open_flags]) fd +syz_open_dev$mouse(dev ptr[in, string["/dev/input/mouse#"]], id intptr, flags flags[open_flags]) fd +syz_open_dev$mice(dev ptr[in, string["/dev/input/mice"]], id const[0], flags flags[open_flags]) fd -syz_open_dev$evdev(dev strconst["/dev/input/event#"], id intptr, flags flags[open_flags]) fd_evdev +syz_open_dev$evdev(dev ptr[in, string["/dev/input/event#"]], id intptr, flags flags[open_flags]) fd_evdev write$evdev(fd fd_evdev, data ptr[in, array[input_event]], len bytesize[data]) diff --git a/sys/kdbus.txt b/sys/kdbus.txt index 5d40b8625..97bd49e70 100644 --- a/sys/kdbus.txt +++ b/sys/kdbus.txt @@ -6,7 +6,7 @@ include resource fd_kdbus[fd] -openat$kdbus(fd const[AT_FDCWD], file strconst["/dev/kdbus"], flags flags[open_flags], mode const[0]) fd_kdbus +openat$kdbus(fd const[AT_FDCWD], file ptr[in, string["/dev/kdbus"]], flags flags[open_flags], mode const[0]) fd_kdbus ioctl$kdbus_bus_make(fd fd_kdbus, cmd const[KDBUS_CMD_BUS_MAKE], arg ptr[in, kdbus_cmd_bus_make]) ioctl$kdbus_ep_make(fd fd_kdbus, cmd const[KDBUS_CMD_ENDPOINT_MAKE], arg ptr[in, kdbus_cmd_ep_make]) ioctl$kdbus_ep_update(fd fd_kdbus, cmd const[KDBUS_CMD_ENDPOINT_UPDATE], arg ptr[in, kdbus_cmd_ep_update]) diff --git a/sys/kvm.txt b/sys/kvm.txt index b80f4ce72..96e73d74e 100644 --- a/sys/kvm.txt +++ b/sys/kvm.txt @@ -9,7 +9,7 @@ resource fd_kvm[fd] resource fd_kvmvm[fd] resource fd_kvmcpu[fd] -syz_open_dev$kvm(dev strconst["/dev/kvm"], id const[0], flags flags[open_flags]) fd_kvm +syz_open_dev$kvm(dev ptr[in, string["/dev/kvm"]], id const[0], flags flags[open_flags]) fd_kvm ioctl$KVM_CREATE_VM(fd fd_kvm, cmd const[KVM_CREATE_VM], type const[0]) fd_kvmvm ioctl$KVM_GET_MSR_INDEX_LIST(fd fd_kvm, cmd const[KVM_GET_MSR_INDEX_LIST], arg ptr[in, kvm_msr_list]) @@ -99,7 +99,7 @@ ioctl$KVM_SET_GUEST_DEBUG(fd fd_kvmcpu, cmd const[KVM_SET_GUEST_DEBUG], arg ptr[ ioctl$KVM_SMI(fd fd_kvmcpu, cmd const[KVM_SMI]) # TODO: extend support (there are some ioctls) -openat$xenevtchn(fd const[AT_FDCWD], file strconst["/dev/xen/evtchn"], flags flags[open_flags], mode const[0]) fd +openat$xenevtchn(fd const[AT_FDCWD], file ptr[in, string["/dev/xen/evtchn"]], flags flags[open_flags], mode const[0]) fd kvm_mem_region_flags = KVM_MEM_LOG_DIRTY_PAGES, KVM_MEM_READONLY, KVM_MEMSLOT_INVALID, KVM_MEMSLOT_INCOHERENT kvm_mp_state = KVM_MP_STATE_RUNNABLE, KVM_MP_STATE_UNINITIALIZED, KVM_MP_STATE_INIT_RECEIVED, KVM_MP_STATE_HALTED, KVM_MP_STATE_SIPI_RECEIVED, KVM_MP_STATE_STOPPED, KVM_MP_STATE_CHECK_STOP, KVM_MP_STATE_OPERATING, KVM_MP_STATE_LOAD diff --git a/sys/random.txt b/sys/random.txt index 7c8fd11c0..234d1be40 100755 --- a/sys/random.txt +++ b/sys/random.txt @@ -5,8 +5,8 @@ include resource fd_random[fd] -syz_open_dev$random(dev strconst["/dev/random"], id const[0], flags flags[open_flags]) fd_random -syz_open_dev$urandom(dev strconst["/dev/urandom"], id const[0], flags flags[open_flags]) fd_random +syz_open_dev$random(dev ptr[in, string["/dev/random"]], id const[0], flags flags[open_flags]) fd_random +syz_open_dev$urandom(dev ptr[in, string["/dev/urandom"]], id const[0], flags flags[open_flags]) fd_random ioctl$RNDGETENTCNT(fd fd_random, cmd const[RNDGETENTCNT], arg ptr[out, int32]) ioctl$RNDADDTOENTCNT(fd fd_random, cmd const[RNDADDTOENTCNT], arg ptr[in, int32]) diff --git a/sys/sndcontrol.txt b/sys/sndcontrol.txt index 3e3b8a359..1ec602f03 100644 --- a/sys/sndcontrol.txt +++ b/sys/sndcontrol.txt @@ -5,7 +5,7 @@ include resource fd_sndctrl[fd] -syz_open_dev$sndctrl(dev strconst["/dev/snd/controlC#"], id intptr, flags flags[open_flags]) fd_sndctrl +syz_open_dev$sndctrl(dev ptr[in, string["/dev/snd/controlC#"]], id intptr, flags flags[open_flags]) fd_sndctrl ioctl$SNDRV_CTL_IOCTL_PVERSION(fd fd_sndctrl, cmd const[SNDRV_CTL_IOCTL_PVERSION], arg buffer[out]) ioctl$SNDRV_CTL_IOCTL_CARD_INFO(fd fd_sndctrl, cmd const[SNDRV_CTL_IOCTL_CARD_INFO], arg buffer[out]) diff --git a/sys/sndseq.txt b/sys/sndseq.txt index 62a844ed7..40ad7118d 100644 --- a/sys/sndseq.txt +++ b/sys/sndseq.txt @@ -6,7 +6,7 @@ include resource fd_sndseq[fd] -syz_open_dev$sndseq(dev strconst["/dev/snd/seq"], id const[0], flags flags[open_flags]) fd_sndseq +syz_open_dev$sndseq(dev ptr[in, string["/dev/snd/seq"]], id const[0], flags flags[open_flags]) fd_sndseq write$sndseq(fd fd_sndseq, data ptr[in, array[snd_seq_event]], len bytesize[data]) ioctl$SNDRV_SEQ_IOCTL_PVERSION(fd fd_sndseq, cmd const[SNDRV_SEQ_IOCTL_PVERSION], arg ptr[out, int32]) diff --git a/sys/sndtimer.txt b/sys/sndtimer.txt index 67e0a13a8..f7eebc2af 100644 --- a/sys/sndtimer.txt +++ b/sys/sndtimer.txt @@ -5,7 +5,7 @@ include resource fd_sndtimer[fd] -syz_open_dev$sndtimer(dev strconst["/dev/snd/timer"], id const[0], flags flags[open_flags]) fd_sndtimer +syz_open_dev$sndtimer(dev ptr[in, string["/dev/snd/timer"]], id const[0], flags flags[open_flags]) fd_sndtimer ioctl$SNDRV_TIMER_IOCTL_PVERSION(fd fd_sndtimer, cmd const[SNDRV_TIMER_IOCTL_PVERSION], arg ptr[out, int32]) ioctl$SNDRV_TIMER_IOCTL_NEXT_DEVICE(fd fd_sndtimer, cmd const[SNDRV_TIMER_IOCTL_NEXT_DEVICE], arg ptr[in, snd_timer_id]) diff --git a/sys/sys.txt b/sys/sys.txt index 13d2d2830..c6da9a800 100644 --- a/sys/sys.txt +++ b/sys/sys.txt @@ -345,14 +345,16 @@ getdents64(fd fd_dir, ent buffer[out], count len[ent]) name_to_handle_at(fd fd_dir, file filename, handle ptr[in, file_handle], mnt ptr[out, int32], flags flags[name_to_handle_at_flags]) open_by_handle_at(mountdirfd fd, handle ptr[in, file_handle], flags flags[open_flags]) -mount(src filename, dst filename, type filesystem, flags flags[mount_flags], data buffer[in]) -mount$fs(src filesystem, dst filename, type filesystem, flags flags[mount_flags], data buffer[in]) +mount(src filename, dst filename, type ptr[in, string[filesystem]], flags flags[mount_flags], data buffer[in]) +mount$fs(src ptr[in, string[filesystem]], dst filename, type ptr[in, string[filesystem]], flags flags[mount_flags], data buffer[in]) umount2(path filename, flags flags[umount_flags]) pivot_root(new_root filename, put_old filename) -sysfs$1(option flags[sysfs_opt1], fsname ptr[in, string]) -sysfs$2(option flags[sysfs_opt2], fsindex intptr, fsname buffer[out]) -sysfs$3(option flags[sysfs_opt3]) +filesystem = "sysfs", "rootfs", "ramfs", "tmpfs", "devtmpfs", "debugfs", "securityfs", "sockfs", "pipefs", "anon_inodefs", "devpts", "ext3", "ext2", "ext4", "hugetlbfs", "vfat", "ecryptfs", "kdbusfs", "fuseblk", "fuse", "rpc_pipefs", "nfs", "nfs4", "nfsd", "binfmt_misc", "autofs", "xfs", "jfs", "msdos", "ntfs", "minix", "hfs", "hfsplus", "qnx4", "ufs", "btrfs", "configfs", "ncpfs", "qnx6", "exofs", "befs", "vxfs", "gfs2", "gfs2meta", "fusectl", "bfs", "nsfs", "efs", "cifs", "efivarfs", "affs", "tracefs", "bdev", "ocfs2", "ocfs2_dlmfs", "hpfs", "proc", "afs", "reiserfs", "jffs2", "romfs", "aio", "sysv", "v7", "udf", "ceph", "pstore", "adfs", "9p", "hostfs", "squashfs", "cramfs", "iso9660", "coda", "nilfs2", "logfs", "overlay", "f2fs", "omfs", "ubifs", "openpromfs" + +sysfs$1(option const[1], fsname ptr[in, string]) +sysfs$2(option const[2], fsindex intptr, fsname buffer[out]) +sysfs$3(option const[3]) statfs(path filename, buf buffer[out]) fstatfs(fd fd, buf buffer[out]) @@ -463,55 +465,55 @@ membarrier(cmd const[1], flags const[0]) # These devices are relatively safe (don't reboot and don't corrupt kernel memory). # They need a more comprehensive support. But let at least open them for now, # maybe fuzzer will be able to skrew them in a useful way. -syz_open_dev$floppy(dev strconst["/dev/fd#"], id intptr, flags flags[open_flags]) fd -syz_open_dev$pktcdvd(dev strconst["/dev/pktcdvd/control"], id const[0], flags flags[open_flags]) fd -syz_open_dev$lightnvm(dev strconst["/dev/lightnvm/control"], id const[0], flags flags[open_flags]) fd -syz_open_dev$vcs(dev strconst["/dev/vcs"], id const[0], flags flags[open_flags]) fd -syz_open_dev$vcsn(dev strconst["/dev/vcs#"], id intptr, flags flags[open_flags]) fd -syz_open_dev$vcsa(dev strconst["/dev/vcsa#"], id intptr, flags flags[open_flags]) fd -syz_open_dev$vga_arbiter(dev strconst["/dev/vga_arbiter"], id const[0], flags flags[open_flags]) fd -syz_open_dev$vhci(dev strconst["/dev/vhci"], id const[0], flags flags[open_flags]) fd -syz_open_dev$userio(dev strconst["/dev/userio"], id const[0], flags flags[open_flags]) fd -syz_open_dev$rtc(dev strconst["/dev/rtc"], id const[0], flags flags[open_flags]) fd -syz_open_dev$rfkill(dev strconst["/dev/rfkill"], id const[0], flags flags[open_flags]) fd -syz_open_dev$qat_adf_ctl(dev strconst["/dev/qat_adf_ctl"], id const[0], flags flags[open_flags]) fd -syz_open_dev$ppp(dev strconst["/dev/ppp"], id const[0], flags flags[open_flags]) fd -syz_open_dev$mixer(dev strconst["/dev/mixer"], id const[0], flags flags[open_flags]) fd -syz_open_dev$irnet(dev strconst["/dev/irnet"], id const[0], flags flags[open_flags]) fd -syz_open_dev$hwrng(dev strconst["/dev/hwrng"], id const[0], flags flags[open_flags]) fd -syz_open_dev$hpet(dev strconst["/dev/hpet"], id const[0], flags flags[open_flags]) fd -syz_open_dev$hidraw0(dev strconst["/dev/hidraw0"], id const[0], flags flags[open_flags]) fd -syz_open_dev$fb0(dev strconst["/dev/fb0"], id const[0], flags flags[open_flags]) fd -syz_open_dev$cuse(dev strconst["/dev/cuse"], id const[0], flags flags[open_flags]) fd -syz_open_dev$console(dev strconst["/dev/console"], id const[0], flags flags[open_flags]) fd -syz_open_dev$capi20(dev strconst["/dev/capi20"], id const[0], flags flags[open_flags]) fd -syz_open_dev$autofs(dev strconst["/dev/autofs"], id const[0], flags flags[open_flags]) fd -syz_open_dev$binder(dev strconst["/dev/binder"], id const[0], flags flags[open_flags]) fd -syz_open_dev$ion(dev strconst["/dev/ion"], id const[0], flags flags[open_flags]) fd -syz_open_dev$keychord(dev strconst["/dev/keychord"], id const[0], flags flags[open_flags]) fd -syz_open_dev$zygote(dev strconst["/dev/socket/zygote"], id const[0], flags flags[open_flags]) fd -syz_open_dev$sw_sync(dev strconst["/dev/sw_sync"], id const[0], flags flags[open_flags]) fd -syz_open_dev$sr(dev strconst["/dev/sr0"], id const[0], flags flags[open_flags]) fd -syz_open_dev$sequencer(dev strconst["/dev/sequencer"], id const[0], flags flags[open_flags]) fd -syz_open_dev$sequencer2(dev strconst["/dev/sequencer2"], id const[0], flags flags[open_flags]) fd -syz_open_dev$dsp(dev strconst["/dev/dsp"], id const[0], flags flags[open_flags]) fd -syz_open_dev$audio(dev strconst["/dev/audio"], id const[0], flags flags[open_flags]) fd -syz_open_dev$usbmon(dev strconst["/dev/usbmon#"], id intptr, flags flags[open_flags]) fd -syz_open_dev$sg(dev strconst["/dev/sg#"], id intptr, flags flags[open_flags]) fd -syz_open_dev$midi(dev strconst["/dev/midi#"], id intptr, flags flags[open_flags]) fd -syz_open_dev$loop(dev strconst["/dev/loop#"], id intptr, flags flags[open_flags]) fd -syz_open_dev$ircomm(dev strconst["/dev/ircomm#"], id intptr, flags flags[open_flags]) fd -syz_open_dev$dspn(dev strconst["/dev/dsp#"], id intptr, flags flags[open_flags]) fd -syz_open_dev$dmmidi(dev strconst["/dev/dmmidi#"], id intptr, flags flags[open_flags]) fd -syz_open_dev$admmidi(dev strconst["/dev/admmidi#"], id intptr, flags flags[open_flags]) fd -syz_open_dev$adsp(dev strconst["/dev/adsp#"], id intptr, flags flags[open_flags]) fd -syz_open_dev$amidi(dev strconst["/dev/amidi#"], id intptr, flags flags[open_flags]) fd -syz_open_dev$audion(dev strconst["/dev/audio#"], id intptr, flags flags[open_flags]) fd -syz_open_dev$usb(dev strconst["/dev/bus/usb/00#/00#"], id intptr, flags flags[open_flags]) fd -syz_open_dev$sndhw(dev strconst["/dev/snd/hwC#D#"], id intptr, flags flags[open_flags]) fd -syz_open_dev$sndmidi(dev strconst["/dev/snd/midiC#D#"], id intptr, flags flags[open_flags]) fd -syz_open_dev$sndpcmc(dev strconst["/dev/snd/pcmC#D#c"], id intptr, flags flags[open_flags]) fd -syz_open_dev$sndpcmp(dev strconst["/dev/snd/pcmC#D#p"], id intptr, flags flags[open_flags]) fd +syz_open_dev$floppy(dev ptr[in, string["/dev/fd#"]], id intptr, flags flags[open_flags]) fd +syz_open_dev$pktcdvd(dev ptr[in, string["/dev/pktcdvd/control"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$lightnvm(dev ptr[in, string["/dev/lightnvm/control"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$vcs(dev ptr[in, string["/dev/vcs"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$vcsn(dev ptr[in, string["/dev/vcs#"]], id intptr, flags flags[open_flags]) fd +syz_open_dev$vcsa(dev ptr[in, string["/dev/vcsa#"]], id intptr, flags flags[open_flags]) fd +syz_open_dev$vga_arbiter(dev ptr[in, string["/dev/vga_arbiter"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$vhci(dev ptr[in, string["/dev/vhci"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$userio(dev ptr[in, string["/dev/userio"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$rtc(dev ptr[in, string["/dev/rtc"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$rfkill(dev ptr[in, string["/dev/rfkill"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$qat_adf_ctl(dev ptr[in, string["/dev/qat_adf_ctl"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$ppp(dev ptr[in, string["/dev/ppp"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$mixer(dev ptr[in, string["/dev/mixer"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$irnet(dev ptr[in, string["/dev/irnet"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$hwrng(dev ptr[in, string["/dev/hwrng"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$hpet(dev ptr[in, string["/dev/hpet"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$hidraw0(dev ptr[in, string["/dev/hidraw0"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$fb0(dev ptr[in, string["/dev/fb0"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$cuse(dev ptr[in, string["/dev/cuse"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$console(dev ptr[in, string["/dev/console"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$capi20(dev ptr[in, string["/dev/capi20"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$autofs(dev ptr[in, string["/dev/autofs"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$binder(dev ptr[in, string["/dev/binder"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$ion(dev ptr[in, string["/dev/ion"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$keychord(dev ptr[in, string["/dev/keychord"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$zygote(dev ptr[in, string["/dev/socket/zygote"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$sw_sync(dev ptr[in, string["/dev/sw_sync"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$sr(dev ptr[in, string["/dev/sr0"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$sequencer(dev ptr[in, string["/dev/sequencer"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$sequencer2(dev ptr[in, string["/dev/sequencer2"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$dsp(dev ptr[in, string["/dev/dsp"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$audio(dev ptr[in, string["/dev/audio"]], id const[0], flags flags[open_flags]) fd +syz_open_dev$usbmon(dev ptr[in, string["/dev/usbmon#"]], id intptr, flags flags[open_flags]) fd +syz_open_dev$sg(dev ptr[in, string["/dev/sg#"]], id intptr, flags flags[open_flags]) fd +syz_open_dev$midi(dev ptr[in, string["/dev/midi#"]], id intptr, flags flags[open_flags]) fd +syz_open_dev$loop(dev ptr[in, string["/dev/loop#"]], id intptr, flags flags[open_flags]) fd +syz_open_dev$ircomm(dev ptr[in, string["/dev/ircomm#"]], id intptr, flags flags[open_flags]) fd +syz_open_dev$dspn(dev ptr[in, string["/dev/dsp#"]], id intptr, flags flags[open_flags]) fd +syz_open_dev$dmmidi(dev ptr[in, string["/dev/dmmidi#"]], id intptr, flags flags[open_flags]) fd +syz_open_dev$admmidi(dev ptr[in, string["/dev/admmidi#"]], id intptr, flags flags[open_flags]) fd +syz_open_dev$adsp(dev ptr[in, string["/dev/adsp#"]], id intptr, flags flags[open_flags]) fd +syz_open_dev$amidi(dev ptr[in, string["/dev/amidi#"]], id intptr, flags flags[open_flags]) fd +syz_open_dev$audion(dev ptr[in, string["/dev/audio#"]], id intptr, flags flags[open_flags]) fd +syz_open_dev$usb(dev ptr[in, string["/dev/bus/usb/00#/00#"]], id intptr, flags flags[open_flags]) fd +syz_open_dev$sndhw(dev ptr[in, string["/dev/snd/hwC#D#"]], id intptr, flags flags[open_flags]) fd +syz_open_dev$sndmidi(dev ptr[in, string["/dev/snd/midiC#D#"]], id intptr, flags flags[open_flags]) fd +syz_open_dev$sndpcmc(dev ptr[in, string["/dev/snd/pcmC#D#c"]], id intptr, flags flags[open_flags]) fd +syz_open_dev$sndpcmp(dev ptr[in, string["/dev/snd/pcmC#D#p"]], id intptr, flags flags[open_flags]) fd @@ -1167,9 +1169,6 @@ ioprio_which_uid = IOPRIO_WHO_USER setxattr_flags = XATTR_CREATE, XATTR_REPLACE ns_type = 0, CLONE_NEWIPC, CLONE_NEWNET, CLONE_NEWUTS personality_flags = PER_LINUX, PER_SVR4, PER_SVR3, PER_OSR5, PER_WYSEV386, PER_ISCR4, PER_BSD, PER_XENIX, PER_LINUX32, PER_IRIX32, PER_IRIXN32, PER_IRIX64, PER_RISCOS, PER_SOLARIS, PER_UW7, PER_OSF4, PER_HPUX, ADDR_NO_RANDOMIZE, MMAP_PAGE_ZERO, ADDR_COMPAT_LAYOUT, READ_IMPLIES_EXEC, ADDR_LIMIT_32BIT, SHORT_INODE, WHOLE_SECONDS, STICKY_TIMEOUTS, ADDR_LIMIT_3GB -sysfs_opt1 = 1 -sysfs_opt2 = 2 -sysfs_opt3 = 3 clock_id = CLOCK_REALTIME, CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC, CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_RAW, CLOCK_BOOTTIME, CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID sigprocmask_how = SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK getitimer_which = ITIMER_REAL, ITIMER_VIRTUAL, ITIMER_PROF diff --git a/sys/tlk_device.txt b/sys/tlk_device.txt index 7535d16f7..1d5bd8229 100644 --- a/sys/tlk_device.txt +++ b/sys/tlk_device.txt @@ -12,7 +12,7 @@ include resource fd_tlk[fd] resource te_session_id[int32] -syz_open_dev$tlk_device(dev strconst["/dev/tlk_device"], id const[0], flags flags[open_flags]) fd_tlk +syz_open_dev$tlk_device(dev ptr[in, string["/dev/tlk_device"]], id const[0], flags flags[open_flags]) fd_tlk ioctl$TE_IOCTL_OPEN_CLIENT_SESSION(fd fd_tlk, cmd const[TE_IOCTL_OPEN_CLIENT_SESSION], arg ptr[inout, te_opensession]) ioctl$TE_IOCTL_CLOSE_CLIENT_SESSION(fd fd_tlk, cmd const[TE_IOCTL_CLOSE_CLIENT_SESSION], arg ptr[inout, te_closesession]) diff --git a/sys/tty.txt b/sys/tty.txt index 67b11b754..e9717806c 100644 --- a/sys/tty.txt +++ b/sys/tty.txt @@ -8,7 +8,7 @@ include resource fd_tty[fd] -openat$ptmx(fd const[AT_FDCWD], file strconst["/dev/ptmx"], flags flags[open_flags], mode const[0]) fd_tty +openat$ptmx(fd const[AT_FDCWD], file ptr[in, string["/dev/ptmx"]], flags flags[open_flags], mode const[0]) fd_tty syz_open_pts(fd fd_tty, flags flags[open_flags]) fd_tty ioctl$TCGETS(fd fd_tty, cmd const[TCGETS], arg ptr[out, termios]) ioctl$TCSETS(fd fd_tty, cmd const[TCSETS], arg ptr[in, termios]) diff --git a/sys/tun.txt b/sys/tun.txt index 04e640786..a730ed86a 100755 --- a/sys/tun.txt +++ b/sys/tun.txt @@ -6,7 +6,7 @@ include resource fd_tun[fd] -syz_open_dev$tun(dev strconst["/dev/net/tun"], id const[0], flags flags[open_flags]) fd_tun +syz_open_dev$tun(dev ptr[in, string["/dev/net/tun"]], id const[0], flags flags[open_flags]) fd_tun write$tun(fd fd_tun, buf ptr[in, tun_buffer], count len[buf]) ioctl$TUNGETFEATURES(fd fd_tun, cmd const[TUNGETFEATURES], arg ptr[out, int32]) diff --git a/sysgen/sysgen.go b/sysgen/sysgen.go index 7159ef70c..6913b9c81 100644 --- a/sysgen/sysgen.go +++ b/sysgen/sysgen.go @@ -407,19 +407,27 @@ func generateArg( opt = false fmt.Fprintf(out, "&PtrType{%v, Type: &BufferType{%v, Kind: BufferBlobRand}}", ptrCommonHdr, common()) case "string": - if want := 0; len(a) != want { - failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a)) + if len(a) != 0 && len(a) != 1 { + failf("wrong number of arguments for %v arg %v, want 0 or 1, got %v", typ, name, len(a)) } - fmt.Fprintf(out, "&BufferType{%v, Kind: BufferString}", common()) - case "filesystem": - canBeArg = true - if want := 0; len(a) != want { - failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a)) + var vals []string + subkind := "" + if len(a) == 1 { + if a[0][0] == '"' { + vals = append(vals, a[0][1:len(a[0])-1]) + } else { + ok := false + vals, ok = desc.StrFlags[a[0]] + if !ok { + failf("unknown string flags %v", a[0]) + } + subkind = a[0] + } + for i, s := range vals { + vals[i] = s + "\x00" + } } - ptrCommonHdr := common() - dir = "in" - opt = false - fmt.Fprintf(out, "&PtrType{%v, Type: &BufferType{%v, Kind: BufferFilesystem}}", ptrCommonHdr, common()) + fmt.Fprintf(out, "&BufferType{%v, Kind: BufferString, SubKind: %q, Values: %#v}", common(), subkind, vals) case "sockaddr": if want := 0; len(a) != want { failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a)) @@ -503,15 +511,6 @@ func generateArg( skipSyscall(fmt.Sprintf("missing const %v", a[0])) } fmt.Fprintf(out, "&ConstType{%v, TypeSize: %v, BigEndian: %v, Val: uintptr(%v)}", common(), size, bigEndian, val) - case "strconst": - canBeArg = true - if want := 1; len(a) != want { - failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a)) - } - ptrCommonHdr := common() - dir = "in" - opt = false - fmt.Fprintf(out, "&PtrType{%v, Type: &StrConstType{%v, Val: \"%v\"}}", ptrCommonHdr, common(), a[0]+"\\x00") case "int8", "int16", "int32", "int64", "intptr", "int16be", "int32be", "int64be", "intptrbe": canBeArg = true size, bigEndian := decodeIntType(typ) diff --git a/sysparser/lexer.go b/sysparser/lexer.go index 18143c901..a3b8f58ed 100644 --- a/sysparser/lexer.go +++ b/sysparser/lexer.go @@ -18,6 +18,7 @@ type Description struct { Structs map[string]Struct Unnamed map[string][]string Flags map[string][]string + StrFlags map[string][]string Resources map[string]Resource } @@ -51,6 +52,7 @@ func Parse(in io.Reader) *Description { structs := make(map[string]Struct) unnamed := make(map[string][]string) flags := make(map[string][]string) + strflags := make(map[string][]string) resources := make(map[string]Resource) var str *Struct for p.Scan() { @@ -192,12 +194,24 @@ func Parse(in io.Reader) *Description { case '=': // flag p.Parse('=') - vals := []string{p.Ident()} - for !p.EOF() { + str := p.Char() == '"' + var vals []string + for { + v := p.Ident() + if str { + v = v[1 : len(v)-1] + } + vals = append(vals, v) + if p.EOF() { + break + } p.Parse(',') - vals = append(vals, p.Ident()) } - flags[name] = vals + if str { + strflags[name] = vals + } else { + flags[name] = vals + } case '{', '[': p.Parse(ch) if _, ok := structs[name]; ok { @@ -224,6 +238,7 @@ func Parse(in io.Reader) *Description { Structs: structs, Unnamed: unnamed, Flags: flags, + StrFlags: strflags, Resources: resources, } } diff --git a/sysparser/parser.go b/sysparser/parser.go index 590847b0e..d5021eee6 100644 --- a/sysparser/parser.go +++ b/sysparser/parser.go @@ -70,11 +70,10 @@ func (p *parser) Ident() string { start, end := p.i, 0 if p.Char() == '"' { p.Parse('"') - start++ for p.Char() != '"' { p.i++ } - end = p.i + end = p.i + 1 p.Parse('"') } else { for p.i < len(p.s) && -- cgit mrf-deployment