diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2025-01-17 10:39:49 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2025-01-22 17:12:18 +0000 |
| commit | 8aaf5d60aa0b3ddb05e117f52c0e30ec246b7aad (patch) | |
| tree | 63ddc4520d1e4b865925a014d3401b5e15c1fed3 /pkg/declextract/entity.go | |
| parent | ac680c7cc91ea82316471433537f3101c2af39ea (diff) | |
tools/syz-declextract: support function scopes
Extract info about function scopes formed by switch'es on function arguments.
For example if we have:
void foo(..., int cmd, ...)
{
...
switch (cmd) {
case FOO:
... block 1 ...
case BAR:
... block 2 ...
}
...
}
We record that any data flow within block 1 is only relevant
when foo's arg cmd has value FOO, similarly for block 2 and BAR.
This allows to do 3 things:
1. Locate ioctl commands that are switched on within transitively
called functions.
2. Infer return value for each ioctl command.
3. Infer argument type when it's not specified in _IO macro.
This will also allow to infer other multiplexed syscalls.
Descriptions generated on Linux commit c4b9570cfb63501.
Diffstat (limited to 'pkg/declextract/entity.go')
| -rw-r--r-- | pkg/declextract/entity.go | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/pkg/declextract/entity.go b/pkg/declextract/entity.go index 83f56ba52..5562ff570 100644 --- a/pkg/declextract/entity.go +++ b/pkg/declextract/entity.go @@ -17,24 +17,36 @@ type Output struct { Structs []*Struct `json:"structs,omitempty"` Syscalls []*Syscall `json:"syscalls,omitempty"` FileOps []*FileOps `json:"file_ops,omitempty"` + Ioctls []*Ioctl `json:"ioctls,omitempty"` IouringOps []*IouringOp `json:"iouring_ops,omitempty"` NetlinkFamilies []*NetlinkFamily `json:"netlink_families,omitempty"` NetlinkPolicies []*NetlinkPolicy `json:"netlink_policies,omitempty"` } type Function struct { - Name string `json:"name,omitempty"` - File string `json:"file,omitempty"` - IsStatic bool `json:"is_static,omitempty"` - LOC int `json:"loc,omitempty"` - Calls []string `json:"calls,omitempty"` - Facts []*TypingFact `json:"facts,omitempty"` + Name string `json:"name,omitempty"` + File string `json:"file,omitempty"` + IsStatic bool `json:"is_static,omitempty"` + // Information about function scopes. There is a global scope (with Arg=-1), + // and scope for each switch case on the function argument. + Scopes []*FunctionScope `json:"scopes,omitempty"` callers int calls []*Function facts map[string]*typingNode } +type FunctionScope struct { + // The function argument index that is switched on (-1 for the global scope). + Arg int `json:"arg"` + // The set of case values for this scope. + // It's empt for the global scope for the default case scope. + Values []string `json:"values,omitempty"` + LOC int `json:"loc,omitempty"` + Calls []string `json:"calls,omitempty"` + Facts []*TypingFact `json:"facts,omitempty"` +} + type ConstInfo struct { Name string `json:"name"` Filename string `json:"filename"` @@ -63,16 +75,15 @@ type Syscall struct { type FileOps struct { Name string `json:"name,omitempty"` // Names of callback functions. - Open string `json:"open,omitempty"` - Read string `json:"read,omitempty"` - Write string `json:"write,omitempty"` - Mmap string `json:"mmap,omitempty"` - Ioctl string `json:"ioctl,omitempty"` - IoctlCmds []*IoctlCmd `json:"ioctl_cmds,omitempty"` - SourceFile string `json:"source_file,omitempty"` + Open string `json:"open,omitempty"` + Read string `json:"read,omitempty"` + Write string `json:"write,omitempty"` + Mmap string `json:"mmap,omitempty"` + Ioctl string `json:"ioctl,omitempty"` + SourceFile string `json:"source_file,omitempty"` } -type IoctlCmd struct { +type Ioctl struct { // Literal name of the command (e.g. KCOV_REMOTE_ENABLE). Name string `json:"name,omitempty"` Type *Type `json:"type,omitempty"` @@ -207,6 +218,7 @@ func (out *Output) Merge(other *Output) { out.Structs = append(out.Structs, other.Structs...) out.Syscalls = append(out.Syscalls, other.Syscalls...) out.FileOps = append(out.FileOps, other.FileOps...) + out.Ioctls = append(out.Ioctls, other.Ioctls...) out.IouringOps = append(out.IouringOps, other.IouringOps...) out.NetlinkFamilies = append(out.NetlinkFamilies, other.NetlinkFamilies...) out.NetlinkPolicies = append(out.NetlinkPolicies, other.NetlinkPolicies...) @@ -219,6 +231,7 @@ func (out *Output) SortAndDedup() { out.Structs = sortAndDedupSlice(out.Structs) out.Syscalls = sortAndDedupSlice(out.Syscalls) out.FileOps = sortAndDedupSlice(out.FileOps) + out.Ioctls = sortAndDedupSlice(out.Ioctls) out.IouringOps = sortAndDedupSlice(out.IouringOps) out.NetlinkFamilies = sortAndDedupSlice(out.NetlinkFamilies) out.NetlinkPolicies = sortAndDedupSlice(out.NetlinkPolicies) |
