aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pkg/compiler/gen.go15
-rw-r--r--pkg/mgrconfig/config.go3
-rw-r--r--pkg/mgrconfig/load.go39
-rw-r--r--pkg/vminfo/linux_syscalls.go12
-rw-r--r--pkg/vminfo/syscalls.go7
-rw-r--r--prog/types.go1
-rw-r--r--tools/syz-execprog/execprog.go2
-rw-r--r--tools/syz-mutate/mutate.go2
-rw-r--r--tools/syz-showprio/showprio.go2
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)