diff options
| -rw-r--r-- | pkg/compiler/gen.go | 15 | ||||
| -rw-r--r-- | pkg/mgrconfig/config.go | 3 | ||||
| -rw-r--r-- | pkg/mgrconfig/load.go | 39 | ||||
| -rw-r--r-- | pkg/vminfo/linux_syscalls.go | 12 | ||||
| -rw-r--r-- | pkg/vminfo/syscalls.go | 7 | ||||
| -rw-r--r-- | prog/types.go | 1 | ||||
| -rw-r--r-- | tools/syz-execprog/execprog.go | 2 | ||||
| -rw-r--r-- | tools/syz-mutate/mutate.go | 2 | ||||
| -rw-r--r-- | tools/syz-showprio/showprio.go | 2 |
9 files changed, 66 insertions, 17 deletions
diff --git a/pkg/compiler/gen.go b/pkg/compiler/gen.go index 1fcf8dcac..891cd1644 100644 --- a/pkg/compiler/gen.go +++ b/pkg/compiler/gen.go @@ -78,7 +78,7 @@ func (comp *compiler) collectCallArgSizes() map[string][]uint64 { comp.error(arg.Pos, "%v arg %v is larger than pointer size", n.Name.Name, arg.Name.Name) continue } - argID := fmt.Sprintf("%v|%v", n.CallName, i) + argID := fmt.Sprintf("%v|%v", getCallName(n), i) if _, ok := argPos[argID]; !ok { argSizes[i] = typ.Size() argPos[argID] = arg.Pos @@ -90,17 +90,26 @@ func (comp *compiler) collectCallArgSizes() map[string][]uint64 { continue } } - callArgSizes[n.CallName] = argSizes + callArgSizes[getCallName(n)] = argSizes } return callArgSizes } +func getCallName(n *ast.Call) string { + for _, attr := range n.Attrs { + if attr.Ident == "automatic" { + return n.Name.Name + } + } + return n.CallName +} + func (comp *compiler) genSyscalls() []*prog.Syscall { callArgSizes := comp.collectCallArgSizes() var calls []*prog.Syscall for _, decl := range comp.desc.Nodes { if n, ok := decl.(*ast.Call); ok && n.NR != ^uint64(0) { - calls = append(calls, comp.genSyscall(n, callArgSizes[n.CallName])) + calls = append(calls, comp.genSyscall(n, callArgSizes[getCallName(n)])) } } // We assign SquashableElem here rather than during pointer type generation diff --git a/pkg/mgrconfig/config.go b/pkg/mgrconfig/config.go index b4368f6d5..2ea0d8ad9 100644 --- a/pkg/mgrconfig/config.go +++ b/pkg/mgrconfig/config.go @@ -232,6 +232,9 @@ type Experimental struct { // Hash adjacent PCs to form fuzzing feedback signal, otherwise use PCs as signal (default: true). CoverEdges bool `json:"cover_edges"` + + // Use automatically (auto) generated or manually (manual) written descriptions or any (any) (default: manual) + DescriptionsMode string `json:"descriptions_mode"` } type Subsystem struct { diff --git a/pkg/mgrconfig/load.go b/pkg/mgrconfig/load.go index 6f92a232e..9120dd236 100644 --- a/pkg/mgrconfig/load.go +++ b/pkg/mgrconfig/load.go @@ -94,12 +94,32 @@ func defaultValues() *Config { Procs: 6, PreserveCorpus: true, Experimental: Experimental{ - RemoteCover: true, - CoverEdges: true, + RemoteCover: true, + CoverEdges: true, + DescriptionsMode: manualDescriptions, }, } } +type DescriptionsMode int + +const ( + invalidDescriptions = iota + ManualDescriptions + AutoDescriptions + AnyDescriptions +) + +const manualDescriptions = "manual" + +var ( + strToDescriptionsMode = map[string]DescriptionsMode{ + manualDescriptions: ManualDescriptions, + "auto": AutoDescriptions, + "any": AnyDescriptions, + } +) + func loadPartial(cfg *Config) (*Config, error) { var err error cfg.TargetOS, cfg.TargetVMArch, cfg.TargetArch, err = splitTarget(cfg.RawTarget) @@ -171,7 +191,8 @@ func Complete(cfg *Config) error { } var err error - cfg.Syscalls, err = ParseEnabledSyscalls(cfg.Target, cfg.EnabledSyscalls, cfg.DisabledSyscalls) + cfg.Syscalls, err = ParseEnabledSyscalls(cfg.Target, cfg.EnabledSyscalls, cfg.DisabledSyscalls, + strToDescriptionsMode[cfg.Experimental.DescriptionsMode]) if err != nil { return err } @@ -317,7 +338,12 @@ func splitTarget(target string) (string, string, string, error) { return os, vmarch, arch, nil } -func ParseEnabledSyscalls(target *prog.Target, enabled, disabled []string) ([]int, error) { +func ParseEnabledSyscalls(target *prog.Target, enabled, disabled []string, + descriptionsMode DescriptionsMode) ([]int, error) { + if descriptionsMode == invalidDescriptions { + return nil, fmt.Errorf("config param descriptions_mode must contain one of auto/manual/any") + } + syscalls := make(map[int]bool) if len(enabled) != 0 { for _, c := range enabled { @@ -337,8 +363,11 @@ func ParseEnabledSyscalls(target *prog.Target, enabled, disabled []string) ([]in syscalls[call.ID] = true } } + for call := range syscalls { - if target.Syscalls[call].Attrs.Disabled { + if target.Syscalls[call].Attrs.Disabled || + descriptionsMode == ManualDescriptions && target.Syscalls[call].Attrs.Automatic || + descriptionsMode == AutoDescriptions && !target.Syscalls[call].Attrs.Automatic { delete(syscalls, call) } } diff --git a/pkg/vminfo/linux_syscalls.go b/pkg/vminfo/linux_syscalls.go index b27846e01..3f675c6a9 100644 --- a/pkg/vminfo/linux_syscalls.go +++ b/pkg/vminfo/linux_syscalls.go @@ -102,11 +102,12 @@ var linuxSyscallChecks = map[string]func(*checkContext, *prog.Syscall) string{ } func linuxSyzOpenDevSupported(ctx *checkContext, call *prog.Syscall) string { - if _, ok := call.Args[0].Type.(*prog.ConstType); ok { + if _, ok := call.Args[0].Type.(*prog.ConstType); ok || call.Attrs.Automatic { // This is for syz_open_dev$char/block. + // second operand for when we have an automatically generated description return "" } - fname, ok := extractStringConst(call.Args[0].Type) + fname, ok := extractStringConst(call.Args[0].Type, call.Attrs.Automatic) if !ok { panic("first open arg is not a pointer to string const") } @@ -192,7 +193,10 @@ func linuxSyzMountImageSupported(ctx *checkContext, call *prog.Syscall) string { } func linuxSupportedFilesystem(ctx *checkContext, call *prog.Syscall, fsarg int) string { - fstype, ok := extractStringConst(call.Args[fsarg].Type) + if call.Attrs.Automatic { + return "" + } + fstype, ok := extractStringConst(call.Args[fsarg].Type, call.Attrs.Automatic) if !ok { panic(fmt.Sprintf("%v: filesystem is not string const", call.Name)) } @@ -224,7 +228,7 @@ func linuxSyzReadPartTableSupported(ctx *checkContext, call *prog.Syscall) strin } func linuxSupportedSocket(ctx *checkContext, call *prog.Syscall) string { - if call.Name == "socket" || call.Name == "socketpair" { + if call.Name == "socket" || call.Name == "socketpair" || call.Attrs.Automatic { return "" // generic versions are always supported } af := uint64(0) diff --git a/pkg/vminfo/syscalls.go b/pkg/vminfo/syscalls.go index 178e5d52c..707ab6543 100644 --- a/pkg/vminfo/syscalls.go +++ b/pkg/vminfo/syscalls.go @@ -161,7 +161,7 @@ func (ctx *checkContext) supportedSyscalls(names []string) string { } func supportedOpenat(ctx *checkContext, call *prog.Syscall) string { - fname, ok := extractStringConst(call.Args[1].Type) + fname, ok := extractStringConst(call.Args[1].Type, call.Attrs.Automatic) if !ok || fname[0] != '/' { return "" } @@ -277,7 +277,10 @@ func alwaysSupported(ctx *checkContext, call *prog.Syscall) string { return "" } -func extractStringConst(typ prog.Type) (string, bool) { +func extractStringConst(typ prog.Type, isAutomatic bool) (string, bool) { + if isAutomatic { + return "", false + } ptr, ok := typ.(*prog.PtrType) if !ok { panic("first open arg is not a pointer to string const") diff --git a/prog/types.go b/prog/types.go index 50588cb19..dcf838528 100644 --- a/prog/types.go +++ b/prog/types.go @@ -45,6 +45,7 @@ type SyscallAttrs struct { NoGenerate bool NoMinimize bool RemoteCover bool + Automatic bool } // MaxArgs is maximum number of syscall arguments. diff --git a/tools/syz-execprog/execprog.go b/tools/syz-execprog/execprog.go index e86d09053..550b3c114 100644 --- a/tools/syz-execprog/execprog.go +++ b/tools/syz-execprog/execprog.go @@ -109,7 +109,7 @@ func main() { if *flagSyscalls == "" { syscallList = nil } - requestedSyscalls, err = mgrconfig.ParseEnabledSyscalls(target, syscallList, nil) + requestedSyscalls, err = mgrconfig.ParseEnabledSyscalls(target, syscallList, nil, mgrconfig.AnyDescriptions) if err != nil { tool.Failf("failed to parse enabled syscalls: %v", err) } diff --git a/tools/syz-mutate/mutate.go b/tools/syz-mutate/mutate.go index 351d0ae6a..aa812a447 100644 --- a/tools/syz-mutate/mutate.go +++ b/tools/syz-mutate/mutate.go @@ -42,7 +42,7 @@ func main() { var syscalls map[*prog.Syscall]bool if *flagEnable != "" { enabled := strings.Split(*flagEnable, ",") - syscallsIDs, err := mgrconfig.ParseEnabledSyscalls(target, enabled, nil) + syscallsIDs, err := mgrconfig.ParseEnabledSyscalls(target, enabled, nil, mgrconfig.AnyDescriptions) if err != nil { fmt.Fprintf(os.Stderr, "failed to parse enabled syscalls: %v\n", err) os.Exit(1) diff --git a/tools/syz-showprio/showprio.go b/tools/syz-showprio/showprio.go index 0729f4388..f9ec2ff69 100644 --- a/tools/syz-showprio/showprio.go +++ b/tools/syz-showprio/showprio.go @@ -35,7 +35,7 @@ func main() { os.Exit(1) } enabled := strings.Split(*flagEnable, ",") - _, err = mgrconfig.ParseEnabledSyscalls(target, enabled, nil) + _, err = mgrconfig.ParseEnabledSyscalls(target, enabled, nil, mgrconfig.AnyDescriptions) if err != nil { fmt.Fprintf(os.Stderr, "failed to parse enabled syscalls: %v\n", err) os.Exit(1) |
