diff options
Diffstat (limited to 'pkg')
| -rw-r--r-- | pkg/declextract/declextract.go | 1 | ||||
| -rw-r--r-- | pkg/declextract/entity.go | 3 | ||||
| -rw-r--r-- | pkg/declextract/netlink.go | 95 | ||||
| -rw-r--r-- | pkg/declextract/serialization.go | 21 |
4 files changed, 42 insertions, 78 deletions
diff --git a/pkg/declextract/declextract.go b/pkg/declextract/declextract.go index 49a515ddb..f950cee1e 100644 --- a/pkg/declextract/declextract.go +++ b/pkg/declextract/declextract.go @@ -22,7 +22,6 @@ func Run(out *Output, syscallRename map[string][]string) ([]byte, []*Interface, ctx.processStructs() ctx.processSyscalls() ctx.processIouring() - ctx.fabricateNetlinkPolicies() ctx.serialize() ctx.finishInterfaces() diff --git a/pkg/declextract/entity.go b/pkg/declextract/entity.go index 57e589e40..6e9ddac85 100644 --- a/pkg/declextract/entity.go +++ b/pkg/declextract/entity.go @@ -80,9 +80,6 @@ type Struct struct { IsPacked bool `json:"is_packed,omitempty"` Align int `json:"align,omitempty"` Fields []*Field `json:"fields,omitempty"` - - // TODO: remove me. - isVarlen bool } type Enum struct { diff --git a/pkg/declextract/netlink.go b/pkg/declextract/netlink.go index ad80122dc..3f2384cc6 100644 --- a/pkg/declextract/netlink.go +++ b/pkg/declextract/netlink.go @@ -5,69 +5,28 @@ package declextract import ( "fmt" - "sort" "strings" ) -func (ctx *context) fabricateNetlinkPolicies() { +func (ctx *context) serializeNetlink() { + // policyQueue helps to emit policies on their first use. + pq := &policyQueue{ + policies: make(map[string]*NetlinkPolicy), + } for _, pol := range ctx.NetlinkPolicies { - if len(pol.Attrs) == 0 { - continue - } - str := &Struct{ - Name: pol.Name + autoSuffix, - IsUnion: true, - isVarlen: true, - } - for _, attr := range pol.Attrs { - str.Fields = append(str.Fields, &Field{ - Name: attr.Name, - syzType: ctx.nlattrType(attr), - }) - } - ctx.Structs = append(ctx.Structs, str) + pq.policies[pol.Name] = pol } - ctx.Structs = sortAndDedupSlice(ctx.Structs) -} - -func (ctx *context) emitNetlinkTypes() { for _, fam := range ctx.NetlinkFamilies { if isEmptyFamily(fam) { continue } id := stringIdentifier(fam.Name) ctx.fmt("resource genl_%v_family_id%v[int16]\n", id, autoSuffix) - } - for _, fam := range ctx.NetlinkFamilies { - if isEmptyFamily(fam) { - continue - } - id := stringIdentifier(fam.Name) ctx.fmt("type msghdr_%v%v[CMD, POLICY] msghdr_netlink[netlink_msg_t"+ "[genl_%v_family_id%v, genlmsghdr_t[CMD], POLICY]]\n", id, autoSuffix, id, autoSuffix) - } - for _, pol := range ctx.NetlinkPolicies { - if len(pol.Attrs) == 0 { - ctx.fmt("type %v auto_todo\n", pol.Name+autoSuffix) - } - } -} - -func (ctx *context) emitNetlinkGetFamily() { - for _, fam := range ctx.NetlinkFamilies { - if isEmptyFamily(fam) { - continue - } - id := stringIdentifier(fam.Name) ctx.fmt("syz_genetlink_get_family_id%v_%v(name ptr[in, string[\"%v\"]],"+ - " fd sock_nl_generic) genl_%v_family_id%v\n", autoSuffix, id, fam.Name, id, autoSuffix) - } -} + " fd sock_nl_generic) genl_%v_family_id%v\n\n", autoSuffix, id, fam.Name, id, autoSuffix) -func (ctx *context) emitNetlinkSendmsgs() { - var syscalls []string - for _, fam := range ctx.NetlinkFamilies { - id := stringIdentifier(fam.Name) dedup := make(map[string]bool) for _, op := range fam.Ops { // TODO: emit these as well, these are dump commands w/o input arguments. @@ -80,9 +39,10 @@ func (ctx *context) emitNetlinkSendmsgs() { continue } dedup[op.Name] = true - syscalls = append(syscalls, fmt.Sprintf("sendmsg%v_%v(fd sock_nl_generic,"+ + ctx.fmt("sendmsg%v_%v(fd sock_nl_generic,"+ " msg ptr[in, msghdr_%v%v[%v, %v]], f flags[send_flags])\n", - autoSuffix, op.Name, id, autoSuffix, op.Name, op.Policy+autoSuffix)) + autoSuffix, op.Name, id, autoSuffix, op.Name, op.Policy+autoSuffix) + pq.policyUsed(op.Policy) ctx.noteInterface(&Interface{ Type: IfaceNetlinkOp, @@ -94,11 +54,37 @@ func (ctx *context) emitNetlinkSendmsgs() { AutoDescriptions: true, }) } + + for len(pq.pending) != 0 { + pol := pq.pending[0] + pq.pending = pq.pending[1:] + ctx.serializeNetlinkPolicy(pol, pq) + } + } +} + +type policyQueue struct { + policies map[string]*NetlinkPolicy + pending []*NetlinkPolicy +} + +func (pq *policyQueue) policyUsed(name string) { + if pol := pq.policies[name]; pol != nil { + delete(pq.policies, name) + pq.pending = append(pq.pending, pol) + } +} + +func (ctx *context) serializeNetlinkPolicy(pol *NetlinkPolicy, pq *policyQueue) { + if len(pol.Attrs) == 0 { + ctx.fmt("type %v auto_todo\n", pol.Name+autoSuffix) + return } - sort.Strings(syscalls) - for _, call := range syscalls { - ctx.fmt("%s", call) + ctx.fmt("%v [\n", pol.Name+autoSuffix) + for _, attr := range pol.Attrs { + ctx.fmt("%v %v\n", attr.Name, ctx.nlattrType(attr, pq)) } + ctx.fmt("] [varlen]\n") } func isEmptyFamily(fam *NetlinkFamily) bool { @@ -110,7 +96,7 @@ func isEmptyFamily(fam *NetlinkFamily) bool { return true } -func (ctx *context) nlattrType(attr *NetlinkAttr) string { +func (ctx *context) nlattrType(attr *NetlinkAttr, pq *policyQueue) string { nlattr, typ := "nlattr", "" switch attr.Kind { case "NLA_BITFIELD32": @@ -124,6 +110,7 @@ func (ctx *context) nlattrType(attr *NetlinkAttr) string { nlattr = "nlnest" policy := "nl_generic_attr" if attr.NestedPolicy != "" { + pq.policyUsed(attr.NestedPolicy) policy = attr.NestedPolicy + autoSuffix } typ = fmt.Sprintf("array[%v]", policy) diff --git a/pkg/declextract/serialization.go b/pkg/declextract/serialization.go index c737a675c..1bc82a86b 100644 --- a/pkg/declextract/serialization.go +++ b/pkg/declextract/serialization.go @@ -14,8 +14,8 @@ func (ctx *context) serialize() { ctx.fmt(header) ctx.serializeIncludes() ctx.serializeEnums() - ctx.emitNetlinkTypes() ctx.serializeSyscalls() + ctx.serializeNetlink() ctx.serializeStructs() ctx.serializeDefines() } @@ -47,28 +47,12 @@ func (ctx *context) serializeDefines() { } func (ctx *context) serializeSyscalls() { - printedGetFamily, printedSendmsg := false, false for _, call := range ctx.Syscalls { ctx.fmt("%v(", call.Func) for i, arg := range call.Args { ctx.fmt("%v%v %v", comma(i), arg.Name, arg.syzType) } ctx.fmt(")\n") - - if call.Func == "syslog$auto" { - printedGetFamily = true - ctx.emitNetlinkGetFamily() - } - if call.Func == "sendmsg$auto" { - printedSendmsg = true - ctx.emitNetlinkSendmsgs() - } - } - if !printedGetFamily { - ctx.emitNetlinkGetFamily() - } - if !printedSendmsg { - ctx.emitNetlinkSendmsgs() } ctx.fmt("\n") } @@ -102,9 +86,6 @@ func (ctx *context) serializeStructs() { if str.Align != 0 { attrs = append(attrs, fmt.Sprintf("align[%v]", str.Align)) } - if str.isVarlen { - attrs = append(attrs, "varlen") - } if len(attrs) != 0 { ctx.fmt(" [%v]", strings.Join(attrs, ", ")) } |
