mirror of
https://github.com/reactos/syzkaller.git
synced 2024-11-23 03:19:51 +00:00
initial commit
This commit is contained in:
commit
874c5754bb
9
AUTHORS
Normal file
9
AUTHORS
Normal file
@ -0,0 +1,9 @@
|
||||
# This is the official list of the syzkaller project authors for copyright purposes.
|
||||
# This file is distinct from the CONTRIBUTORS file. See the latter for an explanation.
|
||||
|
||||
# Names should be added to this file as
|
||||
# Name or Organization
|
||||
# Email addresses for individuals are tracked elsewhere to avoid spam.
|
||||
|
||||
Google Inc.
|
||||
|
8
CONTRIBUTORS
Normal file
8
CONTRIBUTORS
Normal file
@ -0,0 +1,8 @@
|
||||
# This is the official list of people who can contribute (and who have contributed)
|
||||
# code to the syzkaller project repository. The AUTHORS file lists the copyright holders;
|
||||
# this file lists people. For example, Google employees are listed here
|
||||
# but not in AUTHORS, because Google holds the copyright.
|
||||
|
||||
Google Inc.
|
||||
Dmitry Vyukov
|
||||
|
174
LICENSE
Normal file
174
LICENSE
Normal file
@ -0,0 +1,174 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
71
README.md
Normal file
71
README.md
Normal file
@ -0,0 +1,71 @@
|
||||
# syzkaller - linux syscall fuzzer
|
||||
|
||||
```syzkaller``` is a distributed, unsupervised, coverage-guided Linux syscall fuzzer.
|
||||
It is meant to be used with [KASAN](https://www.kernel.org/doc/Documentation/kasan.txt) (```CONFIG_KASAN=y```),
|
||||
[KTSAN](https://github.com/google/ktsan) (```CONFIG_KTSAN=y```),
|
||||
or [KUBSAN] (http://developerblog.redhat.com/2014/10/16/gcc-undefined-behavior-sanitizer-ubsan/) ([patch](https://lkml.org/lkml/2014/10/20/181)).
|
||||
|
||||
Project [mailing list](https://groups.google.com/forum/#!forum/syzkaller).
|
||||
|
||||
This is work-in-progress, some things may not work yet.
|
||||
|
||||
## Usage
|
||||
|
||||
Coverage support is not upstreamed yet, so you need to apply [this patch](https://codereview.appspot.com/267910043)
|
||||
to gcc (tested on revision 227353) and [this patch](https://github.com/dvyukov/linux/commit/3506cff7ed260596a783c3766a852869cd913a5e)
|
||||
to kernel. Then build kernel with ```CONFIG_KASAN``` or ```CONFIG_KTSAN``` and the new ```CONFIG_SANCOV```.
|
||||
|
||||
Then, build ```syzkaller/master```, ```syzkaller/manager```, ```syzkaller/fuzzer``` and ```syzkaller/executor```.
|
||||
The latter is build using ```make``` in the dir, the rest are build using ```go build```.
|
||||
|
||||
Then, write manager config based on ```manager/example.cfg```.
|
||||
|
||||
Then, start the master process as:
|
||||
|
||||
```$ ./master -workdir=./workdir -addr=myhost.com:48342 -http=myhost.com:29855```
|
||||
|
||||
and start the manager process as:
|
||||
|
||||
```$ ./manager -config my.cfg```
|
||||
|
||||
The manager process will wind up qemu virtual machines and start fuzzing in them.
|
||||
If you open the HTTP address (in our case ```http://myhost.com:29855```),
|
||||
you will see how corpus collection progresses.
|
||||
|
||||
## Process Structure
|
||||
|
||||
Master process is responsible for persistent corpus and crash storage.
|
||||
It communicates with one or more manager processes via RPC.
|
||||
|
||||
Manager process starts, monitors and restarts several VM instances (support for
|
||||
physical machines is not implemented yet), and starts fuzzer process inside of the VMs.
|
||||
Manager process also serves as a persistent proxy between fuzzer processes and the master process.
|
||||
As opposed to fuzzer processes, it runs on a host with stable kernel which does not
|
||||
experience white-noise fuzzer load.
|
||||
|
||||
Fuzzer process runs inside of presumably unstable VMs (or physical machines under test).
|
||||
Fuzzer guides fuzzing process itself (input generation, mutation, minimization, etc)
|
||||
and sends inputs that trigger new coverage back to the manager process via RPC.
|
||||
It also starts transient executor processes.
|
||||
|
||||
Executor process executes a single input (a sequence of syscalls).
|
||||
It accepts the program to execute from fuzzer process and sends results back.
|
||||
It is designed to be as simple as possible (to not interfere with fuzzing process),
|
||||
written in C++, compiled as static binary and uses shared memory for communication.
|
||||
|
||||
## Syscall description
|
||||
|
||||
syzkaller uses declarative description of syscalls to generate, mutate, minimize,
|
||||
serialize and deserialize programs (sequences of syscalls). Below you can see
|
||||
(hopefully self-explanatory) excerpt from the description:
|
||||
|
||||
```
|
||||
open(file filename, flags flags[open_flags], mode flags[open_mode]) fd
|
||||
read(fd fd, buf buffer[out], count len[buf]) len[buf]
|
||||
close(fd fd)
|
||||
open_mode = S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP, S_IXGRP, S_IROTH, S_IWOTH, S_IXOTH
|
||||
```
|
||||
|
||||
The description is contained in ```syzkaller/sys/sys.txt``` file.
|
||||
|
||||
This is not an official Google product.
|
139
cover/cover.go
Normal file
139
cover/cover.go
Normal file
@ -0,0 +1,139 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
/* Package cover implements set operations on slices (arrays of coverage PCs). */
|
||||
package cover
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
type Cover []uint32
|
||||
|
||||
func (a Cover) Len() int { return len(a) }
|
||||
func (a Cover) Less(i, j int) bool { return a[i] < a[j] }
|
||||
func (a Cover) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
|
||||
const sent = ^uint32(0)
|
||||
|
||||
func Copy(cov Cover) Cover {
|
||||
return append(Cover{}, cov...)
|
||||
}
|
||||
|
||||
/* Canonicalize sorts and removes duplicates. */
|
||||
func Canonicalize(cov []uint32) Cover {
|
||||
sort.Sort(Cover(cov))
|
||||
i := 0
|
||||
last := sent
|
||||
for _, pc := range cov {
|
||||
if pc != last {
|
||||
last = pc
|
||||
cov[i] = pc
|
||||
i++
|
||||
}
|
||||
}
|
||||
return Cover(cov[:i])
|
||||
}
|
||||
|
||||
func Difference(cov0, cov1 Cover) Cover {
|
||||
return foreach(cov0, cov1, func(v0, v1 uint32) uint32 {
|
||||
if v0 < v1 {
|
||||
return v0
|
||||
}
|
||||
return sent
|
||||
})
|
||||
}
|
||||
|
||||
func SymmetricDifference(cov0, cov1 Cover) Cover {
|
||||
return foreach(cov0, cov1, func(v0, v1 uint32) uint32 {
|
||||
if v0 < v1 {
|
||||
return v0
|
||||
}
|
||||
if v1 < v0 {
|
||||
return v1
|
||||
}
|
||||
return sent
|
||||
})
|
||||
}
|
||||
|
||||
func Union(cov0, cov1 Cover) Cover {
|
||||
return foreach(cov0, cov1, func(v0, v1 uint32) uint32 {
|
||||
if v0 <= v1 {
|
||||
return v0
|
||||
}
|
||||
return v1
|
||||
})
|
||||
}
|
||||
|
||||
func Intersection(cov0, cov1 Cover) Cover {
|
||||
return foreach(cov0, cov1, func(v0, v1 uint32) uint32 {
|
||||
if v0 == v1 {
|
||||
return v0
|
||||
}
|
||||
return sent
|
||||
})
|
||||
}
|
||||
|
||||
func foreach(cov0, cov1 Cover, f func(uint32, uint32) uint32) Cover {
|
||||
var res []uint32
|
||||
for i0, i1 := 0, 0; i0 < len(cov0) || i1 < len(cov1); {
|
||||
v0, v1 := sent, sent
|
||||
if i0 < len(cov0) {
|
||||
v0 = cov0[i0]
|
||||
}
|
||||
if i1 < len(cov1) {
|
||||
v1 = cov1[i1]
|
||||
}
|
||||
if v0 <= v1 {
|
||||
i0++
|
||||
}
|
||||
if v1 <= v0 {
|
||||
i1++
|
||||
}
|
||||
if v := f(v0, v1); v != sent {
|
||||
res = append(res, v)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Minimize returns a minimal set of inputs that give the same coverage as the full corpus.
|
||||
func Minimize(corpus []Cover) []int {
|
||||
inputs := make([]*minInput, len(corpus))
|
||||
for i, cov := range corpus {
|
||||
inputs[i] = &minInput{
|
||||
idx: i,
|
||||
cov: cov,
|
||||
}
|
||||
}
|
||||
sort.Sort(minInputArray(inputs))
|
||||
var min []int
|
||||
covered := make(map[uint32]struct{})
|
||||
for _, inp := range inputs {
|
||||
hit := false
|
||||
for _, pc := range inp.cov {
|
||||
if !hit {
|
||||
if _, ok := covered[pc]; !ok {
|
||||
hit = true
|
||||
min = append(min, inp.idx)
|
||||
}
|
||||
}
|
||||
if hit {
|
||||
covered[pc] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
return min
|
||||
}
|
||||
|
||||
type minInput struct {
|
||||
idx int
|
||||
cov Cover
|
||||
}
|
||||
|
||||
type minInputArray []*minInput
|
||||
|
||||
// Inputs with larger coverage come first.
|
||||
func (a minInputArray) Len() int { return len(a) }
|
||||
func (a minInputArray) Less(i, j int) bool { return len(a[i].cov) > len(a[j].cov) }
|
||||
func (a minInputArray) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
205
cover/cover_test.go
Normal file
205
cover/cover_test.go
Normal file
@ -0,0 +1,205 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package cover
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func initTest(t *testing.T) (*rand.Rand, int) {
|
||||
iters := 1000
|
||||
if testing.Short() {
|
||||
iters = 100
|
||||
}
|
||||
seed := int64(time.Now().UnixNano())
|
||||
rs := rand.NewSource(seed)
|
||||
t.Logf("seed=%v", seed)
|
||||
return rand.New(rs), iters
|
||||
}
|
||||
|
||||
type Test struct {
|
||||
V0 Cover
|
||||
V1 Cover
|
||||
R Cover
|
||||
}
|
||||
|
||||
func runTest(t *testing.T, f func(Cover, Cover) Cover, sorted, symmetric bool, tests []Test) {
|
||||
if symmetric {
|
||||
for _, test := range tests {
|
||||
tests = append(tests, Test{test.V1, test.V0, test.R})
|
||||
}
|
||||
}
|
||||
tests = append(tests, Test{Cover{}, Cover{}, Cover{}})
|
||||
for _, test := range tests {
|
||||
if sorted {
|
||||
if !sort.IsSorted(test.V0) {
|
||||
t.Fatalf("input is not sorted: %+v", test.V0)
|
||||
}
|
||||
if !sort.IsSorted(test.V1) {
|
||||
t.Fatalf("input is not sorted: %+v", test.V1)
|
||||
}
|
||||
}
|
||||
if !sort.IsSorted(test.R) {
|
||||
t.Fatalf("golden is not sorted: %+v", test.R)
|
||||
}
|
||||
res := f(test.V0, test.V1)
|
||||
if !sort.IsSorted(res) {
|
||||
t.Fatalf("output is not sorted: %+v", res)
|
||||
}
|
||||
if (len(res) != 0 || len(test.R) != 0) && !reflect.DeepEqual(res, test.R) {
|
||||
t.Fatalf("f(%+v, %+v) = %+v (expect: %+v)", test.V0, test.V1, res, test.R)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCanonicalize(t *testing.T) {
|
||||
runTest(t, func(c0, c1 Cover) Cover { return Canonicalize([]uint32(c0)) }, false, false, []Test{
|
||||
{Cover{1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 6}, Cover{}, Cover{1, 2, 3, 4, 5, 6}},
|
||||
{Cover{6, 2, 3, 4, 5, 1}, Cover{}, Cover{1, 2, 3, 4, 5, 6}},
|
||||
{Cover{6, 1, 2, 6, 3, 3, 4, 5, 1}, Cover{}, Cover{1, 2, 3, 4, 5, 6}},
|
||||
})
|
||||
}
|
||||
|
||||
func TestDifference(t *testing.T) {
|
||||
runTest(t, Difference, true, false, []Test{
|
||||
{Cover{1, 2, 3, 4, 5, 6}, Cover{}, Cover{1, 2, 3, 4, 5, 6}},
|
||||
{Cover{1, 2, 3, 4, 5, 6}, Cover{3}, Cover{1, 2, 4, 5, 6}},
|
||||
{Cover{1, 2, 3, 4, 5, 6}, Cover{1, 6}, Cover{2, 3, 4, 5}},
|
||||
{Cover{1, 2, 3, 4, 5, 6}, Cover{0, 10}, Cover{1, 2, 3, 4, 5, 6}},
|
||||
{Cover{1, 2, 3, 4, 5, 6}, Cover{0, 3, 6}, Cover{1, 2, 4, 5}},
|
||||
})
|
||||
}
|
||||
|
||||
func TestSymmetricDifference(t *testing.T) {
|
||||
runTest(t, SymmetricDifference, true, true, []Test{
|
||||
{Cover{1, 2, 3, 4, 5, 6}, Cover{}, Cover{1, 2, 3, 4, 5, 6}},
|
||||
{Cover{1, 2, 3, 4, 5, 6}, Cover{1, 2, 3, 4, 5, 6}, Cover{}},
|
||||
{Cover{1, 2, 3, 4, 5, 6}, Cover{2, 4, 6}, Cover{1, 3, 5}},
|
||||
{Cover{2, 4, 6}, Cover{1, 3, 5}, Cover{1, 2, 3, 4, 5, 6}},
|
||||
})
|
||||
}
|
||||
|
||||
func TestUnion(t *testing.T) {
|
||||
runTest(t, Union, true, true, []Test{
|
||||
{Cover{1, 2, 3, 4, 5, 6}, Cover{}, Cover{1, 2, 3, 4, 5, 6}},
|
||||
{Cover{1, 2, 3, 4, 5, 6}, Cover{1, 2, 3, 4, 5, 6}, Cover{1, 2, 3, 4, 5, 6}},
|
||||
{Cover{1, 3, 5}, Cover{2, 4, 6}, Cover{1, 2, 3, 4, 5, 6}},
|
||||
{Cover{1, 2, 3, 5}, Cover{2, 4, 5, 6}, Cover{1, 2, 3, 4, 5, 6}},
|
||||
})
|
||||
}
|
||||
|
||||
func TestIntersection(t *testing.T) {
|
||||
runTest(t, Intersection, true, true, []Test{
|
||||
{Cover{1, 2, 3, 4, 5, 6}, Cover{}, Cover{}},
|
||||
{Cover{1, 2, 3}, Cover{4, 5, 6}, Cover{}},
|
||||
{Cover{1, 2, 3}, Cover{2, 3, 5}, Cover{2, 3}},
|
||||
})
|
||||
}
|
||||
|
||||
func TestMinimize(t *testing.T) {
|
||||
tests := []struct {
|
||||
inp []Cover
|
||||
out []int
|
||||
}{
|
||||
// Take all.
|
||||
{
|
||||
[]Cover{
|
||||
{1, 2, 3},
|
||||
{4, 5, 6},
|
||||
{7, 8, 9},
|
||||
},
|
||||
[]int{0, 1, 2},
|
||||
},
|
||||
// Take one.
|
||||
{
|
||||
[]Cover{
|
||||
{1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
{1},
|
||||
{2, 3, 4, 5},
|
||||
{6, 7, 8},
|
||||
},
|
||||
[]int{0},
|
||||
},
|
||||
// Take two.
|
||||
{
|
||||
[]Cover{
|
||||
{1, 2, 3, 4, 5, 6, 7, 8, 9},
|
||||
{1},
|
||||
{2, 3, 4, 5},
|
||||
{10},
|
||||
},
|
||||
[]int{0, 3},
|
||||
},
|
||||
// Take another two.
|
||||
{
|
||||
[]Cover{
|
||||
{1, 2, 3, 4},
|
||||
{1, 2},
|
||||
{3, 4, 5, 6, 7},
|
||||
{3, 7},
|
||||
},
|
||||
[]int{2, 0},
|
||||
},
|
||||
// Take the largest one.
|
||||
{
|
||||
[]Cover{
|
||||
{1, 2},
|
||||
{1, 2, 3, 4, 5},
|
||||
{3, 4, 5},
|
||||
},
|
||||
[]int{1},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
res := Minimize(test.inp)
|
||||
if !reflect.DeepEqual(res, test.out) {
|
||||
t.Logf("corpus:")
|
||||
for _, in := range test.inp {
|
||||
t.Logf(" %+v", in)
|
||||
}
|
||||
t.Fatalf("expect: %+v, got: %+v", test.out, res)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMinimizeRandom(t *testing.T) {
|
||||
rnd, iters := initTest(t)
|
||||
for i := 0; i < iters; i++ {
|
||||
n := rnd.Intn(20)
|
||||
cov := make([]Cover, n)
|
||||
for i := range cov {
|
||||
tmp := make(Cover, rnd.Intn(10))
|
||||
for j := range tmp {
|
||||
tmp[j] = uint32(rnd.Intn(100))
|
||||
}
|
||||
cov[i] = Canonicalize(tmp)
|
||||
}
|
||||
var total Cover
|
||||
for _, c := range cov {
|
||||
total = Union(total, c)
|
||||
}
|
||||
mini := Minimize(cov)
|
||||
var minimized Cover
|
||||
for _, idx := range mini {
|
||||
minimized = Union(minimized, cov[idx])
|
||||
}
|
||||
t.Logf("minimized %v -> %v", len(cov), len(mini))
|
||||
if !reflect.DeepEqual(total, minimized) {
|
||||
t.Logf("corpus:")
|
||||
for _, in := range cov {
|
||||
t.Logf(" %+v", in)
|
||||
}
|
||||
t.Logf("minimized:")
|
||||
for _, in := range cov {
|
||||
t.Logf(" %+v", in)
|
||||
}
|
||||
|
||||
t.Fatalf("better luck next time")
|
||||
}
|
||||
}
|
||||
}
|
9
executor/Makefile
Normal file
9
executor/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
# Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
executor: executor.cc syscalls.h
|
||||
gcc executor.cc -o executor -lpthread -static -Wall -O1 -g
|
||||
|
||||
format: executor.cc
|
||||
clang-format --style=file -i executor.cc
|
||||
|
478
executor/executor.cc
Normal file
478
executor/executor.cc
Normal file
@ -0,0 +1,478 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <pthread.h>
|
||||
#include "syscalls.h"
|
||||
|
||||
const int kInFd = 3;
|
||||
const int kOutFd = 4;
|
||||
const int kMaxInput = 1 << 20;
|
||||
const int kMaxOutput = 16 << 20;
|
||||
const int kMaxArgs = 6;
|
||||
const int kMaxThreads = 16;
|
||||
const int kMaxCommands = 4 << 10;
|
||||
|
||||
const uint64_t instr_eof = -1;
|
||||
const uint64_t instr_copyin = -2;
|
||||
const uint64_t instr_copyout = -3;
|
||||
|
||||
const uint64_t arg_const = 0;
|
||||
const uint64_t arg_result = 1;
|
||||
const uint64_t arg_data = 2;
|
||||
|
||||
// We use the default value instead of results of failed syscalls.
|
||||
// -1 is an invalid fd and an invalid address and deterministic,
|
||||
// so good enough for our purposes.
|
||||
const uint64_t default_value = -1;
|
||||
|
||||
bool flag_debug;
|
||||
bool flag_cover;
|
||||
bool flag_threaded;
|
||||
|
||||
__attribute__((aligned(64 << 10))) char input_data[kMaxInput];
|
||||
__attribute__((aligned(64 << 10))) char output_data[kMaxOutput];
|
||||
uint32_t* output_pos;
|
||||
int completed;
|
||||
|
||||
struct res_t {
|
||||
bool executed;
|
||||
uint64_t val;
|
||||
};
|
||||
|
||||
res_t results[kMaxCommands];
|
||||
|
||||
struct thread_t {
|
||||
bool created;
|
||||
int id;
|
||||
pthread_t th;
|
||||
int cover_fd;
|
||||
uint32_t cover_data[16 << 10];
|
||||
uint64_t* copyout_pos;
|
||||
bool ready;
|
||||
bool done;
|
||||
bool handled;
|
||||
int call_n;
|
||||
int call_index;
|
||||
int call_num;
|
||||
int num_args;
|
||||
uint64_t args[kMaxArgs];
|
||||
uint64_t res;
|
||||
int cover_size;
|
||||
};
|
||||
|
||||
thread_t threads[kMaxThreads];
|
||||
|
||||
__attribute__((noreturn)) void fail(const char* msg, ...);
|
||||
__attribute__((noreturn)) void error(const char* msg, ...);
|
||||
void debug(const char* msg, ...);
|
||||
uint64_t read_input(uint64_t** input_posp);
|
||||
uint64_t read_arg(uint64_t** input_posp);
|
||||
uint64_t read_result(uint64_t** input_posp);
|
||||
void write_output(uint32_t v);
|
||||
void copyin(char* addr, uint64_t val, uint64_t size);
|
||||
uint64_t copyout(char* addr, uint64_t size);
|
||||
thread_t* schedule_call(int n, int call_index, int call_num, uint64_t num_args, uint64_t* args, uint64_t* pos);
|
||||
void execute_call(thread_t* th);
|
||||
void handle_completion(thread_t* th);
|
||||
void* worker_thread(void* arg);
|
||||
uint64_t current_time_ms();
|
||||
void cover_init(thread_t* th);
|
||||
void cover_reset(thread_t* th);
|
||||
int cover_read(thread_t* th);
|
||||
|
||||
int main()
|
||||
{
|
||||
if (mmap(&input_data[0], kMaxInput, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, kInFd, 0) != &input_data[0])
|
||||
fail("mmap of input file failed");
|
||||
if (mmap(&output_data[0], kMaxOutput, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, kOutFd, 0) != &output_data[0])
|
||||
fail("mmap of output file failed");
|
||||
uint64_t* input_pos = (uint64_t*)&input_data[0];
|
||||
uint64_t flags = read_input(&input_pos);
|
||||
flag_debug = flags & (1 << 0);
|
||||
flag_cover = flags & (1 << 1);
|
||||
flag_threaded = flags & (1 << 2);
|
||||
output_pos = (uint32_t*)&output_data[0];
|
||||
write_output(0); // Number of executed syscalls (updated later).
|
||||
|
||||
if (!flag_threaded)
|
||||
cover_init(&threads[0]);
|
||||
|
||||
int call_index = 0;
|
||||
for (int n = 0;; n++) {
|
||||
uint64_t call_num = read_input(&input_pos);
|
||||
if (call_num == instr_eof)
|
||||
break;
|
||||
if (call_num == instr_copyin) {
|
||||
char* addr = (char*)read_input(&input_pos);
|
||||
uint64_t typ = read_input(&input_pos);
|
||||
uint64_t size = read_input(&input_pos);
|
||||
debug("copyin to %p\n", addr);
|
||||
switch (typ) {
|
||||
case arg_const: {
|
||||
uint64_t arg = read_input(&input_pos);
|
||||
copyin(addr, arg, size);
|
||||
break;
|
||||
}
|
||||
case arg_result: {
|
||||
uint64_t val = read_result(&input_pos);
|
||||
copyin(addr, val, size);
|
||||
break;
|
||||
}
|
||||
case arg_data: {
|
||||
memcpy(addr, input_pos, size);
|
||||
// Read out the data.
|
||||
for (uint64_t i = 0; i < (size + 7) / 8; i++)
|
||||
read_input(&input_pos);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fail("bad argument type %lu", typ);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (call_num == instr_copyout) {
|
||||
read_input(&input_pos); // addr
|
||||
read_input(&input_pos); // size
|
||||
// The copyout will happen when/if the call completes.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Normal syscall.
|
||||
if (call_num >= sizeof(syscalls) / sizeof(syscalls[0]))
|
||||
fail("invalid command number %lu", call_num);
|
||||
uint64_t num_args = read_input(&input_pos);
|
||||
if (num_args > kMaxArgs)
|
||||
fail("command has bad number of arguments %lu", num_args);
|
||||
uint64_t args[kMaxArgs] = {};
|
||||
for (uint64_t i = 0; i < num_args; i++)
|
||||
args[i] = read_arg(&input_pos);
|
||||
for (uint64_t i = num_args; i < 6; i++)
|
||||
args[i] = 0;
|
||||
thread_t* th = schedule_call(n, call_index++, call_num, num_args, args, input_pos);
|
||||
|
||||
if (flag_threaded) {
|
||||
// Wait for call completion.
|
||||
uint64_t start = current_time_ms();
|
||||
while (!__atomic_load_n(&th->done, __ATOMIC_ACQUIRE) && (current_time_ms() - start) < 100)
|
||||
usleep(10);
|
||||
if (__atomic_load_n(&th->done, __ATOMIC_ACQUIRE))
|
||||
handle_completion(th);
|
||||
// Check if any of previous calls have completed.
|
||||
usleep(100);
|
||||
for (int i = 0; i < kMaxThreads; i++) {
|
||||
th = &threads[i];
|
||||
if (__atomic_load_n(&th->done, __ATOMIC_ACQUIRE) && !th->handled)
|
||||
handle_completion(th);
|
||||
}
|
||||
} else {
|
||||
// Execute directly.
|
||||
if (th != &threads[0])
|
||||
fail("using non-main thread in non-thread mode");
|
||||
execute_call(th);
|
||||
handle_completion(th);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: handle hanged threads.
|
||||
debug("exiting\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
thread_t* schedule_call(int n, int call_index, int call_num, uint64_t num_args, uint64_t* args, uint64_t* pos)
|
||||
{
|
||||
// Find a spare thread to execute the call.
|
||||
thread_t* th = 0;
|
||||
for (int i = 0; i < kMaxThreads; i++) {
|
||||
th = &threads[i];
|
||||
if (!th->created) {
|
||||
th->created = true;
|
||||
th->id = i;
|
||||
th->done = true;
|
||||
th->handled = true;
|
||||
if (flag_threaded) {
|
||||
if (pthread_create(&th->th, 0, worker_thread, th))
|
||||
fail("pthread_create failed");
|
||||
}
|
||||
}
|
||||
if (__atomic_load_n(&th->done, __ATOMIC_ACQUIRE)) {
|
||||
if (!th->handled)
|
||||
handle_completion(th);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (th == &threads[kMaxThreads])
|
||||
fail("out of threads");
|
||||
debug("scheduling call %d [%s] on thread %d\n", call_index, syscalls[call_num].name, th->id);
|
||||
if (th->ready || !th->done || !th->handled)
|
||||
fail("bad thread state in schedule: ready=%d done=%d handled=%d",
|
||||
th->ready, th->done, th->handled);
|
||||
th->copyout_pos = pos;
|
||||
th->done = false;
|
||||
th->handled = false;
|
||||
th->call_n = n;
|
||||
th->call_index = call_index;
|
||||
th->call_num = call_num;
|
||||
th->num_args = num_args;
|
||||
for (int i = 0; i < kMaxArgs; i++)
|
||||
th->args[i] = args[i];
|
||||
__atomic_store_n(&th->ready, true, __ATOMIC_RELEASE);
|
||||
return th;
|
||||
}
|
||||
|
||||
void handle_completion(thread_t* th)
|
||||
{
|
||||
debug("completion of call %d [%s] on thread %d\n", th->call_index, syscalls[th->call_num].name, th->id);
|
||||
if (th->ready || !th->done || th->handled)
|
||||
fail("bad thread state in completion: ready=%d done=%d handled=%d",
|
||||
th->ready, th->done, th->handled);
|
||||
if (th->res != (uint64_t)-1) {
|
||||
results[th->call_n].executed = true;
|
||||
results[th->call_n].val = th->res;
|
||||
for (;;) {
|
||||
th->call_n++;
|
||||
uint64_t call_num = read_input(&th->copyout_pos);
|
||||
if (call_num != instr_copyout)
|
||||
break;
|
||||
char* addr = (char*)read_input(&th->copyout_pos);
|
||||
uint64_t size = read_input(&th->copyout_pos);
|
||||
uint64_t val = copyout(addr, size);
|
||||
results[th->call_n].executed = true;
|
||||
results[th->call_n].val = val;
|
||||
debug("copyout from %p\n", addr);
|
||||
}
|
||||
}
|
||||
write_output(th->call_index);
|
||||
write_output(th->call_num);
|
||||
write_output(th->cover_size);
|
||||
for (int i = 0; i < th->cover_size; i++)
|
||||
write_output(th->cover_data[i]);
|
||||
completed++;
|
||||
__atomic_store_n((uint32_t*)&output_data[0], completed, __ATOMIC_RELEASE);
|
||||
th->handled = true;
|
||||
}
|
||||
|
||||
void* worker_thread(void* arg)
|
||||
{
|
||||
thread_t* th = (thread_t*)arg;
|
||||
|
||||
cover_init(th);
|
||||
for (;;) {
|
||||
while (!__atomic_load_n(&th->ready, __ATOMIC_ACQUIRE))
|
||||
usleep(10);
|
||||
execute_call(th);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void execute_call(thread_t* th)
|
||||
{
|
||||
th->ready = false;
|
||||
call_t* call = &syscalls[th->call_num];
|
||||
debug("#%d: %s(", th->id, call->name);
|
||||
for (int i = 0; i < th->num_args; i++) {
|
||||
if (i != 0)
|
||||
debug(", ");
|
||||
debug("0x%lx", th->args[i]);
|
||||
}
|
||||
debug(")\n");
|
||||
|
||||
if (kMaxArgs != 6)
|
||||
fail("inconsistent number of arguments");
|
||||
|
||||
cover_reset(th);
|
||||
th->res = syscall(call->sys_nr, th->args[0], th->args[1], th->args[2], th->args[3], th->args[4], th->args[5]);
|
||||
int errno0 = errno;
|
||||
th->cover_size = cover_read(th);
|
||||
|
||||
if (th->res == (uint64_t)-1)
|
||||
debug("#%d: %s = errno(%d)\n", th->id, call->name, errno0);
|
||||
else
|
||||
debug("#%d: %s = %lx\n", th->id, call->name, th->res);
|
||||
__atomic_store_n(&th->done, true, __ATOMIC_RELEASE);
|
||||
}
|
||||
|
||||
void cover_init(thread_t* th)
|
||||
{
|
||||
if (!flag_cover)
|
||||
return;
|
||||
debug("#%d: opening /proc/cover\n", th->id);
|
||||
th->cover_fd = open("/proc/cover", O_RDWR);
|
||||
if (th->cover_fd == -1)
|
||||
fail("open of /proc/cover failed");
|
||||
char cmd[128];
|
||||
sprintf(cmd, "enable=%d", (int)(sizeof(th->cover_data) / sizeof(th->cover_data[0])));
|
||||
int n = write(th->cover_fd, cmd, strlen(cmd));
|
||||
if (n != (int)strlen(cmd))
|
||||
fail("cover enable write failed");
|
||||
debug("#%d: opened /proc/cover\n", th->id);
|
||||
}
|
||||
|
||||
void cover_reset(thread_t* th)
|
||||
{
|
||||
if (!flag_cover)
|
||||
return;
|
||||
debug("#%d: resetting /proc/cover\n", th->id);
|
||||
int n = write(th->cover_fd, "reset", sizeof("reset") - 1);
|
||||
if (n != sizeof("reset") - 1)
|
||||
fail("cover reset write failed");
|
||||
}
|
||||
|
||||
int cover_read(thread_t* th)
|
||||
{
|
||||
if (!flag_cover)
|
||||
return 0;
|
||||
int n = read(th->cover_fd, th->cover_data, sizeof(th->cover_data));
|
||||
if (n < 0 || n > (int)sizeof(th->cover_data) || (n % sizeof(th->cover_data[0])) != 0)
|
||||
fail("cover read failed after %s (n=%d)", syscalls[th->call_num].name, n);
|
||||
n /= sizeof(th->cover_data[0]);
|
||||
debug("#%d: read /proc/cover = %d\n", th->id, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
void copyin(char* addr, uint64_t val, uint64_t size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1:
|
||||
*(uint8_t*)addr = val;
|
||||
break;
|
||||
case 2:
|
||||
*(uint16_t*)addr = val;
|
||||
break;
|
||||
case 4:
|
||||
*(uint32_t*)addr = val;
|
||||
break;
|
||||
case 8:
|
||||
*(uint64_t*)addr = val;
|
||||
break;
|
||||
default:
|
||||
fail("copyin: bad argument size %lu", size);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t copyout(char* addr, uint64_t size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1:
|
||||
return *(uint8_t*)addr;
|
||||
case 2:
|
||||
return *(uint16_t*)addr;
|
||||
case 4:
|
||||
return *(uint32_t*)addr;
|
||||
case 8:
|
||||
return *(uint64_t*)addr;
|
||||
default:
|
||||
fail("copyout: bad argument size %lu", size);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t read_arg(uint64_t** input_posp)
|
||||
{
|
||||
uint64_t typ = read_input(input_posp);
|
||||
uint64_t size = read_input(input_posp);
|
||||
(void)size;
|
||||
uint64_t arg = 0;
|
||||
switch (typ) {
|
||||
case arg_const: {
|
||||
arg = read_input(input_posp);
|
||||
break;
|
||||
}
|
||||
case arg_result: {
|
||||
arg = read_result(input_posp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fail("bad argument type %lu", typ);
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
|
||||
uint64_t read_result(uint64_t** input_posp)
|
||||
{
|
||||
uint64_t idx = read_input(input_posp);
|
||||
uint64_t op_div = read_input(input_posp);
|
||||
uint64_t op_add = read_input(input_posp);
|
||||
if (idx >= kMaxCommands)
|
||||
fail("command refers to bad result %ld", idx);
|
||||
uint64_t arg = default_value;
|
||||
if (results[idx].executed) {
|
||||
arg = results[idx].val;
|
||||
if (op_div != 0)
|
||||
arg = arg / op_div;
|
||||
arg += op_add;
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
|
||||
uint64_t read_input(uint64_t** input_posp)
|
||||
{
|
||||
uint64_t* input_pos = *input_posp;
|
||||
if ((char*)input_pos >= input_data + kMaxInput)
|
||||
fail("input command overflows input");
|
||||
*input_posp = input_pos + 1;
|
||||
return *input_pos;
|
||||
}
|
||||
|
||||
void write_output(uint32_t v)
|
||||
{
|
||||
if ((char*)output_pos >= output_data + kMaxOutput)
|
||||
fail("output overflow");
|
||||
*output_pos++ = v;
|
||||
}
|
||||
|
||||
uint64_t current_time_ms()
|
||||
{
|
||||
timespec ts;
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts))
|
||||
fail("clock_gettime failed");
|
||||
return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
|
||||
}
|
||||
|
||||
// logical error (e.g. invalid input program)
|
||||
void fail(const char* msg, ...)
|
||||
{
|
||||
int e = errno;
|
||||
fflush(stdout);
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
vfprintf(stderr, msg, args);
|
||||
va_end(args);
|
||||
fprintf(stderr, " (errno %d)\n", e);
|
||||
exit(67);
|
||||
}
|
||||
|
||||
// kernel error (e.g. wrong syscall return value)
|
||||
void error(const char* msg, ...)
|
||||
{
|
||||
fflush(stdout);
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
vfprintf(stderr, msg, args);
|
||||
va_end(args);
|
||||
fprintf(stderr, "\n");
|
||||
exit(68);
|
||||
}
|
||||
|
||||
void debug(const char* msg, ...)
|
||||
{
|
||||
if (!flag_debug)
|
||||
return;
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
vfprintf(stdout, msg, args);
|
||||
va_end(args);
|
||||
fflush(stdout);
|
||||
}
|
307
executor/syscalls.h
Normal file
307
executor/syscalls.h
Normal file
@ -0,0 +1,307 @@
|
||||
// AUTOGENERATED FILE
|
||||
|
||||
struct call_t {
|
||||
const char* name;
|
||||
int sys_nr;
|
||||
};
|
||||
|
||||
call_t syscalls[] = {
|
||||
{"open", __NR_open},
|
||||
{"openat", __NR_openat},
|
||||
{"creat", __NR_creat},
|
||||
{"close", __NR_close},
|
||||
{"read", __NR_read},
|
||||
{"pread64", __NR_pread64},
|
||||
{"readv", __NR_readv},
|
||||
{"preadv", __NR_preadv},
|
||||
{"write", __NR_write},
|
||||
{"pwrite64", __NR_pwrite64},
|
||||
{"writev", __NR_writev},
|
||||
{"pwritev", __NR_pwritev},
|
||||
{"lseek", __NR_lseek},
|
||||
{"dup", __NR_dup},
|
||||
{"dup2", __NR_dup2},
|
||||
{"dup3", __NR_dup3},
|
||||
{"pipe", __NR_pipe},
|
||||
{"pipe2", __NR_pipe2},
|
||||
{"tee", __NR_tee},
|
||||
{"splice", __NR_splice},
|
||||
{"vmsplice", __NR_vmsplice},
|
||||
{"sendfile", __NR_sendfile},
|
||||
{"stat", __NR_stat},
|
||||
{"lstat", __NR_lstat},
|
||||
{"fstat", __NR_fstat},
|
||||
{"poll", __NR_poll},
|
||||
{"ppoll", __NR_ppoll},
|
||||
{"select", __NR_select},
|
||||
{"pselect6", __NR_pselect6},
|
||||
{"epoll_create", __NR_epoll_create},
|
||||
{"epoll_create1", __NR_epoll_create1},
|
||||
{"epoll_ctl", __NR_epoll_ctl},
|
||||
{"epoll_wait", __NR_epoll_wait},
|
||||
{"epoll_pwait", __NR_epoll_pwait},
|
||||
{"signalfd", __NR_signalfd},
|
||||
{"signalfd4", __NR_signalfd4},
|
||||
{"eventfd", __NR_eventfd},
|
||||
{"eventfd2", __NR_eventfd2},
|
||||
{"timerfd_create", __NR_timerfd_create},
|
||||
{"timerfd_settime", __NR_timerfd_settime},
|
||||
{"timerfd_gettime", __NR_timerfd_gettime},
|
||||
{"mmap", __NR_mmap},
|
||||
{"munmap", __NR_munmap},
|
||||
{"mremap", __NR_mremap},
|
||||
{"remap_file_pages", __NR_remap_file_pages},
|
||||
{"mprotect", __NR_mprotect},
|
||||
{"msync", __NR_msync},
|
||||
{"madvise", __NR_madvise},
|
||||
{"fadvise64", __NR_fadvise64},
|
||||
{"readahead", __NR_readahead},
|
||||
{"mbind", __NR_mbind},
|
||||
{"move_pages", __NR_move_pages},
|
||||
{"migrate_pages", __NR_migrate_pages},
|
||||
{"set_mempolicy", __NR_set_mempolicy},
|
||||
{"get_mempolicy", __NR_get_mempolicy},
|
||||
{"mincore", __NR_mincore},
|
||||
{"mlock", __NR_mlock},
|
||||
{"munlock", __NR_munlock},
|
||||
{"mlockall", __NR_mlockall},
|
||||
{"munlockall", __NR_munlockall},
|
||||
{"unshare", __NR_unshare},
|
||||
{"kcmp", __NR_kcmp},
|
||||
{"futex", __NR_futex},
|
||||
{"set_robust_list", __NR_set_robust_list},
|
||||
{"get_robust_list", __NR_get_robust_list},
|
||||
{"restart_syscall", __NR_restart_syscall},
|
||||
{"socket", __NR_socket},
|
||||
{"socketpair", __NR_socketpair},
|
||||
{"accept", __NR_accept},
|
||||
{"accept4", __NR_accept4},
|
||||
{"bind", __NR_bind},
|
||||
{"listen", __NR_listen},
|
||||
{"connect", __NR_connect},
|
||||
{"shutdown", __NR_shutdown},
|
||||
{"sendto", __NR_sendto},
|
||||
{"sendmsg", __NR_sendmsg},
|
||||
{"sendmmsg", __NR_sendmmsg},
|
||||
{"recvfrom", __NR_recvfrom},
|
||||
{"recvmsg", __NR_recvmsg},
|
||||
{"recvmmsg", __NR_recvmmsg},
|
||||
{"getsockname", __NR_getsockname},
|
||||
{"getpeername", __NR_getpeername},
|
||||
{"getsockopt", __NR_getsockopt},
|
||||
{"setsockopt", __NR_setsockopt},
|
||||
{"ioctl", __NR_ioctl},
|
||||
{"fcntl$dupfd", __NR_fcntl},
|
||||
{"fcntl$getflags", __NR_fcntl},
|
||||
{"fcntl$setflags", __NR_fcntl},
|
||||
{"fcntl$setstatus", __NR_fcntl},
|
||||
{"fcntl$lock", __NR_fcntl},
|
||||
{"fcntl$getown", __NR_fcntl},
|
||||
{"fcntl$setown", __NR_fcntl},
|
||||
{"fcntl$getownex", __NR_fcntl},
|
||||
{"fcntl$setownex", __NR_fcntl},
|
||||
{"fcntl$setsig", __NR_fcntl},
|
||||
{"fcntl$setlease", __NR_fcntl},
|
||||
{"fcntl$notify", __NR_fcntl},
|
||||
{"fcntl$setpipe", __NR_fcntl},
|
||||
{"ptrace", __NR_ptrace},
|
||||
{"ptrace$peek", __NR_ptrace},
|
||||
{"ptrace$poke", __NR_ptrace},
|
||||
{"ptrace$peekuser", __NR_ptrace},
|
||||
{"ptrace$pokeuser", __NR_ptrace},
|
||||
{"ptrace$getregs", __NR_ptrace},
|
||||
{"ptrace$getregset", __NR_ptrace},
|
||||
{"ptrace$setregs", __NR_ptrace},
|
||||
{"ptrace$setregset", __NR_ptrace},
|
||||
{"ptrace$getsig", __NR_ptrace},
|
||||
{"ptrace$setsig", __NR_ptrace},
|
||||
{"ptrace$setopts", __NR_ptrace},
|
||||
{"ptrace$getenv", __NR_ptrace},
|
||||
{"ptrace$cont", __NR_ptrace},
|
||||
{"io_setup", __NR_io_setup},
|
||||
{"io_destroy", __NR_io_destroy},
|
||||
{"io_getevents", __NR_io_getevents},
|
||||
{"io_submit", __NR_io_submit},
|
||||
{"io_cancel", __NR_io_cancel},
|
||||
{"capget", __NR_capget},
|
||||
{"capset", __NR_capset},
|
||||
{"prctl", __NR_prctl},
|
||||
{"arch_prctl", __NR_arch_prctl},
|
||||
{"seccomp", __NR_seccomp},
|
||||
{"add_key", __NR_add_key},
|
||||
{"request_key", __NR_request_key},
|
||||
{"keyctl", __NR_keyctl},
|
||||
{"mq_open", __NR_mq_open},
|
||||
{"mq_timedsend", __NR_mq_timedsend},
|
||||
{"mq_timedreceive", __NR_mq_timedreceive},
|
||||
{"mq_notify", __NR_mq_notify},
|
||||
{"mq_getsetattr", __NR_mq_getsetattr},
|
||||
{"mq_unlink", __NR_mq_unlink},
|
||||
{"msgget", __NR_msgget},
|
||||
{"msgsnd", __NR_msgsnd},
|
||||
{"msgrcv", __NR_msgrcv},
|
||||
{"msgctl", __NR_msgctl},
|
||||
{"semget", __NR_semget},
|
||||
{"semop", __NR_semop},
|
||||
{"semtimedop", __NR_semtimedop},
|
||||
{"semctl", __NR_semctl},
|
||||
{"shmget", __NR_shmget},
|
||||
{"shmat", __NR_shmat},
|
||||
{"shmctl", __NR_shmctl},
|
||||
{"shmdt", __NR_shmdt},
|
||||
{"mknod", __NR_mknod},
|
||||
{"mknodat", __NR_mknodat},
|
||||
{"chmod", __NR_chmod},
|
||||
{"fchmod", __NR_fchmod},
|
||||
{"fchmodat", __NR_fchmodat},
|
||||
{"chown", __NR_chown},
|
||||
{"lchown", __NR_lchown},
|
||||
{"fchown", __NR_fchown},
|
||||
{"fchownat", __NR_fchownat},
|
||||
{"fallocate", __NR_fallocate},
|
||||
{"faccessat", __NR_faccessat},
|
||||
{"utime", __NR_utime},
|
||||
{"utimes", __NR_utimes},
|
||||
{"futimesat", __NR_futimesat},
|
||||
{"utimensat", __NR_utimensat},
|
||||
{"getgid", __NR_getgid},
|
||||
{"getegid", __NR_getegid},
|
||||
{"setuid", __NR_setuid},
|
||||
{"setgid", __NR_setgid},
|
||||
{"getuid", __NR_getuid},
|
||||
{"geteuid", __NR_geteuid},
|
||||
{"setpgid", __NR_setpgid},
|
||||
{"getpgid", __NR_getpgid},
|
||||
{"getpgrp", __NR_getpgrp},
|
||||
{"getpid", __NR_getpid},
|
||||
{"gettid", __NR_gettid},
|
||||
{"setreuid", __NR_setreuid},
|
||||
{"setregid", __NR_setregid},
|
||||
{"setresuid", __NR_setresuid},
|
||||
{"setresgid", __NR_setresgid},
|
||||
{"getresuid", __NR_getresuid},
|
||||
{"getresgid", __NR_getresgid},
|
||||
{"setfsuid", __NR_setfsuid},
|
||||
{"setfsgid", __NR_setfsgid},
|
||||
{"getgroups", __NR_getgroups},
|
||||
{"setgroups", __NR_setgroups},
|
||||
{"personality", __NR_personality},
|
||||
{"inotify_init", __NR_inotify_init},
|
||||
{"inotify_init1", __NR_inotify_init1},
|
||||
{"inotify_add_watch", __NR_inotify_add_watch},
|
||||
{"inotify_rm_watch", __NR_inotify_rm_watch},
|
||||
{"fanotify_init", __NR_fanotify_init},
|
||||
{"fanotify_mark", __NR_fanotify_mark},
|
||||
{"link", __NR_link},
|
||||
{"linkat", __NR_linkat},
|
||||
{"symlinkat", __NR_symlinkat},
|
||||
{"symlink", __NR_symlink},
|
||||
{"unlink", __NR_unlink},
|
||||
{"unlinkat", __NR_unlinkat},
|
||||
{"readlink", __NR_readlink},
|
||||
{"readlinkat", __NR_readlinkat},
|
||||
{"rename", __NR_rename},
|
||||
{"renameat", __NR_renameat},
|
||||
{"renameat2", __NR_renameat2},
|
||||
{"mkdir", __NR_mkdir},
|
||||
{"mkdirat", __NR_mkdirat},
|
||||
{"rmdir", __NR_rmdir},
|
||||
{"truncate", __NR_truncate},
|
||||
{"ftruncate", __NR_ftruncate},
|
||||
{"flock", __NR_flock},
|
||||
{"fsync", __NR_fsync},
|
||||
{"fdatasync", __NR_fdatasync},
|
||||
{"sync", __NR_sync},
|
||||
{"syncfs", __NR_syncfs},
|
||||
{"sync_file_range", __NR_sync_file_range},
|
||||
{"lookup_dcookie", __NR_lookup_dcookie},
|
||||
{"getdents", __NR_getdents},
|
||||
{"getdents64", __NR_getdents64},
|
||||
{"name_to_handle_at", __NR_name_to_handle_at},
|
||||
{"open_by_handle_at", __NR_open_by_handle_at},
|
||||
{"mount", __NR_mount},
|
||||
{"umount2", __NR_umount2},
|
||||
{"pivot_root", __NR_pivot_root},
|
||||
{"sysfs", __NR_sysfs},
|
||||
{"statfs", __NR_statfs},
|
||||
{"fstatfs", __NR_fstatfs},
|
||||
{"uselib", __NR_uselib},
|
||||
{"init_module", __NR_init_module},
|
||||
{"finit_module", __NR_finit_module},
|
||||
{"delete_module", __NR_delete_module},
|
||||
{"kexec_load", __NR_kexec_load},
|
||||
{"get_kernel_syms", __NR_get_kernel_syms},
|
||||
{"syslog", __NR_syslog},
|
||||
{"uname", __NR_uname},
|
||||
{"sysinfo", __NR_sysinfo},
|
||||
{"ustat", __NR_ustat},
|
||||
{"acct", __NR_acct},
|
||||
{"getrusage", __NR_getrusage},
|
||||
{"getrlimit", __NR_getrlimit},
|
||||
{"setrlimit", __NR_setrlimit},
|
||||
{"prlimit64", __NR_prlimit64},
|
||||
{"iopl", __NR_iopl},
|
||||
{"ioperm", __NR_ioperm},
|
||||
{"ioprio_get", __NR_ioprio_get},
|
||||
{"ioprio_set", __NR_ioprio_set},
|
||||
{"setns", __NR_setns},
|
||||
{"setxattr", __NR_setxattr},
|
||||
{"lsetxattr", __NR_lsetxattr},
|
||||
{"fsetxattr", __NR_fsetxattr},
|
||||
{"getxattr", __NR_getxattr},
|
||||
{"lgetxattr", __NR_lgetxattr},
|
||||
{"fgetxattr", __NR_fgetxattr},
|
||||
{"listxattr", __NR_listxattr},
|
||||
{"llistxattr", __NR_llistxattr},
|
||||
{"flistxattr", __NR_flistxattr},
|
||||
{"removexattr", __NR_removexattr},
|
||||
{"lremovexattr", __NR_lremovexattr},
|
||||
{"fremovexattr", __NR_fremovexattr},
|
||||
{"time", __NR_time},
|
||||
{"clock_gettime", __NR_clock_gettime},
|
||||
{"clock_settime", __NR_clock_settime},
|
||||
{"clock_adjtime", __NR_clock_adjtime},
|
||||
{"clock_getres", __NR_clock_getres},
|
||||
{"clock_nanosleep", __NR_clock_nanosleep},
|
||||
{"timer_create", __NR_timer_create},
|
||||
{"timer_gettime", __NR_timer_gettime},
|
||||
{"timer_getoverrun", __NR_timer_getoverrun},
|
||||
{"timer_settime", __NR_timer_settime},
|
||||
{"timer_delete", __NR_timer_delete},
|
||||
{"rt_sigaction", __NR_rt_sigaction},
|
||||
{"rt_sigprocmask", __NR_rt_sigprocmask},
|
||||
{"rt_sigreturn", __NR_rt_sigreturn},
|
||||
{"rt_sigpending", __NR_rt_sigpending},
|
||||
{"rt_sigtimedwait", __NR_rt_sigtimedwait},
|
||||
{"rt_sigsuspend", __NR_rt_sigsuspend},
|
||||
{"rt_sigqueueinfo", __NR_rt_sigqueueinfo},
|
||||
{"rt_tgsigqueueinfo", __NR_rt_tgsigqueueinfo},
|
||||
{"sigaltstack", __NR_sigaltstack},
|
||||
{"tgkill", __NR_tgkill},
|
||||
{"tkill", __NR_tkill},
|
||||
{"pause", __NR_pause},
|
||||
{"alarm", __NR_alarm},
|
||||
{"nanosleep", __NR_nanosleep},
|
||||
{"getitimer", __NR_getitimer},
|
||||
{"setitimer", __NR_setitimer},
|
||||
{"exit", __NR_exit},
|
||||
{"exit_group", __NR_exit_group},
|
||||
{"waitid", __NR_waitid},
|
||||
{"wait4", __NR_wait4},
|
||||
{"times", __NR_times},
|
||||
{"set_thread_area", __NR_set_thread_area},
|
||||
{"get_thread_area", __NR_get_thread_area},
|
||||
{"set_tid_address", __NR_set_tid_address},
|
||||
{"getpriority", __NR_getpriority},
|
||||
{"setpriority", __NR_setpriority},
|
||||
{"sched_getscheduler", __NR_sched_getscheduler},
|
||||
{"sched_setscheduler", __NR_sched_setscheduler},
|
||||
{"sched_rr_get_interval", __NR_sched_rr_get_interval},
|
||||
{"sched_getparam", __NR_sched_getparam},
|
||||
{"sched_setparam", __NR_sched_setparam},
|
||||
{"sched_getaffinity", __NR_sched_getaffinity},
|
||||
{"sched_setaffinity", __NR_sched_setaffinity},
|
||||
{"sched_getattr", __NR_sched_getattr},
|
||||
{"sched_setattr", __NR_sched_setattr},
|
||||
{"sched_yield", __NR_sched_yield},
|
||||
};
|
418
fuzzer/fuzzer.go
Normal file
418
fuzzer/fuzzer.go
Normal file
@ -0,0 +1,418 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
// TODO: implement some form of smashing of new inputs.
|
||||
// E.g. alter arguments while the program still gives the new coverage,
|
||||
// i.e. aim at cracking new branches and triggering bugs in that new piece of code.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha1"
|
||||
"encoding/binary"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net/rpc"
|
||||
"os"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/google/syzkaller/cover"
|
||||
"github.com/google/syzkaller/ipc"
|
||||
"github.com/google/syzkaller/prog"
|
||||
. "github.com/google/syzkaller/rpctype"
|
||||
"github.com/google/syzkaller/sys"
|
||||
)
|
||||
|
||||
var (
|
||||
flagName = flag.String("name", "", "unique name for manager")
|
||||
flagExecutor = flag.String("executor", "", "path to executor binary")
|
||||
flagManager = flag.String("manager", "", "manager rpc address")
|
||||
flagStrace = flag.Bool("strace", false, "run executor under strace")
|
||||
flagParallel = flag.Int("parallel", 1, "run that many tests in parallel")
|
||||
flagSaveProg = flag.Bool("saveprog", false, "save programs into local file before executing")
|
||||
flagSyscalls = flag.String("calls", "", "comma-delimited list of enabled syscall IDs (empty string for all syscalls)")
|
||||
flagV = flag.Int("v", 0, "verbosity")
|
||||
)
|
||||
|
||||
const (
|
||||
programLength = 30
|
||||
)
|
||||
|
||||
type Sig [sha1.Size]byte
|
||||
|
||||
func hash(data []byte) Sig {
|
||||
return Sig(sha1.Sum(data))
|
||||
}
|
||||
|
||||
type Input struct {
|
||||
p *prog.Prog
|
||||
call int
|
||||
cover cover.Cover
|
||||
}
|
||||
|
||||
var (
|
||||
corpusCover []cover.Cover
|
||||
maxCover []cover.Cover
|
||||
flakes cover.Cover
|
||||
corpus []Input
|
||||
corpusHashes map[Sig]struct{}
|
||||
triage []Input
|
||||
manager *rpc.Client
|
||||
|
||||
workerIn = make(chan *prog.Prog, 10)
|
||||
workerOut = make(chan []Input, 10)
|
||||
)
|
||||
|
||||
func main() {
|
||||
debug.SetGCPercent(50)
|
||||
flag.Parse()
|
||||
logf(0, "started")
|
||||
|
||||
var calls []*sys.Call
|
||||
if *flagSyscalls != "" {
|
||||
for _, id := range strings.Split(*flagSyscalls, ",") {
|
||||
n, err := strconv.ParseUint(id, 10, 64)
|
||||
if err != nil || n >= uint64(len(sys.Calls)) {
|
||||
panic(fmt.Sprintf("invalid syscall in -calls flag: '%v", id))
|
||||
}
|
||||
calls = append(calls, sys.Calls[n])
|
||||
}
|
||||
}
|
||||
|
||||
corpusCover = make([]cover.Cover, sys.CallCount)
|
||||
maxCover = make([]cover.Cover, sys.CallCount)
|
||||
corpusHashes = make(map[Sig]struct{})
|
||||
|
||||
conn, err := rpc.Dial("tcp", *flagManager)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
manager = conn
|
||||
a := &ManagerConnectArgs{*flagName}
|
||||
r := &ManagerConnectRes{}
|
||||
if err := manager.Call("Manager.Connect", a, r); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if *flagParallel <= 0 {
|
||||
*flagParallel = 1
|
||||
}
|
||||
flags := ipc.FlagCover
|
||||
if *flagStrace {
|
||||
flags |= ipc.FlagStrace
|
||||
}
|
||||
workerIn = make(chan *prog.Prog, *flagParallel+10)
|
||||
workerOut = make(chan []Input, *flagParallel)
|
||||
for i := 0; i < *flagParallel; i++ {
|
||||
env, err := ipc.MakeEnv(*flagExecutor, 4*time.Second, flags)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
workerId := i + 1
|
||||
go func() {
|
||||
for p := range workerIn {
|
||||
workerOut <- execute(env, p, workerId)
|
||||
}
|
||||
}()
|
||||
}
|
||||
env, err := ipc.MakeEnv(*flagExecutor, 4*time.Second, flags)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
rs := rand.NewSource(time.Now().UnixNano())
|
||||
rnd := rand.New(rs)
|
||||
var lastPoll time.Time
|
||||
var lastPrint time.Time
|
||||
secondTicker := time.NewTicker(100 * time.Millisecond).C
|
||||
for i := 0; ; i++ {
|
||||
if !*flagSaveProg && time.Since(lastPrint) > 10*time.Second {
|
||||
// Keep-alive for manager.
|
||||
logf(0, "#%v: alive", i)
|
||||
lastPrint = time.Now()
|
||||
}
|
||||
if len(triage) != 0 {
|
||||
last := len(triage) - 1
|
||||
inp := triage[last]
|
||||
triage = triage[:last]
|
||||
logf(1, "#%v: triaging : %s", i, inp.p)
|
||||
triageInput(env, inp)
|
||||
continue
|
||||
}
|
||||
if time.Since(lastPoll) > 10*time.Second {
|
||||
a := &ManagerPollArgs{*flagName}
|
||||
r := &ManagerPollRes{}
|
||||
if err := manager.Call("Manager.Poll", a, r); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, inp := range r.NewInputs {
|
||||
addInput(inp)
|
||||
}
|
||||
for _, data := range r.Candidates {
|
||||
p, err := prog.Deserialize(data)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
inputs := execute(env, p, 0)
|
||||
for _, inp := range inputs {
|
||||
call := inp.p.Calls[inp.call].Meta
|
||||
maxCover[call.CallID] = cover.Union(maxCover[call.CallID], inp.cover)
|
||||
triage = append(triage, inp)
|
||||
}
|
||||
}
|
||||
if len(r.NewInputs) == 0 && len(r.Candidates) == 0 {
|
||||
lastPoll = time.Now()
|
||||
}
|
||||
continue
|
||||
}
|
||||
// Parallel part.
|
||||
pending := 0
|
||||
for ; ; i++ {
|
||||
if !(!*flagSaveProg && time.Since(lastPrint) > 10*time.Second) &&
|
||||
!(len(triage) != 0) &&
|
||||
!(time.Since(lastPoll) > 10*time.Second) {
|
||||
// No need to do any work above.
|
||||
// Send new inputs to workers, if they need some.
|
||||
for len(workerIn) < *flagParallel {
|
||||
if len(corpus) == 0 || i%10 == 0 {
|
||||
p := prog.Generate(rnd, programLength, calls)
|
||||
logf(1, "#%v: generated: %s", i, p)
|
||||
workerIn <- p
|
||||
pending++
|
||||
p = p.Clone()
|
||||
p.Mutate(rnd, programLength, calls)
|
||||
logf(1, "#%v: mutated: %s", i, p)
|
||||
workerIn <- p
|
||||
pending++
|
||||
} else {
|
||||
inp := corpus[rnd.Intn(len(corpus))]
|
||||
p := inp.p.Clone()
|
||||
p.Mutate(rs, programLength, calls)
|
||||
logf(1, "#%v: mutated: %s <- %s", i, p, inp.p)
|
||||
workerIn <- p
|
||||
pending++
|
||||
}
|
||||
}
|
||||
} else if pending == 0 {
|
||||
// Need to do some work above.
|
||||
// Break if collected all pending results.
|
||||
break
|
||||
}
|
||||
// Collect results.
|
||||
select {
|
||||
case inputs := <-workerOut:
|
||||
pending--
|
||||
for _, inp := range inputs {
|
||||
triage = append(triage, inp)
|
||||
}
|
||||
case <-secondTicker:
|
||||
}
|
||||
}
|
||||
// Do this after the parallel section because workers access maxCover.
|
||||
for _, inp := range triage {
|
||||
call := inp.p.Calls[inp.call].Meta
|
||||
maxCover[call.CallID] = cover.Union(maxCover[call.CallID], inp.cover)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func addInput(inp RpcInput) {
|
||||
p, err := prog.Deserialize(inp.Prog)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if inp.CallIndex < 0 || inp.CallIndex >= len(p.Calls) {
|
||||
panic("bad call index")
|
||||
}
|
||||
call := p.Calls[inp.CallIndex].Meta
|
||||
sig := hash(inp.Prog)
|
||||
if _, ok := corpusHashes[sig]; ok {
|
||||
return
|
||||
}
|
||||
cov := cover.Canonicalize(inp.Cover)
|
||||
diff := cover.Difference(cov, maxCover[call.CallID])
|
||||
diff = cover.Difference(diff, flakes)
|
||||
if len(diff) == 0 {
|
||||
return
|
||||
}
|
||||
inp1 := Input{p, inp.CallIndex, cov}
|
||||
corpus = append(corpus, inp1)
|
||||
corpusCover[call.CallID] = cover.Union(corpusCover[call.CallID], cov)
|
||||
maxCover[call.CallID] = cover.Union(maxCover[call.CallID], cov)
|
||||
corpusHashes[hash(inp.Prog)] = struct{}{}
|
||||
}
|
||||
|
||||
func triageInput(env *ipc.Env, inp Input) {
|
||||
call := inp.p.Calls[inp.call].Meta
|
||||
newCover := cover.Difference(inp.cover, corpusCover[call.CallID])
|
||||
newCover = cover.Difference(newCover, flakes)
|
||||
if len(newCover) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if _, ok := corpusHashes[hash(inp.p.Serialize())]; ok {
|
||||
return
|
||||
}
|
||||
|
||||
minCover := inp.cover
|
||||
for i := 0; i < 3; i++ {
|
||||
allCover := execute1(env, inp.p, 0)
|
||||
if len(allCover[inp.call]) == 0 {
|
||||
// The call was not executed. Happens sometimes, reason unknown.
|
||||
continue
|
||||
}
|
||||
cov := allCover[inp.call]
|
||||
diff := cover.SymmetricDifference(inp.cover, cov)
|
||||
if len(diff) != 0 {
|
||||
flakes = cover.Union(flakes, diff)
|
||||
}
|
||||
minCover = cover.Intersection(minCover, cov)
|
||||
}
|
||||
stableNewCover := cover.Intersection(newCover, minCover)
|
||||
if len(stableNewCover) == 0 {
|
||||
return
|
||||
}
|
||||
inp.p, inp.call = prog.Minimize(inp.p, inp.call, func(p1 *prog.Prog, call1 int) bool {
|
||||
allCover := execute1(env, p1, 0)
|
||||
if len(allCover[call1]) == 0 {
|
||||
return false // The call was not executed.
|
||||
}
|
||||
cov := allCover[call1]
|
||||
if len(cover.Intersection(stableNewCover, cov)) != len(stableNewCover) {
|
||||
return false
|
||||
}
|
||||
minCover = cover.Intersection(minCover, cov)
|
||||
return true
|
||||
})
|
||||
inp.cover = minCover
|
||||
corpusCover[call.CallID] = cover.Union(corpusCover[call.CallID], minCover)
|
||||
corpus = append(corpus, inp)
|
||||
data := inp.p.Serialize()
|
||||
corpusHashes[hash(data)] = struct{}{}
|
||||
|
||||
logf(2, "added new input for %v to corpus:\n%s", call.CallName, data)
|
||||
|
||||
a := &NewManagerInputArgs{*flagName, RpcInput{call.CallName, inp.p.Serialize(), inp.call, []uint32(inp.cover)}}
|
||||
if err := manager.Call("Manager.NewInput", a, nil); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func execute(env *ipc.Env, p *prog.Prog, workerId int) []Input {
|
||||
allCover := execute1(env, p, workerId)
|
||||
var inputs []Input
|
||||
for i, cov := range allCover {
|
||||
if len(cov) == 0 {
|
||||
continue
|
||||
}
|
||||
c := p.Calls[i].Meta
|
||||
diff := cover.Difference(cov, maxCover[c.CallID])
|
||||
diff = cover.Difference(diff, flakes)
|
||||
if len(diff) != 0 {
|
||||
p1 := p.Clone()
|
||||
p1.TrimAfter(i)
|
||||
inputs = append(inputs, Input{p1, i, cover.Copy(cov)})
|
||||
}
|
||||
}
|
||||
return inputs
|
||||
}
|
||||
|
||||
var logMu sync.Mutex
|
||||
|
||||
func execute1(env *ipc.Env, p *prog.Prog, workerId int) []cover.Cover {
|
||||
if *flagSaveProg {
|
||||
f, err := os.Create(fmt.Sprintf("%v-%v.prog", *flagName, workerId))
|
||||
if err == nil {
|
||||
f.Write(p.Serialize())
|
||||
f.Close()
|
||||
}
|
||||
} else {
|
||||
// The following output helps to understand what program crashed kernel.
|
||||
// It must not be intermixed.
|
||||
logMu.Lock()
|
||||
log.Printf("worker #%v: executing program:\n%s", workerId, p.Serialize())
|
||||
logMu.Unlock()
|
||||
}
|
||||
|
||||
try := 0
|
||||
retry:
|
||||
exec := p.SerializeForExec()
|
||||
if len(exec) > len(env.In) {
|
||||
panic("program is too long")
|
||||
}
|
||||
copy(env.In, exec)
|
||||
// Zero out the first word (ncmd), so that we don't have garbage there
|
||||
// if executor crashes before writing non-garbage there.
|
||||
for i := 0; i < 4; i++ {
|
||||
env.Out[i] = 0
|
||||
}
|
||||
output, strace, failed, hanged, err := env.Exec()
|
||||
if err != nil {
|
||||
if try > 10 {
|
||||
panic(err)
|
||||
}
|
||||
try++
|
||||
debug.FreeOSMemory()
|
||||
time.Sleep(time.Second)
|
||||
goto retry
|
||||
}
|
||||
logf(4, "result failed=%v hanged=%v:\n%v\n", failed, hanged, string(output))
|
||||
if len(strace) != 0 {
|
||||
logf(4, "strace:\n%s\n", strace)
|
||||
}
|
||||
r := bytes.NewReader(env.Out)
|
||||
var ncmd uint32
|
||||
if err := binary.Read(r, binary.LittleEndian, &ncmd); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
cov := make([]cover.Cover, len(p.Calls))
|
||||
for i := uint32(0); i < ncmd; i++ {
|
||||
var callIndex, callNum, coverSize, pc uint32
|
||||
if err := binary.Read(r, binary.LittleEndian, &callIndex); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := binary.Read(r, binary.LittleEndian, &callNum); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := binary.Read(r, binary.LittleEndian, &coverSize); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if int(callIndex) > len(cov) {
|
||||
panic(fmt.Sprintf("expect index %v, got %v", i, callIndex))
|
||||
}
|
||||
c := p.Calls[callIndex]
|
||||
if num := c.Meta.ID; uint32(num) != callNum {
|
||||
logf(0, "ERROR: call %v: expect syscall %v, got %v, executed %v", callIndex, num, callNum, ncmd)
|
||||
logf(0, "program:\n%s", p.Serialize())
|
||||
logf(0, "output:\n%s", output)
|
||||
}
|
||||
cover1 := make([]uint32, 0, coverSize)
|
||||
for j := uint32(0); j < coverSize; j++ {
|
||||
if err := binary.Read(r, binary.LittleEndian, &pc); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
cover1 = append(cover1, pc)
|
||||
}
|
||||
if *flagV >= 4 {
|
||||
log.Printf("%v:", c.Meta.Name)
|
||||
for _, pc := range cover1 {
|
||||
log.Printf(" 0x%x", (1<<32-1)<<32|uint64(pc))
|
||||
}
|
||||
log.Printf("\n")
|
||||
}
|
||||
cov[callIndex] = cover.Canonicalize(cover1)
|
||||
}
|
||||
return cov
|
||||
}
|
||||
|
||||
func logf(v int, msg string, args ...interface{}) {
|
||||
if *flagV >= v {
|
||||
log.Printf(msg, args...)
|
||||
}
|
||||
}
|
222
ipc/ipc.go
Normal file
222
ipc/ipc.go
Normal file
@ -0,0 +1,222 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package ipc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Env struct {
|
||||
In []byte
|
||||
Out []byte
|
||||
|
||||
inFile *os.File
|
||||
outFile *os.File
|
||||
bin []string
|
||||
timeout time.Duration
|
||||
flags uint64
|
||||
}
|
||||
|
||||
const (
|
||||
FlagDebug = uint64(1) << iota // debug output from executor
|
||||
FlagCover // collect coverage
|
||||
FlagThreaded // use multiple threads to mitigate blocked syscalls
|
||||
FlagStrace // run executor under strace
|
||||
)
|
||||
|
||||
func MakeEnv(bin string, timeout time.Duration, flags uint64) (*Env, error) {
|
||||
inf, inmem, err := createMapping(1 << 20)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
outf, outmem, err := createMapping(16 << 20)
|
||||
if err != nil {
|
||||
closeMapping(inf, inmem)
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < 8; i++ {
|
||||
inmem[i] = byte(flags >> (8 * uint(i)))
|
||||
}
|
||||
inmem = inmem[8:]
|
||||
env := &Env{
|
||||
In: inmem,
|
||||
Out: outmem,
|
||||
inFile: inf,
|
||||
outFile: outf,
|
||||
bin: strings.Split(bin, " "),
|
||||
timeout: timeout,
|
||||
flags: flags,
|
||||
}
|
||||
if len(env.bin) == 0 {
|
||||
return nil, fmt.Errorf("binary is empty string")
|
||||
}
|
||||
return env, nil
|
||||
}
|
||||
|
||||
func (env *Env) Close() error {
|
||||
err1 := closeMapping(env.inFile, env.In)
|
||||
err2 := closeMapping(env.outFile, env.Out)
|
||||
switch {
|
||||
case err1 != nil:
|
||||
return err1
|
||||
case err2 != nil:
|
||||
return err2
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (env *Env) Exec() (output, strace []byte, failed, hanged bool, err0 error) {
|
||||
dir, err := ioutil.TempDir("./", "syzkaller-testdir")
|
||||
if err != nil {
|
||||
err0 = fmt.Errorf("failed to create temp dir: %v", err)
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
rp, wp, err := os.Pipe()
|
||||
if err != nil {
|
||||
err0 = fmt.Errorf("failed to create pipe: %v", err)
|
||||
return
|
||||
}
|
||||
defer rp.Close()
|
||||
defer wp.Close()
|
||||
cmd := exec.Command(env.bin[0], env.bin[1:]...)
|
||||
traceFile := ""
|
||||
if env.flags&FlagStrace != 0 {
|
||||
f, err := ioutil.TempFile("./", "syzkaller-strace")
|
||||
if err != nil {
|
||||
err0 = fmt.Errorf("failed to create temp file: %v", err)
|
||||
return
|
||||
}
|
||||
f.Close()
|
||||
defer os.Remove(f.Name())
|
||||
traceFile, _ = filepath.Abs(f.Name())
|
||||
args := []string{"-s", "8", "-o", traceFile}
|
||||
args = append(args, env.bin...)
|
||||
if env.flags&FlagThreaded != 0 {
|
||||
args = append([]string{"-f"}, args...)
|
||||
}
|
||||
cmd = exec.Command("strace", args...)
|
||||
}
|
||||
cmd.ExtraFiles = append(cmd.ExtraFiles, env.inFile, env.outFile)
|
||||
cmd.Env = []string{}
|
||||
cmd.Dir = dir
|
||||
cmd.Stdout = wp
|
||||
cmd.Stderr = wp
|
||||
if syscall.Getuid() == 0 {
|
||||
// Running under root, more isolation is possible.
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true, Cloneflags: syscall.CLONE_NEWNS}
|
||||
} else {
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
}
|
||||
if err := cmd.Start(); err != nil {
|
||||
err0 = fmt.Errorf("failed to start executor binary: %v", err)
|
||||
return
|
||||
}
|
||||
wp.Close()
|
||||
done := make(chan bool)
|
||||
hang := make(chan bool)
|
||||
go func() {
|
||||
t := time.NewTimer(env.timeout)
|
||||
select {
|
||||
case <-t.C:
|
||||
// We started the process in its own process group and now kill the whole group.
|
||||
// This solves a potential problem with strace:
|
||||
// if we kill just strace, executor still runs and ReadAll below hangs.
|
||||
syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
|
||||
syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
|
||||
syscall.Kill(cmd.Process.Pid, syscall.SIGKILL)
|
||||
syscall.Kill(cmd.Process.Pid, syscall.SIGKILL)
|
||||
hang <- true
|
||||
case <-done:
|
||||
t.Stop()
|
||||
hang <- false
|
||||
}
|
||||
}()
|
||||
output, err = ioutil.ReadAll(rp)
|
||||
readErr := err
|
||||
close(done)
|
||||
if err = cmd.Wait(); <-hang && err != nil {
|
||||
hanged = true
|
||||
failed = true
|
||||
}
|
||||
if err != nil {
|
||||
output = append(output, []byte(err.Error())...)
|
||||
output = append(output, '\n')
|
||||
}
|
||||
if cmd.ProcessState != nil {
|
||||
sys := cmd.ProcessState.Sys()
|
||||
if ws, ok := sys.(syscall.WaitStatus); ok {
|
||||
// Magic values returned by executor.
|
||||
if ws.ExitStatus() == 67 {
|
||||
err0 = fmt.Errorf("executor failed: %s", output)
|
||||
return
|
||||
}
|
||||
if ws.ExitStatus() == 68 {
|
||||
failed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if readErr != nil {
|
||||
err0 = fmt.Errorf("failed to read executor output: %v", err)
|
||||
return
|
||||
}
|
||||
if traceFile != "" {
|
||||
strace, err = ioutil.ReadFile(traceFile)
|
||||
if err != nil {
|
||||
err0 = fmt.Errorf("failed to read strace output: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createMapping(size int) (f *os.File, mem []byte, err error) {
|
||||
f, err = ioutil.TempFile("./", "syzkaller-shm")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if _, err = f.Write(make([]byte, size)); err != nil {
|
||||
// if err = f.Truncate(int64(size)); err != nil {
|
||||
f.Close()
|
||||
os.Remove(f.Name())
|
||||
return
|
||||
}
|
||||
f.Close()
|
||||
f, err = os.OpenFile(f.Name(), os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
os.Remove(f.Name())
|
||||
return
|
||||
}
|
||||
mem, err = syscall.Mmap(int(f.Fd()), 0, size, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED)
|
||||
if err != nil {
|
||||
f.Close()
|
||||
os.Remove(f.Name())
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func closeMapping(f *os.File, mem []byte) error {
|
||||
err1 := syscall.Munmap(mem)
|
||||
err2 := f.Close()
|
||||
err3 := os.Remove(f.Name())
|
||||
switch {
|
||||
case err1 != nil:
|
||||
return err1
|
||||
case err2 != nil:
|
||||
return err2
|
||||
case err3 != nil:
|
||||
return err3
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
235
ipc/ipc_test.go
Normal file
235
ipc/ipc_test.go
Normal file
@ -0,0 +1,235 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package ipc
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/syzkaller/prog"
|
||||
)
|
||||
|
||||
func buildExecutor(t *testing.T) string {
|
||||
return buildProgram(t, "../executor/executor.cc")
|
||||
}
|
||||
|
||||
func buildSource(t *testing.T, src []byte) string {
|
||||
srcf, err := ioutil.TempFile("", "syzkaller")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create temp file: %v", err)
|
||||
}
|
||||
srcf.Close()
|
||||
os.Remove(srcf.Name())
|
||||
name := srcf.Name() + ".c"
|
||||
if err := ioutil.WriteFile(name, src, 0600); err != nil {
|
||||
t.Fatalf("failed to write temp file: %v", err)
|
||||
}
|
||||
defer os.Remove(name)
|
||||
return buildProgram(t, name)
|
||||
}
|
||||
|
||||
func buildProgram(t *testing.T, src string) string {
|
||||
bin, err := ioutil.TempFile("", "syzkaller")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create temp file: %v", err)
|
||||
}
|
||||
bin.Close()
|
||||
out, err := exec.Command("gcc", src, "-o", bin.Name(), "-lpthread", "-static", "-O1", "-g").CombinedOutput()
|
||||
if err != nil {
|
||||
os.Remove(bin.Name())
|
||||
data, _ := ioutil.ReadFile(src)
|
||||
t.Fatalf("failed to build program:\n%s\n%s", data, out)
|
||||
}
|
||||
return bin.Name()
|
||||
}
|
||||
|
||||
func initTest(t *testing.T) (rand.Source, int) {
|
||||
iters := 100
|
||||
if testing.Short() {
|
||||
iters = 10
|
||||
}
|
||||
seed := int64(time.Now().UnixNano())
|
||||
rs := rand.NewSource(seed)
|
||||
t.Logf("seed=%v", seed)
|
||||
return rs, iters
|
||||
}
|
||||
|
||||
func TestEmptyProg(t *testing.T) {
|
||||
bin := buildExecutor(t)
|
||||
defer os.Remove(bin)
|
||||
|
||||
env, err := MakeEnv(bin, time.Second, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create env: %v", err)
|
||||
}
|
||||
defer env.Close()
|
||||
|
||||
p := new(prog.Prog)
|
||||
data := p.SerializeForExec()
|
||||
copy(env.In, data)
|
||||
|
||||
output, strace, failed, hanged, err := env.Exec()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run executor: %v", err)
|
||||
}
|
||||
if len(output) != 0 {
|
||||
t.Fatalf("output on empty program")
|
||||
}
|
||||
if len(strace) != 0 {
|
||||
t.Fatalf("strace output when not stracing")
|
||||
}
|
||||
if failed || hanged {
|
||||
t.Fatalf("empty program failed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStrace(t *testing.T) {
|
||||
bin := buildExecutor(t)
|
||||
defer os.Remove(bin)
|
||||
|
||||
env, err := MakeEnv(bin, time.Second, FlagStrace)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create env: %v", err)
|
||||
}
|
||||
defer env.Close()
|
||||
|
||||
p := new(prog.Prog)
|
||||
data := p.SerializeForExec()
|
||||
copy(env.In, data)
|
||||
|
||||
_, strace, failed, hanged, err := env.Exec()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run executor: %v", err)
|
||||
}
|
||||
if len(strace) == 0 {
|
||||
t.Fatalf("no strace output")
|
||||
}
|
||||
if failed || hanged {
|
||||
t.Fatalf("empty program failed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestExecute(t *testing.T) {
|
||||
bin := buildExecutor(t)
|
||||
defer os.Remove(bin)
|
||||
|
||||
rs, iters := initTest(t)
|
||||
flags := []uint64{0, FlagStrace, FlagThreaded, FlagStrace | FlagThreaded}
|
||||
for _, flag := range flags {
|
||||
env, err := MakeEnv(bin, time.Second, flag)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create env: %v", err)
|
||||
}
|
||||
defer env.Close()
|
||||
|
||||
for i := 0; i < iters/len(flags); i++ {
|
||||
p := prog.Generate(rs, 10, nil)
|
||||
data := p.SerializeForExec()
|
||||
copy(env.In, data)
|
||||
|
||||
_, _, _, _, err := env.Exec()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run executor: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompare(t *testing.T) {
|
||||
t.Skip("flaky")
|
||||
|
||||
bin := buildExecutor(t)
|
||||
defer os.Remove(bin)
|
||||
|
||||
// Sequence of syscalls that statically linked libc produces on startup.
|
||||
rawTracePrefix := []string{"execve", "uname", "brk", "brk", "arch_prctl",
|
||||
"readlink", "brk", "brk", "access"}
|
||||
executorTracePrefix := []string{"execve", "uname", "brk", "brk", "arch_prctl",
|
||||
"set_tid_address", "set_robust_list", "futex", "rt_sigaction", "rt_sigaction",
|
||||
"rt_sigprocmask", "getrlimit", "readlink", "brk", "brk", "access", "mmap", "mmap"}
|
||||
// These calls produce non-deterministic results, ignore them.
|
||||
nondet := []string{"getrusage", "msgget", "msgrcv", "msgsnd", "shmget", "semat", "io_setup", "getpgrp",
|
||||
"getpid", "getpgid", "getppid", "setsid", "ppoll", "keyctl", "ioprio_get",
|
||||
"move_pages", "kcmp"}
|
||||
|
||||
env1, err := MakeEnv(bin, time.Second, FlagStrace)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create env: %v", err)
|
||||
}
|
||||
defer env1.Close()
|
||||
|
||||
rs, iters := initTest(t)
|
||||
for i := 0; i < iters; i++ {
|
||||
p := prog.Generate(rs, 10, nil)
|
||||
data := p.SerializeForExec()
|
||||
copy(env1.In, data)
|
||||
|
||||
_, strace1, _, _, err := env1.Exec()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run executor: %v", err)
|
||||
}
|
||||
|
||||
src := p.WriteCSource()
|
||||
cprog := buildSource(t, src)
|
||||
defer os.Remove(cprog)
|
||||
|
||||
env2, err := MakeEnv(cprog, time.Second, FlagStrace)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create env: %v", err)
|
||||
}
|
||||
defer env2.Close() // yes, that's defer in a loop
|
||||
|
||||
_, strace2, _, _, err := env2.Exec()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to run c binary: %v", err)
|
||||
}
|
||||
stripPrefix := func(data []byte, prefix []string) string {
|
||||
prefix0 := prefix
|
||||
buf := new(bytes.Buffer)
|
||||
s := bufio.NewScanner(bytes.NewReader(data))
|
||||
for s.Scan() {
|
||||
if strings.HasPrefix(s.Text(), "--- SIG") {
|
||||
// Signal parameters can contain pid and pc.
|
||||
continue
|
||||
}
|
||||
if len(prefix) == 0 {
|
||||
skip := false
|
||||
for _, c := range nondet {
|
||||
if strings.HasPrefix(s.Text(), c) {
|
||||
skip = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if skip {
|
||||
continue
|
||||
}
|
||||
buf.WriteString(s.Text())
|
||||
buf.Write([]byte{'\n'})
|
||||
continue
|
||||
}
|
||||
if !strings.HasPrefix(s.Text(), prefix[0]) {
|
||||
t.Fatalf("strace output does not start with expected prefix\ngot:\n%s\nexpect prefix: %+v\ncurrent call: %v", data, prefix0, prefix[0])
|
||||
}
|
||||
prefix = prefix[1:]
|
||||
}
|
||||
if err := s.Err(); err != nil {
|
||||
t.Fatalf("failed to scan strace output: %v", err)
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
s1 := stripPrefix(strace1, executorTracePrefix)
|
||||
s2 := stripPrefix(strace2, rawTracePrefix)
|
||||
if s1 == "" || s1 != s2 {
|
||||
t.Logf("program:\n%s\n", p.Serialize())
|
||||
t.Fatalf("strace output differs:\n%s\n\n\n%s\n", s1, s2)
|
||||
}
|
||||
}
|
||||
}
|
286
manager/cover.go
Normal file
286
manager/cover.go
Normal file
@ -0,0 +1,286 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os/exec"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type LineInfo struct {
|
||||
file string
|
||||
line int
|
||||
}
|
||||
|
||||
var (
|
||||
mu sync.Mutex
|
||||
pcLines = make(map[uint32][]LineInfo)
|
||||
parsedFiles = make(map[string][][]byte)
|
||||
htmlReplacer = strings.NewReplacer(">", ">", "<", "<", "&", "&", "\t", " ")
|
||||
sourcePrefix string
|
||||
)
|
||||
|
||||
func generateCoverHtml(w io.Writer, vmlinux string, cov []uint32) error {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
info, err := covToLineInfo(vmlinux, cov)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
files := fileSet(info)
|
||||
for f := range files {
|
||||
if _, ok := parsedFiles[f]; ok {
|
||||
continue
|
||||
}
|
||||
if err := parseFile(f); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
var d templateData
|
||||
for f, covered := range files {
|
||||
lines := parsedFiles[f]
|
||||
coverage := len(covered)
|
||||
var buf bytes.Buffer
|
||||
for i, ln := range lines {
|
||||
if len(covered) > 0 && covered[0] == i+1 {
|
||||
buf.Write([]byte("<span id='covered'>"))
|
||||
buf.Write(ln)
|
||||
buf.Write([]byte("</span>\n"))
|
||||
covered = covered[1:]
|
||||
} else {
|
||||
buf.Write(ln)
|
||||
buf.Write([]byte("\n"))
|
||||
}
|
||||
}
|
||||
stripped := f
|
||||
if len(stripped) > len(sourcePrefix) {
|
||||
stripped = stripped[len(sourcePrefix):]
|
||||
}
|
||||
d.Files = append(d.Files, &templateFile{
|
||||
Name: stripped,
|
||||
Body: template.HTML(buf.String()),
|
||||
Coverage: coverage,
|
||||
})
|
||||
}
|
||||
|
||||
sort.Sort(templateFileArray(d.Files))
|
||||
if err := coverTemplate.Execute(w, d); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func covToLineInfo(vmlinux string, cov []uint32) ([]LineInfo, error) {
|
||||
var missing []uint32
|
||||
for _, pc := range cov {
|
||||
if _, ok := pcLines[pc]; !ok {
|
||||
missing = append(missing, pc)
|
||||
}
|
||||
}
|
||||
if len(missing) > 0 {
|
||||
if err := symbolize(vmlinux, missing); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
var info []LineInfo
|
||||
for _, pc := range cov {
|
||||
info = append(info, pcLines[pc]...)
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func fileSet(info []LineInfo) map[string][]int {
|
||||
files := make(map[string]map[int]struct{})
|
||||
for _, li := range info {
|
||||
if files[li.file] == nil {
|
||||
files[li.file] = make(map[int]struct{})
|
||||
}
|
||||
files[li.file][li.line] = struct{}{}
|
||||
}
|
||||
res := make(map[string][]int)
|
||||
for f, lines := range files {
|
||||
sorted := make([]int, 0, len(lines))
|
||||
for ln := range lines {
|
||||
sorted = append(sorted, ln)
|
||||
}
|
||||
sort.Ints(sorted)
|
||||
res[f] = sorted
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func parseFile(fn string) error {
|
||||
data, err := ioutil.ReadFile(fn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var lines [][]byte
|
||||
for {
|
||||
idx := bytes.IndexByte(data, '\n')
|
||||
if idx == -1 {
|
||||
break
|
||||
}
|
||||
lines = append(lines, []byte(htmlReplacer.Replace(string(data[:idx]))))
|
||||
data = data[idx+1:]
|
||||
}
|
||||
if len(data) != 0 {
|
||||
lines = append(lines, data)
|
||||
}
|
||||
parsedFiles[fn] = lines
|
||||
if sourcePrefix == "" {
|
||||
sourcePrefix = fn
|
||||
} else {
|
||||
i := 0
|
||||
for ; i < len(sourcePrefix) && i < len(fn); i++ {
|
||||
if sourcePrefix[i] != fn[i] {
|
||||
break
|
||||
}
|
||||
}
|
||||
sourcePrefix = sourcePrefix[:i]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func symbolize(vmlinux string, cov []uint32) error {
|
||||
cmd := exec.Command("addr2line", "-a", "-i", "-e", vmlinux)
|
||||
stdin, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer stdin.Close()
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer stdout.Close()
|
||||
if err := cmd.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer cmd.Wait()
|
||||
go func() {
|
||||
for _, pc := range cov {
|
||||
fmt.Fprintf(stdin, "0xffffffff%x\n", pc-1)
|
||||
}
|
||||
stdin.Close()
|
||||
}()
|
||||
s := bufio.NewScanner(stdout)
|
||||
var pc uint32
|
||||
for s.Scan() {
|
||||
ln := s.Text()
|
||||
if len(ln) > 3 && ln[0] == '0' && ln[1] == 'x' {
|
||||
v, err := strconv.ParseUint(ln, 0, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse pc in addr2line output: %v", err)
|
||||
}
|
||||
pc = uint32(v) + 1
|
||||
continue
|
||||
}
|
||||
colon := strings.IndexByte(ln, ':')
|
||||
if colon == -1 {
|
||||
continue
|
||||
}
|
||||
file := ln[:colon]
|
||||
line, err := strconv.Atoi(ln[colon+1:])
|
||||
if err != nil || pc == 0 || file == "" || file == "??" || line <= 0 {
|
||||
continue
|
||||
}
|
||||
pcLines[pc] = append(pcLines[pc], LineInfo{file, line})
|
||||
}
|
||||
if err := s.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type templateData struct {
|
||||
Files []*templateFile
|
||||
}
|
||||
|
||||
type templateFile struct {
|
||||
Name string
|
||||
Body template.HTML
|
||||
Coverage int
|
||||
}
|
||||
|
||||
type templateFileArray []*templateFile
|
||||
|
||||
func (a templateFileArray) Len() int { return len(a) }
|
||||
func (a templateFileArray) Less(i, j int) bool { return a[i].Name < a[j].Name }
|
||||
func (a templateFileArray) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
|
||||
var coverTemplate = template.Must(template.New("").Parse(
|
||||
`
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<style>
|
||||
body {
|
||||
background: white;
|
||||
}
|
||||
#topbar {
|
||||
background: black;
|
||||
position: fixed;
|
||||
top: 0; left: 0; right: 0;
|
||||
height: 42px;
|
||||
border-bottom: 1px solid rgb(70, 70, 70);
|
||||
}
|
||||
#nav {
|
||||
float: left;
|
||||
margin-left: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
#content {
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
color: rgb(70, 70, 70);
|
||||
margin-top: 50px;
|
||||
}
|
||||
#covered {
|
||||
color: rgb(0, 0, 0);
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="topbar">
|
||||
<div id="nav">
|
||||
<select id="files">
|
||||
{{range $i, $f := .Files}}
|
||||
<option value="file{{$i}}">{{$f.Name}} ({{$f.Coverage}})</option>
|
||||
{{end}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
{{range $i, $f := .Files}}
|
||||
<pre class="file" id="file{{$i}}" {{if $i}}style="display: none"{{end}}>{{$f.Body}}</pre>
|
||||
{{end}}
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
(function() {
|
||||
var files = document.getElementById('files');
|
||||
var visible = document.getElementById('file0');
|
||||
files.addEventListener('change', onChange, false);
|
||||
function onChange() {
|
||||
visible.style.display = 'none';
|
||||
visible = document.getElementById(files.value);
|
||||
visible.style.display = 'block';
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</html>
|
||||
`))
|
25
manager/example.cfg
Normal file
25
manager/example.cfg
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "my-qemu-asan",
|
||||
"http": "myhost.com:56741",
|
||||
"master": "myhost.com:48342",
|
||||
"workdir": "/syzkaller/manager/workdir",
|
||||
"vmlinux": "/linux/vmlinux",
|
||||
"type": "qemu",
|
||||
"count": 16,
|
||||
"port": 23504,
|
||||
"params": {
|
||||
"kernel": "/linux/arch/x86/boot/bzImage",
|
||||
"image": "/linux_image/wheezy.img",
|
||||
"sshkey": "/linux_image/ssh/id_rsa",
|
||||
"fuzzer": "/syzkaller/fuzzer/fuzzer",
|
||||
"executor": "/syzkaller/executor/executor",
|
||||
"port": 23505,
|
||||
"cpu": 2,
|
||||
"mem": 2048
|
||||
},
|
||||
"disable_syscalls": [
|
||||
"keyctl",
|
||||
"add_key",
|
||||
"request_key"
|
||||
]
|
||||
}
|
188
manager/html.go
Normal file
188
manager/html.go
Normal file
@ -0,0 +1,188 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"github.com/google/syzkaller/cover"
|
||||
"github.com/google/syzkaller/prog"
|
||||
)
|
||||
|
||||
func (mgr *Manager) httpInfo(w http.ResponseWriter, r *http.Request) {
|
||||
mgr.mu.Lock()
|
||||
defer mgr.mu.Unlock()
|
||||
|
||||
type CallCov struct {
|
||||
count int
|
||||
cov cover.Cover
|
||||
}
|
||||
calls := make(map[string]*CallCov)
|
||||
for _, inp := range mgr.corpus {
|
||||
if calls[inp.Call] == nil {
|
||||
calls[inp.Call] = new(CallCov)
|
||||
}
|
||||
cc := calls[inp.Call]
|
||||
cc.count++
|
||||
cc.cov = cover.Union(cc.cov, cover.Cover(inp.Cover))
|
||||
}
|
||||
|
||||
data := &UIData{
|
||||
Name: mgr.cfg.Name,
|
||||
MasterHttp: mgr.masterHttp,
|
||||
MasterCorpusSize: len(mgr.masterCorpus),
|
||||
CorpusSize: len(mgr.corpus),
|
||||
}
|
||||
|
||||
var cov cover.Cover
|
||||
for c, cc := range calls {
|
||||
cov = cover.Union(cov, cc.cov)
|
||||
data.Calls = append(data.Calls, UICallType{c, cc.count, len(cc.cov)})
|
||||
}
|
||||
sort.Sort(UICallTypeArray(data.Calls))
|
||||
data.CoverSize = len(cov)
|
||||
|
||||
if err := htmlTemplate.Execute(w, data); err != nil {
|
||||
http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
func (mgr *Manager) httpCorpus(w http.ResponseWriter, r *http.Request) {
|
||||
mgr.mu.Lock()
|
||||
defer mgr.mu.Unlock()
|
||||
|
||||
var data []UIInput
|
||||
call := r.FormValue("call")
|
||||
for i, inp := range mgr.corpus {
|
||||
if call != inp.Call {
|
||||
continue
|
||||
}
|
||||
p, err := prog.Deserialize(inp.Prog)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("failed to deserialize program: %v", err), http.StatusInternalServerError)
|
||||
}
|
||||
data = append(data, UIInput{
|
||||
Short: p.String(),
|
||||
Full: string(inp.Prog),
|
||||
Cover: len(inp.Cover),
|
||||
N: i,
|
||||
})
|
||||
}
|
||||
sort.Sort(UIInputArray(data))
|
||||
|
||||
if err := corpusTemplate.Execute(w, data); err != nil {
|
||||
http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
func (mgr *Manager) httpCover(w http.ResponseWriter, r *http.Request) {
|
||||
mgr.mu.Lock()
|
||||
defer mgr.mu.Unlock()
|
||||
|
||||
var cov cover.Cover
|
||||
call := r.FormValue("call")
|
||||
if n, err := strconv.Atoi(call); err == nil && n < len(mgr.corpus) {
|
||||
cov = mgr.corpus[n].Cover
|
||||
} else {
|
||||
for _, inp := range mgr.corpus {
|
||||
if call == "" || call == inp.Call {
|
||||
cov = cover.Union(cov, cover.Cover(inp.Cover))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := generateCoverHtml(w, mgr.cfg.Vmlinux, cov); err != nil {
|
||||
http.Error(w, fmt.Sprintf("failed to generate coverage profile: %v", err), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
func (mgr *Manager) httpCurrentCorpus(w http.ResponseWriter, r *http.Request) {
|
||||
mgr.mu.Lock()
|
||||
defer mgr.mu.Unlock()
|
||||
|
||||
mgr.minimizeCorpus()
|
||||
var hashes []string
|
||||
for _, inp := range mgr.corpus {
|
||||
hash := hash(inp.Prog)
|
||||
hashes = append(hashes, hex.EncodeToString(hash[:]))
|
||||
}
|
||||
data, err := json.Marshal(&hashes)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("failed to marshal corpus: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.Write(data)
|
||||
}
|
||||
|
||||
type UIData struct {
|
||||
Name string
|
||||
MasterHttp string
|
||||
MasterCorpusSize int
|
||||
CorpusSize int
|
||||
CoverSize int
|
||||
Calls []UICallType
|
||||
}
|
||||
|
||||
type UICallType struct {
|
||||
Name string
|
||||
Inputs int
|
||||
Cover int
|
||||
}
|
||||
|
||||
type UIInput struct {
|
||||
Short string
|
||||
Full string
|
||||
Calls int
|
||||
Cover int
|
||||
N int
|
||||
}
|
||||
|
||||
type UICallTypeArray []UICallType
|
||||
|
||||
func (a UICallTypeArray) Len() int { return len(a) }
|
||||
func (a UICallTypeArray) Less(i, j int) bool { return a[i].Name < a[j].Name }
|
||||
func (a UICallTypeArray) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
|
||||
type UIInputArray []UIInput
|
||||
|
||||
func (a UIInputArray) Len() int { return len(a) }
|
||||
func (a UIInputArray) Less(i, j int) bool { return a[i].Cover > a[j].Cover }
|
||||
func (a UIInputArray) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
|
||||
var htmlTemplate = template.Must(template.New("").Parse(`
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>syzkaller {{.Name}}</title>
|
||||
</head>
|
||||
<body>
|
||||
Manager: {{.Name}} <a href='http://{{.MasterHttp}}'>[master]</a> <br>
|
||||
Master corpus: {{.MasterCorpusSize}} <br>
|
||||
Corpus: {{.CorpusSize}}<br>
|
||||
<a href='/cover'>Cover: {{.CoverSize}}</a> <br>
|
||||
<br>
|
||||
{{range $c := $.Calls}}
|
||||
{{$c.Name}} <a href='/corpus?call={{$c.Name}}'>inputs:{{$c.Inputs}}</a> <a href='/cover?call={{$c.Name}}'>cover:{{$c.Cover}}</a><br>
|
||||
{{end}}
|
||||
</body></html>
|
||||
`))
|
||||
|
||||
var corpusTemplate = template.Must(template.New("").Parse(`
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>syzkaller corpus</title>
|
||||
</head>
|
||||
<body>
|
||||
{{range $c := $}}
|
||||
<span title="{{$c.Full}}">{{$c.Short}}</span> <a href='/cover?call={{$c.N}}'>cover:{{$c.Cover}}</a> <br>
|
||||
{{end}}
|
||||
</body></html>
|
||||
`))
|
139
manager/main.go
Normal file
139
manager/main.go
Normal file
@ -0,0 +1,139 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
|
||||
"github.com/google/syzkaller/sys"
|
||||
"github.com/google/syzkaller/vm"
|
||||
_ "github.com/google/syzkaller/vm/local"
|
||||
_ "github.com/google/syzkaller/vm/qemu"
|
||||
)
|
||||
|
||||
var (
|
||||
flagConfig = flag.String("config", "", "configuration file")
|
||||
flagV = flag.Int("v", 0, "verbosity")
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Name string
|
||||
Http string
|
||||
Master string
|
||||
Workdir string
|
||||
Vmlinux string
|
||||
Type string
|
||||
Count int
|
||||
Port int
|
||||
Nocover bool
|
||||
Params map[string]interface{}
|
||||
Enable_Syscalls []string
|
||||
Disable_Syscalls []string
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
cfg, syscalls := parseConfig()
|
||||
var instances []vm.Instance
|
||||
for i := 0; i < cfg.Count; i++ {
|
||||
params, err := json.Marshal(cfg.Params)
|
||||
if err != nil {
|
||||
fatalf("failed to marshal config params: %v", err)
|
||||
}
|
||||
inst, err := vm.Create(cfg.Type, cfg.Workdir, syscalls, cfg.Port, i, params)
|
||||
if err != nil {
|
||||
fatalf("failed to create an instance: %v", err)
|
||||
}
|
||||
instances = append(instances, inst)
|
||||
}
|
||||
RunManager(cfg, syscalls, instances)
|
||||
}
|
||||
|
||||
func parseConfig() (*Config, map[int]bool) {
|
||||
if *flagConfig == "" {
|
||||
fatalf("supply config file name in -config flag")
|
||||
}
|
||||
data, err := ioutil.ReadFile(*flagConfig)
|
||||
if err != nil {
|
||||
fatalf("failed to read config file: %v", err)
|
||||
}
|
||||
cfg := new(Config)
|
||||
if err := json.Unmarshal(data, cfg); err != nil {
|
||||
fatalf("failed to parse config file: %v", err)
|
||||
}
|
||||
if cfg.Name == "" {
|
||||
fatalf("config param name is empty")
|
||||
}
|
||||
if cfg.Http == "" {
|
||||
fatalf("config param http is empty")
|
||||
}
|
||||
if cfg.Master == "" {
|
||||
fatalf("config param master is empty")
|
||||
}
|
||||
if cfg.Workdir == "" {
|
||||
fatalf("config param workdir is empty")
|
||||
}
|
||||
if cfg.Vmlinux == "" {
|
||||
fatalf("config param vmlinux is empty")
|
||||
}
|
||||
if cfg.Type == "" {
|
||||
fatalf("config param type is empty")
|
||||
}
|
||||
if cfg.Count <= 0 || cfg.Count > 1000 {
|
||||
fatalf("invalid config param count: %v, want (1, 1000]", cfg.Count)
|
||||
}
|
||||
|
||||
var syscalls map[int]bool
|
||||
if len(cfg.Enable_Syscalls) != 0 || len(cfg.Disable_Syscalls) != 0 {
|
||||
syscalls = make(map[int]bool)
|
||||
if len(cfg.Enable_Syscalls) != 0 {
|
||||
for _, c := range cfg.Enable_Syscalls {
|
||||
n := 0
|
||||
for _, call := range sys.Calls {
|
||||
if call.CallName == c {
|
||||
syscalls[call.ID] = true
|
||||
n++
|
||||
}
|
||||
}
|
||||
if n == 0 {
|
||||
fatalf("unknown enabled syscall: %v", c)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, call := range sys.Calls {
|
||||
syscalls[call.ID] = true
|
||||
}
|
||||
}
|
||||
for _, c := range cfg.Disable_Syscalls {
|
||||
n := 0
|
||||
for _, call := range sys.Calls {
|
||||
if call.CallName == c {
|
||||
delete(syscalls, call.ID)
|
||||
n++
|
||||
}
|
||||
}
|
||||
if n == 0 {
|
||||
fatalf("unknown disabled syscall: %v", c)
|
||||
}
|
||||
}
|
||||
// They will be generated anyway.
|
||||
syscalls[sys.CallMap["mmap"].ID] = true
|
||||
syscalls[sys.CallMap["clock_gettime"].ID] = true
|
||||
}
|
||||
|
||||
return cfg, syscalls
|
||||
}
|
||||
|
||||
func logf(v int, msg string, args ...interface{}) {
|
||||
if *flagV >= v {
|
||||
log.Printf(msg, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func fatalf(msg string, args ...interface{}) {
|
||||
log.Fatalf(msg, args...)
|
||||
}
|
238
manager/manager.go
Normal file
238
manager/manager.go
Normal file
@ -0,0 +1,238 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/rpc"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/google/syzkaller/cover"
|
||||
"github.com/google/syzkaller/prog"
|
||||
. "github.com/google/syzkaller/rpctype"
|
||||
"github.com/google/syzkaller/sys"
|
||||
"github.com/google/syzkaller/vm"
|
||||
)
|
||||
|
||||
type Sig [sha1.Size]byte
|
||||
|
||||
func hash(data []byte) Sig {
|
||||
return Sig(sha1.Sum(data))
|
||||
}
|
||||
|
||||
type Manager struct {
|
||||
cfg *Config
|
||||
master *rpc.Client
|
||||
masterHttp string
|
||||
instances []vm.Instance
|
||||
|
||||
mu sync.Mutex
|
||||
masterCorpus [][]byte // mirror of master corpus
|
||||
masterHashes map[Sig]struct{} // hashes of master corpus
|
||||
candidates [][]byte // new untriaged inputs from master
|
||||
syscalls map[int]bool
|
||||
|
||||
corpus []RpcInput
|
||||
corpusCover []cover.Cover
|
||||
|
||||
fuzzers map[string]*Fuzzer
|
||||
}
|
||||
|
||||
type Fuzzer struct {
|
||||
name string
|
||||
input int
|
||||
}
|
||||
|
||||
func RunManager(cfg *Config, syscalls map[int]bool, instances []vm.Instance) {
|
||||
// Connect to master.
|
||||
master, err := rpc.Dial("tcp", cfg.Master)
|
||||
if err != nil {
|
||||
fatalf("failed to dial mastger: %v", err)
|
||||
}
|
||||
a := &MasterConnectArgs{cfg.Name, cfg.Http}
|
||||
r := &MasterConnectRes{}
|
||||
if err := master.Call("Master.Connect", a, r); err != nil {
|
||||
fatalf("failed to connect to master: %v", err)
|
||||
}
|
||||
logf(0, "connected to master at %v", cfg.Master)
|
||||
|
||||
mgr := &Manager{
|
||||
cfg: cfg,
|
||||
master: master,
|
||||
masterHttp: r.Http,
|
||||
instances: instances,
|
||||
masterHashes: make(map[Sig]struct{}),
|
||||
syscalls: syscalls,
|
||||
corpusCover: make([]cover.Cover, sys.CallCount),
|
||||
fuzzers: make(map[string]*Fuzzer),
|
||||
}
|
||||
|
||||
http.HandleFunc("/", mgr.httpInfo)
|
||||
http.HandleFunc("/corpus", mgr.httpCorpus)
|
||||
http.HandleFunc("/cover", mgr.httpCover)
|
||||
http.HandleFunc("/current_corpus", mgr.httpCurrentCorpus)
|
||||
go func() {
|
||||
logf(0, "serving http on http://%v", cfg.Http)
|
||||
panic(http.ListenAndServe(cfg.Http, nil))
|
||||
}()
|
||||
|
||||
// Create RPC server for fuzzers.
|
||||
rpcAddr := fmt.Sprintf("localhost:%v", cfg.Port)
|
||||
ln, err := net.Listen("tcp", rpcAddr)
|
||||
if err != nil {
|
||||
fatalf("failed to listen on port %v: %v", cfg.Port, err)
|
||||
}
|
||||
s := rpc.NewServer()
|
||||
s.Register(mgr)
|
||||
go s.Accept(ln)
|
||||
logf(0, "serving rpc on tcp://%v", rpcAddr)
|
||||
|
||||
mgr.run()
|
||||
}
|
||||
|
||||
func (mgr *Manager) run() {
|
||||
mgr.pollMaster()
|
||||
for _, inst := range mgr.instances {
|
||||
go inst.Run()
|
||||
}
|
||||
pollTicker := time.NewTicker(10 * time.Second).C
|
||||
for {
|
||||
select {
|
||||
case <-pollTicker:
|
||||
mgr.mu.Lock()
|
||||
mgr.pollMaster()
|
||||
mgr.mu.Unlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (mgr *Manager) pollMaster() {
|
||||
for {
|
||||
a := &MasterPollArgs{mgr.cfg.Name}
|
||||
r := &MasterPollRes{}
|
||||
if err := mgr.master.Call("Master.PollInputs", a, r); err != nil {
|
||||
fatalf("failed to poll master: %v", err)
|
||||
}
|
||||
logf(3, "polling master, got %v inputs", len(r.Inputs))
|
||||
if len(r.Inputs) == 0 {
|
||||
break
|
||||
}
|
||||
nextProg:
|
||||
for _, prg := range r.Inputs {
|
||||
p, err := prog.Deserialize(prg)
|
||||
if err != nil {
|
||||
logf(0, "failed to deserialize master program: %v", err)
|
||||
continue
|
||||
}
|
||||
if mgr.syscalls != nil {
|
||||
for _, c := range p.Calls {
|
||||
if !mgr.syscalls[c.Meta.ID] {
|
||||
continue nextProg
|
||||
}
|
||||
}
|
||||
}
|
||||
sig := hash(prg)
|
||||
if _, ok := mgr.masterHashes[sig]; ok {
|
||||
continue
|
||||
}
|
||||
mgr.masterHashes[sig] = struct{}{}
|
||||
mgr.masterCorpus = append(mgr.masterCorpus, prg)
|
||||
mgr.candidates = append(mgr.candidates, prg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (mgr *Manager) minimizeCorpus() {
|
||||
if len(mgr.corpus) == 0 {
|
||||
return
|
||||
}
|
||||
// First, sort corpus per call.
|
||||
type Call struct {
|
||||
inputs []RpcInput
|
||||
cov []cover.Cover
|
||||
}
|
||||
calls := make(map[string]Call)
|
||||
for _, inp := range mgr.corpus {
|
||||
c := calls[inp.Call]
|
||||
c.inputs = append(c.inputs, inp)
|
||||
c.cov = append(c.cov, inp.Cover)
|
||||
calls[inp.Call] = c
|
||||
}
|
||||
// Now minimize and build new corpus.
|
||||
var newCorpus []RpcInput
|
||||
for _, c := range calls {
|
||||
for _, idx := range cover.Minimize(c.cov) {
|
||||
newCorpus = append(newCorpus, c.inputs[idx])
|
||||
}
|
||||
}
|
||||
logf(1, "minimized corpus: %v -> %v", len(mgr.corpus), len(newCorpus))
|
||||
mgr.corpus = newCorpus
|
||||
}
|
||||
|
||||
func (mgr *Manager) Connect(a *ManagerConnectArgs, r *ManagerConnectRes) error {
|
||||
logf(1, "fuzzer %v connected", a.Name)
|
||||
mgr.mu.Lock()
|
||||
defer mgr.mu.Unlock()
|
||||
|
||||
mgr.minimizeCorpus()
|
||||
mgr.fuzzers[a.Name] = &Fuzzer{
|
||||
name: a.Name,
|
||||
input: 0,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mgr *Manager) NewInput(a *NewManagerInputArgs, r *int) error {
|
||||
logf(2, "new input from fuzzer %v", a.Name)
|
||||
mgr.mu.Lock()
|
||||
defer mgr.mu.Unlock()
|
||||
|
||||
call := sys.CallID[a.Call]
|
||||
if len(cover.Difference(a.Cover, mgr.corpusCover[call])) == 0 {
|
||||
return nil
|
||||
}
|
||||
mgr.corpusCover[call] = cover.Union(mgr.corpusCover[call], a.Cover)
|
||||
mgr.corpus = append(mgr.corpus, a.RpcInput)
|
||||
|
||||
sig := hash(a.Prog)
|
||||
if _, ok := mgr.masterHashes[sig]; !ok {
|
||||
mgr.masterHashes[sig] = struct{}{}
|
||||
mgr.masterCorpus = append(mgr.masterCorpus, a.Prog)
|
||||
|
||||
a1 := &NewMasterInputArgs{mgr.cfg.Name, a.Prog}
|
||||
if err := mgr.master.Call("Master.NewInput", a1, nil); err != nil {
|
||||
fatalf("call Master.NewInput failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mgr *Manager) Poll(a *ManagerPollArgs, r *ManagerPollRes) error {
|
||||
logf(2, "poll from %v", a.Name)
|
||||
mgr.mu.Lock()
|
||||
defer mgr.mu.Unlock()
|
||||
|
||||
f := mgr.fuzzers[a.Name]
|
||||
if f == nil {
|
||||
fatalf("fuzzer %v is not connected", a.Name)
|
||||
}
|
||||
|
||||
for i := 0; i < 100 && f.input < len(mgr.corpus); i++ {
|
||||
r.NewInputs = append(r.NewInputs, mgr.corpus[f.input])
|
||||
f.input++
|
||||
}
|
||||
|
||||
for i := 0; i < 10 && len(mgr.candidates) > 0; i++ {
|
||||
last := len(mgr.candidates) - 1
|
||||
r.Candidates = append(r.Candidates, mgr.candidates[last])
|
||||
mgr.candidates = mgr.candidates[:last]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
94
master/html.go
Normal file
94
master/html.go
Normal file
@ -0,0 +1,94 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (m *Master) httpInfo(w http.ResponseWriter, r *http.Request) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
data := &UIData{
|
||||
CorpusLen: len(m.corpus.m),
|
||||
}
|
||||
for _, mgr := range m.managers {
|
||||
data.Managers = append(data.Managers, UIManager{
|
||||
Name: mgr.name,
|
||||
Http: mgr.http,
|
||||
})
|
||||
}
|
||||
if err := htmlTemplate.Execute(w, data); err != nil {
|
||||
http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Master) httpMinimize(w http.ResponseWriter, r *http.Request) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
corpus := make(map[string]bool)
|
||||
for _, mgr := range m.managers {
|
||||
resp, err := http.Get("http://" + mgr.http + "/current_corpus")
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("failed to query corpus from %v: %v", mgr.name, err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("failed to query corpus from %v: %v", mgr.name, err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
var hashes []string
|
||||
err = json.Unmarshal(data, &hashes)
|
||||
if err != nil || len(hashes) == 0 {
|
||||
http.Error(w, fmt.Sprintf("failed to parse corpus from %v: %v", mgr.name, err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
for _, hash := range hashes {
|
||||
corpus[hash] = true
|
||||
}
|
||||
}
|
||||
orig := len(m.corpus.m)
|
||||
m.corpus.minimize(corpus)
|
||||
fmt.Printf("minimized: %v -> %v -> %v\n", orig, len(corpus), len(m.corpus.m))
|
||||
for _, mgr := range m.managers {
|
||||
mgr.input = 0
|
||||
}
|
||||
}
|
||||
|
||||
type UIData struct {
|
||||
CorpusLen int
|
||||
Managers []UIManager
|
||||
}
|
||||
|
||||
type UIManager struct {
|
||||
Name string
|
||||
Http string
|
||||
}
|
||||
|
||||
var htmlTemplate = template.Must(template.New("").Parse(`
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>syzkaller master</title>
|
||||
</head>
|
||||
<body>
|
||||
Corpus: {{.CorpusLen}} <br>
|
||||
{{if .Managers}}
|
||||
Managers:<br>
|
||||
{{range $mgr := $.Managers}}
|
||||
<a href='http://{{$mgr.Http}}'>{{$mgr.Name}}</a><br>
|
||||
{{end}}
|
||||
{{else}}
|
||||
No managers connected<br>
|
||||
{{end}}
|
||||
</body></html>
|
||||
`))
|
170
master/master.go
Normal file
170
master/master.go
Normal file
@ -0,0 +1,170 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/rpc"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/google/syzkaller/prog"
|
||||
. "github.com/google/syzkaller/rpctype"
|
||||
)
|
||||
|
||||
var (
|
||||
flagWorkdir = flag.String("workdir", "", "dir with persistent artifacts")
|
||||
flagAddr = flag.String("addr", "", "RPC listen address to connect managers")
|
||||
flagHTTP = flag.String("http", "", "HTTP server listen address")
|
||||
flagV = flag.Int("v", 0, "verbosity")
|
||||
)
|
||||
|
||||
// Master manages persistent fuzzer state (input corpus and crashers).
|
||||
type Master struct {
|
||||
mu sync.Mutex
|
||||
managers map[string]*Manager
|
||||
corpus *PersistentSet
|
||||
crashers *PersistentSet
|
||||
startTime time.Time
|
||||
lastInput time.Time
|
||||
}
|
||||
|
||||
type Manager struct {
|
||||
name string
|
||||
http string
|
||||
input int
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
if *flagWorkdir == "" {
|
||||
fatalf("-workdir is not set")
|
||||
}
|
||||
if *flagAddr == "" {
|
||||
fatalf("-addr is not set")
|
||||
}
|
||||
if *flagHTTP == "" {
|
||||
fatalf("-http is not set")
|
||||
}
|
||||
ln, err := net.Listen("tcp", *flagAddr)
|
||||
if err != nil {
|
||||
fatalf("failed to listen: %v", err)
|
||||
}
|
||||
|
||||
m := &Master{}
|
||||
m.managers = make(map[string]*Manager)
|
||||
m.startTime = time.Now()
|
||||
m.lastInput = time.Now()
|
||||
logf(0, "loading corpus...")
|
||||
m.corpus = newPersistentSet(filepath.Join(*flagWorkdir, "corpus"), func(data []byte) bool {
|
||||
if _, err := prog.Deserialize(data); err != nil {
|
||||
logf(0, "deleting broken program: %v\n%s", err, data)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
m.crashers = newPersistentSet(filepath.Join(*flagWorkdir, "crashers"), nil)
|
||||
|
||||
http.HandleFunc("/", m.httpInfo)
|
||||
http.HandleFunc("/minimize", m.httpMinimize)
|
||||
go func() {
|
||||
logf(0, "serving http on http://%v", *flagHTTP)
|
||||
panic(http.ListenAndServe(*flagHTTP, nil))
|
||||
}()
|
||||
|
||||
logf(0, "serving rpc on tcp://%v", *flagAddr)
|
||||
s := rpc.NewServer()
|
||||
s.Register(m)
|
||||
go s.Accept(ln)
|
||||
|
||||
m.loop()
|
||||
}
|
||||
|
||||
func (m *Master) loop() {
|
||||
for range time.NewTicker(1 * time.Second).C {
|
||||
}
|
||||
}
|
||||
|
||||
// Connect attaches new manager to master.
|
||||
func (m *Master) Connect(a *MasterConnectArgs, r *MasterConnectRes) error {
|
||||
logf(1, "connect from %v (http://%v)", a.Name, a.Http)
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
mgr := &Manager{
|
||||
name: a.Name,
|
||||
http: a.Http,
|
||||
}
|
||||
m.managers[a.Name] = mgr
|
||||
r.Http = *flagHTTP
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewInput saves new interesting input on master.
|
||||
func (m *Master) NewInput(a *NewMasterInputArgs, r *int) error {
|
||||
p, err := prog.Deserialize(a.Prog)
|
||||
if err != nil {
|
||||
logf(0, "bogus new input from %v: %v\n%s\n", a.Name, err, a.Prog)
|
||||
return fmt.Errorf("the program is bogus: %v", err)
|
||||
}
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
if !m.corpus.add(a.Prog) {
|
||||
return nil
|
||||
}
|
||||
m.lastInput = time.Now()
|
||||
logf(1, "new input from %v: %s", a.Name, p)
|
||||
return nil
|
||||
}
|
||||
|
||||
type NewCrasherArgs struct {
|
||||
Name string
|
||||
Text []byte
|
||||
Suppression []byte
|
||||
Prog []byte
|
||||
}
|
||||
|
||||
// NewCrasher saves new crasher input on master.
|
||||
func (m *Master) NewCrasher(a *NewCrasherArgs, r *int) error {
|
||||
logf(0, "new crasher from %v", a.Name)
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
if !m.crashers.add(a.Text) {
|
||||
return nil // Already have this.
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Master) PollInputs(a *MasterPollArgs, r *MasterPollRes) error {
|
||||
logf(2, "poll from %v", a.Name)
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
mgr := m.managers[a.Name]
|
||||
if mgr == nil {
|
||||
return fmt.Errorf("manager is not connected")
|
||||
}
|
||||
for i := 0; i < 100 && mgr.input < len(m.corpus.a); i++ {
|
||||
r.Inputs = append(r.Inputs, m.corpus.a[mgr.input])
|
||||
mgr.input++
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func logf(v int, msg string, args ...interface{}) {
|
||||
if *flagV >= v {
|
||||
log.Printf(msg, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func fatalf(msg string, args ...interface{}) {
|
||||
log.Fatalf(msg, args...)
|
||||
}
|
129
master/persistent.go
Normal file
129
master/persistent.go
Normal file
@ -0,0 +1,129 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type Sig [sha1.Size]byte
|
||||
|
||||
// PersistentSet is a set of binary blobs with a persistent mirror on disk.
|
||||
type PersistentSet struct {
|
||||
dir string
|
||||
m map[Sig][]byte
|
||||
a [][]byte
|
||||
}
|
||||
|
||||
func hash(data []byte) Sig {
|
||||
return Sig(sha1.Sum(data))
|
||||
}
|
||||
|
||||
func newPersistentSet(dir string, verify func(data []byte) bool) *PersistentSet {
|
||||
ps := &PersistentSet{
|
||||
dir: dir,
|
||||
m: make(map[Sig][]byte),
|
||||
}
|
||||
os.MkdirAll(dir, 0770)
|
||||
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
log.Fatalf("error during dir walk: %v\n", err)
|
||||
}
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
log.Fatalf("error during file read: %v\n", err)
|
||||
return nil
|
||||
}
|
||||
sig := hash(data)
|
||||
if _, ok := ps.m[sig]; ok {
|
||||
return nil
|
||||
}
|
||||
name := info.Name()
|
||||
if len(data) == 0 {
|
||||
// This can happen is master runs on machine-under-test,
|
||||
// and it has crashed midway.
|
||||
log.Printf("removing empty file %v", name)
|
||||
os.Remove(path)
|
||||
return nil
|
||||
}
|
||||
const hexLen = 2 * sha1.Size
|
||||
if len(name) > hexLen+1 && isHexString(name[:hexLen]) && name[hexLen] == '.' {
|
||||
return nil // description file
|
||||
}
|
||||
if len(name) != hexLen || !isHexString(name) {
|
||||
log.Fatalf("unknown file in persistent dir %v: %v", dir, name)
|
||||
}
|
||||
if verify != nil && !verify(data) {
|
||||
os.Remove(path)
|
||||
return nil
|
||||
}
|
||||
if name != hex.EncodeToString(sig[:]) {
|
||||
log.Printf("bad hash in persistent dir %v for file %v, expect %v", dir, name, hex.EncodeToString(sig[:]))
|
||||
if err := ioutil.WriteFile(filepath.Join(ps.dir, hex.EncodeToString(sig[:])), data, 0660); err != nil {
|
||||
log.Fatalf("failed to write file: %v", err)
|
||||
}
|
||||
os.Remove(path)
|
||||
}
|
||||
ps.m[sig] = data
|
||||
ps.a = append(ps.a, data)
|
||||
return nil
|
||||
})
|
||||
return ps
|
||||
}
|
||||
|
||||
func isHexString(s string) bool {
|
||||
for _, v := range []byte(s) {
|
||||
if v >= '0' && v <= '9' || v >= 'a' && v <= 'f' {
|
||||
continue
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (ps *PersistentSet) add(data []byte) bool {
|
||||
sig := hash(data)
|
||||
if _, ok := ps.m[sig]; ok {
|
||||
return false
|
||||
}
|
||||
data = append([]byte{}, data...)
|
||||
ps.m[sig] = data
|
||||
ps.a = append(ps.a, data)
|
||||
fname := filepath.Join(ps.dir, hex.EncodeToString(sig[:]))
|
||||
if err := ioutil.WriteFile(fname, data, 0660); err != nil {
|
||||
log.Fatalf("failed to write file: %v", err)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// addDescription creates a complementary to data file on disk.
|
||||
func (ps *PersistentSet) addDescription(data []byte, desc []byte, typ string) {
|
||||
sig := hash(data)
|
||||
fname := filepath.Join(ps.dir, fmt.Sprintf("%v.%v", hex.EncodeToString(sig[:]), typ))
|
||||
if err := ioutil.WriteFile(fname, desc, 0660); err != nil {
|
||||
log.Fatalf("failed to write file: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (ps *PersistentSet) minimize(set map[string]bool) {
|
||||
ps.a = nil
|
||||
for sig, data := range ps.m {
|
||||
s := hex.EncodeToString(sig[:])
|
||||
if set[s] {
|
||||
ps.a = append(ps.a, data)
|
||||
} else {
|
||||
delete(ps.m, sig)
|
||||
os.Remove(filepath.Join(ps.dir, s))
|
||||
}
|
||||
}
|
||||
}
|
245
prog/analysis.go
Normal file
245
prog/analysis.go
Normal file
@ -0,0 +1,245 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
// Conservative resource-related analysis of programs.
|
||||
// The analysis figures out what files descriptors are [potentially] opened
|
||||
// at a particular point in program, what pages are [potentially] mapped,
|
||||
// what files were already referenced in calls, etc.
|
||||
|
||||
package prog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/google/syzkaller/sys"
|
||||
)
|
||||
|
||||
const (
|
||||
maxPages = 4 << 10
|
||||
)
|
||||
|
||||
type state struct {
|
||||
enabledCalls []*sys.Call
|
||||
files map[string]bool
|
||||
resources map[sys.ResourceKind]map[sys.ResourceSubkind][]*Arg
|
||||
strings map[string]bool
|
||||
pages [maxPages]bool
|
||||
}
|
||||
|
||||
// analyze analyzes the program p up to but not including call c.
|
||||
func analyze(enabledCalls []*sys.Call, p *Prog, c *Call) *state {
|
||||
s := newState(enabledCalls)
|
||||
for _, c1 := range p.Calls {
|
||||
if c1 == c {
|
||||
break
|
||||
}
|
||||
s.analyze(c1)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func newState(enabledCalls []*sys.Call) *state {
|
||||
s := &state{
|
||||
enabledCalls: enabledCalls,
|
||||
files: make(map[string]bool),
|
||||
resources: make(map[sys.ResourceKind]map[sys.ResourceSubkind][]*Arg),
|
||||
strings: make(map[string]bool),
|
||||
}
|
||||
if len(s.enabledCalls) == 0 {
|
||||
s.enabledCalls = sys.Calls
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *state) analyze(c *Call) {
|
||||
foreachArgArray(&c.Args, c.Ret, func(arg, base *Arg, _ *[]*Arg) {
|
||||
switch typ := arg.Type.(type) {
|
||||
case sys.FilenameType:
|
||||
if arg.Kind == ArgData && arg.Dir != DirOut {
|
||||
s.files[string(arg.Data)] = true
|
||||
}
|
||||
case sys.ResourceType:
|
||||
if arg.Dir != DirIn {
|
||||
if s.resources[typ.Kind] == nil {
|
||||
s.resources[typ.Kind] = make(map[sys.ResourceSubkind][]*Arg)
|
||||
}
|
||||
s.resources[typ.Kind][typ.Subkind] = append(s.resources[typ.Kind][typ.Subkind], arg)
|
||||
}
|
||||
case sys.BufferType:
|
||||
if typ.Kind == sys.BufferString && arg.Kind == ArgData && len(arg.Data) != 0 {
|
||||
s.strings[string(arg.Data)] = true
|
||||
}
|
||||
}
|
||||
})
|
||||
switch c.Meta.Name {
|
||||
case "mmap":
|
||||
// Filter out only very wrong arguments.
|
||||
length := c.Args[1]
|
||||
if length.AddrPage == 0 && length.AddrOffset == 0 {
|
||||
break
|
||||
}
|
||||
if flags, fd := c.Args[4], c.Args[3]; flags.Val&MAP_ANONYMOUS == 0 && fd.Kind == ArgConst && fd.Val == sys.InvalidFD {
|
||||
break
|
||||
}
|
||||
s.addressable(c.Args[0], length, true)
|
||||
case "munmap":
|
||||
s.addressable(c.Args[0], c.Args[1], false)
|
||||
case "mremap":
|
||||
s.addressable(c.Args[4], c.Args[2], true)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *state) addressable(addr, size *Arg, ok bool) {
|
||||
if addr.Kind != ArgPointer || size.Kind != ArgPageSize {
|
||||
panic("mmap/munmap/mremap args are not pages")
|
||||
}
|
||||
n := size.AddrPage
|
||||
if size.AddrOffset != 0 {
|
||||
n++
|
||||
}
|
||||
if addr.AddrPage+n > uintptr(len(s.pages)) {
|
||||
panic(fmt.Sprintf("address is out of bounds: page=%v len=%v (%v, %v) bound=%v", addr.AddrPage, n, size.AddrPage, size.AddrOffset, len(s.pages)))
|
||||
}
|
||||
for i := uintptr(0); i < n; i++ {
|
||||
s.pages[addr.AddrPage+i] = ok
|
||||
}
|
||||
}
|
||||
|
||||
func foreachArgArray(args *[]*Arg, ret *Arg, f func(arg, base *Arg, parent *[]*Arg)) {
|
||||
var rec func(arg, base *Arg, parent *[]*Arg)
|
||||
rec = func(arg, base *Arg, parent *[]*Arg) {
|
||||
f(arg, base, parent)
|
||||
for _, arg1 := range arg.Inner {
|
||||
parent1 := parent
|
||||
if _, ok := arg.Type.(sys.StructType); ok {
|
||||
parent1 = &arg.Inner
|
||||
}
|
||||
rec(arg1, base, parent1)
|
||||
}
|
||||
if arg.Kind == ArgPointer && arg.Res != nil {
|
||||
rec(arg.Res, arg, parent)
|
||||
}
|
||||
}
|
||||
for _, arg := range *args {
|
||||
rec(arg, nil, args)
|
||||
}
|
||||
if ret != nil {
|
||||
rec(ret, nil, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func foreachArg(c *Call, f func(arg, base *Arg, parent *[]*Arg)) {
|
||||
foreachArgArray(&c.Args, nil, f)
|
||||
}
|
||||
|
||||
func referencedArgs(args []*Arg, ret *Arg) (res []*Arg) {
|
||||
f := func(arg, _ *Arg, _ *[]*Arg) {
|
||||
for arg1 := range arg.Uses {
|
||||
if arg1.Kind != ArgResult {
|
||||
panic("use references not ArgResult")
|
||||
}
|
||||
res = append(res, arg1)
|
||||
}
|
||||
}
|
||||
foreachArgArray(&args, ret, f)
|
||||
return
|
||||
}
|
||||
|
||||
func assignTypeAndDir(c *Call) {
|
||||
var rec func(arg *Arg, typ sys.Type, dir ArgDir)
|
||||
rec = func(arg *Arg, typ sys.Type, dir ArgDir) {
|
||||
if arg.Call != nil && arg.Call != c {
|
||||
panic(fmt.Sprintf("different call is already assigned: %p %p %v %v", arg.Call, c, arg.Call.Meta.Name, c.Meta.Name))
|
||||
}
|
||||
arg.Call = c
|
||||
if arg.Type != nil && arg.Type.Name() != typ.Name() {
|
||||
panic("different type is already assigned")
|
||||
}
|
||||
arg.Type = typ
|
||||
switch arg.Kind {
|
||||
case ArgPointer:
|
||||
arg.Dir = DirIn
|
||||
switch typ1 := typ.(type) {
|
||||
case sys.FilenameType:
|
||||
rec(arg.Res, typ, dir)
|
||||
case sys.PtrType:
|
||||
if arg.Res != nil {
|
||||
rec(arg.Res, typ1.Type, ArgDir(typ1.Dir))
|
||||
}
|
||||
}
|
||||
case ArgGroup:
|
||||
arg.Dir = dir
|
||||
switch typ1 := typ.(type) {
|
||||
case sys.StructType:
|
||||
for i, arg1 := range arg.Inner {
|
||||
rec(arg1, typ1.Fields[i], dir)
|
||||
}
|
||||
case sys.ArrayType:
|
||||
for _, arg1 := range arg.Inner {
|
||||
rec(arg1, typ1.Type, dir)
|
||||
}
|
||||
}
|
||||
default:
|
||||
arg.Dir = dir
|
||||
}
|
||||
}
|
||||
for i, arg := range c.Args {
|
||||
rec(arg, c.Meta.Args[i], DirIn)
|
||||
}
|
||||
if c.Ret == nil {
|
||||
c.Ret = returnArg()
|
||||
c.Ret.Call = c
|
||||
c.Ret.Type = c.Meta.Ret
|
||||
c.Ret.Dir = DirOut
|
||||
}
|
||||
}
|
||||
|
||||
func sanitizeCall(c *Call) {
|
||||
switch c.Meta.Name {
|
||||
case "mmap":
|
||||
// Add MAP_FIXED flag, otherwise it produces non-deterministic results.
|
||||
addr := c.Args[0]
|
||||
if addr.Kind != ArgPointer {
|
||||
panic("mmap address is not ArgPointer")
|
||||
}
|
||||
length := c.Args[1]
|
||||
if length.Kind != ArgPageSize {
|
||||
panic("mmap length is not ArgPageSize")
|
||||
}
|
||||
flags := c.Args[3]
|
||||
if flags.Kind != ArgConst {
|
||||
panic("mmap flag arg is not const")
|
||||
}
|
||||
flags.Val |= MAP_FIXED
|
||||
case "mremap":
|
||||
// Add MREMAP_FIXED flag, otherwise it produces non-deterministic results.
|
||||
flags := c.Args[3]
|
||||
if flags.Kind != ArgConst {
|
||||
panic("mremap flag arg is not const")
|
||||
}
|
||||
if flags.Val&MREMAP_MAYMOVE != 0 {
|
||||
flags.Val |= MREMAP_FIXED
|
||||
}
|
||||
case "mknod":
|
||||
mode := c.Args[1]
|
||||
if mode.Kind != ArgConst {
|
||||
panic("mknod mode is not const")
|
||||
}
|
||||
// Char and block devices read/write io ports, kernel memory and do other nasty things.
|
||||
if mode.Val != S_IFREG && mode.Val != S_IFIFO && mode.Val != S_IFSOCK {
|
||||
mode.Val = S_IFIFO
|
||||
}
|
||||
case "syslog":
|
||||
cmd := c.Args[0]
|
||||
// These disable console output, but we need it.
|
||||
if cmd.Val == SYSLOG_ACTION_CONSOLE_OFF || cmd.Val == SYSLOG_ACTION_CONSOLE_ON {
|
||||
cmd.Val = SYSLOG_ACTION_SIZE_UNREAD
|
||||
}
|
||||
case "exit", "exit_group":
|
||||
code := c.Args[0]
|
||||
// These codes are reserved by executor.
|
||||
if code.Val%128 == 67 || code.Val%128 == 68 {
|
||||
code.Val = 1
|
||||
}
|
||||
}
|
||||
}
|
49
prog/clone.go
Normal file
49
prog/clone.go
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package prog
|
||||
|
||||
func (p *Prog) Clone() *Prog {
|
||||
p1 := new(Prog)
|
||||
newargs := make(map[*Arg]*Arg)
|
||||
for _, c := range p.Calls {
|
||||
c1 := new(Call)
|
||||
c1.Meta = c.Meta
|
||||
c1.Ret = c.Ret.clone(c1, newargs)
|
||||
for _, arg := range c.Args {
|
||||
c1.Args = append(c1.Args, arg.clone(c1, newargs))
|
||||
}
|
||||
p1.Calls = append(p1.Calls, c1)
|
||||
}
|
||||
if err := p1.validate(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return p1
|
||||
}
|
||||
|
||||
func (arg *Arg) clone(c *Call, newargs map[*Arg]*Arg) *Arg {
|
||||
arg1 := new(Arg)
|
||||
*arg1 = *arg
|
||||
arg1.Call = c
|
||||
arg1.Data = append([]byte{}, arg.Data...)
|
||||
switch arg.Kind {
|
||||
case ArgPointer:
|
||||
if arg.Res != nil {
|
||||
arg1.Res = arg.Res.clone(c, newargs)
|
||||
}
|
||||
case ArgResult:
|
||||
r := newargs[arg.Res]
|
||||
arg1.Res = r
|
||||
if r.Uses == nil {
|
||||
r.Uses = make(map[*Arg]bool)
|
||||
}
|
||||
r.Uses[arg1] = true
|
||||
}
|
||||
arg1.Inner = nil
|
||||
for _, arg2 := range arg.Inner {
|
||||
arg1.Inner = append(arg1.Inner, arg2.clone(c, newargs))
|
||||
}
|
||||
arg1.Uses = nil // filled when we clone the referent
|
||||
newargs[arg] = arg1
|
||||
return arg1
|
||||
}
|
598
prog/consts.go
Normal file
598
prog/consts.go
Normal file
@ -0,0 +1,598 @@
|
||||
// AUTOGENERATED FILE
|
||||
package prog
|
||||
|
||||
const (
|
||||
ADDR_COMPAT_LAYOUT = 2097152
|
||||
ADDR_LIMIT_32BIT = 8388608
|
||||
ADDR_LIMIT_3GB = 134217728
|
||||
ADDR_NO_RANDOMIZE = 262144
|
||||
AF_APPLETALK = 5
|
||||
AF_ATMPVC = 8
|
||||
AF_AX25 = 3
|
||||
AF_INET = 2
|
||||
AF_INET6 = 10
|
||||
AF_IPX = 4
|
||||
AF_LOCAL = 1
|
||||
AF_NETLINK = 16
|
||||
AF_PACKET = 17
|
||||
AF_X25 = 9
|
||||
ARCH_GET_FS = 4099
|
||||
ARCH_GET_GS = 4100
|
||||
ARCH_SET_FS = 4098
|
||||
ARCH_SET_GS = 4097
|
||||
AT_EACCESS = 512
|
||||
AT_EMPTY_PATH = 4096
|
||||
AT_FDCWD = 18446744073709551516
|
||||
AT_REMOVEDIR = 512
|
||||
AT_SYMLINK_FOLLOW = 1024
|
||||
AT_SYMLINK_NOFOLLOW = 256
|
||||
CLOCK_BOOTTIME = 7
|
||||
CLOCK_MONOTONIC = 1
|
||||
CLOCK_MONOTONIC_COARSE = 6
|
||||
CLOCK_MONOTONIC_RAW = 4
|
||||
CLOCK_PROCESS_CPUTIME_ID = 2
|
||||
CLOCK_REALTIME = 0
|
||||
CLOCK_REALTIME_COARSE = 5
|
||||
CLOCK_THREAD_CPUTIME_ID = 3
|
||||
CLONE_CHILD_CLEARTID = 2097152
|
||||
CLONE_CHILD_SETTID = 16777216
|
||||
CLONE_FILES = 1024
|
||||
CLONE_FS = 512
|
||||
CLONE_IO = 2147483648
|
||||
CLONE_NEWIPC = 134217728
|
||||
CLONE_NEWNET = 1073741824
|
||||
CLONE_NEWNS = 131072
|
||||
CLONE_NEWPID = 536870912
|
||||
CLONE_NEWUTS = 67108864
|
||||
CLONE_PARENT = 32768
|
||||
CLONE_PARENT_SETTID = 1048576
|
||||
CLONE_PTRACE = 8192
|
||||
CLONE_SETTLS = 524288
|
||||
CLONE_SIGHAND = 2048
|
||||
CLONE_SYSVSEM = 262144
|
||||
CLONE_THREAD = 65536
|
||||
CLONE_UNTRACED = 8388608
|
||||
CLONE_VFORK = 16384
|
||||
CLONE_VM = 256
|
||||
DN_ACCESS = 1
|
||||
DN_ATTRIB = 32
|
||||
DN_CREATE = 4
|
||||
DN_DELETE = 8
|
||||
DN_MODIFY = 2
|
||||
DN_MULTISHOT = 2147483648
|
||||
DN_RENAME = 16
|
||||
EFD_CLOEXEC = 524288
|
||||
EFD_NONBLOCK = 2048
|
||||
EFD_SEMAPHORE = 1
|
||||
EPOLLERR = 8
|
||||
EPOLLET = 2147483648
|
||||
EPOLLHUP = 16
|
||||
EPOLLIN = 1
|
||||
EPOLLONESHOT = 1073741824
|
||||
EPOLLOUT = 4
|
||||
EPOLLPRI = 2
|
||||
EPOLLRDHUP = 8192
|
||||
EPOLL_CLOEXEC = 524288
|
||||
EPOLL_CTL_ADD = 1
|
||||
EPOLL_CTL_DEL = 2
|
||||
EPOLL_CTL_MOD = 3
|
||||
FALLOC_FL_KEEP_SIZE = 1
|
||||
FALLOC_FL_PUNCH_HOLE = 2
|
||||
FAN_ACCESS = 1
|
||||
FAN_ACCESS_PERM = 131072
|
||||
FAN_CLASS_CONTENT = 4
|
||||
FAN_CLASS_NOTIF = 0
|
||||
FAN_CLASS_PRE_CONTENT = 8
|
||||
FAN_CLOEXEC = 1
|
||||
FAN_CLOSE_NOWRITE = 16
|
||||
FAN_CLOSE_WRITE = 8
|
||||
FAN_EVENT_ON_CHILD = 134217728
|
||||
FAN_MARK_ADD = 1
|
||||
FAN_MARK_DONT_FOLLOW = 4
|
||||
FAN_MARK_FLUSH = 128
|
||||
FAN_MARK_IGNORED_MASK = 32
|
||||
FAN_MARK_IGNORED_SURV_MODIFY = 64
|
||||
FAN_MARK_MOUNT = 16
|
||||
FAN_MARK_ONLYDIR = 8
|
||||
FAN_MARK_REMOVE = 2
|
||||
FAN_MODIFY = 2
|
||||
FAN_NONBLOCK = 2
|
||||
FAN_ONDIR = 1073741824
|
||||
FAN_OPEN = 32
|
||||
FAN_OPEN_PERM = 65536
|
||||
FAN_UNLIMITED_MARKS = 32
|
||||
FAN_UNLIMITED_QUEUE = 16
|
||||
FD_CLOEXEC = 1
|
||||
FUTEX_CMP_REQUEUE = 4
|
||||
FUTEX_REQUEUE = 3
|
||||
FUTEX_WAIT = 0
|
||||
FUTEX_WAIT_BITSET = 9
|
||||
FUTEX_WAKE = 1
|
||||
F_DUPFD = 0
|
||||
F_DUPFD_CLOEXEC = 1030
|
||||
F_GETFD = 1
|
||||
F_GETFL = 3
|
||||
F_GETLEASE = 1025
|
||||
F_GETLK = 5
|
||||
F_GETOWN = 9
|
||||
F_GETOWN_EX = 16
|
||||
F_GETPIPE_SZ = 1032
|
||||
F_GETSIG = 11
|
||||
F_NOTIFY = 1026
|
||||
F_OWNER_PGRP = 2
|
||||
F_OWNER_PID = 1
|
||||
F_OWNER_TID = 0
|
||||
F_RDLCK = 0
|
||||
F_SETFD = 2
|
||||
F_SETFL = 4
|
||||
F_SETLEASE = 1024
|
||||
F_SETLK = 6
|
||||
F_SETLKW = 7
|
||||
F_SETOWN = 8
|
||||
F_SETOWN_EX = 15
|
||||
F_SETPIPE_SZ = 1031
|
||||
F_SETSIG = 10
|
||||
F_UNLCK = 2
|
||||
F_WRLCK = 1
|
||||
GETALL = 13
|
||||
GETNCNT = 14
|
||||
GETPID = 11
|
||||
GETVAL = 12
|
||||
GETZCNT = 15
|
||||
IN_ACCESS = 1
|
||||
IN_ATTRIB = 4
|
||||
IN_CLOEXEC = 524288
|
||||
IN_CLOSE_NOWRITE = 16
|
||||
IN_CLOSE_WRITE = 8
|
||||
IN_CREATE = 256
|
||||
IN_DELETE = 512
|
||||
IN_DELETE_SELF = 1024
|
||||
IN_DONT_FOLLOW = 33554432
|
||||
IN_EXCL_UNLINK = 67108864
|
||||
IN_MASK_ADD = 536870912
|
||||
IN_MODIFY = 2
|
||||
IN_MOVED_FROM = 64
|
||||
IN_MOVED_TO = 128
|
||||
IN_MOVE_SELF = 2048
|
||||
IN_NONBLOCK = 2048
|
||||
IN_ONESHOT = 2147483648
|
||||
IN_ONLYDIR = 16777216
|
||||
IN_OPEN = 32
|
||||
IOCB_CMD_FDSYNC = 3
|
||||
IOCB_CMD_FSYNC = 2
|
||||
IOCB_CMD_NOOP = 6
|
||||
IOCB_CMD_POLL = 5
|
||||
IOCB_CMD_PREAD = 0
|
||||
IOCB_CMD_PREADV = 7
|
||||
IOCB_CMD_PREADX = 4
|
||||
IOCB_CMD_PWRITE = 1
|
||||
IOCB_CMD_PWRITEV = 8
|
||||
IOCB_FLAG_RESFD = 1
|
||||
IOPRIO_WHO_PGRP = 2
|
||||
IOPRIO_WHO_PROCESS = 1
|
||||
IOPRIO_WHO_USER = 3
|
||||
IPC_CREAT = 512
|
||||
IPC_EXCL = 1024
|
||||
IPC_INFO = 3
|
||||
IPC_NOWAIT = 2048
|
||||
IPC_RMID = 0
|
||||
IPC_SET = 1
|
||||
IPC_STAT = 2
|
||||
ITIMER_PROF = 2
|
||||
ITIMER_REAL = 0
|
||||
ITIMER_VIRTUAL = 1
|
||||
KCMP_FILE = 0
|
||||
KCMP_FILES = 2
|
||||
KCMP_FS = 3
|
||||
KCMP_IO = 5
|
||||
KCMP_SIGHAND = 4
|
||||
KCMP_SYSVSEM = 6
|
||||
KCMP_VM = 1
|
||||
KEXEC_ARCH_386 = 196608
|
||||
KEXEC_ARCH_ARM = 2621440
|
||||
KEXEC_ARCH_IA_64 = 3276800
|
||||
KEXEC_ARCH_MIPS = 524288
|
||||
KEXEC_ARCH_MIPS_LE = 655360
|
||||
KEXEC_ARCH_PPC = 1310720
|
||||
KEXEC_ARCH_PPC64 = 1376256
|
||||
KEXEC_ARCH_S390 = 1441792
|
||||
KEXEC_ARCH_SH = 2752512
|
||||
KEXEC_ARCH_X86_64 = 4063232
|
||||
KEXEC_ON_CRASH = 1
|
||||
KEXEC_PRESERVE_CONTEXT = 2
|
||||
KEYCTL_ASSUME_AUTHORITY = 16
|
||||
KEYCTL_CHOWN = 4
|
||||
KEYCTL_CLEAR = 7
|
||||
KEYCTL_DESCRIBE = 6
|
||||
KEYCTL_GET_KEYRING_ID = 0
|
||||
KEYCTL_GET_PERSISTENT = 22
|
||||
KEYCTL_GET_SECURITY = 17
|
||||
KEYCTL_INSTANTIATE = 12
|
||||
KEYCTL_INSTANTIATE_IOV = 20
|
||||
KEYCTL_INVALIDATE = 21
|
||||
KEYCTL_JOIN_SESSION_KEYRING = 1
|
||||
KEYCTL_LINK = 8
|
||||
KEYCTL_NEGATE = 13
|
||||
KEYCTL_READ = 11
|
||||
KEYCTL_REJECT = 19
|
||||
KEYCTL_REVOKE = 3
|
||||
KEYCTL_SEARCH = 10
|
||||
KEYCTL_SESSION_TO_PARENT = 18
|
||||
KEYCTL_SETPERM = 5
|
||||
KEYCTL_SET_REQKEY_KEYRING = 14
|
||||
KEYCTL_SET_TIMEOUT = 15
|
||||
KEYCTL_UNLINK = 9
|
||||
KEYCTL_UPDATE = 2
|
||||
KEY_REQKEY_DEFL_DEFAULT = 0
|
||||
KEY_REQKEY_DEFL_GROUP_KEYRING = 6
|
||||
KEY_REQKEY_DEFL_NO_CHANGE = 18446744073709551615
|
||||
KEY_REQKEY_DEFL_PROCESS_KEYRING = 2
|
||||
KEY_REQKEY_DEFL_REQUESTOR_KEYRING = 7
|
||||
KEY_REQKEY_DEFL_SESSION_KEYRING = 3
|
||||
KEY_REQKEY_DEFL_THREAD_KEYRING = 1
|
||||
KEY_REQKEY_DEFL_USER_KEYRING = 4
|
||||
KEY_REQKEY_DEFL_USER_SESSION_KEYRING = 5
|
||||
KEY_SPEC_GROUP_KEYRING = 18446744073709551610
|
||||
KEY_SPEC_PROCESS_KEYRING = 18446744073709551614
|
||||
KEY_SPEC_REQKEY_AUTH_KEY = 18446744073709551609
|
||||
KEY_SPEC_REQUESTOR_KEYRING = 18446744073709551608
|
||||
KEY_SPEC_SESSION_KEYRING = 18446744073709551613
|
||||
KEY_SPEC_THREAD_KEYRING = 18446744073709551615
|
||||
KEY_SPEC_USER_KEYRING = 18446744073709551612
|
||||
KEY_SPEC_USER_SESSION_KEYRING = 18446744073709551611
|
||||
LOCK_EX = 2
|
||||
LOCK_NB = 4
|
||||
LOCK_SH = 1
|
||||
LOCK_UN = 8
|
||||
MADV_DODUMP = 17
|
||||
MADV_DOFORK = 11
|
||||
MADV_DONTDUMP = 16
|
||||
MADV_DONTFORK = 10
|
||||
MADV_DONTNEED = 4
|
||||
MADV_HUGEPAGE = 14
|
||||
MADV_HWPOISON = 100
|
||||
MADV_MERGEABLE = 12
|
||||
MADV_NOHUGEPAGE = 15
|
||||
MADV_NORMAL = 0
|
||||
MADV_RANDOM = 1
|
||||
MADV_REMOVE = 9
|
||||
MADV_SEQUENTIAL = 2
|
||||
MADV_SOFT_OFFLINE = 101
|
||||
MADV_UNMERGEABLE = 13
|
||||
MADV_WILLNEED = 3
|
||||
MAP_32BIT = 64
|
||||
MAP_ANONYMOUS = 32
|
||||
MAP_DENYWRITE = 2048
|
||||
MAP_EXECUTABLE = 4096
|
||||
MAP_FILE = 0
|
||||
MAP_FIXED = 16
|
||||
MAP_GROWSDOWN = 256
|
||||
MAP_HUGETLB = 262144
|
||||
MAP_LOCKED = 8192
|
||||
MAP_NONBLOCK = 65536
|
||||
MAP_NORESERVE = 16384
|
||||
MAP_POPULATE = 32768
|
||||
MAP_PRIVATE = 2
|
||||
MAP_SHARED = 1
|
||||
MAP_STACK = 131072
|
||||
MAP_UNINITIALIZED = 67108864
|
||||
MCL_CURRENT = 1
|
||||
MCL_FUTURE = 2
|
||||
MMAP_PAGE_ZERO = 1048576
|
||||
MNT_DETACH = 2
|
||||
MNT_EXPIRE = 4
|
||||
MNT_FORCE = 1
|
||||
MODULE_INIT_IGNORE_MODVERSIONS = 1
|
||||
MODULE_INIT_IGNORE_VERMAGIC = 2
|
||||
MPOL_BIND = 2
|
||||
MPOL_DEFAULT = 0
|
||||
MPOL_F_ADDR = 2
|
||||
MPOL_F_MEMS_ALLOWED = 4
|
||||
MPOL_F_NODE = 1
|
||||
MPOL_F_RELATIVE_NODES = 16384
|
||||
MPOL_F_STATIC_NODES = 32768
|
||||
MPOL_INTERLEAVE = 3
|
||||
MPOL_MF_MOVE = 2
|
||||
MPOL_MF_MOVE_ALL = 4
|
||||
MPOL_MF_STRICT = 1
|
||||
MPOL_PREFERRED = 1
|
||||
MREMAP_FIXED = 2
|
||||
MREMAP_MAYMOVE = 1
|
||||
MSG_CMSG_CLOEXEC = 1073741824
|
||||
MSG_CONFIRM = 2048
|
||||
MSG_DONTROUTE = 4
|
||||
MSG_DONTWAIT = 64
|
||||
MSG_EOR = 128
|
||||
MSG_ERRQUEUE = 8192
|
||||
MSG_EXCEPT = 8192
|
||||
MSG_INFO = 12
|
||||
MSG_MORE = 32768
|
||||
MSG_NOERROR = 4096
|
||||
MSG_NOSIGNAL = 16384
|
||||
MSG_OOB = 1
|
||||
MSG_PEEK = 2
|
||||
MSG_STAT = 11
|
||||
MSG_TRUNC = 32
|
||||
MSG_WAITALL = 256
|
||||
MSG_WAITFORONE = 65536
|
||||
MS_ASYNC = 1
|
||||
MS_BIND = 4096
|
||||
MS_DIRSYNC = 128
|
||||
MS_INVALIDATE = 2
|
||||
MS_MANDLOCK = 64
|
||||
MS_MOVE = 8192
|
||||
MS_NOATIME = 1024
|
||||
MS_NODEV = 4
|
||||
MS_NODIRATIME = 2048
|
||||
MS_NOEXEC = 8
|
||||
MS_NOSUID = 2
|
||||
MS_RDONLY = 1
|
||||
MS_RELATIME = 2097152
|
||||
MS_REMOUNT = 32
|
||||
MS_SILENT = 32768
|
||||
MS_STRICTATIME = 16777216
|
||||
MS_SYNC = 4
|
||||
MS_SYNCHRONOUS = 16
|
||||
NT_386_IOPERM = 513
|
||||
NT_386_TLS = 512
|
||||
NT_AUXV = 6
|
||||
NT_PRFPREG = 2
|
||||
NT_PRPSINFO = 3
|
||||
NT_PRSTATUS = 1
|
||||
NT_TASKSTRUCT = 4
|
||||
NT_X86_XSTATE = 514
|
||||
O_APPEND = 1024
|
||||
O_ASYNC = 8192
|
||||
O_CLOEXEC = 524288
|
||||
O_CREAT = 64
|
||||
O_DIRECT = 16384
|
||||
O_DIRECTORY = 65536
|
||||
O_DSYNC = 4096
|
||||
O_EXCL = 128
|
||||
O_LARGEFILE = 0
|
||||
O_NOATIME = 262144
|
||||
O_NOCTTY = 256
|
||||
O_NOFOLLOW = 131072
|
||||
O_NONBLOCK = 2048
|
||||
O_PATH = 2097152
|
||||
O_RDONLY = 0
|
||||
O_RDWR = 2
|
||||
O_SYNC = 1052672
|
||||
O_TRUNC = 512
|
||||
O_WRONLY = 1
|
||||
POSIX_FADV_DONTNEED = 4
|
||||
POSIX_FADV_NOREUSE = 5
|
||||
POSIX_FADV_NORMAL = 0
|
||||
POSIX_FADV_RANDOM = 1
|
||||
POSIX_FADV_SEQUENTIAL = 2
|
||||
POSIX_FADV_WILLNEED = 3
|
||||
PRIO_PGRP = 1
|
||||
PRIO_PROCESS = 0
|
||||
PRIO_USER = 2
|
||||
PROT_EXEC = 4
|
||||
PROT_READ = 1
|
||||
PROT_WRITE = 2
|
||||
PR_CAPBSET_DROP = 24
|
||||
PR_CAPBSET_READ = 23
|
||||
PR_GET_CHILD_SUBREAPER = 37
|
||||
PR_GET_DUMPABLE = 3
|
||||
PR_GET_ENDIAN = 19
|
||||
PR_GET_FPEMU = 9
|
||||
PR_GET_FPEXC = 11
|
||||
PR_GET_KEEPCAPS = 7
|
||||
PR_GET_NAME = 16
|
||||
PR_GET_NO_NEW_PRIVS = 39
|
||||
PR_GET_PDEATHSIG = 2
|
||||
PR_GET_SECCOMP = 21
|
||||
PR_GET_SECUREBITS = 27
|
||||
PR_GET_TID_ADDRESS = 40
|
||||
PR_GET_TIMERSLACK = 30
|
||||
PR_GET_TIMING = 13
|
||||
PR_GET_TSC = 25
|
||||
PR_GET_UNALIGN = 5
|
||||
PR_MCE_KILL = 33
|
||||
PR_MCE_KILL_GET = 34
|
||||
PR_SET_CHILD_SUBREAPER = 36
|
||||
PR_SET_DUMPABLE = 4
|
||||
PR_SET_ENDIAN = 20
|
||||
PR_SET_FPEMU = 10
|
||||
PR_SET_FPEXC = 12
|
||||
PR_SET_KEEPCAPS = 8
|
||||
PR_SET_MM = 35
|
||||
PR_SET_NAME = 15
|
||||
PR_SET_NO_NEW_PRIVS = 38
|
||||
PR_SET_PDEATHSIG = 1
|
||||
PR_SET_PTRACER = 1499557217
|
||||
PR_SET_SECCOMP = 22
|
||||
PR_SET_SECUREBITS = 28
|
||||
PR_SET_TIMERSLACK = 29
|
||||
PR_SET_TIMING = 14
|
||||
PR_SET_TSC = 26
|
||||
PR_SET_UNALIGN = 6
|
||||
PR_TASK_PERF_EVENTS_DISABLE = 31
|
||||
PR_TASK_PERF_EVENTS_ENABLE = 32
|
||||
PTRACE_ATTACH = 16
|
||||
PTRACE_CONT = 7
|
||||
PTRACE_DETACH = 17
|
||||
PTRACE_GETEVENTMSG = 16897
|
||||
PTRACE_GETFPREGS = 14
|
||||
PTRACE_GETREGS = 12
|
||||
PTRACE_GETREGSET = 16900
|
||||
PTRACE_GETSIGINFO = 16898
|
||||
PTRACE_INTERRUPT = 16903
|
||||
PTRACE_KILL = 8
|
||||
PTRACE_LISTEN = 16904
|
||||
PTRACE_O_EXITKILL = 1048576
|
||||
PTRACE_O_TRACECLONE = 8
|
||||
PTRACE_O_TRACEEXEC = 16
|
||||
PTRACE_O_TRACEEXIT = 64
|
||||
PTRACE_O_TRACEFORK = 2
|
||||
PTRACE_O_TRACESYSGOOD = 1
|
||||
PTRACE_O_TRACEVFORK = 4
|
||||
PTRACE_O_TRACEVFORKDONE = 32
|
||||
PTRACE_PEEKDATA = 2
|
||||
PTRACE_PEEKTEXT = 1
|
||||
PTRACE_PEEKUSER = 3
|
||||
PTRACE_POKEDATA = 5
|
||||
PTRACE_POKETEXT = 4
|
||||
PTRACE_POKEUSER = 6
|
||||
PTRACE_SEIZE = 16902
|
||||
PTRACE_SETFPREGS = 15
|
||||
PTRACE_SETOPTIONS = 16896
|
||||
PTRACE_SETREGS = 13
|
||||
PTRACE_SETREGSET = 16901
|
||||
PTRACE_SETSIGINFO = 16899
|
||||
PTRACE_SINGLESTEP = 9
|
||||
PTRACE_SYSCALL = 24
|
||||
PTRACE_SYSEMU = 31
|
||||
PTRACE_SYSEMU_SINGLESTEP = 32
|
||||
PTRACE_TRACEME = 0
|
||||
P_ALL = 0
|
||||
P_PGID = 2
|
||||
P_PID = 1
|
||||
READ_IMPLIES_EXEC = 4194304
|
||||
RENAME_EXCHANGE = 2
|
||||
RENAME_NOREPLACE = 1
|
||||
RENAME_WHITEOUT = 4
|
||||
RLIMIT_AS = 9
|
||||
RLIMIT_CORE = 4
|
||||
RLIMIT_CPU = 0
|
||||
RLIMIT_DATA = 2
|
||||
RLIMIT_FSIZE = 1
|
||||
RLIMIT_LOCKS = 10
|
||||
RLIMIT_MEMLOCK = 8
|
||||
RLIMIT_MSGQUEUE = 12
|
||||
RLIMIT_NICE = 13
|
||||
RLIMIT_NOFILE = 7
|
||||
RLIMIT_NPROC = 6
|
||||
RLIMIT_RSS = 5
|
||||
RLIMIT_RTPRIO = 14
|
||||
RLIMIT_RTTIME = 15
|
||||
RLIMIT_SIGPENDING = 11
|
||||
RLIMIT_STACK = 3
|
||||
RUSAGE_CHILDREN = 18446744073709551615
|
||||
RUSAGE_SELF = 0
|
||||
RUSAGE_THREAD = 1
|
||||
SA_NOCLDSTOP = 1
|
||||
SA_NOCLDWAIT = 2
|
||||
SA_NODEFER = 1073741824
|
||||
SA_ONSTACK = 134217728
|
||||
SA_RESETHAND = 2147483648
|
||||
SA_RESTART = 268435456
|
||||
SA_SIGINFO = 4
|
||||
SCHED_BATCH = 3
|
||||
SCHED_DEADLINE = 6
|
||||
SCHED_FIFO = 1
|
||||
SCHED_FLAG_RESET_ON_FORK = 1
|
||||
SCHED_IDLE = 5
|
||||
SCHED_OTHER = 0
|
||||
SCHED_RR = 2
|
||||
SECCOMP_FILTER_FLAG_TSYNC = 1
|
||||
SECCOMP_SET_MODE_FILTER = 1
|
||||
SECCOMP_SET_MODE_STRICT = 0
|
||||
SEEK_CUR = 1
|
||||
SEEK_DATA = 3
|
||||
SEEK_END = 2
|
||||
SEEK_HOLE = 4
|
||||
SEEK_SET = 0
|
||||
SEM_INFO = 19
|
||||
SEM_STAT = 18
|
||||
SEM_UNDO = 4096
|
||||
SETALL = 17
|
||||
SETVAL = 16
|
||||
SFD_CLOEXEC = 524288
|
||||
SFD_NONBLOCK = 2048
|
||||
SHM_HUGETLB = 2048
|
||||
SHM_INFO = 14
|
||||
SHM_LOCK = 11
|
||||
SHM_NORESERVE = 4096
|
||||
SHM_RDONLY = 4096
|
||||
SHM_REMAP = 16384
|
||||
SHM_RND = 8192
|
||||
SHM_STAT = 13
|
||||
SHM_UNLOCK = 12
|
||||
SHORT_INODE = 16777216
|
||||
SHUT_RD = 0
|
||||
SHUT_WR = 1
|
||||
SIGEV_NONE = 1
|
||||
SIGEV_SIGNAL = 0
|
||||
SIGEV_THREAD = 2
|
||||
SIG_BLOCK = 0
|
||||
SIG_SETMASK = 2
|
||||
SIG_UNBLOCK = 1
|
||||
SOCK_CLOEXEC = 524288
|
||||
SOCK_DGRAM = 2
|
||||
SOCK_NONBLOCK = 2048
|
||||
SOCK_PACKET = 10
|
||||
SOCK_RAW = 3
|
||||
SOCK_RDM = 4
|
||||
SOCK_SEQPACKET = 5
|
||||
SOCK_STREAM = 1
|
||||
SPLICE_F_GIFT = 8
|
||||
SPLICE_F_MORE = 4
|
||||
SPLICE_F_MOVE = 1
|
||||
SPLICE_F_NONBLOCK = 2
|
||||
STICKY_TIMEOUTS = 67108864
|
||||
SYNC_FILE_RANGE_WAIT_AFTER = 4
|
||||
SYNC_FILE_RANGE_WAIT_BEFORE = 1
|
||||
SYNC_FILE_RANGE_WRITE = 2
|
||||
SYSLOG_ACTION_CLEAR = 5
|
||||
SYSLOG_ACTION_CLOSE = 0
|
||||
SYSLOG_ACTION_CONSOLE_LEVEL = 8
|
||||
SYSLOG_ACTION_CONSOLE_OFF = 6
|
||||
SYSLOG_ACTION_CONSOLE_ON = 7
|
||||
SYSLOG_ACTION_OPEN = 1
|
||||
SYSLOG_ACTION_READ = 2
|
||||
SYSLOG_ACTION_READ_ALL = 3
|
||||
SYSLOG_ACTION_READ_CLEAR = 4
|
||||
SYSLOG_ACTION_SIZE_BUFFER = 10
|
||||
SYSLOG_ACTION_SIZE_UNREAD = 9
|
||||
SYZ_PER_BSD = 6
|
||||
SYZ_PER_HPUX = 16
|
||||
SYZ_PER_IRIX32 = 9
|
||||
SYZ_PER_IRIX64 = 11
|
||||
SYZ_PER_IRIXN32 = 10
|
||||
SYZ_PER_ISCR4 = 5
|
||||
SYZ_PER_LINUX = 0
|
||||
SYZ_PER_LINUX32 = 8
|
||||
SYZ_PER_OSF4 = 15
|
||||
SYZ_PER_OSR5 = 3
|
||||
SYZ_PER_RISCOS = 12
|
||||
SYZ_PER_SOLARIS = 13
|
||||
SYZ_PER_SVR3 = 2
|
||||
SYZ_PER_SVR4 = 1
|
||||
SYZ_PER_UW7 = 14
|
||||
SYZ_PER_WYSEV386 = 4
|
||||
SYZ_PER_XENIX = 7
|
||||
S_IFBLK = 24576
|
||||
S_IFCHR = 8192
|
||||
S_IFIFO = 4096
|
||||
S_IFREG = 32768
|
||||
S_IFSOCK = 49152
|
||||
S_IRGRP = 32
|
||||
S_IROTH = 4
|
||||
S_IRUSR = 256
|
||||
S_IWGRP = 16
|
||||
S_IWOTH = 2
|
||||
S_IWUSR = 128
|
||||
S_IXGRP = 8
|
||||
S_IXOTH = 1
|
||||
S_IXUSR = 64
|
||||
TFD_CLOEXEC = 524288
|
||||
TFD_NONBLOCK = 2048
|
||||
TFD_TIMER_ABSTIME = 1
|
||||
TIMER_ABSTIME = 1
|
||||
UMOUNT_NOFOLLOW = 8
|
||||
WCONTINUED = 8
|
||||
WEXITED = 4
|
||||
WHOLE_SECONDS = 33554432
|
||||
WNOHANG = 1
|
||||
WNOWAIT = 16777216
|
||||
WSTOPPED = 2
|
||||
WUNTRACED = 2
|
||||
XATTR_CREATE = 1
|
||||
XATTR_REPLACE = 2
|
||||
__WALL = 1073741824
|
||||
__WCLONE = 2147483648
|
||||
__WNOTHREAD = 536870912
|
||||
)
|
411
prog/encoding.go
Normal file
411
prog/encoding.go
Normal file
@ -0,0 +1,411 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package prog
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
|
||||
"github.com/google/syzkaller/sys"
|
||||
)
|
||||
|
||||
// String generates a very compact program description (mostly for debug output).
|
||||
func (p *Prog) String() string {
|
||||
buf := new(bytes.Buffer)
|
||||
for i, c := range p.Calls {
|
||||
if i != 0 {
|
||||
fmt.Fprintf(buf, "-")
|
||||
}
|
||||
fmt.Fprintf(buf, "%v", c.Meta.Name)
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (p *Prog) Serialize() []byte {
|
||||
/*
|
||||
if err := p.validate(); err != nil {
|
||||
panic("serializing invalid program")
|
||||
}
|
||||
*/
|
||||
buf := new(bytes.Buffer)
|
||||
vars := make(map[*Arg]int)
|
||||
varSeq := 0
|
||||
for _, c := range p.Calls {
|
||||
if len(c.Ret.Uses) != 0 {
|
||||
fmt.Fprintf(buf, "r%v = ", varSeq)
|
||||
vars[c.Ret] = varSeq
|
||||
varSeq++
|
||||
}
|
||||
fmt.Fprintf(buf, "%v(", c.Meta.Name)
|
||||
for i, a := range c.Args {
|
||||
if i != 0 {
|
||||
fmt.Fprintf(buf, ", ")
|
||||
}
|
||||
a.serialize(buf, vars, &varSeq)
|
||||
}
|
||||
fmt.Fprintf(buf, ")\n")
|
||||
}
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func (a *Arg) serialize(buf io.Writer, vars map[*Arg]int, varSeq *int) {
|
||||
if a == nil {
|
||||
fmt.Fprintf(buf, "nil")
|
||||
return
|
||||
}
|
||||
if len(a.Uses) != 0 {
|
||||
fmt.Fprintf(buf, "[r%v=]", *varSeq)
|
||||
vars[a] = *varSeq
|
||||
*varSeq++
|
||||
}
|
||||
switch a.Kind {
|
||||
case ArgConst:
|
||||
fmt.Fprintf(buf, "0x%x", a.Val)
|
||||
case ArgResult:
|
||||
id, ok := vars[a.Res]
|
||||
if !ok {
|
||||
panic("no result")
|
||||
}
|
||||
fmt.Fprintf(buf, "r%v", id)
|
||||
if a.OpDiv != 0 {
|
||||
fmt.Fprintf(buf, "/%v", a.OpDiv)
|
||||
}
|
||||
if a.OpAdd != 0 {
|
||||
fmt.Fprintf(buf, "+%v", a.OpAdd)
|
||||
}
|
||||
case ArgPointer:
|
||||
fmt.Fprintf(buf, "&%v=", serializeAddr(a, true))
|
||||
a.Res.serialize(buf, vars, varSeq)
|
||||
case ArgPageSize:
|
||||
fmt.Fprintf(buf, "%v", serializeAddr(a, false))
|
||||
case ArgData:
|
||||
fmt.Fprintf(buf, "\"%v\"", hex.EncodeToString(a.Data))
|
||||
case ArgGroup:
|
||||
fmt.Fprintf(buf, "{")
|
||||
for i, a1 := range a.Inner {
|
||||
if i != 0 {
|
||||
fmt.Fprintf(buf, ", ")
|
||||
}
|
||||
a1.serialize(buf, vars, varSeq)
|
||||
}
|
||||
fmt.Fprintf(buf, "}")
|
||||
default:
|
||||
panic("unknown arg kind")
|
||||
}
|
||||
}
|
||||
|
||||
func Deserialize(data []byte) (prog *Prog, err error) {
|
||||
prog = new(Prog)
|
||||
p := &parser{r: bufio.NewScanner(bytes.NewReader(data))}
|
||||
vars := make(map[string]*Arg)
|
||||
for p.Scan() {
|
||||
if p.EOF() {
|
||||
continue
|
||||
}
|
||||
name := p.Ident()
|
||||
r := ""
|
||||
if p.Char() == '=' {
|
||||
r = name
|
||||
p.Parse('=')
|
||||
name = p.Ident()
|
||||
|
||||
}
|
||||
meta := sys.CallMap[name]
|
||||
if meta == nil {
|
||||
return nil, fmt.Errorf("unknown syscall %v", name)
|
||||
}
|
||||
c := &Call{Meta: meta}
|
||||
prog.Calls = append(prog.Calls, c)
|
||||
p.Parse('(')
|
||||
for i := 0; p.Char() != ')'; i++ {
|
||||
arg, err := parseArg(p, vars)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.Args = append(c.Args, arg)
|
||||
if p.Char() != ')' {
|
||||
p.Parse(',')
|
||||
}
|
||||
}
|
||||
p.Parse(')')
|
||||
if !p.EOF() {
|
||||
return nil, fmt.Errorf("tailing data (line #%v)", p.l)
|
||||
}
|
||||
if len(c.Args) != len(meta.Args) {
|
||||
return nil, fmt.Errorf("wrong call arg count: %v, want %v", len(c.Args), len(meta.Args))
|
||||
}
|
||||
assignTypeAndDir(c)
|
||||
if r != "" {
|
||||
vars[r] = c.Ret
|
||||
}
|
||||
}
|
||||
if p.Err() != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := prog.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func parseArg(p *parser, vars map[string]*Arg) (*Arg, error) {
|
||||
r := ""
|
||||
if p.Char() == '[' {
|
||||
p.Parse('[')
|
||||
r = p.Ident()
|
||||
p.Parse('=')
|
||||
p.Parse(']')
|
||||
}
|
||||
var arg *Arg
|
||||
switch p.Char() {
|
||||
case '0':
|
||||
val := p.Ident()
|
||||
v, err := strconv.ParseUint(val, 0, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("wrong arg value '%v': %v", val, err)
|
||||
}
|
||||
arg = constArg(uintptr(v))
|
||||
case 'r':
|
||||
id := p.Ident()
|
||||
v, ok := vars[id]
|
||||
if !ok || v == nil {
|
||||
return nil, fmt.Errorf("result %v references unknown variable (vars=%+v)", id, vars)
|
||||
}
|
||||
arg = resultArg(v)
|
||||
if p.Char() == '/' {
|
||||
p.Parse('/')
|
||||
op := p.Ident()
|
||||
v, err := strconv.ParseUint(op, 0, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("wrong result div op: '%v'", op)
|
||||
}
|
||||
arg.OpDiv = uintptr(v)
|
||||
}
|
||||
if p.Char() == '+' {
|
||||
p.Parse('+')
|
||||
op := p.Ident()
|
||||
v, err := strconv.ParseUint(op, 0, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("wrong result add op: '%v'", op)
|
||||
}
|
||||
arg.OpAdd = uintptr(v)
|
||||
}
|
||||
case '&':
|
||||
p.Parse('&')
|
||||
page, off, err := parseAddr(p, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.Parse('=')
|
||||
inner, err := parseArg(p, vars)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
arg = pointerArg(page, off, inner)
|
||||
case '(':
|
||||
page, off, err := parseAddr(p, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
arg = pageSizeArg(page, off)
|
||||
case '"':
|
||||
p.Parse('"')
|
||||
val := ""
|
||||
if p.Char() != '"' {
|
||||
val = p.Ident()
|
||||
}
|
||||
p.Parse('"')
|
||||
data, err := hex.DecodeString(val)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("data arg has bad value '%v'", val)
|
||||
}
|
||||
arg = dataArg(data)
|
||||
case '{':
|
||||
p.Parse('{')
|
||||
var inner []*Arg
|
||||
for p.Char() != '}' {
|
||||
arg, err := parseArg(p, vars)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
inner = append(inner, arg)
|
||||
if p.Char() != '}' {
|
||||
p.Parse(',')
|
||||
}
|
||||
}
|
||||
p.Parse('}')
|
||||
arg = groupArg(inner)
|
||||
case 'n':
|
||||
p.Parse('n')
|
||||
p.Parse('i')
|
||||
p.Parse('l')
|
||||
if r != "" {
|
||||
return nil, fmt.Errorf("named nil argument")
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("failed to parse argument at %v (line #%v/%v: %v)", int(p.Char()), p.l, p.i, p.s)
|
||||
}
|
||||
if r != "" {
|
||||
vars[r] = arg
|
||||
}
|
||||
return arg, nil
|
||||
}
|
||||
|
||||
const (
|
||||
encodingAddrBase = 0x7f0000000000
|
||||
encodingPageSize = 4 << 10
|
||||
)
|
||||
|
||||
func serializeAddr(a *Arg, base bool) string {
|
||||
page := a.AddrPage * encodingPageSize
|
||||
if base {
|
||||
page += encodingAddrBase
|
||||
}
|
||||
soff := ""
|
||||
if off := a.AddrOffset; off != 0 {
|
||||
sign := "+"
|
||||
if off < 0 {
|
||||
sign = "-"
|
||||
off = -off
|
||||
page += encodingPageSize
|
||||
}
|
||||
soff = fmt.Sprintf("%v0x%x", sign, off)
|
||||
}
|
||||
return fmt.Sprintf("(0x%x%v)", page, soff)
|
||||
}
|
||||
|
||||
func parseAddr(p *parser, base bool) (uintptr, int, error) {
|
||||
p.Parse('(')
|
||||
pstr := p.Ident()
|
||||
page, err := strconv.ParseUint(pstr, 0, 64)
|
||||
if err != nil {
|
||||
return 0, 0, fmt.Errorf("failed to parse addr page: '%v'", pstr)
|
||||
}
|
||||
if page%encodingPageSize != 0 {
|
||||
return 0, 0, fmt.Errorf("address base is not page size aligned: '%v'", pstr)
|
||||
}
|
||||
if base {
|
||||
if page < encodingAddrBase {
|
||||
return 0, 0, fmt.Errorf("address without base offset: '%v'", pstr)
|
||||
}
|
||||
page -= encodingAddrBase
|
||||
}
|
||||
var off int64
|
||||
if p.Char() == '+' || p.Char() == '-' {
|
||||
minus := false
|
||||
if p.Char() == '-' {
|
||||
minus = true
|
||||
p.Parse('-')
|
||||
} else {
|
||||
p.Parse('+')
|
||||
}
|
||||
ostr := p.Ident()
|
||||
off, err = strconv.ParseInt(ostr, 0, 64)
|
||||
if err != nil {
|
||||
return 0, 0, fmt.Errorf("failed to parse addr offset: '%v'", ostr)
|
||||
}
|
||||
if minus {
|
||||
page -= encodingPageSize
|
||||
off = -off
|
||||
}
|
||||
}
|
||||
p.Parse(')')
|
||||
page /= encodingPageSize
|
||||
return uintptr(page), int(off), nil
|
||||
}
|
||||
|
||||
type parser struct {
|
||||
r *bufio.Scanner
|
||||
s string
|
||||
i int
|
||||
l int
|
||||
e error
|
||||
}
|
||||
|
||||
func (p *parser) Scan() bool {
|
||||
if p.e != nil {
|
||||
return false
|
||||
}
|
||||
if !p.r.Scan() {
|
||||
p.e = p.r.Err()
|
||||
return false
|
||||
}
|
||||
p.s = p.r.Text()
|
||||
p.i = 0
|
||||
p.l++
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *parser) Err() error {
|
||||
return p.e
|
||||
}
|
||||
|
||||
func (p *parser) Str() string {
|
||||
return p.s
|
||||
}
|
||||
|
||||
func (p *parser) EOF() bool {
|
||||
return p.i == len(p.s)
|
||||
}
|
||||
|
||||
func (p *parser) Char() byte {
|
||||
if p.e != nil {
|
||||
return 0
|
||||
}
|
||||
if p.EOF() {
|
||||
p.failf("unexpected eof")
|
||||
return 0
|
||||
}
|
||||
return p.s[p.i]
|
||||
}
|
||||
|
||||
func (p *parser) Parse(ch byte) {
|
||||
if p.e != nil {
|
||||
return
|
||||
}
|
||||
if p.EOF() {
|
||||
p.failf("want %s, got EOF", string(ch))
|
||||
return
|
||||
}
|
||||
if p.s[p.i] != ch {
|
||||
p.failf("want '%v', got '%v'", string(ch), string(p.s[p.i]))
|
||||
return
|
||||
}
|
||||
p.i++
|
||||
p.SkipWs()
|
||||
}
|
||||
|
||||
func (p *parser) SkipWs() {
|
||||
for p.i < len(p.s) && (p.s[p.i] == ' ' || p.s[p.i] == '\t') {
|
||||
p.i++
|
||||
}
|
||||
}
|
||||
|
||||
func (p *parser) Ident() string {
|
||||
i := p.i
|
||||
for p.i < len(p.s) &&
|
||||
(p.s[p.i] >= 'a' && p.s[p.i] <= 'z' ||
|
||||
p.s[p.i] >= 'A' && p.s[p.i] <= 'Z' ||
|
||||
p.s[p.i] >= '0' && p.s[p.i] <= '9' ||
|
||||
p.s[p.i] == '_' || p.s[p.i] == '$') {
|
||||
p.i++
|
||||
}
|
||||
if i == p.i {
|
||||
p.failf("failed to parse identifier at pos %v", i)
|
||||
return ""
|
||||
}
|
||||
if ch := p.s[i]; ch >= '0' && ch <= '9' {
|
||||
}
|
||||
s := p.s[i:p.i]
|
||||
p.SkipWs()
|
||||
return s
|
||||
}
|
||||
|
||||
func (p *parser) failf(msg string, args ...interface{}) {
|
||||
p.e = fmt.Errorf("%v\nline #%v: %v", fmt.Sprintf(msg, args...), p.l, p.s)
|
||||
}
|
114
prog/encodingc.go
Normal file
114
prog/encodingc.go
Normal file
@ -0,0 +1,114 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package prog
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"unsafe"
|
||||
|
||||
"github.com/google/syzkaller/sys"
|
||||
)
|
||||
|
||||
func (p *Prog) WriteCSource() []byte {
|
||||
exec := p.SerializeForExec()
|
||||
buf := new(bytes.Buffer)
|
||||
writeCSource(buf, exec)
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func writeCSource(w io.Writer, exec []byte) {
|
||||
fmt.Fprintf(w, `// autogenerated by syzkaller (http://github.com/google/syzkaller)
|
||||
#include <syscall.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
`)
|
||||
read := func() uintptr {
|
||||
if len(exec) < 8 {
|
||||
panic("exec program overflow")
|
||||
}
|
||||
v := *(*uint64)(unsafe.Pointer(&exec[0]))
|
||||
exec = exec[8:]
|
||||
return uintptr(v)
|
||||
}
|
||||
resultRef := func() string {
|
||||
arg := read()
|
||||
res := fmt.Sprintf("r%v", arg)
|
||||
if opDiv := read(); opDiv != 0 {
|
||||
res = fmt.Sprintf("%v/%v", res, opDiv)
|
||||
}
|
||||
if opAdd := read(); opAdd != 0 {
|
||||
res = fmt.Sprintf("%v+%v", res, opAdd)
|
||||
}
|
||||
return res
|
||||
}
|
||||
lastCall := 0
|
||||
for n := 0; ; n++ {
|
||||
switch instr := read(); instr {
|
||||
case instrEOF:
|
||||
fmt.Fprintf(w, "\treturn 0;\n}\n")
|
||||
return
|
||||
case instrCopyin:
|
||||
addr := read()
|
||||
typ := read()
|
||||
size := read()
|
||||
switch typ {
|
||||
case execArgConst:
|
||||
arg := read()
|
||||
fmt.Fprintf(w, "\t*(uint%v_t*)0x%x = 0x%x;\n", size*8, addr, arg)
|
||||
case execArgResult:
|
||||
fmt.Fprintf(w, "\t*(uint%v_t*)0x%x = %v;\n", size*8, addr, resultRef())
|
||||
case execArgData:
|
||||
data := exec[:size]
|
||||
exec = exec[(size+7)/8*8:]
|
||||
var esc []byte
|
||||
for _, v := range data {
|
||||
hex := func(v byte) byte {
|
||||
if v < 10 {
|
||||
return '0' + v
|
||||
}
|
||||
return 'a' + v - 10
|
||||
}
|
||||
esc = append(esc, '\\', 'x', hex(v>>4), hex(v<<4>>4))
|
||||
}
|
||||
fmt.Fprintf(w, "\tmemcpy((void*)0x%x, \"%s\", %v);\n", addr, esc, size)
|
||||
default:
|
||||
panic("bad argument type")
|
||||
}
|
||||
case instrCopyout:
|
||||
addr := read()
|
||||
size := read()
|
||||
fmt.Fprintf(w, "\tlong r%v = -1;\n", n)
|
||||
fmt.Fprintf(w, "\tif (r%v != -1)\n", lastCall)
|
||||
fmt.Fprintf(w, "\t\tr%v = *(uint%v_t*)0x%x;\n", n, size*8, addr)
|
||||
default:
|
||||
// Normal syscall.
|
||||
meta := sys.Calls[instr]
|
||||
fmt.Fprintf(w, "\tlong r%v = syscall(SYS_%v", n, meta.CallName)
|
||||
nargs := read()
|
||||
for i := uintptr(0); i < nargs; i++ {
|
||||
typ := read()
|
||||
size := read()
|
||||
_ = size
|
||||
switch typ {
|
||||
case execArgConst:
|
||||
fmt.Fprintf(w, ", 0x%xul", read())
|
||||
case execArgResult:
|
||||
fmt.Fprintf(w, ", %v", resultRef())
|
||||
default:
|
||||
panic("unknown arg type")
|
||||
}
|
||||
}
|
||||
for i := nargs; i < 6; i++ {
|
||||
fmt.Fprintf(w, ", 0")
|
||||
}
|
||||
fmt.Fprintf(w, ");\n")
|
||||
lastCall = n
|
||||
}
|
||||
}
|
||||
}
|
172
prog/encodingexec.go
Normal file
172
prog/encodingexec.go
Normal file
@ -0,0 +1,172 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
// This file does serialization of programs for executor binary.
|
||||
// The format aims at simple parsing: binary and irreversible.
|
||||
|
||||
package prog
|
||||
|
||||
const (
|
||||
instrEOF = ^uintptr(iota)
|
||||
instrCopyin
|
||||
instrCopyout
|
||||
)
|
||||
|
||||
const (
|
||||
execArgConst = uintptr(iota)
|
||||
execArgResult
|
||||
execArgData
|
||||
)
|
||||
|
||||
const (
|
||||
ptrSize = 8
|
||||
pageSize = 4 << 10
|
||||
dataOffset = 512 << 20
|
||||
)
|
||||
|
||||
func (p *Prog) SerializeForExec() []byte {
|
||||
if err := p.validate(); err != nil {
|
||||
panic("serializing invalid program")
|
||||
}
|
||||
var instrSeq uintptr
|
||||
w := &execContext{args: make(map[*Arg]*argInfo)}
|
||||
for _, c := range p.Calls {
|
||||
// Calculate arg offsets within structs.
|
||||
foreachArg(c, func(arg, base *Arg, _ *[]*Arg) {
|
||||
if base == nil || arg.Kind == ArgGroup {
|
||||
return
|
||||
}
|
||||
if w.args[base] == nil {
|
||||
w.args[base] = &argInfo{}
|
||||
}
|
||||
w.args[arg] = &argInfo{Offset: w.args[base].CurSize}
|
||||
w.args[base].CurSize += arg.Size(arg.Type)
|
||||
})
|
||||
// Generate copyin instructions that fill in data into pointer arguments.
|
||||
foreachArg(c, func(arg, _ *Arg, _ *[]*Arg) {
|
||||
if arg.Kind == ArgPointer && arg.Res != nil {
|
||||
var rec func(*Arg)
|
||||
rec = func(arg1 *Arg) {
|
||||
if arg1.Kind == ArgGroup {
|
||||
for _, arg2 := range arg1.Inner {
|
||||
rec(arg2)
|
||||
}
|
||||
return
|
||||
}
|
||||
if arg1.Dir == DirOut || arg1.Kind == ArgData && len(arg1.Data) == 0 {
|
||||
return
|
||||
}
|
||||
w.write(instrCopyin)
|
||||
w.write(physicalAddr(arg) + w.args[arg1].Offset)
|
||||
w.writeArg(arg1)
|
||||
instrSeq++
|
||||
}
|
||||
rec(arg.Res)
|
||||
}
|
||||
})
|
||||
// Generate the call itself.
|
||||
w.write(uintptr(c.Meta.ID))
|
||||
w.write(uintptr(len(c.Args)))
|
||||
for _, arg := range c.Args {
|
||||
w.writeArg(arg)
|
||||
}
|
||||
w.args[c.Ret] = &argInfo{Idx: instrSeq}
|
||||
instrSeq++
|
||||
// Generate copyout instructions that persist interesting return values.
|
||||
foreachArg(c, func(arg, base *Arg, _ *[]*Arg) {
|
||||
if len(arg.Uses) == 0 {
|
||||
return
|
||||
}
|
||||
switch arg.Kind {
|
||||
case ArgReturn:
|
||||
// Idx is already assigned above.
|
||||
case ArgConst, ArgResult:
|
||||
// Create a separate copyout instruction that has own Idx.
|
||||
if base.Kind != ArgPointer {
|
||||
panic("arg base is not a pointer")
|
||||
}
|
||||
info := w.args[arg]
|
||||
info.Idx = instrSeq
|
||||
instrSeq++
|
||||
w.write(instrCopyout)
|
||||
w.write(physicalAddr(base) + info.Offset)
|
||||
w.write(arg.Size(arg.Type))
|
||||
default:
|
||||
panic("bad arg kind in copyout")
|
||||
}
|
||||
})
|
||||
}
|
||||
w.write(instrEOF)
|
||||
return w.buf
|
||||
}
|
||||
|
||||
func physicalAddr(arg *Arg) uintptr {
|
||||
if arg.Kind != ArgPointer {
|
||||
panic("physicalAddr: bad arg kind")
|
||||
}
|
||||
addr := arg.AddrPage*pageSize + dataOffset
|
||||
if arg.AddrOffset >= 0 {
|
||||
addr += uintptr(arg.AddrOffset)
|
||||
} else {
|
||||
addr += pageSize - uintptr(-arg.AddrOffset)
|
||||
}
|
||||
return addr
|
||||
}
|
||||
|
||||
type execContext struct {
|
||||
buf []byte
|
||||
args map[*Arg]*argInfo
|
||||
}
|
||||
|
||||
type argInfo struct {
|
||||
Offset uintptr // from base pointer
|
||||
CurSize uintptr
|
||||
Idx uintptr // instruction index
|
||||
}
|
||||
|
||||
func (w *execContext) write(v uintptr) {
|
||||
w.buf = append(w.buf, byte(v>>0), byte(v>>8), byte(v>>16), byte(v>>24), byte(v>>32), byte(v>>40), byte(v>>48), byte(v>>56))
|
||||
}
|
||||
|
||||
func (w *execContext) writeArg(arg *Arg) {
|
||||
switch arg.Kind {
|
||||
case ArgConst:
|
||||
w.write(execArgConst)
|
||||
w.write(arg.Size(arg.Type))
|
||||
w.write(arg.Val)
|
||||
case ArgResult:
|
||||
w.write(execArgResult)
|
||||
w.write(arg.Size(arg.Type))
|
||||
w.write(w.args[arg.Res].Idx)
|
||||
w.write(arg.OpDiv)
|
||||
w.write(arg.OpAdd)
|
||||
case ArgPointer:
|
||||
w.write(execArgConst)
|
||||
w.write(arg.Size(arg.Type))
|
||||
w.write(physicalAddr(arg))
|
||||
case ArgPageSize:
|
||||
w.write(execArgConst)
|
||||
w.write(arg.Size(arg.Type))
|
||||
w.write(arg.AddrPage * pageSize)
|
||||
case ArgData:
|
||||
w.write(execArgData)
|
||||
w.write(uintptr(len(arg.Data)))
|
||||
for i := 0; i < len(arg.Data); i += 8 {
|
||||
var v uintptr
|
||||
for j := 0; j < 8; j++ {
|
||||
if i+j >= len(arg.Data) {
|
||||
break
|
||||
}
|
||||
v |= uintptr(arg.Data[i+j]) << uint(j*8)
|
||||
}
|
||||
w.write(v)
|
||||
}
|
||||
case ArgGroup:
|
||||
// Squash groups.
|
||||
for _, arg1 := range arg.Inner {
|
||||
w.writeArg(arg1)
|
||||
}
|
||||
default:
|
||||
panic("unknown arg type")
|
||||
}
|
||||
}
|
29
prog/generation.go
Normal file
29
prog/generation.go
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package prog
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
|
||||
"github.com/google/syzkaller/sys"
|
||||
)
|
||||
|
||||
// Generate generates a random program of length ~ncalls.
|
||||
// calls is a set of allowed syscalls, if nil all syscalls are used.
|
||||
func Generate(rs rand.Source, ncalls int, enabledCalls []*sys.Call) *Prog {
|
||||
p := new(Prog)
|
||||
r := newRand(rs)
|
||||
s := newState(enabledCalls)
|
||||
for len(p.Calls) < ncalls {
|
||||
calls := r.generateCall(s)
|
||||
for _, c := range calls {
|
||||
s.analyze(c)
|
||||
p.Calls = append(p.Calls, c)
|
||||
}
|
||||
}
|
||||
if err := p.validate(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return p
|
||||
}
|
377
prog/mutation.go
Normal file
377
prog/mutation.go
Normal file
@ -0,0 +1,377 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package prog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/google/syzkaller/sys"
|
||||
)
|
||||
|
||||
func (p *Prog) Mutate(rs rand.Source, ncalls int, enabledCalls []*sys.Call) {
|
||||
r := newRand(rs)
|
||||
for stop := false; !stop; stop = r.bin() {
|
||||
r.choose(
|
||||
10, func() {
|
||||
// Insert a new call.
|
||||
if len(p.Calls) >= ncalls {
|
||||
return
|
||||
}
|
||||
idx := r.Intn(len(p.Calls) + 1)
|
||||
var c *Call
|
||||
if idx < len(p.Calls) {
|
||||
c = p.Calls[idx]
|
||||
}
|
||||
s := analyze(enabledCalls, p, c)
|
||||
calls := r.generateCall(s)
|
||||
p.insertBefore(c, calls)
|
||||
},
|
||||
10, func() {
|
||||
// Change args of a call.
|
||||
if len(p.Calls) == 0 {
|
||||
return
|
||||
}
|
||||
c := p.Calls[r.Intn(len(p.Calls))]
|
||||
if len(c.Args) == 0 {
|
||||
return
|
||||
}
|
||||
s := analyze(enabledCalls, p, c)
|
||||
for stop := false; !stop; stop = r.bin() {
|
||||
args, bases, parents := mutationArgs(c)
|
||||
idx := r.Intn(len(args))
|
||||
arg, base, parent := args[idx], bases[idx], parents[idx]
|
||||
var baseSize uintptr
|
||||
if base != nil {
|
||||
if base.Kind != ArgPointer || base.Res == nil {
|
||||
panic("bad base arg")
|
||||
}
|
||||
baseSize = base.Res.Size(base.Res.Type)
|
||||
}
|
||||
var size *Arg
|
||||
switch a := arg.Type.(type) {
|
||||
case sys.IntType, sys.FlagsType, sys.FileoffType, sys.ResourceType, sys.VmaType:
|
||||
arg1, size1, calls1 := r.generateArg(s, arg.Type, arg.Dir, nil)
|
||||
replaceArg(p, arg, arg1, calls1)
|
||||
size = size1
|
||||
case sys.BufferType:
|
||||
switch a.Kind {
|
||||
case sys.BufferBlob:
|
||||
var data []byte
|
||||
switch arg.Kind {
|
||||
case ArgData:
|
||||
data = append([]byte{}, arg.Data...)
|
||||
case ArgConst:
|
||||
// 0 is OK for optional args.
|
||||
if arg.Val != 0 {
|
||||
panic(fmt.Sprintf("BufferType has non-zero const value: %v", arg.Val))
|
||||
}
|
||||
default:
|
||||
panic(fmt.Sprintf("bad arg kind for BufferType: %v", arg.Kind))
|
||||
}
|
||||
arg.Data = mutateData(r, data)
|
||||
case sys.BufferString:
|
||||
if r.bin() {
|
||||
arg.Data = mutateData(r, append([]byte{}, arg.Data...))
|
||||
} else {
|
||||
arg.Data = r.randString(s)
|
||||
}
|
||||
case sys.BufferSockaddr:
|
||||
arg.Data = r.sockaddr(s)
|
||||
default:
|
||||
panic("unknown buffer kind")
|
||||
}
|
||||
size = constArg(uintptr(len(arg.Data)))
|
||||
case sys.FilenameType:
|
||||
filename := r.filename(s)
|
||||
arg.Data = []byte(filename)
|
||||
case sys.ArrayType:
|
||||
count := r.rand(6)
|
||||
if count > uintptr(len(arg.Inner)) {
|
||||
var calls []*Call
|
||||
for count > uintptr(len(arg.Inner)) {
|
||||
arg1, _, calls1 := r.generateArg(s, a.Type, arg.Dir, nil)
|
||||
arg.Inner = append(arg.Inner, arg1)
|
||||
for _, c1 := range calls1 {
|
||||
calls = append(calls, c1)
|
||||
s.analyze(c1)
|
||||
}
|
||||
}
|
||||
for _, c1 := range calls {
|
||||
assignTypeAndDir(c1)
|
||||
sanitizeCall(c1)
|
||||
}
|
||||
assignTypeAndDir(c)
|
||||
sanitizeCall(c)
|
||||
p.insertBefore(c, calls)
|
||||
} else if count < uintptr(len(arg.Inner)) {
|
||||
removed := arg.Inner[count:]
|
||||
arg.Inner = arg.Inner[:count]
|
||||
|
||||
foreachArgArray(&removed, nil, func(arg, _ *Arg, _ *[]*Arg) {
|
||||
if arg.Kind == ArgResult {
|
||||
if _, ok := arg.Res.Uses[arg]; !ok {
|
||||
panic("broken tree")
|
||||
}
|
||||
delete(arg.Res.Uses, arg)
|
||||
}
|
||||
})
|
||||
|
||||
for _, arg := range referencedArgs(removed, nil) {
|
||||
c1 := arg.Call
|
||||
s := analyze(enabledCalls, p, c1)
|
||||
arg1, _, calls1 := r.generateArg(s, arg.Type, arg.Dir, nil)
|
||||
replaceArg(p, arg, arg1, calls1)
|
||||
}
|
||||
}
|
||||
// TODO: swap elements of the array
|
||||
size = constArg(count)
|
||||
case sys.PtrType:
|
||||
// TODO: we don't know size for out args
|
||||
size := uintptr(1)
|
||||
if arg.Res != nil {
|
||||
size = arg.Res.Size(arg.Res.Type)
|
||||
}
|
||||
arg1, calls1 := r.addr(s, size, arg.Res)
|
||||
replaceArg(p, arg, arg1, calls1)
|
||||
case sys.StructType:
|
||||
switch a.Name() {
|
||||
case "timespec", "timeval":
|
||||
arg1, _, calls1 := r.generateArg(s, arg.Type, arg.Dir, nil)
|
||||
replaceArg(p, arg.Inner[0], arg1.Inner[0], calls1)
|
||||
replaceArg(p, arg.Inner[1], arg1.Inner[1], nil)
|
||||
default:
|
||||
panic("bad arg returned by mutationArgs: StructType")
|
||||
}
|
||||
case sys.LenType:
|
||||
panic("bad arg returned by mutationArgs: LenType")
|
||||
default:
|
||||
panic(fmt.Sprintf("bad arg returned by mutationArgs: %#v, type=%#v", *arg, arg.Type))
|
||||
}
|
||||
|
||||
// Update associated size argument if there is one.
|
||||
if size != nil {
|
||||
name := arg.Type.Name()
|
||||
if name == "" && base != nil {
|
||||
name = base.Type.Name()
|
||||
}
|
||||
for _, arg1 := range *parent {
|
||||
if sz, ok := arg1.Type.(sys.LenType); ok && sz.Buf == name {
|
||||
if arg1.Kind != ArgConst && arg1.Kind != ArgPageSize {
|
||||
panic(fmt.Sprintf("size arg is not const: %#v", *arg1))
|
||||
}
|
||||
arg1.Val = size.Val
|
||||
arg1.AddrPage = size.AddrPage
|
||||
arg1.AddrOffset = size.AddrOffset
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update base pointer if size has increased.
|
||||
if base != nil && baseSize < base.Res.Size(base.Res.Type) {
|
||||
arg1, calls1 := r.addr(s, base.Res.Size(base.Res.Type), base.Res)
|
||||
for _, c := range calls1 {
|
||||
assignTypeAndDir(c)
|
||||
sanitizeCall(c)
|
||||
}
|
||||
p.insertBefore(c, calls1)
|
||||
arg.AddrPage = arg1.AddrPage
|
||||
arg.AddrOffset = arg1.AddrOffset
|
||||
}
|
||||
}
|
||||
},
|
||||
1, func() {
|
||||
// Remove a random call.
|
||||
if len(p.Calls) == 0 {
|
||||
return
|
||||
}
|
||||
idx := r.Intn(len(p.Calls))
|
||||
c := p.Calls[idx]
|
||||
copy(p.Calls[idx:], p.Calls[idx+1:])
|
||||
p.Calls = p.Calls[:len(p.Calls)-1]
|
||||
|
||||
foreachArg(c, func(arg, _ *Arg, _ *[]*Arg) {
|
||||
if arg.Kind == ArgResult {
|
||||
if _, ok := arg.Res.Uses[arg]; !ok {
|
||||
panic("broken tree")
|
||||
}
|
||||
delete(arg.Res.Uses, arg)
|
||||
}
|
||||
})
|
||||
|
||||
for _, arg := range referencedArgs(c.Args, c.Ret) {
|
||||
c1 := arg.Call
|
||||
s := analyze(enabledCalls, p, c1)
|
||||
arg1, _, calls1 := r.generateArg(s, arg.Type, arg.Dir, nil)
|
||||
replaceArg(p, arg, arg1, calls1)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
for _, c := range p.Calls {
|
||||
assignTypeAndDir(c)
|
||||
sanitizeCall(c)
|
||||
}
|
||||
if err := p.validate(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Minimize minimizes program p into an equivalent program using the equivalence
|
||||
// predicate pred. It iteratively generates simpler programs and asks pred
|
||||
// whether it is equal to the orginal program or not. If it is equivalent then
|
||||
// the simplification attempt is committed and the process continues.
|
||||
func Minimize(p0 *Prog, callIndex0 int, pred func(*Prog, int) bool) (*Prog, int) {
|
||||
if callIndex0 < 0 || callIndex0 >= len(p0.Calls) {
|
||||
panic("bad call index")
|
||||
}
|
||||
name0 := p0.Calls[callIndex0].Meta.Name
|
||||
// Try to remove all calls except the last one one-by-one.
|
||||
for i := len(p0.Calls) - 1; i >= 0; i-- {
|
||||
if i == callIndex0 {
|
||||
continue
|
||||
}
|
||||
callIndex := callIndex0
|
||||
if i < callIndex {
|
||||
callIndex--
|
||||
}
|
||||
c := p0.Calls[i]
|
||||
p := p0.Clone()
|
||||
c = p.Calls[i]
|
||||
copy(p.Calls[i:], p.Calls[i+1:])
|
||||
p.Calls = p.Calls[:len(p.Calls)-1]
|
||||
for _, arg := range referencedArgs(c.Args, c.Ret) {
|
||||
arg1 := constArg(arg.Type.Default())
|
||||
replaceArg(p, arg, arg1, nil)
|
||||
}
|
||||
foreachArg(c, func(arg, _ *Arg, _ *[]*Arg) {
|
||||
if arg.Kind == ArgResult {
|
||||
delete(arg.Res.Uses, arg)
|
||||
}
|
||||
})
|
||||
if !pred(p, callIndex) {
|
||||
continue
|
||||
}
|
||||
p0 = p
|
||||
callIndex0 = callIndex
|
||||
}
|
||||
// TODO: simplify individual arguments:
|
||||
// - replace constants with 0
|
||||
// - reset bits in constants
|
||||
// - remove offsets from addresses
|
||||
// - replace file descriptors with -1
|
||||
// etc
|
||||
if callIndex0 < 0 || callIndex0 >= len(p0.Calls) || name0 != p0.Calls[callIndex0].Meta.Name {
|
||||
panic(fmt.Sprintf("bad call index after minimizatoin: ncalls=%v index=%v call=%v/%v",
|
||||
len(p0.Calls), callIndex0, name0, p0.Calls[callIndex0].Meta.Name))
|
||||
}
|
||||
return p0, callIndex0
|
||||
}
|
||||
|
||||
func (p *Prog) TrimAfter(idx int) {
|
||||
if idx < 0 || idx >= len(p.Calls) {
|
||||
panic("trimming non-existing call")
|
||||
}
|
||||
for i := len(p.Calls) - 1; i > idx; i-- {
|
||||
c := p.Calls[i]
|
||||
foreachArg(c, func(arg, _ *Arg, _ *[]*Arg) {
|
||||
if arg.Kind == ArgResult {
|
||||
delete(arg.Res.Uses, arg)
|
||||
}
|
||||
})
|
||||
}
|
||||
p.Calls = p.Calls[:idx+1]
|
||||
}
|
||||
|
||||
func mutationArgs(c *Call) (args, bases []*Arg, parents []*[]*Arg) {
|
||||
foreachArg(c, func(arg, base *Arg, parent *[]*Arg) {
|
||||
switch arg.Type.(type) {
|
||||
case sys.StructType:
|
||||
switch arg.Type.Name() {
|
||||
default:
|
||||
// For structs only individual fields are updated.
|
||||
return
|
||||
case "timespec", "timeval":
|
||||
// These special structs are mutated as a whole.
|
||||
}
|
||||
case sys.LenType:
|
||||
// Size is updated when the size-of arg change.
|
||||
return
|
||||
}
|
||||
if arg.Dir == DirOut {
|
||||
return
|
||||
}
|
||||
if base != nil {
|
||||
if _, ok := base.Type.(sys.StructType); ok && (base.Type.Name() == "timespec" || base.Type.Name() == "timeval") {
|
||||
// These special structs are mutated as a whole.
|
||||
return
|
||||
}
|
||||
}
|
||||
args = append(args, arg)
|
||||
bases = append(bases, base)
|
||||
parents = append(parents, parent)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func mutateData(r *randGen, data []byte) []byte {
|
||||
for stop := false; !stop; stop = r.bin() {
|
||||
r.choose(
|
||||
1, func() {
|
||||
data = append(data, byte(r.rand(256)))
|
||||
},
|
||||
1, func() {
|
||||
if len(data) == 0 {
|
||||
return
|
||||
}
|
||||
data[r.Intn(len(data))] = byte(r.rand(256))
|
||||
},
|
||||
1, func() {
|
||||
if len(data) == 0 {
|
||||
return
|
||||
}
|
||||
byt := r.Intn(len(data))
|
||||
bit := r.Intn(8)
|
||||
data[byt] ^= 1 << uint(bit)
|
||||
},
|
||||
1, func() {
|
||||
if len(data) == 0 {
|
||||
return
|
||||
}
|
||||
i := r.Intn(len(data))
|
||||
copy(data[i:], data[i+1:])
|
||||
data = data[:len(data)-1]
|
||||
},
|
||||
)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func replaceArg(p *Prog, arg, arg1 *Arg, calls []*Call) {
|
||||
if arg.Kind != ArgConst && arg.Kind != ArgResult && arg.Kind != ArgPointer {
|
||||
panic(fmt.Sprintf("replaceArg: bad arg kind %v", arg.Kind))
|
||||
}
|
||||
if arg1.Kind != ArgConst && arg1.Kind != ArgResult && arg1.Kind != ArgPointer {
|
||||
panic(fmt.Sprintf("replaceArg: bad arg1 kind %v", arg1.Kind))
|
||||
}
|
||||
if arg.Kind == ArgResult {
|
||||
delete(arg.Res.Uses, arg)
|
||||
}
|
||||
for _, c := range calls {
|
||||
assignTypeAndDir(c)
|
||||
sanitizeCall(c)
|
||||
}
|
||||
c := arg.Call
|
||||
p.insertBefore(c, calls)
|
||||
// Somewhat hacky, but safe and preserves references to arg.
|
||||
uses := arg.Uses
|
||||
*arg = *arg1
|
||||
arg.Uses = uses
|
||||
if arg.Kind == ArgResult {
|
||||
delete(arg.Res.Uses, arg1)
|
||||
arg.Res.Uses[arg] = true
|
||||
}
|
||||
assignTypeAndDir(c)
|
||||
sanitizeCall(c)
|
||||
}
|
268
prog/mutation_test.go
Normal file
268
prog/mutation_test.go
Normal file
@ -0,0 +1,268 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package prog
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestClone(t *testing.T) {
|
||||
rs, iters := initTest(t)
|
||||
for i := 0; i < iters; i++ {
|
||||
p := Generate(rs, 10, nil)
|
||||
p1 := p.Clone()
|
||||
data := p.Serialize()
|
||||
data1 := p1.Serialize()
|
||||
if !bytes.Equal(data, data1) {
|
||||
t.Fatalf("program changed after clone\noriginal:\n%s\n\nnew:\n%s\n", data, data1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMutate(t *testing.T) {
|
||||
rs, iters := initTest(t)
|
||||
next:
|
||||
for i := 0; i < iters; i++ {
|
||||
p := Generate(rs, 10, nil)
|
||||
data0 := p.Serialize()
|
||||
p1 := p.Clone()
|
||||
// There is a chance that mutation will produce the same program.
|
||||
// So we check that at least 1 out of 10 mutations actually change the program.
|
||||
for try := 0; try < 10; try++ {
|
||||
p1.Mutate(rs, 10, nil)
|
||||
data := p.Serialize()
|
||||
if !bytes.Equal(data0, data) {
|
||||
t.Fatalf("program changed after clone/mutate\noriginal:\n%s\n\nnew:\n%s\n", data0, data)
|
||||
}
|
||||
data1 := p1.Serialize()
|
||||
if !bytes.Equal(data, data1) {
|
||||
continue next
|
||||
}
|
||||
}
|
||||
t.Fatalf("mutation does not change program")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMutateTable(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping in short mode")
|
||||
}
|
||||
tests := [][2]string{
|
||||
// Insert calls.
|
||||
{
|
||||
"mmap(&(0x7f0000000000)=nil, (0x1000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
|
||||
"pipe2(&(0x7f0000000000)={0x0, 0x0}, 0x0)\n",
|
||||
|
||||
"mmap(&(0x7f0000000000)=nil, (0x1000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
|
||||
"sched_yield()\n" +
|
||||
"pipe2(&(0x7f0000000000)={0x0, 0x0}, 0x0)\n",
|
||||
},
|
||||
// Remove calls and update args.
|
||||
{
|
||||
"r0 = open(&(0x7f0000001000)=\"2e2f66696c653000\", 0x22c0, 0x1)\n" +
|
||||
"sched_yield()\n" +
|
||||
"read(r0, &(0x7f0000000000)=0x0, 0x1)\n" +
|
||||
"sched_yield()\n",
|
||||
|
||||
"sched_yield()\n" +
|
||||
"read(0xffffffffffffffff, &(0x7f0000000000)=0x0, 0x1)\n" +
|
||||
"sched_yield()\n",
|
||||
},
|
||||
// Mutate flags.
|
||||
{
|
||||
"r0 = open(&(0x7f0000001000)=\"2e2f66696c653000\", 0x22c0, 0x1)\n" +
|
||||
"sched_yield()\n" +
|
||||
"read(r0, &(0x7f0000000000)=0x0, 0x1)\n" +
|
||||
"sched_yield()\n",
|
||||
|
||||
"r0 = open(&(0x7f0000001000)=\"2e2f66696c653000\", 0x22c0, 0x2)\n" +
|
||||
"sched_yield()\n" +
|
||||
"read(r0, &(0x7f0000000000)=0x0, 0x1)\n" +
|
||||
"sched_yield()\n",
|
||||
},
|
||||
// Mutate data (delete byte and update size).
|
||||
{
|
||||
"r0 = open(&(0x7f0000001000)=\"2e2f66696c653000\", 0x22c0, 0x1)\n" +
|
||||
"write(r0, &(0x7f0000000000)=\"11223344\", 0x4)\n",
|
||||
|
||||
"r0 = open(&(0x7f0000001000)=\"2e2f66696c653000\", 0x22c0, 0x1)\n" +
|
||||
"write(r0, &(0x7f0000000000)=\"112244\", 0x3)\n",
|
||||
},
|
||||
// Mutate data (insert byte and update size).
|
||||
{
|
||||
"r0 = open(&(0x7f0000001000)=\"2e2f66696c653000\", 0x22c0, 0x1)\n" +
|
||||
"write(r0, &(0x7f0000000000)=\"1122\", 0x2)\n",
|
||||
|
||||
"r0 = open(&(0x7f0000001000)=\"2e2f66696c653000\", 0x22c0, 0x1)\n" +
|
||||
"write(r0, &(0x7f0000000000)=\"112255\", 0x3)\n",
|
||||
},
|
||||
// Mutate data (change byte).
|
||||
{
|
||||
"r0 = open(&(0x7f0000001000)=\"2e2f66696c653000\", 0x22c0, 0x1)\n" +
|
||||
"write(r0, &(0x7f0000000000)=\"1122\", 0x2)\n",
|
||||
|
||||
"r0 = open(&(0x7f0000001000)=\"2e2f66696c653000\", 0x22c0, 0x1)\n" +
|
||||
"write(r0, &(0x7f0000000000)=\"1155\", 0x2)\n",
|
||||
},
|
||||
// Change filename.
|
||||
{
|
||||
"open(&(0x7f0000001000)=\"2e2f66696c653000\", 0x22c0, 0x1)\n" +
|
||||
"r0 = open(&(0x7f0000001000)=\"2e2f66696c653000\", 0x22c0, 0x1)\n" +
|
||||
"write(r0, &(0x7f0000000000)=\"\", 0x0)\n",
|
||||
|
||||
"open(&(0x7f0000001000)=\"2e2f66696c653000\", 0x22c0, 0x1)\n" +
|
||||
"r0 = open(&(0x7f0000001000)=\"2e2f66696c653100\", 0x22c0, 0x1)\n" +
|
||||
"write(r0, &(0x7f0000000000)=\"\", 0x0)\n",
|
||||
},
|
||||
// Extend an array.
|
||||
{
|
||||
"r0 = open(&(0x7f0000001000)=\"2e2f66696c653000\", 0x22c0, 0x1)\n" +
|
||||
"readv(r0, &(0x7f0000000000)={{&(0x7f0000001000)=nil, 0x1}, {&(0x7f0000002000)=nil, 0x2}}, 0x2)\n",
|
||||
|
||||
"mmap(&(0x7f0000000000)=nil, (0x1000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
|
||||
"r0 = open(&(0x7f0000001000)=\"2e2f66696c653000\", 0x22c0, 0x1)\n" +
|
||||
"readv(r0, &(0x7f0000000000)={{&(0x7f0000001000)=nil, 0x1}, {&(0x7f0000002000)=nil, 0x2}, {&(0x7f0000000000)=nil, 0x3}}, 0x3)\n",
|
||||
},
|
||||
}
|
||||
rs, _ := initTest(t)
|
||||
nextTest:
|
||||
for ti, test := range tests {
|
||||
p, err := Deserialize([]byte(test[0]))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to deserialize original program: %v", err)
|
||||
}
|
||||
for i := 0; i < 1e6; i++ {
|
||||
p1 := p.Clone()
|
||||
p1.Mutate(rs, 30, nil)
|
||||
data1 := p1.Serialize()
|
||||
if string(data1) == test[1] {
|
||||
t.Logf("test #%v: success on iter %v", ti, i)
|
||||
continue nextTest
|
||||
}
|
||||
_ = fmt.Printf
|
||||
}
|
||||
t.Fatalf("failed to achieve mutation goal\noriginal:\n%s\n\ngoal:\n%s\n", test[0], test[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestMinimize(t *testing.T) {
|
||||
tests := []struct {
|
||||
orig string
|
||||
callIndex int
|
||||
pred func(*Prog, int) bool
|
||||
result string
|
||||
}{
|
||||
// Predicate always returns false, so must get the same program.
|
||||
{
|
||||
"mmap(&(0x7f0000000000)=nil, (0x1000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
|
||||
"sched_yield()\n" +
|
||||
"pipe2(&(0x7f0000000000)={0x0, 0x0}, 0x0)\n",
|
||||
2,
|
||||
func(p *Prog, callIndex int) bool {
|
||||
if len(p.Calls) == 0 {
|
||||
t.Fatalf("got an empty program")
|
||||
}
|
||||
if p.Calls[len(p.Calls)-1].Meta.Name != "pipe2" {
|
||||
t.Fatalf("last call is removed")
|
||||
}
|
||||
return false
|
||||
},
|
||||
"mmap(&(0x7f0000000000)=nil, (0x1000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
|
||||
"sched_yield()\n" +
|
||||
"pipe2(&(0x7f0000000000)={0x0, 0x0}, 0x0)\n",
|
||||
},
|
||||
// Remove a call.
|
||||
{
|
||||
"mmap(&(0x7f0000000000)=nil, (0x1000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
|
||||
"sched_yield()\n" +
|
||||
"pipe2(&(0x7f0000000000)={0x0, 0x0}, 0x0)\n",
|
||||
2,
|
||||
func(p *Prog, callIndex int) bool {
|
||||
// Aim at removal of sched_yield.
|
||||
return len(p.Calls) == 2 && p.Calls[0].Meta.Name == "mmap" && p.Calls[1].Meta.Name == "pipe2"
|
||||
},
|
||||
"mmap(&(0x7f0000000000)=nil, (0x1000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
|
||||
"pipe2(&(0x7f0000000000)={0x0, 0x0}, 0x0)\n",
|
||||
},
|
||||
// Remove two dependent calls.
|
||||
{
|
||||
"mmap(&(0x7f0000000000)=nil, (0x1000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
|
||||
"pipe2(&(0x7f0000000000)={0x0, 0x0}, 0x0)\n" +
|
||||
"sched_yield()\n",
|
||||
2,
|
||||
func(p *Prog, callIndex int) bool {
|
||||
// Aim at removal of pipe2 and then mmap.
|
||||
if len(p.Calls) == 2 && p.Calls[0].Meta.Name == "mmap" && p.Calls[1].Meta.Name == "sched_yield" {
|
||||
return true
|
||||
}
|
||||
if len(p.Calls) == 1 && p.Calls[0].Meta.Name == "sched_yield" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
"sched_yield()\n",
|
||||
},
|
||||
// Remove a call and replace results.
|
||||
{
|
||||
"mmap(&(0x7f0000000000)=nil, (0x1000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
|
||||
"pipe2(&(0x7f0000000000)={[r0=]0x0, 0x0}, 0x0)\n" +
|
||||
"write(r0, &(0x7f0000000000)=\"1155\", 0x2)\n" +
|
||||
"sched_yield()\n",
|
||||
3,
|
||||
func(p *Prog, callIndex int) bool {
|
||||
return p.String() == "mmap-write-sched_yield"
|
||||
},
|
||||
"mmap(&(0x7f0000000000)=nil, (0x1000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
|
||||
"write(0xffffffffffffffff, &(0x7f0000000000)=\"1155\", 0x2)\n" +
|
||||
"sched_yield()\n",
|
||||
},
|
||||
// Remove a call and replace results.
|
||||
{
|
||||
"mmap(&(0x7f0000000000)=nil, (0x1000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
|
||||
"r0=open(&(0x7f0000000000)=\"1155\", 0x0, 0x0)\n" +
|
||||
"write(r0, &(0x7f0000000000)=\"1155\", 0x2)\n" +
|
||||
"sched_yield()\n",
|
||||
3,
|
||||
func(p *Prog, callIndex int) bool {
|
||||
return p.String() == "mmap-write-sched_yield"
|
||||
},
|
||||
"mmap(&(0x7f0000000000)=nil, (0x1000), 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
|
||||
"write(0xffffffffffffffff, &(0x7f0000000000)=\"1155\", 0x2)\n" +
|
||||
"sched_yield()\n",
|
||||
},
|
||||
}
|
||||
for ti, test := range tests {
|
||||
p, err := Deserialize([]byte(test.orig))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to deserialize original program: %v", err)
|
||||
}
|
||||
p1, _ := Minimize(p, test.callIndex, test.pred)
|
||||
res := p1.Serialize()
|
||||
if string(res) != test.result {
|
||||
t.Fatalf("minimization produced wrong result #%v\norig:\n%v\nexpect:\n%v\ngot:\n%v\n",
|
||||
ti, test.orig, test.result, string(res))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMinimizeRandom(t *testing.T) {
|
||||
rs, iters := initTest(t)
|
||||
for i := 0; i < iters; i++ {
|
||||
p := Generate(rs, 10, nil)
|
||||
Minimize(p, len(p.Calls)-1, func(p1 *Prog, callIndex int) bool {
|
||||
if err := p1.validate(); err != nil {
|
||||
t.Fatalf("invalid program: %v", err)
|
||||
}
|
||||
return false
|
||||
})
|
||||
Minimize(p, len(p.Calls)-1, func(p1 *Prog, callIndex int) bool {
|
||||
if err := p1.validate(); err != nil {
|
||||
t.Fatalf("invalid program: %v", err)
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
}
|
143
prog/prog.go
Normal file
143
prog/prog.go
Normal file
@ -0,0 +1,143 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package prog
|
||||
|
||||
import (
|
||||
"github.com/google/syzkaller/sys"
|
||||
)
|
||||
|
||||
type Prog struct {
|
||||
Calls []*Call
|
||||
}
|
||||
|
||||
type Call struct {
|
||||
Meta *sys.Call
|
||||
Args []*Arg
|
||||
Ret *Arg
|
||||
}
|
||||
|
||||
type Arg struct {
|
||||
Call *Call
|
||||
Type sys.Type
|
||||
Kind ArgKind
|
||||
Dir ArgDir
|
||||
Val uintptr // value of ArgConst
|
||||
AddrPage uintptr // page index for ArgPointer address, page count for ArgPageSize
|
||||
AddrOffset int // page offset for ArgPointer address
|
||||
Data []byte // data of ArgData
|
||||
Inner []*Arg // subargs of ArgGroup
|
||||
Res *Arg // target of ArgResult, pointee for ArgPointer
|
||||
Uses map[*Arg]bool // this arg is used by those ArgResult args
|
||||
OpDiv uintptr // divide result for ArgResult (executed before OpAdd)
|
||||
OpAdd uintptr // add to result for ArgResult
|
||||
}
|
||||
|
||||
type ArgKind int
|
||||
|
||||
const (
|
||||
ArgConst ArgKind = iota
|
||||
ArgResult
|
||||
ArgPointer // even if these are always constant (for reproducibility), we use a separate type because they are represented in an abstract (base+page+offset) form
|
||||
ArgPageSize // same as ArgPointer but base is not added, so it represents "lengths" in pages
|
||||
ArgData
|
||||
ArgGroup // logical group of args (struct or array)
|
||||
ArgReturn // fake value denoting syscall return value
|
||||
)
|
||||
|
||||
type ArgDir sys.Dir
|
||||
|
||||
const (
|
||||
DirIn = ArgDir(sys.DirIn)
|
||||
DirOut = ArgDir(sys.DirOut)
|
||||
DirInOut = ArgDir(sys.DirInOut)
|
||||
)
|
||||
|
||||
func (a *Arg) Size(typ sys.Type) uintptr {
|
||||
switch typ1 := typ.(type) {
|
||||
case sys.IntType:
|
||||
return typ1.TypeSize
|
||||
case sys.LenType:
|
||||
return typ1.TypeSize
|
||||
case sys.FlagsType:
|
||||
return typ1.TypeSize
|
||||
case sys.FileoffType:
|
||||
return typ1.TypeSize
|
||||
case sys.ResourceType:
|
||||
return typ1.Size()
|
||||
case sys.VmaType:
|
||||
return ptrSize
|
||||
case sys.FilenameType:
|
||||
return uintptr(len(a.Data))
|
||||
case sys.PtrType:
|
||||
return ptrSize
|
||||
case sys.StructType:
|
||||
var size uintptr
|
||||
for i, f := range typ1.Fields {
|
||||
size += a.Inner[i].Size(f)
|
||||
}
|
||||
return size
|
||||
case sys.ArrayType:
|
||||
if len(a.Inner) == 0 {
|
||||
return 0
|
||||
}
|
||||
return uintptr(len(a.Inner)) * a.Inner[0].Size(typ1.Type)
|
||||
case sys.BufferType:
|
||||
return uintptr(len(a.Data))
|
||||
default:
|
||||
panic("unknown arg type")
|
||||
}
|
||||
}
|
||||
|
||||
func constArg(v uintptr) *Arg {
|
||||
return &Arg{Kind: ArgConst, Val: v}
|
||||
}
|
||||
|
||||
func resultArg(r *Arg) *Arg {
|
||||
arg := &Arg{Kind: ArgResult, Res: r}
|
||||
if r.Uses == nil {
|
||||
r.Uses = make(map[*Arg]bool)
|
||||
}
|
||||
if r.Uses[arg] {
|
||||
panic("already used")
|
||||
}
|
||||
r.Uses[arg] = true
|
||||
return arg
|
||||
}
|
||||
|
||||
func dataArg(data []byte) *Arg {
|
||||
return &Arg{Kind: ArgData, Data: append([]byte{}, data...)}
|
||||
}
|
||||
|
||||
func pointerArg(page uintptr, off int, obj *Arg) *Arg {
|
||||
return &Arg{Kind: ArgPointer, AddrPage: page, AddrOffset: off, Res: obj}
|
||||
}
|
||||
|
||||
func pageSizeArg(npages uintptr, off int) *Arg {
|
||||
return &Arg{Kind: ArgPageSize, AddrPage: npages, AddrOffset: off}
|
||||
}
|
||||
|
||||
func groupArg(inner []*Arg) *Arg {
|
||||
return &Arg{Kind: ArgGroup, Inner: inner}
|
||||
}
|
||||
|
||||
func returnArg() *Arg {
|
||||
return &Arg{Kind: ArgReturn, Dir: DirOut}
|
||||
}
|
||||
|
||||
func (p *Prog) insertBefore(c *Call, calls []*Call) {
|
||||
idx := 0
|
||||
for ; idx < len(p.Calls); idx++ {
|
||||
if p.Calls[idx] == c {
|
||||
break
|
||||
}
|
||||
}
|
||||
var newCalls []*Call
|
||||
newCalls = append(newCalls, p.Calls[:idx]...)
|
||||
newCalls = append(newCalls, calls...)
|
||||
if idx < len(p.Calls) {
|
||||
newCalls = append(newCalls, p.Calls[idx])
|
||||
newCalls = append(newCalls, p.Calls[idx+1:]...)
|
||||
}
|
||||
p.Calls = newCalls
|
||||
}
|
77
prog/prog_test.go
Normal file
77
prog/prog_test.go
Normal file
@ -0,0 +1,77 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package prog
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func initTest(t *testing.T) (rand.Source, int) {
|
||||
iters := 10000
|
||||
if testing.Short() {
|
||||
iters = 100
|
||||
}
|
||||
seed := int64(time.Now().UnixNano())
|
||||
rs := rand.NewSource(seed)
|
||||
t.Logf("seed=%v", seed)
|
||||
return rs, iters
|
||||
}
|
||||
|
||||
func TestGeneration(t *testing.T) {
|
||||
rs, iters := initTest(t)
|
||||
for i := 0; i < iters; i++ {
|
||||
p := Generate(rs, 20, nil)
|
||||
hasGettime, hasSelect := false, false
|
||||
for _, c := range p.Calls {
|
||||
if c.Meta.Name == "clock_gettime" {
|
||||
hasGettime = true
|
||||
}
|
||||
if c.Meta.Name == "select" {
|
||||
hasSelect = true
|
||||
}
|
||||
}
|
||||
if hasGettime && hasSelect {
|
||||
fmt.Printf("%s\n\n", p.WriteCSource())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSerialize(t *testing.T) {
|
||||
rs, iters := initTest(t)
|
||||
for i := 0; i < iters; i++ {
|
||||
p := Generate(rs, 10, nil)
|
||||
data := p.Serialize()
|
||||
p1, err := Deserialize(data)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to deserialize program: %v\n%s", err, data)
|
||||
}
|
||||
data1 := p1.Serialize()
|
||||
if len(p.Calls) != len(p1.Calls) {
|
||||
t.Fatalf("different number of calls")
|
||||
}
|
||||
if !bytes.Equal(data, data1) {
|
||||
t.Fatalf("program changed after serialize/deserialize\noriginal:\n%s\n\nnew:\n%s\n", data, data1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSerializeForExec(t *testing.T) {
|
||||
rs, iters := initTest(t)
|
||||
for i := 0; i < iters; i++ {
|
||||
p := Generate(rs, 10, nil)
|
||||
p.SerializeForExec()
|
||||
}
|
||||
}
|
||||
|
||||
func TestSerializeC(t *testing.T) {
|
||||
rs, iters := initTest(t)
|
||||
for i := 0; i < iters; i++ {
|
||||
p := Generate(rs, 10, nil)
|
||||
p.WriteCSource()
|
||||
}
|
||||
}
|
638
prog/rand.go
Normal file
638
prog/rand.go
Normal file
@ -0,0 +1,638 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package prog
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/google/syzkaller/sys"
|
||||
)
|
||||
|
||||
type randGen struct {
|
||||
*rand.Rand
|
||||
createDepth int
|
||||
}
|
||||
|
||||
func newRand(rs rand.Source) *randGen {
|
||||
return &randGen{rand.New(rs), 0}
|
||||
}
|
||||
|
||||
func (r *randGen) rand(n int) uintptr {
|
||||
return uintptr(r.Intn(n))
|
||||
}
|
||||
|
||||
func (r *randGen) bin() bool {
|
||||
return r.Intn(2) == 0
|
||||
}
|
||||
|
||||
func (r *randGen) oneOf(n int) bool {
|
||||
return r.Intn(n) == 0
|
||||
}
|
||||
|
||||
func (r *randGen) rand64() uintptr {
|
||||
v := uintptr(r.Int63())
|
||||
if r.bin() {
|
||||
v |= 1 << 63
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (r *randGen) randInt() uintptr {
|
||||
v := r.rand64()
|
||||
r.choose(
|
||||
100, func() { v %= 10 },
|
||||
10, func() { v %= 256 },
|
||||
10, func() { v %= 4 << 10 },
|
||||
10, func() { v %= 64 << 10 },
|
||||
1, func() { v %= 1 << 31 },
|
||||
1, func() {},
|
||||
)
|
||||
r.choose(
|
||||
10, func() {},
|
||||
1, func() { v = uintptr(-int(v)) },
|
||||
)
|
||||
return v
|
||||
}
|
||||
|
||||
func (r *randGen) randBufLen() (n uintptr) {
|
||||
r.choose(
|
||||
1, func() { n = 0 },
|
||||
50, func() { n = r.rand(256) },
|
||||
5, func() { n = 4 << 10 },
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
func (r *randGen) randPageCount() (n uintptr) {
|
||||
r.choose(
|
||||
100, func() { n = r.rand(4) + 1 },
|
||||
5, func() { n = r.rand(20) + 1 },
|
||||
1, func() { n = (r.rand(3) + 1) * 1024 },
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
func (r *randGen) flags(vv []uintptr) uintptr {
|
||||
var v uintptr
|
||||
r.choose(
|
||||
10, func() { v = 0 },
|
||||
10, func() { v = vv[r.rand(len(vv))] },
|
||||
90, func() {
|
||||
for stop := false; !stop; stop = r.bin() {
|
||||
v |= vv[r.rand(len(vv))]
|
||||
}
|
||||
},
|
||||
1, func() { v = r.rand64() },
|
||||
)
|
||||
return v
|
||||
}
|
||||
|
||||
func (r *randGen) filename(s *state) string {
|
||||
// TODO: support procfs and sysfs
|
||||
dir := "."
|
||||
if r.oneOf(5) && len(s.files) != 0 {
|
||||
files := make([]string, 0, len(s.files))
|
||||
for f := range s.files {
|
||||
files = append(files, f)
|
||||
}
|
||||
dir = files[r.Intn(len(files))]
|
||||
if len(dir) > 0 && dir[len(dir)-1] == 0 {
|
||||
dir = dir[:len(dir)-1]
|
||||
}
|
||||
}
|
||||
if len(s.files) == 0 || r.oneOf(10) {
|
||||
// Generate a new name.
|
||||
for i := 0; ; i++ {
|
||||
f := fmt.Sprintf("%v/file%v\x00", dir, i)
|
||||
if !s.files[f] {
|
||||
return f
|
||||
}
|
||||
}
|
||||
}
|
||||
files := make([]string, 0, len(s.files))
|
||||
for f := range s.files {
|
||||
files = append(files, f)
|
||||
}
|
||||
return files[r.Intn(len(files))]
|
||||
}
|
||||
|
||||
var sockFamilies = []uint16{AF_LOCAL, AF_INET, AF_INET6, AF_IPX, AF_NETLINK, AF_X25, AF_AX25, AF_ATMPVC, AF_APPLETALK, AF_PACKET}
|
||||
|
||||
func (r *randGen) sockaddr(s *state) []byte {
|
||||
fa := sockFamilies[r.Intn(len(sockFamilies))]
|
||||
port := 13269 + uint16(r.Intn(20))
|
||||
buf := new(bytes.Buffer)
|
||||
binary.Write(buf, binary.LittleEndian, fa) // this is actually host byte order
|
||||
switch fa {
|
||||
case AF_LOCAL:
|
||||
buf.WriteString(r.filename(s))
|
||||
case AF_INET:
|
||||
binary.Write(buf, binary.BigEndian, port)
|
||||
binary.Write(buf, binary.BigEndian, uint32(127<<24+0<<16+0<<8+1))
|
||||
case AF_INET6:
|
||||
binary.Write(buf, binary.BigEndian, port)
|
||||
binary.Write(buf, binary.BigEndian, uint32(r.Int63())) // flow info
|
||||
binary.Write(buf, binary.BigEndian, uint64(0)) // addr: loopback
|
||||
binary.Write(buf, binary.BigEndian, uint64(1)) // addr: loopback
|
||||
binary.Write(buf, binary.BigEndian, uint32(r.Int63())) // scope id
|
||||
case AF_IPX:
|
||||
case AF_NETLINK:
|
||||
case AF_X25:
|
||||
case AF_AX25:
|
||||
case AF_ATMPVC:
|
||||
case AF_APPLETALK:
|
||||
case AF_PACKET:
|
||||
binary.Write(buf, binary.BigEndian, uint16(0)) // Physical-layer protocol
|
||||
binary.Write(buf, binary.BigEndian, uint32(0)) // Interface number
|
||||
binary.Write(buf, binary.BigEndian, uint16(0)) // ARP hardware type
|
||||
binary.Write(buf, binary.BigEndian, uint8(0)) // Packet type
|
||||
binary.Write(buf, binary.BigEndian, uint8(0)) // Length of address
|
||||
binary.Write(buf, binary.BigEndian, uint64(0)) // Physical-layer address
|
||||
default:
|
||||
panic("unknown socket domain")
|
||||
}
|
||||
if r.oneOf(2) {
|
||||
buf.Write(make([]byte, 128-len(buf.Bytes())))
|
||||
}
|
||||
data := buf.Bytes()
|
||||
if r.oneOf(100) {
|
||||
data = data[:r.Intn(len(data))]
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func (r *randGen) randString(s *state) []byte {
|
||||
if len(s.strings) != 0 && r.bin() {
|
||||
// Return an existing string.
|
||||
strings := make([]string, 0, len(s.strings))
|
||||
for s := range s.strings {
|
||||
strings = append(strings, s)
|
||||
}
|
||||
return []byte(strings[r.Intn(len(strings))])
|
||||
}
|
||||
dict := []string{"user", "keyring", "trusted", "system", "security", "selinux",
|
||||
"posix_acl_access", "mime_type", "md5sum", "nodev", "self", "sysfs", "rootfs",
|
||||
"ramfs", "bdev", "proc", "cgroup", "cpuset", "tmpfs", "devtmpfs", "debugfs",
|
||||
"securityfs", "sockfs", "pipefs", "anon_inodefs", "devpts", "ext3", "ext2",
|
||||
"ext4", "hugetlbfs", "vfat", "ecryptfs", "fuseblk", "fuse", "fusectl", "pstore",
|
||||
"mqueue", "rpc_pipefs", "nfs", "nfs4", "nfsd", "binfmt_misc", "autofs", "xfs",
|
||||
"jfs", "msdos", "ntfs", "minix", "hfs", "hfsplus", "qnx4", "ufs", "btrfs"}
|
||||
punct := []byte{'!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '+', '\\',
|
||||
'/', ':', '.', ',', '-', '\'', '[', ']', '{', '}'}
|
||||
buf := new(bytes.Buffer)
|
||||
for !r.oneOf(4) {
|
||||
r.choose(
|
||||
10, func() { buf.WriteString(dict[r.Intn(len(dict))]) },
|
||||
10, func() { buf.Write([]byte{punct[r.Intn(len(punct))]}) },
|
||||
1, func() { buf.Write([]byte{byte(r.Intn(256))}) },
|
||||
)
|
||||
}
|
||||
if !r.oneOf(100) {
|
||||
buf.Write([]byte{0})
|
||||
}
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func (r *randGen) timespec(s *state, usec bool) (arg *Arg, calls []*Call) {
|
||||
// We need to generate timespec/timeval that are either (1) definitely in the past,
|
||||
// or (2) definitely in unreachable fututre, or (3) few ms ahead of now.
|
||||
// Note timespec/timeval can be absolute or relative to now.
|
||||
r.choose(
|
||||
1, func() {
|
||||
// now for relative, past for absolute
|
||||
arg = groupArg([]*Arg{constArg(0), constArg(0)})
|
||||
},
|
||||
1, func() {
|
||||
// few ms ahead for relative, past for absolute
|
||||
nsec := uintptr(10 * 1e6)
|
||||
if usec {
|
||||
nsec /= 1e3
|
||||
}
|
||||
arg = groupArg([]*Arg{constArg(0), constArg(nsec)})
|
||||
},
|
||||
1, func() {
|
||||
// unreachable fututre for both relative and absolute
|
||||
arg = groupArg([]*Arg{constArg(2e9), constArg(0)})
|
||||
},
|
||||
1, func() {
|
||||
// few ms ahead for absolute
|
||||
tp := groupArg([]*Arg{constArg(0), constArg(0)})
|
||||
var tpaddr *Arg
|
||||
tpaddr, calls = r.addr(s, 2*ptrSize, tp)
|
||||
gettime := &Call{
|
||||
Meta: sys.CallMap["clock_gettime"],
|
||||
Args: []*Arg{
|
||||
constArg(CLOCK_REALTIME),
|
||||
tpaddr,
|
||||
},
|
||||
}
|
||||
calls = append(calls, gettime)
|
||||
sec := resultArg(tp.Inner[0])
|
||||
nsec := resultArg(tp.Inner[1])
|
||||
if usec {
|
||||
nsec.OpDiv = 1e3
|
||||
nsec.OpAdd = 10 * 1e3
|
||||
} else {
|
||||
nsec.OpAdd = 10 * 1e6
|
||||
}
|
||||
arg = groupArg([]*Arg{sec, nsec})
|
||||
},
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
func (r *randGen) addr1(s *state, size uintptr, data *Arg) (*Arg, []*Call) {
|
||||
npages := (size + pageSize - 1) / pageSize
|
||||
if r.oneOf(10) {
|
||||
return r.randPageAddr(s, npages, data), nil
|
||||
}
|
||||
for i := uintptr(0); i < maxPages-npages; i++ {
|
||||
free := true
|
||||
for j := uintptr(0); j < npages; j++ {
|
||||
if s.pages[i+j] {
|
||||
free = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if !free {
|
||||
continue
|
||||
}
|
||||
c := &Call{
|
||||
Meta: sys.CallMap["mmap"],
|
||||
Args: []*Arg{
|
||||
pointerArg(i, 0, nil),
|
||||
pageSizeArg(npages, 0),
|
||||
constArg(PROT_READ | PROT_WRITE),
|
||||
constArg(MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED),
|
||||
constArg(sys.InvalidFD),
|
||||
constArg(0),
|
||||
},
|
||||
}
|
||||
return pointerArg(i, 0, data), []*Call{c}
|
||||
}
|
||||
return r.randPageAddr(s, npages, data), nil
|
||||
}
|
||||
|
||||
func (r *randGen) addr(s *state, size uintptr, data *Arg) (*Arg, []*Call) {
|
||||
arg, calls := r.addr1(s, size, data)
|
||||
if arg.Kind != ArgPointer {
|
||||
panic("bad")
|
||||
}
|
||||
// Patch offset of the address.
|
||||
r.choose(
|
||||
1, func() {},
|
||||
1, func() { arg.AddrOffset = -int(size) },
|
||||
1, func() {
|
||||
if size > 0 {
|
||||
arg.AddrOffset = -r.Intn(int(size))
|
||||
}
|
||||
},
|
||||
1, func() { arg.AddrOffset = r.Intn(pageSize) },
|
||||
)
|
||||
return arg, calls
|
||||
}
|
||||
|
||||
func (r *randGen) randPageAddr(s *state, npages uintptr, data *Arg) *Arg {
|
||||
var starts []uintptr
|
||||
for i := uintptr(0); i < maxPages-npages; i++ {
|
||||
busy := true
|
||||
for j := uintptr(0); j < npages; j++ {
|
||||
if !s.pages[i+j] {
|
||||
busy = false
|
||||
break
|
||||
}
|
||||
}
|
||||
// TODO: it does not need to be completely busy,
|
||||
// for example, mmap addr arg can be new memory.
|
||||
if !busy {
|
||||
continue
|
||||
}
|
||||
starts = append(starts, i)
|
||||
}
|
||||
if len(starts) != 0 {
|
||||
return pointerArg(starts[r.rand(len(starts))], 0, data)
|
||||
} else {
|
||||
return pointerArg(r.rand(int(maxPages-npages)), 0, data)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *randGen) createResource(s *state, res sys.ResourceType) (arg *Arg, calls []*Call) {
|
||||
if r.createDepth > 2 {
|
||||
special := res.SpecialValues()
|
||||
return constArg(special[r.Intn(len(special))]), nil
|
||||
}
|
||||
r.createDepth++
|
||||
defer func() { r.createDepth-- }()
|
||||
|
||||
sk := res.Subkind
|
||||
if r.oneOf(50) {
|
||||
// Spoof resource subkind.
|
||||
all := res.SubKinds()
|
||||
sk = all[r.Intn(len(all))]
|
||||
}
|
||||
// Find calls that produce the necessary resources.
|
||||
var metas []*sys.Call
|
||||
// Recurse into arguments to see if there is an out/inout arg of necessary type.
|
||||
var checkArg func(typ sys.Type, dir ArgDir) bool
|
||||
checkArg = func(typ sys.Type, dir ArgDir) bool {
|
||||
if resarg, ok := typ.(sys.ResourceType); ok && dir != DirIn && resarg.Kind == res.Kind &&
|
||||
(resarg.Subkind == sk || resarg.Subkind == sys.ResAny || sk == sys.ResAny) {
|
||||
return true
|
||||
}
|
||||
switch typ1 := typ.(type) {
|
||||
case sys.ArrayType:
|
||||
if checkArg(typ1.Type, dir) {
|
||||
return true
|
||||
}
|
||||
case sys.StructType:
|
||||
for _, fld := range typ1.Fields {
|
||||
if checkArg(fld, dir) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
case sys.PtrType:
|
||||
if checkArg(typ1.Type, ArgDir(typ1.Dir)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
for _, meta := range s.enabledCalls {
|
||||
ok := false
|
||||
for _, arg := range meta.Args {
|
||||
if checkArg(arg, DirIn) {
|
||||
ok = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !ok && meta.Ret != nil && checkArg(meta.Ret, DirOut) {
|
||||
ok = true
|
||||
}
|
||||
if ok {
|
||||
metas = append(metas, meta)
|
||||
}
|
||||
}
|
||||
if len(metas) == 0 {
|
||||
if len(s.enabledCalls) != len(sys.Calls) {
|
||||
// We used only a subset of all syscalls,
|
||||
// so we legitimately may not be able to create the resource.
|
||||
return constArg(res.Default()), nil
|
||||
}
|
||||
panic(fmt.Sprintf("can't create resource %v/%v", res.Kind, sk))
|
||||
}
|
||||
|
||||
// Now we have a set of candidate calls that can create the necessary resource.
|
||||
for i := 0; i < 1e3; i++ {
|
||||
// Generate one of them.
|
||||
meta := metas[r.Intn(len(metas))]
|
||||
calls := r.generateParticularCall(s, meta)
|
||||
assignTypeAndDir(calls[len(calls)-1])
|
||||
s1 := newState(s.enabledCalls)
|
||||
s1.analyze(calls[len(calls)-1])
|
||||
// Now see if we have what we want.
|
||||
var allres []*Arg
|
||||
for sk1, ress := range s1.resources[res.Kind] {
|
||||
if sk1 == sys.ResAny || sk == sys.ResAny || sk1 == sk {
|
||||
allres = append(allres, ress...)
|
||||
}
|
||||
}
|
||||
if len(allres) != 0 {
|
||||
// Bingo!
|
||||
arg := resultArg(allres[r.Intn(len(allres))])
|
||||
return arg, calls
|
||||
}
|
||||
switch meta.Name {
|
||||
case "getgroups":
|
||||
// Returns groups in an array.
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpected call failed to create a resource %v/%v: %v", res.Kind, sk, meta.Name))
|
||||
}
|
||||
// Discard unsuccessful calls.
|
||||
for _, c := range calls {
|
||||
foreachArg(c, func(arg, _ *Arg, _ *[]*Arg) {
|
||||
if arg.Kind == ArgResult {
|
||||
delete(arg.Res.Uses, arg)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
// Generally we can loop several times, e.g. when we choose a call that returns
|
||||
// the resource in an array, but then generateArg generated that array of zero length.
|
||||
// But we must succeed eventually.
|
||||
panic("failed to create a resource")
|
||||
}
|
||||
|
||||
func (r *randGen) choose(args ...interface{}) {
|
||||
if len(args) == 0 || len(args)%2 != 0 {
|
||||
panic("bad number of args to choose")
|
||||
}
|
||||
n := len(args) / 2
|
||||
weights := make([]int, n)
|
||||
funcs := make([]func(), n)
|
||||
total := 0
|
||||
for i := 0; i < n; i++ {
|
||||
weights[i] = total + args[i*2].(int)
|
||||
funcs[i] = args[i*2+1].(func())
|
||||
total = weights[i]
|
||||
}
|
||||
x := r.Intn(total)
|
||||
for i, w := range weights {
|
||||
if x < w {
|
||||
funcs[i]()
|
||||
return
|
||||
}
|
||||
}
|
||||
panic("choose is broken")
|
||||
}
|
||||
|
||||
func (r *randGen) generateCall(s *state) []*Call {
|
||||
meta := s.enabledCalls[r.rand(len(s.enabledCalls))]
|
||||
return r.generateParticularCall(s, meta)
|
||||
}
|
||||
|
||||
func (r *randGen) generateParticularCall(s *state, meta *sys.Call) (calls []*Call) {
|
||||
c := &Call{Meta: meta}
|
||||
c.Args, calls = r.generateArgs(s, meta.Args, DirIn)
|
||||
calls = append(calls, c)
|
||||
for _, c1 := range calls {
|
||||
assignTypeAndDir(c1)
|
||||
sanitizeCall(c1)
|
||||
}
|
||||
return calls
|
||||
}
|
||||
|
||||
func (r *randGen) generateArgs(s *state, types []sys.Type, dir ArgDir) ([]*Arg, []*Call) {
|
||||
var calls []*Call
|
||||
args := make([]*Arg, len(types))
|
||||
sizes := make(map[string]*Arg)
|
||||
// Pass 1: generate all args except size arguments.
|
||||
for i, typ := range types {
|
||||
if _, ok := typ.(sys.LenType); ok {
|
||||
continue
|
||||
}
|
||||
arg, size, calls1 := r.generateArg(s, typ, dir, sizes)
|
||||
args[i] = arg
|
||||
calls = append(calls, calls1...)
|
||||
if size != nil {
|
||||
sizes[typ.Name()] = size
|
||||
}
|
||||
}
|
||||
// Pass 2: fill in size arguments.
|
||||
for i, typ := range types {
|
||||
if a, ok := typ.(sys.LenType); ok {
|
||||
size := sizes[a.Buf]
|
||||
if size == nil {
|
||||
panic(fmt.Sprintf("no size for %v[%v] (%+v)", a.Name(), a.Buf, sizes))
|
||||
}
|
||||
args[i] = size
|
||||
}
|
||||
}
|
||||
return args, calls
|
||||
}
|
||||
|
||||
func (r *randGen) generateArg(s *state, typ sys.Type, dir ArgDir, sizes map[string]*Arg) (arg, size *Arg, calls []*Call) {
|
||||
if dir == DirOut {
|
||||
// No need to generate something interesting for output scalar arguments.
|
||||
// But we still need to generate the argument itself so that it can be referenced
|
||||
// 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.FileoffType, sys.ResourceType:
|
||||
return constArg(0), nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
if typ.Optional() && r.oneOf(10) {
|
||||
if _, ok := typ.(sys.BufferType); ok {
|
||||
panic("impossible") // parent PtrType must be Optional instead
|
||||
}
|
||||
return constArg(typ.Default()), constArg(0), nil
|
||||
}
|
||||
|
||||
switch a := typ.(type) {
|
||||
case sys.ResourceType:
|
||||
r.choose(
|
||||
1, func() {
|
||||
special := a.SpecialValues()
|
||||
arg = constArg(special[r.Intn(len(special))])
|
||||
},
|
||||
90, func() {
|
||||
// Get an existing resource.
|
||||
if ress := s.resources[a.Kind]; ress != nil {
|
||||
allres := ress[a.Subkind]
|
||||
allres = append(allres, ress[sys.ResAny]...)
|
||||
if a.Subkind == sys.ResAny || r.oneOf(10) {
|
||||
for _, v := range ress {
|
||||
allres = append(allres, v...)
|
||||
}
|
||||
}
|
||||
if len(allres) != 0 {
|
||||
// TODO: negative PIDs mean process group,
|
||||
// we should be able to negate an existing PID.
|
||||
arg = resultArg(allres[r.Intn(len(allres))])
|
||||
}
|
||||
}
|
||||
if arg == nil {
|
||||
arg, calls = r.createResource(s, a)
|
||||
}
|
||||
},
|
||||
10, func() {
|
||||
// Create a new resource.
|
||||
arg, calls = r.createResource(s, a)
|
||||
},
|
||||
)
|
||||
return arg, nil, calls
|
||||
case sys.FileoffType:
|
||||
// TODO: can do better
|
||||
var arg *Arg
|
||||
r.choose(
|
||||
90, func() { arg = constArg(0) },
|
||||
10, func() { arg = constArg(r.rand(100)) },
|
||||
1, func() { arg = constArg(r.randInt()) },
|
||||
)
|
||||
return arg, nil, nil
|
||||
case sys.BufferType:
|
||||
switch a.Kind {
|
||||
case sys.BufferBlob:
|
||||
sz := r.randBufLen()
|
||||
if dir == DirOut {
|
||||
return nil, constArg(sz), nil
|
||||
}
|
||||
data := make([]byte, sz)
|
||||
for i := range data {
|
||||
data[i] = byte(r.Intn(256))
|
||||
}
|
||||
return dataArg(data), constArg(sz), nil
|
||||
case sys.BufferString:
|
||||
data := r.randString(s)
|
||||
return dataArg(data), constArg(uintptr(len(data))), nil
|
||||
case sys.BufferSockaddr:
|
||||
data := r.sockaddr(s)
|
||||
if dir == DirOut {
|
||||
return nil, constArg(uintptr(len(data))), nil
|
||||
}
|
||||
return dataArg(data), constArg(uintptr(len(data))), nil
|
||||
default:
|
||||
panic("unknown buffer kind")
|
||||
}
|
||||
case sys.VmaType:
|
||||
npages := r.randPageCount()
|
||||
arg := r.randPageAddr(s, npages, nil)
|
||||
return arg, pageSizeArg(npages, 0), nil
|
||||
case sys.FlagsType:
|
||||
return constArg(r.flags(a.Vals)), nil, nil
|
||||
case sys.IntType:
|
||||
v := r.randInt()
|
||||
if a.Limit != 0 && !r.oneOf(100) {
|
||||
v %= a.Limit
|
||||
}
|
||||
return constArg(v), nil, nil
|
||||
case sys.FilenameType:
|
||||
filename := r.filename(s)
|
||||
return dataArg([]byte(filename)), nil, nil
|
||||
case sys.ArrayType:
|
||||
count := r.rand(6)
|
||||
var inner []*Arg
|
||||
var calls []*Call
|
||||
for i := uintptr(0); i < count; i++ {
|
||||
arg1, _, calls1 := r.generateArg(s, a.Type, dir, nil)
|
||||
inner = append(inner, arg1)
|
||||
calls = append(calls, calls1...)
|
||||
}
|
||||
return groupArg(inner), constArg(count), calls
|
||||
case sys.StructType:
|
||||
if dir != DirOut && (a.Name() == "timespec" || a.Name() == "timeval") {
|
||||
usec := a.Name() == "timeval"
|
||||
arg, calls = r.timespec(s, usec)
|
||||
return arg, nil, calls
|
||||
}
|
||||
args, calls := r.generateArgs(s, a.Fields, dir)
|
||||
return groupArg(args), nil, calls
|
||||
case sys.PtrType:
|
||||
inner, size, calls := r.generateArg(s, a.Type, ArgDir(a.Dir), sizes)
|
||||
if ArgDir(a.Dir) == DirOut && inner == nil {
|
||||
// No data, but we should have got size.
|
||||
arg, calls1 := r.addr(s, size.Val, nil)
|
||||
calls = append(calls, calls1...)
|
||||
return arg, size, calls
|
||||
}
|
||||
if size == nil {
|
||||
size = constArg(inner.Size(a.Type))
|
||||
}
|
||||
arg, calls1 := r.addr(s, inner.Size(a.Type), inner)
|
||||
calls = append(calls, calls1...)
|
||||
return arg, size, calls
|
||||
case sys.LenType:
|
||||
if sizes == nil || sizes[a.Buf] == nil {
|
||||
fmt.Printf("name=%v buf=%v sizes=%+v\n", a.Name(), a.Buf, sizes)
|
||||
panic("me no generate len")
|
||||
}
|
||||
return sizes[a.Name()], nil, nil
|
||||
default:
|
||||
panic("unknown argument type")
|
||||
}
|
||||
}
|
168
prog/validation.go
Normal file
168
prog/validation.go
Normal file
@ -0,0 +1,168 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package prog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/google/syzkaller/sys"
|
||||
)
|
||||
|
||||
type validCtx struct {
|
||||
args map[*Arg]bool
|
||||
uses map[*Arg]*Arg
|
||||
}
|
||||
|
||||
func (p *Prog) validate() error {
|
||||
ctx := &validCtx{make(map[*Arg]bool), make(map[*Arg]*Arg)}
|
||||
for _, c := range p.Calls {
|
||||
if err := c.validate(ctx); err != nil {
|
||||
|
||||
fmt.Printf("PROGRAM:\n")
|
||||
for _, c := range p.Calls {
|
||||
fmt.Printf(" %v: %+v %p\n", c.Meta.Name, c.Args, c.Ret)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
for u, orig := range ctx.uses {
|
||||
if !ctx.args[u] {
|
||||
return fmt.Errorf("use of %+v referes to an out-of-tree arg\narg: %#v", *orig, u)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Call) validate(ctx *validCtx) error {
|
||||
if len(c.Args) != len(c.Meta.Args) {
|
||||
return fmt.Errorf("syscall %v: wrong number of arguments, want %v, got %v", c.Meta.Name, len(c.Meta.Args), len(c.Args))
|
||||
}
|
||||
var checkArg func(arg *Arg, typ sys.Type) error
|
||||
checkArg = func(arg *Arg, typ sys.Type) error {
|
||||
if arg == nil {
|
||||
return fmt.Errorf("syscall %v: nil arg", c.Meta.Name)
|
||||
}
|
||||
if arg.Call != c {
|
||||
return fmt.Errorf("syscall %v: arg has wrong call, call=%p, arg=%+v", c.Meta.Name, c, *arg)
|
||||
}
|
||||
if ctx.args[arg] {
|
||||
return fmt.Errorf("syscall %v: arg is referenced several times in the tree", c.Meta.Name)
|
||||
}
|
||||
ctx.args[arg] = true
|
||||
for u := range arg.Uses {
|
||||
ctx.uses[u] = arg
|
||||
}
|
||||
if arg.Type == nil {
|
||||
return fmt.Errorf("syscall %v: no type", c.Meta.Name)
|
||||
}
|
||||
if arg.Type.Name() != typ.Name() {
|
||||
return fmt.Errorf("syscall %v: arg '%v' type mismatch", c.Meta.Name, typ.Name())
|
||||
}
|
||||
if arg.Dir == DirOut {
|
||||
if arg.Val != 0 || arg.AddrPage != 0 || arg.AddrOffset != 0 || len(arg.Data) != 0 {
|
||||
return fmt.Errorf("syscall %v: output arg '%v' has data", c.Meta.Name, typ.Name())
|
||||
}
|
||||
}
|
||||
switch arg.Type.(type) {
|
||||
case sys.ResourceType:
|
||||
switch arg.Kind {
|
||||
case ArgResult:
|
||||
case ArgReturn:
|
||||
case ArgConst:
|
||||
if arg.Dir == DirOut && arg.Val != 0 {
|
||||
return fmt.Errorf("syscall %v: out resource arg '%v' has bad const value %v", c.Meta.Name, typ.Name(), arg.Val)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("syscall %v: fd arg '%v' has bad kind %v", c.Meta.Name, typ.Name(), arg.Kind)
|
||||
}
|
||||
case sys.FilenameType:
|
||||
switch arg.Kind {
|
||||
case ArgData:
|
||||
default:
|
||||
return fmt.Errorf("syscall %v: filename arg '%v' has bad kind %v", c.Meta.Name, typ.Name(), arg.Kind)
|
||||
}
|
||||
}
|
||||
switch arg.Kind {
|
||||
case ArgConst:
|
||||
case ArgResult:
|
||||
if arg.Res == nil {
|
||||
return fmt.Errorf("syscall %v: result arg '%v' has no reference", c.Meta.Name, typ.Name())
|
||||
}
|
||||
if !ctx.args[arg.Res] {
|
||||
return fmt.Errorf("syscall %v: result arg '%v' references out-of-tree result: %p%+v -> %v %p%+v",
|
||||
c.Meta.Name, typ.Name(), arg, arg, arg.Res.Call.Meta.Name, arg.Res, arg.Res)
|
||||
}
|
||||
if _, ok := arg.Res.Uses[arg]; !ok {
|
||||
return fmt.Errorf("syscall %v: result arg '%v' has broken link (%+v)", c.Meta.Name, typ.Name(), arg.Res.Uses)
|
||||
}
|
||||
case ArgPointer:
|
||||
if arg.Dir != DirIn {
|
||||
return fmt.Errorf("syscall %v: pointer arg '%v' has output direction", c.Meta.Name, typ.Name())
|
||||
}
|
||||
switch typ1 := typ.(type) {
|
||||
case sys.VmaType:
|
||||
if arg.Res != nil {
|
||||
return fmt.Errorf("syscall %v: vma arg '%v' has data", c.Meta.Name, typ.Name())
|
||||
}
|
||||
case sys.PtrType:
|
||||
if arg.Res != nil {
|
||||
if err := checkArg(arg.Res, typ1.Type); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("syscall %v: pointer arg '%v' has bad meta type %+v", c.Meta.Name, typ.Name(), typ)
|
||||
}
|
||||
case ArgPageSize:
|
||||
case ArgData:
|
||||
case ArgGroup:
|
||||
switch typ1 := typ.(type) {
|
||||
case sys.StructType:
|
||||
if len(arg.Inner) != len(typ1.Fields) {
|
||||
return fmt.Errorf("syscall %v: struct arg '%v' has wrong number of fields, want %v, got %v", c.Meta.Name, typ.Name(), len(typ1.Fields), len(arg.Inner))
|
||||
}
|
||||
for i, arg1 := range arg.Inner {
|
||||
if err := checkArg(arg1, typ1.Fields[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case sys.ArrayType:
|
||||
for _, arg1 := range arg.Inner {
|
||||
if err := checkArg(arg1, typ1.Type); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("syscall %v: group arg '%v' has bad underlying type %+v", c.Meta.Name, typ.Name(), typ)
|
||||
}
|
||||
case ArgReturn:
|
||||
default:
|
||||
return fmt.Errorf("syscall %v: unknown arg '%v' kind", c.Meta.Name, typ.Name())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
for i, arg := range c.Args {
|
||||
if c.Ret.Kind != ArgReturn {
|
||||
return fmt.Errorf("syscall %v: arg '%v' has wrong return kind", c.Meta.Name, arg.Type.Name())
|
||||
}
|
||||
if err := checkArg(arg, c.Meta.Args[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if c.Ret == nil {
|
||||
return fmt.Errorf("syscall %v: return value is absent", c.Meta.Name)
|
||||
}
|
||||
if c.Ret.Kind != ArgReturn {
|
||||
return fmt.Errorf("syscall %v: return value has wrong kind %v", c.Meta.Name, c.Ret.Kind)
|
||||
}
|
||||
if c.Meta.Ret != nil {
|
||||
if err := checkArg(c.Ret, c.Meta.Ret); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if c.Ret.Type != nil {
|
||||
return fmt.Errorf("syscall %v: return value has spurious type: %+v", c.Meta.Name, c.Ret.Type)
|
||||
}
|
||||
return nil
|
||||
}
|
56
rpctype/rpctype.go
Normal file
56
rpctype/rpctype.go
Normal file
@ -0,0 +1,56 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
// Package rpctype contains types of message passed via net/rpc connections
|
||||
// between various parts of the system.
|
||||
package rpctype
|
||||
|
||||
type RpcInput struct {
|
||||
Call string
|
||||
Prog []byte
|
||||
CallIndex int
|
||||
Cover []uint32
|
||||
}
|
||||
|
||||
type MasterConnectArgs struct {
|
||||
Name string
|
||||
Http string
|
||||
}
|
||||
|
||||
type MasterConnectRes struct {
|
||||
Http string
|
||||
}
|
||||
|
||||
type NewMasterInputArgs struct {
|
||||
Name string
|
||||
Prog []byte
|
||||
}
|
||||
|
||||
type MasterPollArgs struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
type MasterPollRes struct {
|
||||
Inputs [][]byte
|
||||
}
|
||||
|
||||
type ManagerConnectArgs struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
type ManagerConnectRes struct {
|
||||
}
|
||||
|
||||
type NewManagerInputArgs struct {
|
||||
Name string
|
||||
RpcInput
|
||||
}
|
||||
|
||||
type ManagerPollArgs struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
type ManagerPollRes struct {
|
||||
Candidates [][]byte
|
||||
NewInputs []RpcInput
|
||||
}
|
270
sys/decl.go
Normal file
270
sys/decl.go
Normal file
@ -0,0 +1,270 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
//go:generate go install github.com/google/syzkaller/sysgen
|
||||
//go:generate sysgen sys.txt
|
||||
|
||||
package sys
|
||||
|
||||
type Call struct {
|
||||
ID int
|
||||
CallID int
|
||||
Name string
|
||||
CallName string
|
||||
Args []Type
|
||||
Ret Type
|
||||
}
|
||||
|
||||
type Type interface {
|
||||
Name() string
|
||||
Optional() bool
|
||||
Default() uintptr
|
||||
}
|
||||
|
||||
type TypeCommon struct {
|
||||
TypeName string
|
||||
IsOptional bool
|
||||
}
|
||||
|
||||
func (t TypeCommon) Name() string {
|
||||
return t.TypeName
|
||||
}
|
||||
|
||||
func (t TypeCommon) Optional() bool {
|
||||
return t.IsOptional
|
||||
}
|
||||
|
||||
func (t TypeCommon) Default() uintptr {
|
||||
return 0
|
||||
}
|
||||
|
||||
type (
|
||||
ResourceKind int
|
||||
ResourceSubkind int
|
||||
)
|
||||
|
||||
const (
|
||||
ResFD ResourceKind = iota
|
||||
ResIOCtx
|
||||
ResIPC
|
||||
ResKey
|
||||
ResInotifyDesc
|
||||
ResPid
|
||||
ResUid
|
||||
ResGid
|
||||
ResTimerid
|
||||
)
|
||||
|
||||
const (
|
||||
ResAny ResourceSubkind = iota
|
||||
FdFile
|
||||
FdSock
|
||||
FdPipe
|
||||
FdSignal
|
||||
FdEvent
|
||||
FdTimer
|
||||
FdEpoll
|
||||
FdDir
|
||||
FdMq
|
||||
FdInotify
|
||||
FdFanotify
|
||||
|
||||
IPCMsq
|
||||
IPCSem
|
||||
IPCShm
|
||||
)
|
||||
|
||||
const (
|
||||
InvalidFD = ^uintptr(0)
|
||||
BogusFD = uintptr(100000 - 1)
|
||||
)
|
||||
|
||||
type ResourceType struct {
|
||||
TypeCommon
|
||||
Kind ResourceKind
|
||||
Subkind ResourceSubkind
|
||||
}
|
||||
|
||||
func (t ResourceType) Default() uintptr {
|
||||
switch t.Kind {
|
||||
case ResFD:
|
||||
return InvalidFD
|
||||
case ResIOCtx:
|
||||
return 0
|
||||
case ResIPC:
|
||||
return 0
|
||||
case ResKey:
|
||||
return 0
|
||||
case ResInotifyDesc:
|
||||
return 0
|
||||
case ResPid:
|
||||
return 0
|
||||
case ResUid:
|
||||
return 0
|
||||
case ResGid:
|
||||
return 0
|
||||
case ResTimerid:
|
||||
return 0
|
||||
default:
|
||||
panic("unknown resource type")
|
||||
}
|
||||
}
|
||||
|
||||
func (t ResourceType) SpecialValues() []uintptr {
|
||||
switch t.Kind {
|
||||
case ResFD:
|
||||
return []uintptr{InvalidFD, BogusFD}
|
||||
case ResIOCtx:
|
||||
return []uintptr{0}
|
||||
case ResIPC:
|
||||
return []uintptr{0, ^uintptr(0)}
|
||||
case ResKey:
|
||||
return []uintptr{0}
|
||||
case ResInotifyDesc:
|
||||
return []uintptr{0}
|
||||
case ResPid:
|
||||
return []uintptr{0, ^uintptr(0)}
|
||||
case ResUid:
|
||||
return []uintptr{0, ^uintptr(0)}
|
||||
case ResGid:
|
||||
return []uintptr{0, ^uintptr(0)}
|
||||
case ResTimerid:
|
||||
return []uintptr{0}
|
||||
default:
|
||||
panic("unknown resource kind")
|
||||
}
|
||||
}
|
||||
|
||||
func (t ResourceType) Size() uintptr {
|
||||
switch t.Kind {
|
||||
case ResFD:
|
||||
return 4
|
||||
case ResIOCtx:
|
||||
return 8
|
||||
case ResIPC:
|
||||
return 4
|
||||
case ResKey:
|
||||
return 4
|
||||
case ResInotifyDesc:
|
||||
return 4
|
||||
case ResPid:
|
||||
return 4
|
||||
case ResUid:
|
||||
return 4
|
||||
case ResGid:
|
||||
return 4
|
||||
case ResTimerid:
|
||||
return 4
|
||||
default:
|
||||
panic("unknown resource kind")
|
||||
}
|
||||
}
|
||||
|
||||
func (t ResourceType) SubKinds() []ResourceSubkind {
|
||||
switch t.Kind {
|
||||
case ResFD:
|
||||
return []ResourceSubkind{FdFile, FdSock, FdPipe, FdSignal, FdEvent, FdTimer, FdEpoll, FdDir, FdMq, FdInotify, FdFanotify}
|
||||
case ResIPC:
|
||||
return []ResourceSubkind{IPCMsq, IPCSem, IPCShm}
|
||||
case ResIOCtx, ResKey, ResInotifyDesc, ResPid, ResUid, ResGid, ResTimerid:
|
||||
return []ResourceSubkind{ResAny}
|
||||
default:
|
||||
panic("unknown resource kind")
|
||||
}
|
||||
}
|
||||
|
||||
type FileoffType struct {
|
||||
TypeCommon
|
||||
TypeSize uintptr
|
||||
File string
|
||||
}
|
||||
|
||||
type AddrType struct {
|
||||
TypeCommon
|
||||
}
|
||||
|
||||
type BufferKind int
|
||||
|
||||
const (
|
||||
BufferBlob BufferKind = iota
|
||||
BufferString
|
||||
BufferSockaddr
|
||||
)
|
||||
|
||||
type BufferType struct {
|
||||
TypeCommon
|
||||
Kind BufferKind
|
||||
}
|
||||
|
||||
type VmaType struct {
|
||||
TypeCommon
|
||||
}
|
||||
|
||||
type LenType struct {
|
||||
TypeCommon
|
||||
TypeSize uintptr
|
||||
Buf string
|
||||
}
|
||||
|
||||
type FlagsType struct {
|
||||
TypeCommon
|
||||
TypeSize uintptr
|
||||
Vals []uintptr
|
||||
}
|
||||
|
||||
type IntType struct {
|
||||
TypeCommon
|
||||
TypeSize uintptr
|
||||
Limit uintptr
|
||||
}
|
||||
|
||||
type FilenameType struct {
|
||||
TypeCommon
|
||||
}
|
||||
|
||||
type ArrayType struct {
|
||||
TypeCommon
|
||||
Type Type
|
||||
}
|
||||
|
||||
type PtrType struct {
|
||||
TypeCommon
|
||||
Type Type
|
||||
Dir Dir
|
||||
}
|
||||
|
||||
type StructType struct {
|
||||
TypeCommon
|
||||
Fields []Type
|
||||
}
|
||||
|
||||
type Dir int
|
||||
|
||||
const (
|
||||
DirIn Dir = iota
|
||||
DirOut
|
||||
DirInOut
|
||||
)
|
||||
|
||||
var (
|
||||
CallCount int
|
||||
CallMap = make(map[string]*Call)
|
||||
CallID = make(map[string]int)
|
||||
)
|
||||
|
||||
func init() {
|
||||
for _, c := range Calls {
|
||||
if CallMap[c.Name] != nil {
|
||||
println(c.Name)
|
||||
panic("duplicate syscall")
|
||||
}
|
||||
id, ok := CallID[c.CallName]
|
||||
if !ok {
|
||||
id = len(CallID)
|
||||
CallID[c.CallName] = id
|
||||
}
|
||||
c.CallID = id
|
||||
CallMap[c.Name] = c
|
||||
}
|
||||
CallCount = len(CallID)
|
||||
}
|
303
sys/sys.go
Normal file
303
sys/sys.go
Normal file
@ -0,0 +1,303 @@
|
||||
// AUTOGENERATED FILE
|
||||
package sys
|
||||
|
||||
var Calls = []*Call{
|
||||
&Call{ID: 0, Name: "open", CallName: "open", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1, 2, 1024, 8192, 524288, 64, 16384, 65536, 128, 0, 262144, 256, 131072, 2048, 2097152, 1052672, 512}}, FlagsType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 0, Vals: []uintptr{256, 128, 64, 32, 16, 8, 4, 2, 1}}}},
|
||||
&Call{ID: 1, Name: "openat", CallName: "openat", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1, 2, 1024, 8192, 524288, 64, 16384, 65536, 128, 0, 262144, 256, 131072, 2048, 2097152, 1052672, 512}}, FlagsType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 0, Vals: []uintptr{256, 128, 64, 32, 16, 8, 4, 2, 1}}}},
|
||||
&Call{ID: 2, Name: "creat", CallName: "creat", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}}}, FlagsType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 0, Vals: []uintptr{256, 128, 64, 32, 16, 8, 4, 2, 1}}}},
|
||||
&Call{ID: 3, Name: "close", CallName: "close", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}}},
|
||||
&Call{ID: 4, Name: "read", CallName: "read", Ret: LenType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Buf: "buf", TypeSize: 0}, Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "count", IsOptional: false}, Buf: "buf", TypeSize: 0}}},
|
||||
&Call{ID: 5, Name: "pread64", CallName: "pread64", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "count", IsOptional: false}, Buf: "buf", TypeSize: 0}, FileoffType{TypeCommon: TypeCommon{TypeName: "pos", IsOptional: false}, File: "fd", TypeSize: 0}}},
|
||||
&Call{ID: 6, Name: "readv", CallName: "readv", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "vec", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "iovec_out", IsOptional: false}, Fields: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "addr", TypeSize: 8}}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "vlen", IsOptional: false}, Buf: "vec", TypeSize: 0}}},
|
||||
&Call{ID: 7, Name: "preadv", CallName: "preadv", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "vec", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "iovec_out", IsOptional: false}, Fields: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "addr", TypeSize: 8}}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "vlen", IsOptional: false}, Buf: "vec", TypeSize: 0}, FileoffType{TypeCommon: TypeCommon{TypeName: "off", IsOptional: false}, File: "fd", TypeSize: 0}}},
|
||||
&Call{ID: 8, Name: "write", CallName: "write", Ret: LenType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Buf: "buf", TypeSize: 0}, Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "count", IsOptional: false}, Buf: "buf", TypeSize: 0}}},
|
||||
&Call{ID: 9, Name: "pwrite64", CallName: "pwrite64", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "count", IsOptional: false}, Buf: "buf", TypeSize: 0}, FileoffType{TypeCommon: TypeCommon{TypeName: "pos", IsOptional: false}, File: "fd", TypeSize: 0}}},
|
||||
&Call{ID: 10, Name: "writev", CallName: "writev", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "vec", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "iovec_in", IsOptional: false}, Fields: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "addr", TypeSize: 8}}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "vlen", IsOptional: false}, Buf: "vec", TypeSize: 0}}},
|
||||
&Call{ID: 11, Name: "pwritev", CallName: "pwritev", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "vec", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "iovec_in", IsOptional: false}, Fields: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "addr", TypeSize: 8}}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "vlen", IsOptional: false}, Buf: "vec", TypeSize: 0}, FileoffType{TypeCommon: TypeCommon{TypeName: "off", IsOptional: false}, File: "fd", TypeSize: 0}}},
|
||||
&Call{ID: 12, Name: "lseek", CallName: "lseek", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FileoffType{TypeCommon: TypeCommon{TypeName: "offset", IsOptional: false}, File: "fd", TypeSize: 0}, FlagsType{TypeCommon: TypeCommon{TypeName: "whence", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1, 2, 3, 4}}}},
|
||||
&Call{ID: 13, Name: "dup", CallName: "dup", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "oldfd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}}},
|
||||
&Call{ID: 14, Name: "dup2", CallName: "dup2", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "oldfd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, ResourceType{TypeCommon: TypeCommon{TypeName: "newfd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}}},
|
||||
&Call{ID: 15, Name: "dup3", CallName: "dup3", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "oldfd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, ResourceType{TypeCommon: TypeCommon{TypeName: "newfd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{524288}}}},
|
||||
&Call{ID: 16, Name: "pipe", CallName: "pipe", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "pipefd", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "pipefd", IsOptional: false}, Fields: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "rfd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, ResourceType{TypeCommon: TypeCommon{TypeName: "wfd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}}}, Dir: DirOut}}},
|
||||
&Call{ID: 17, Name: "pipe2", CallName: "pipe2", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "pipefd", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "pipefd", IsOptional: false}, Fields: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "rfd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, ResourceType{TypeCommon: TypeCommon{TypeName: "wfd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}}}, Dir: DirOut}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{2048, 524288}}}},
|
||||
&Call{ID: 18, Name: "tee", CallName: "tee", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fdin", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, ResourceType{TypeCommon: TypeCommon{TypeName: "fdout", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, IntType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, TypeSize: 8}, FlagsType{TypeCommon: TypeCommon{TypeName: "f", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 4, 8}}}},
|
||||
&Call{ID: 19, Name: "splice", CallName: "splice", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fdin", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FileoffType{TypeCommon: TypeCommon{TypeName: "offin", IsOptional: false}, File: "fdin", TypeSize: 0}, ResourceType{TypeCommon: TypeCommon{TypeName: "fdout", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FileoffType{TypeCommon: TypeCommon{TypeName: "offout", IsOptional: false}, File: "fdout", TypeSize: 0}, IntType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, TypeSize: 8}, FlagsType{TypeCommon: TypeCommon{TypeName: "f", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 4, 8}}}},
|
||||
&Call{ID: 20, Name: "vmsplice", CallName: "vmsplice", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "vec", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "iovec_in", IsOptional: false}, Fields: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "addr", TypeSize: 8}}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "vlen", IsOptional: false}, Buf: "vec", TypeSize: 0}, FlagsType{TypeCommon: TypeCommon{TypeName: "f", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 4, 8}}}},
|
||||
&Call{ID: 21, Name: "sendfile", CallName: "sendfile", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fdout", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, ResourceType{TypeCommon: TypeCommon{TypeName: "fdin", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "off", IsOptional: true}, Type: FileoffType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, File: "fdin", TypeSize: 8}, Dir: DirInOut}, IntType{TypeCommon: TypeCommon{TypeName: "count", IsOptional: false}, TypeSize: 8}}},
|
||||
&Call{ID: 22, Name: "stat", CallName: "stat", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "statbuf", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "stat", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "dev", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "ino", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "nlink", IsOptional: false}, TypeSize: 2}, ResourceType{TypeCommon: TypeCommon{TypeName: "uid", IsOptional: false}, Kind: ResUid}, ResourceType{TypeCommon: TypeCommon{TypeName: "gid", IsOptional: false}, Kind: ResGid}, IntType{TypeCommon: TypeCommon{TypeName: "rdev", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "blksize", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "blocks", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "atime", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "ansec", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "mtime", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "mnsec", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "ctime", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "cnsec", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false}, TypeSize: 4}}}, Dir: DirOut}}},
|
||||
&Call{ID: 23, Name: "lstat", CallName: "lstat", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "statbuf", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "stat", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "dev", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "ino", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "nlink", IsOptional: false}, TypeSize: 2}, ResourceType{TypeCommon: TypeCommon{TypeName: "uid", IsOptional: false}, Kind: ResUid}, ResourceType{TypeCommon: TypeCommon{TypeName: "gid", IsOptional: false}, Kind: ResGid}, IntType{TypeCommon: TypeCommon{TypeName: "rdev", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "blksize", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "blocks", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "atime", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "ansec", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "mtime", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "mnsec", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "ctime", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "cnsec", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false}, TypeSize: 4}}}, Dir: DirOut}}},
|
||||
&Call{ID: 24, Name: "fstat", CallName: "fstat", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "statbuf", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "stat", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "dev", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "ino", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "nlink", IsOptional: false}, TypeSize: 2}, ResourceType{TypeCommon: TypeCommon{TypeName: "uid", IsOptional: false}, Kind: ResUid}, ResourceType{TypeCommon: TypeCommon{TypeName: "gid", IsOptional: false}, Kind: ResGid}, IntType{TypeCommon: TypeCommon{TypeName: "rdev", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "blksize", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "blocks", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "atime", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "ansec", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "mtime", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "mnsec", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "ctime", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "cnsec", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false}, TypeSize: 4}}}, Dir: DirOut}}},
|
||||
&Call{ID: 25, Name: "poll", CallName: "poll", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "fds", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "pollfd", IsOptional: false}, Fields: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, IntType{TypeCommon: TypeCommon{TypeName: "events", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "revents", IsOptional: false}, TypeSize: 2}}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "nfds", IsOptional: false}, Buf: "fds", TypeSize: 0}, IntType{TypeCommon: TypeCommon{TypeName: "timeout", IsOptional: false}, TypeSize: 4}}},
|
||||
&Call{ID: 26, Name: "ppoll", CallName: "ppoll", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "fds", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "pollfd", IsOptional: false}, Fields: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, IntType{TypeCommon: TypeCommon{TypeName: "events", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "revents", IsOptional: false}, TypeSize: 2}}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "nfds", IsOptional: false}, Buf: "fds", TypeSize: 0}, PtrType{TypeCommon: TypeCommon{TypeName: "tsp", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "sigmask", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sigset", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "mask", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "sigmask", TypeSize: 0}}},
|
||||
&Call{ID: 27, Name: "select", CallName: "select", Args: []Type{LenType{TypeCommon: TypeCommon{TypeName: "n", IsOptional: false}, Buf: "inp", TypeSize: 0}, PtrType{TypeCommon: TypeCommon{TypeName: "inp", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "fd_set", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "mask0", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask1", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask3", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask4", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask5", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask6", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask7", IsOptional: false}, TypeSize: 8}}}, Dir: DirInOut}, PtrType{TypeCommon: TypeCommon{TypeName: "outp", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "fd_set", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "mask0", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask1", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask3", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask4", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask5", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask6", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask7", IsOptional: false}, TypeSize: 8}}}, Dir: DirInOut}, PtrType{TypeCommon: TypeCommon{TypeName: "exp", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "fd_set", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "mask0", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask1", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask3", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask4", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask5", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask6", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask7", IsOptional: false}, TypeSize: 8}}}, Dir: DirInOut}, PtrType{TypeCommon: TypeCommon{TypeName: "tvp", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "timeval", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "usec", IsOptional: false}, TypeSize: 8}}}, Dir: DirInOut}}},
|
||||
&Call{ID: 28, Name: "pselect6", CallName: "pselect6", Args: []Type{LenType{TypeCommon: TypeCommon{TypeName: "n", IsOptional: false}, Buf: "inp", TypeSize: 0}, PtrType{TypeCommon: TypeCommon{TypeName: "inp", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "fd_set", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "mask0", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask1", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask3", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask4", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask5", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask6", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask7", IsOptional: false}, TypeSize: 8}}}, Dir: DirInOut}, PtrType{TypeCommon: TypeCommon{TypeName: "outp", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "fd_set", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "mask0", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask1", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask3", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask4", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask5", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask6", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask7", IsOptional: false}, TypeSize: 8}}}, Dir: DirInOut}, PtrType{TypeCommon: TypeCommon{TypeName: "exp", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "fd_set", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "mask0", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask1", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask3", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask4", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask5", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask6", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mask7", IsOptional: false}, TypeSize: 8}}}, Dir: DirInOut}, PtrType{TypeCommon: TypeCommon{TypeName: "tvp", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, Dir: DirInOut}, PtrType{TypeCommon: TypeCommon{TypeName: "sig", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sigset_size", IsOptional: false}, Fields: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "ss", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sigset", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "mask", IsOptional: false}, TypeSize: 8}}}, Dir: DirInOut}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "ss", TypeSize: 8}}}, Dir: DirIn}}},
|
||||
&Call{ID: 29, Name: "epoll_create", CallName: "epoll_create", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: FdEpoll}, Args: []Type{IntType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, TypeSize: 4}}},
|
||||
&Call{ID: 30, Name: "epoll_create1", CallName: "epoll_create1", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: FdEpoll}, Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{524288}}}},
|
||||
&Call{ID: 31, Name: "epoll_ctl", CallName: "epoll_ctl", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "epfd", IsOptional: false}, Kind: ResFD, Subkind: FdEpoll}, FlagsType{TypeCommon: TypeCommon{TypeName: "op", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 3, 2}}, ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "ev", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "epoll_event", IsOptional: false}, Fields: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "ev", IsOptional: false}, TypeSize: 4, Vals: []uintptr{1, 4, 8192, 2, 8, 16, 2147483648, 1073741824}}, IntType{TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}}},
|
||||
&Call{ID: 32, Name: "epoll_wait", CallName: "epoll_wait", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "epfd", IsOptional: false}, Kind: ResFD, Subkind: FdEpoll}, PtrType{TypeCommon: TypeCommon{TypeName: "events", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "epoll_event", IsOptional: false}, Fields: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "ev", IsOptional: false}, TypeSize: 4, Vals: []uintptr{1, 4, 8192, 2, 8, 16, 2147483648, 1073741824}}, IntType{TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, TypeSize: 8}}}}, Dir: DirOut}, LenType{TypeCommon: TypeCommon{TypeName: "maxevents", IsOptional: false}, Buf: "events", TypeSize: 0}, IntType{TypeCommon: TypeCommon{TypeName: "timeout", IsOptional: false}, TypeSize: 4}}},
|
||||
&Call{ID: 33, Name: "epoll_pwait", CallName: "epoll_pwait", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "epfd", IsOptional: false}, Kind: ResFD, Subkind: FdEpoll}, PtrType{TypeCommon: TypeCommon{TypeName: "events", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "epoll_event", IsOptional: false}, Fields: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "ev", IsOptional: false}, TypeSize: 4, Vals: []uintptr{1, 4, 8192, 2, 8, 16, 2147483648, 1073741824}}, IntType{TypeCommon: TypeCommon{TypeName: "pad", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, TypeSize: 8}}}}, Dir: DirOut}, LenType{TypeCommon: TypeCommon{TypeName: "maxevents", IsOptional: false}, Buf: "events", TypeSize: 0}, IntType{TypeCommon: TypeCommon{TypeName: "timeout", IsOptional: false}, TypeSize: 4}, PtrType{TypeCommon: TypeCommon{TypeName: "sigmask", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sigset", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "mask", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "sigmask", TypeSize: 0}}},
|
||||
&Call{ID: 34, Name: "signalfd", CallName: "signalfd", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: FdSignal}, Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "mask", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sigset", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "mask", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "mask", TypeSize: 0}}},
|
||||
&Call{ID: 35, Name: "signalfd4", CallName: "signalfd4", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: FdSignal}, Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "mask", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sigset", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "mask", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "mask", TypeSize: 0}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{2048, 524288}}}},
|
||||
&Call{ID: 36, Name: "eventfd", CallName: "eventfd", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: FdEvent}, Args: []Type{IntType{TypeCommon: TypeCommon{TypeName: "initval", IsOptional: false}, TypeSize: 4}}},
|
||||
&Call{ID: 37, Name: "eventfd2", CallName: "eventfd2", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: FdEvent}, Args: []Type{IntType{TypeCommon: TypeCommon{TypeName: "initval", IsOptional: false}, TypeSize: 4}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{524288, 2048, 1}}}},
|
||||
&Call{ID: 38, Name: "timerfd_create", CallName: "timerfd_create", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: FdTimer}, Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "clockid", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 5, 1, 6, 4, 7, 2, 3}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{2048, 524288}}}},
|
||||
&Call{ID: 39, Name: "timerfd_settime", CallName: "timerfd_settime", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdTimer}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1}}, PtrType{TypeCommon: TypeCommon{TypeName: "new", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "itimerspec", IsOptional: false}, Fields: []Type{StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}}}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "old", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "itimerspec", IsOptional: false}, Fields: []Type{StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}}}, Dir: DirOut}}},
|
||||
&Call{ID: 40, Name: "timerfd_gettime", CallName: "timerfd_gettime", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdTimer}, PtrType{TypeCommon: TypeCommon{TypeName: "cur", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "itimerspec", IsOptional: false}, Fields: []Type{StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}}}, Dir: DirOut}}},
|
||||
&Call{ID: 41, Name: "mmap", CallName: "mmap", Ret: VmaType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}}, Args: []Type{VmaType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "addr", TypeSize: 0}, FlagsType{TypeCommon: TypeCommon{TypeName: "prot", IsOptional: false}, TypeSize: 0, Vals: []uintptr{4, 1, 2}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 64, 32, 2048, 4096, 0, 16, 256, 262144, 8192, 65536, 16384, 32768, 131072, 67108864}}, ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: true}, Kind: ResFD, Subkind: FdFile}, FileoffType{TypeCommon: TypeCommon{TypeName: "offset", IsOptional: false}, File: "fd", TypeSize: 0}}},
|
||||
&Call{ID: 42, Name: "munmap", CallName: "munmap", Args: []Type{VmaType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "addr", TypeSize: 0}}},
|
||||
&Call{ID: 43, Name: "mremap", CallName: "mremap", Ret: VmaType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}}, Args: []Type{VmaType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "addr", TypeSize: 0}, LenType{TypeCommon: TypeCommon{TypeName: "newlen", IsOptional: false}, Buf: "newaddr", TypeSize: 0}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2}}, VmaType{TypeCommon: TypeCommon{TypeName: "newaddr", IsOptional: false}}}},
|
||||
&Call{ID: 44, Name: "remap_file_pages", CallName: "remap_file_pages", Args: []Type{VmaType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}}, LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "addr", TypeSize: 0}, FlagsType{TypeCommon: TypeCommon{TypeName: "prot", IsOptional: false}, TypeSize: 0, Vals: []uintptr{4, 1, 2}}, IntType{TypeCommon: TypeCommon{TypeName: "pgoff", IsOptional: false}, TypeSize: 8}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 64, 32, 2048, 4096, 0, 16, 256, 262144, 8192, 65536, 16384, 32768, 131072, 67108864}}}},
|
||||
&Call{ID: 45, Name: "mprotect", CallName: "mprotect", Args: []Type{VmaType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "addr", TypeSize: 0}, FlagsType{TypeCommon: TypeCommon{TypeName: "prot", IsOptional: false}, TypeSize: 0, Vals: []uintptr{4, 1, 2}}}},
|
||||
&Call{ID: 46, Name: "msync", CallName: "msync", Args: []Type{VmaType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "addr", TypeSize: 0}, FlagsType{TypeCommon: TypeCommon{TypeName: "f", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 4, 2}}}},
|
||||
&Call{ID: 47, Name: "madvise", CallName: "madvise", Args: []Type{VmaType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "addr", TypeSize: 0}, FlagsType{TypeCommon: TypeCommon{TypeName: "advice", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1, 2, 3, 4, 9, 10, 11, 100, 101, 12, 13, 14, 15, 16, 17}}}},
|
||||
&Call{ID: 48, Name: "fadvise64", CallName: "fadvise64", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FileoffType{TypeCommon: TypeCommon{TypeName: "offset", IsOptional: false}, File: "fd", TypeSize: 0}, IntType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, TypeSize: 8}, FlagsType{TypeCommon: TypeCommon{TypeName: "advice", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 2, 1, 5, 3, 4}}}},
|
||||
&Call{ID: 49, Name: "readahead", CallName: "readahead", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, IntType{TypeCommon: TypeCommon{TypeName: "off", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "count", IsOptional: false}, TypeSize: 8}}},
|
||||
&Call{ID: 50, Name: "mbind", CallName: "mbind", Args: []Type{VmaType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "addr", TypeSize: 0}, FlagsType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 2, 3, 1, 32768, 16384}}, PtrType{TypeCommon: TypeCommon{TypeName: "nodemask", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 8}, Dir: DirIn}, IntType{TypeCommon: TypeCommon{TypeName: "maxnode", IsOptional: false}, TypeSize: 8}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 4}}}},
|
||||
&Call{ID: 51, Name: "move_pages", CallName: "move_pages", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, LenType{TypeCommon: TypeCommon{TypeName: "nr", IsOptional: false}, Buf: "pages", TypeSize: 0}, PtrType{TypeCommon: TypeCommon{TypeName: "pages", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: VmaType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}}}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "nodes", IsOptional: true}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 4}}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "status", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 4}}, Dir: DirOut}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{2, 4}}}},
|
||||
&Call{ID: 52, Name: "migrate_pages", CallName: "migrate_pages", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, IntType{TypeCommon: TypeCommon{TypeName: "maxnode", IsOptional: false}, TypeSize: 8}, PtrType{TypeCommon: TypeCommon{TypeName: "old", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 8}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "new", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 8}, Dir: DirIn}}},
|
||||
&Call{ID: 53, Name: "set_mempolicy", CallName: "set_mempolicy", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 2, 3, 1, 32768, 16384}}, PtrType{TypeCommon: TypeCommon{TypeName: "nodemask", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 8}, Dir: DirIn}, IntType{TypeCommon: TypeCommon{TypeName: "maxnode", IsOptional: false}, TypeSize: 8}}},
|
||||
&Call{ID: 54, Name: "get_mempolicy", CallName: "get_mempolicy", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 4}, Dir: DirOut}, PtrType{TypeCommon: TypeCommon{TypeName: "nodemask", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 8}, Dir: DirOut}, IntType{TypeCommon: TypeCommon{TypeName: "maxnode", IsOptional: false}, TypeSize: 8}, VmaType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 4, 2, 1}}}},
|
||||
&Call{ID: 55, Name: "mincore", CallName: "mincore", Args: []Type{VmaType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}}, LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "addr", TypeSize: 0}, PtrType{TypeCommon: TypeCommon{TypeName: "vec", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "vec", IsOptional: false}, Kind: BufferBlob}}}},
|
||||
&Call{ID: 56, Name: "mlock", CallName: "mlock", Args: []Type{VmaType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}}, LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "addr", TypeSize: 0}}},
|
||||
&Call{ID: 57, Name: "munlock", CallName: "munlock", Args: []Type{VmaType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}}, LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "addr", TypeSize: 0}}},
|
||||
&Call{ID: 58, Name: "mlockall", CallName: "mlockall", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2}}}},
|
||||
&Call{ID: 59, Name: "munlockall", CallName: "munlockall", Args: []Type{}},
|
||||
&Call{ID: 60, Name: "unshare", CallName: "unshare", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{2097152, 16777216, 1024, 512, 2147483648, 134217728, 1073741824, 131072, 536870912, 67108864, 32768, 1048576, 8192, 524288, 2048, 262144, 65536, 8388608, 16384, 256}}}},
|
||||
&Call{ID: 61, Name: "kcmp", CallName: "kcmp", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "pid1", IsOptional: false}, Kind: ResPid}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid2", IsOptional: false}, Kind: ResPid}, FlagsType{TypeCommon: TypeCommon{TypeName: "type", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 2, 3, 5, 4, 6, 1}}, ResourceType{TypeCommon: TypeCommon{TypeName: "fd1", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, ResourceType{TypeCommon: TypeCommon{TypeName: "fd2", IsOptional: false}, Kind: ResFD, Subkind: ResAny}}},
|
||||
&Call{ID: 62, Name: "futex", CallName: "futex", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 4}, Dir: DirIn}, FlagsType{TypeCommon: TypeCommon{TypeName: "op", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 9, 1, 3, 4}}, IntType{TypeCommon: TypeCommon{TypeName: "val", IsOptional: false}, TypeSize: 8}, PtrType{TypeCommon: TypeCommon{TypeName: "timeout", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "addr2", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 4}, Dir: DirIn}, IntType{TypeCommon: TypeCommon{TypeName: "val3", IsOptional: false}, TypeSize: 8}}},
|
||||
&Call{ID: 63, Name: "set_robust_list", CallName: "set_robust_list", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "head", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "robust_list", IsOptional: false}, Fields: []Type{VmaType{TypeCommon: TypeCommon{TypeName: "next", IsOptional: false}}, IntType{TypeCommon: TypeCommon{TypeName: "off", IsOptional: false}, TypeSize: 8}, VmaType{TypeCommon: TypeCommon{TypeName: "pend", IsOptional: false}}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "head", TypeSize: 0}}},
|
||||
&Call{ID: 64, Name: "get_robust_list", CallName: "get_robust_list", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, PtrType{TypeCommon: TypeCommon{TypeName: "head", IsOptional: false}, Type: PtrType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "robust_list", IsOptional: false}, Fields: []Type{VmaType{TypeCommon: TypeCommon{TypeName: "next", IsOptional: false}}, IntType{TypeCommon: TypeCommon{TypeName: "off", IsOptional: false}, TypeSize: 8}, VmaType{TypeCommon: TypeCommon{TypeName: "pend", IsOptional: false}}}}, Dir: DirOut}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Type: LenType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Buf: "head", TypeSize: 8}, Dir: DirInOut}}},
|
||||
&Call{ID: 65, Name: "restart_syscall", CallName: "restart_syscall", Args: []Type{}},
|
||||
&Call{ID: 66, Name: "socket", CallName: "socket", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: FdSock}, Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "domain", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 10, 4, 16, 9, 3, 8, 5, 17}}, FlagsType{TypeCommon: TypeCommon{TypeName: "type", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 5, 3, 4, 10, 2048, 524288}}, IntType{TypeCommon: TypeCommon{TypeName: "proto", IsOptional: false}, TypeSize: 1}}},
|
||||
&Call{ID: 67, Name: "socketpair", CallName: "socketpair", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "domain", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 10, 4, 16, 9, 3, 8, 5, 17}}, FlagsType{TypeCommon: TypeCommon{TypeName: "type", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 5, 3, 4, 10, 2048, 524288}}, IntType{TypeCommon: TypeCommon{TypeName: "proto", IsOptional: false}, TypeSize: 1}, PtrType{TypeCommon: TypeCommon{TypeName: "fds", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "pipefd", IsOptional: false}, Fields: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "rfd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, ResourceType{TypeCommon: TypeCommon{TypeName: "wfd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}}}, Dir: DirOut}}},
|
||||
&Call{ID: 68, Name: "accept", CallName: "accept", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: FdSock}, Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdSock}, PtrType{TypeCommon: TypeCommon{TypeName: "peer", IsOptional: true}, Type: BufferType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: BufferSockaddr}, Dir: DirOut}, PtrType{TypeCommon: TypeCommon{TypeName: "peerlen", IsOptional: false}, Type: LenType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Buf: "peer", TypeSize: 4}, Dir: DirInOut}}},
|
||||
&Call{ID: 69, Name: "accept4", CallName: "accept4", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: FdSock}, Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdSock}, PtrType{TypeCommon: TypeCommon{TypeName: "peer", IsOptional: true}, Type: BufferType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: BufferSockaddr}, Dir: DirOut}, PtrType{TypeCommon: TypeCommon{TypeName: "peerlen", IsOptional: false}, Type: LenType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Buf: "peer", TypeSize: 4}, Dir: DirInOut}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{2048, 524288}}}},
|
||||
&Call{ID: 70, Name: "bind", CallName: "bind", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdSock}, PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Type: BufferType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: BufferSockaddr}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "addrlen", IsOptional: false}, Buf: "addr", TypeSize: 0}}},
|
||||
&Call{ID: 71, Name: "listen", CallName: "listen", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdSock}, IntType{TypeCommon: TypeCommon{TypeName: "backlog", IsOptional: false}, TypeSize: 4}}},
|
||||
&Call{ID: 72, Name: "connect", CallName: "connect", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdSock}, PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Type: BufferType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: BufferSockaddr}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "addrlen", IsOptional: false}, Buf: "addr", TypeSize: 0}}},
|
||||
&Call{ID: 73, Name: "shutdown", CallName: "shutdown", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdSock}, FlagsType{TypeCommon: TypeCommon{TypeName: "how", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1}}}},
|
||||
&Call{ID: 74, Name: "sendto", CallName: "sendto", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdSock}, PtrType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "buf", TypeSize: 0}, FlagsType{TypeCommon: TypeCommon{TypeName: "f", IsOptional: false}, TypeSize: 0, Vals: []uintptr{2048, 4, 64, 128, 32768, 16384, 1}}, PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: true}, Type: BufferType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: BufferSockaddr}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "addrlen", IsOptional: false}, Buf: "addr", TypeSize: 0}}},
|
||||
&Call{ID: 75, Name: "sendmsg", CallName: "sendmsg", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdSock}, PtrType{TypeCommon: TypeCommon{TypeName: "msg", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "send_msghdr", IsOptional: false}, Fields: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Type: BufferType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: BufferSockaddr}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "addrlen", IsOptional: false}, Buf: "addr", TypeSize: 4}, PtrType{TypeCommon: TypeCommon{TypeName: "vec", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "iovec_in", IsOptional: false}, Fields: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "addr", TypeSize: 8}}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "vlen", IsOptional: false}, Buf: "vec", TypeSize: 8}, PtrType{TypeCommon: TypeCommon{TypeName: "ctrl", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "cmsghdr", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "level", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "type", IsOptional: false}, TypeSize: 4}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "ctrllen", IsOptional: false}, Buf: "ctrl", TypeSize: 8}, FlagsType{TypeCommon: TypeCommon{TypeName: "f", IsOptional: false}, TypeSize: 4, Vals: []uintptr{2048, 4, 64, 128, 32768, 16384, 1}}, IntType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, TypeSize: 4}}}, Dir: DirIn}, FlagsType{TypeCommon: TypeCommon{TypeName: "f", IsOptional: false}, TypeSize: 0, Vals: []uintptr{2048, 4, 64, 128, 32768, 16384, 1}}}},
|
||||
&Call{ID: 76, Name: "sendmmsg", CallName: "sendmmsg", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdSock}, PtrType{TypeCommon: TypeCommon{TypeName: "mmsg", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "send_msghdr", IsOptional: false}, Fields: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Type: BufferType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: BufferSockaddr}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "addrlen", IsOptional: false}, Buf: "addr", TypeSize: 4}, PtrType{TypeCommon: TypeCommon{TypeName: "vec", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "iovec_in", IsOptional: false}, Fields: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "addr", TypeSize: 8}}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "vlen", IsOptional: false}, Buf: "vec", TypeSize: 8}, PtrType{TypeCommon: TypeCommon{TypeName: "ctrl", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "cmsghdr", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "level", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "type", IsOptional: false}, TypeSize: 4}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "ctrllen", IsOptional: false}, Buf: "ctrl", TypeSize: 8}, FlagsType{TypeCommon: TypeCommon{TypeName: "f", IsOptional: false}, TypeSize: 4, Vals: []uintptr{2048, 4, 64, 128, 32768, 16384, 1}}, IntType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, TypeSize: 4}}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "vlen", IsOptional: false}, Buf: "mmsg", TypeSize: 0}, FlagsType{TypeCommon: TypeCommon{TypeName: "f", IsOptional: false}, TypeSize: 0, Vals: []uintptr{2048, 4, 64, 128, 32768, 16384, 1}}}},
|
||||
&Call{ID: 77, Name: "recvfrom", CallName: "recvfrom", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdSock}, PtrType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "buf", TypeSize: 0}, FlagsType{TypeCommon: TypeCommon{TypeName: "f", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1073741824, 64, 8192, 1, 2, 32, 256, 65536}}, PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: true}, Type: BufferType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: BufferSockaddr}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "addrlen", IsOptional: false}, Buf: "addr", TypeSize: 0}}},
|
||||
&Call{ID: 78, Name: "recvmsg", CallName: "recvmsg", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdSock}, PtrType{TypeCommon: TypeCommon{TypeName: "msg", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "recv_msghdr", IsOptional: false}, Fields: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Type: BufferType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: BufferSockaddr}, Dir: DirOut}, LenType{TypeCommon: TypeCommon{TypeName: "addrlen", IsOptional: false}, Buf: "addr", TypeSize: 4}, PtrType{TypeCommon: TypeCommon{TypeName: "vec", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "iovec_out", IsOptional: false}, Fields: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "addr", TypeSize: 8}}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "vlen", IsOptional: false}, Buf: "vec", TypeSize: 8}, PtrType{TypeCommon: TypeCommon{TypeName: "ctrl", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "ctrl", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "ctrllen", IsOptional: false}, Buf: "ctrl", TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "f", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, TypeSize: 4}}}, Dir: DirIn}, FlagsType{TypeCommon: TypeCommon{TypeName: "f", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1073741824, 64, 8192, 1, 2, 32, 256, 65536}}}},
|
||||
&Call{ID: 79, Name: "recvmmsg", CallName: "recvmmsg", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdSock}, PtrType{TypeCommon: TypeCommon{TypeName: "mmsg", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "recv_msghdr", IsOptional: false}, Fields: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Type: BufferType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: BufferSockaddr}, Dir: DirOut}, LenType{TypeCommon: TypeCommon{TypeName: "addrlen", IsOptional: false}, Buf: "addr", TypeSize: 4}, PtrType{TypeCommon: TypeCommon{TypeName: "vec", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "iovec_out", IsOptional: false}, Fields: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "addr", TypeSize: 8}}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "vlen", IsOptional: false}, Buf: "vec", TypeSize: 8}, PtrType{TypeCommon: TypeCommon{TypeName: "ctrl", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "ctrl", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "ctrllen", IsOptional: false}, Buf: "ctrl", TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "f", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, TypeSize: 4}}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "vlen", IsOptional: false}, Buf: "mmsg", TypeSize: 0}, FlagsType{TypeCommon: TypeCommon{TypeName: "f", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1073741824, 64, 8192, 1, 2, 32, 256, 65536}}}},
|
||||
&Call{ID: 80, Name: "getsockname", CallName: "getsockname", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdSock}, PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Type: BufferType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: BufferSockaddr}, Dir: DirOut}, PtrType{TypeCommon: TypeCommon{TypeName: "addrlen", IsOptional: false}, Type: LenType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Buf: "addr", TypeSize: 4}, Dir: DirInOut}}},
|
||||
&Call{ID: 81, Name: "getpeername", CallName: "getpeername", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdSock}, PtrType{TypeCommon: TypeCommon{TypeName: "peer", IsOptional: false}, Type: BufferType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: BufferSockaddr}, Dir: DirOut}, PtrType{TypeCommon: TypeCommon{TypeName: "peerlen", IsOptional: false}, Type: LenType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Buf: "peer", TypeSize: 4}, Dir: DirInOut}}},
|
||||
&Call{ID: 82, Name: "getsockopt", CallName: "getsockopt", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdSock}, IntType{TypeCommon: TypeCommon{TypeName: "level", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "optname", IsOptional: false}, TypeSize: 4}, PtrType{TypeCommon: TypeCommon{TypeName: "optval", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "ioctl_arg", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "a0", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a1", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a3", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a4", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a5", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a6", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a7", IsOptional: false}, TypeSize: 8}}}, Dir: DirOut}, PtrType{TypeCommon: TypeCommon{TypeName: "optlen", IsOptional: false}, Type: LenType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Buf: "optval", TypeSize: 4}, Dir: DirInOut}}},
|
||||
&Call{ID: 83, Name: "setsockopt", CallName: "setsockopt", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdSock}, IntType{TypeCommon: TypeCommon{TypeName: "level", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "optname", IsOptional: false}, TypeSize: 4}, PtrType{TypeCommon: TypeCommon{TypeName: "optval", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "ioctl_arg", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "a0", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a1", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a3", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a4", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a5", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a6", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a7", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "optlen", IsOptional: false}, Buf: "optval", TypeSize: 0}}},
|
||||
&Call{ID: 84, Name: "ioctl", CallName: "ioctl", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, IntType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 4}, PtrType{TypeCommon: TypeCommon{TypeName: "arg", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "ioctl_arg", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "a0", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a1", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a3", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a4", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a5", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a6", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a7", IsOptional: false}, TypeSize: 8}}}, Dir: DirInOut}}},
|
||||
&Call{ID: 85, Name: "fcntl$dupfd", CallName: "fcntl", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FlagsType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1030}}, ResourceType{TypeCommon: TypeCommon{TypeName: "arg", IsOptional: false}, Kind: ResFD, Subkind: ResAny}}},
|
||||
&Call{ID: 86, Name: "fcntl$getflags", CallName: "fcntl", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FlagsType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 3, 11, 1025, 1032}}}},
|
||||
&Call{ID: 87, Name: "fcntl$setflags", CallName: "fcntl", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FlagsType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Vals: []uintptr{2}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1}}}},
|
||||
&Call{ID: 88, Name: "fcntl$setstatus", CallName: "fcntl", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FlagsType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Vals: []uintptr{4}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1024, 8192, 16384, 262144, 2048}}}},
|
||||
&Call{ID: 89, Name: "fcntl$lock", CallName: "fcntl", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FlagsType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Vals: []uintptr{6, 7, 5}}, PtrType{TypeCommon: TypeCommon{TypeName: "lock", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "flock", IsOptional: false}, Fields: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "type", IsOptional: false}, TypeSize: 2, Vals: []uintptr{0, 1, 2}}, FlagsType{TypeCommon: TypeCommon{TypeName: "whence", IsOptional: false}, TypeSize: 2, Vals: []uintptr{0, 1, 2, 3, 4}}, IntType{TypeCommon: TypeCommon{TypeName: "start", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, TypeSize: 8}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}}}, Dir: DirIn}}},
|
||||
&Call{ID: 90, Name: "fcntl$getown", CallName: "fcntl", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResPid}, Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FlagsType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Vals: []uintptr{9}}}},
|
||||
&Call{ID: 91, Name: "fcntl$setown", CallName: "fcntl", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FlagsType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Vals: []uintptr{8}}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}}},
|
||||
&Call{ID: 92, Name: "fcntl$getownex", CallName: "fcntl", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FlagsType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Vals: []uintptr{16}}, PtrType{TypeCommon: TypeCommon{TypeName: "arg", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "f_owner_ex", IsOptional: false}, Fields: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "type", IsOptional: false}, TypeSize: 4, Vals: []uintptr{0, 1, 2}}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}}}, Dir: DirOut}}},
|
||||
&Call{ID: 93, Name: "fcntl$setownex", CallName: "fcntl", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FlagsType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Vals: []uintptr{15}}, PtrType{TypeCommon: TypeCommon{TypeName: "arg", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "f_owner_ex", IsOptional: false}, Fields: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "type", IsOptional: false}, TypeSize: 4, Vals: []uintptr{0, 1, 2}}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}}}, Dir: DirIn}}},
|
||||
&Call{ID: 94, Name: "fcntl$setsig", CallName: "fcntl", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FlagsType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Vals: []uintptr{10}}, IntType{TypeCommon: TypeCommon{TypeName: "sig", IsOptional: false}, TypeSize: 4, Limit: 130}}},
|
||||
&Call{ID: 95, Name: "fcntl$setlease", CallName: "fcntl", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FlagsType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1024}}, FlagsType{TypeCommon: TypeCommon{TypeName: "typ", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1, 2}}}},
|
||||
&Call{ID: 96, Name: "fcntl$notify", CallName: "fcntl", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FlagsType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Vals: []uintptr{2147483648, 1, 2, 4, 8, 16, 32}}, FlagsType{TypeCommon: TypeCommon{TypeName: "typ", IsOptional: false}, TypeSize: 0, Vals: []uintptr{2147483648, 1, 2, 4, 8, 16, 32}}}},
|
||||
&Call{ID: 97, Name: "fcntl$setpipe", CallName: "fcntl", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FlagsType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1031}}, IntType{TypeCommon: TypeCommon{TypeName: "sz", IsOptional: false}, TypeSize: 8}}},
|
||||
&Call{ID: 98, Name: "ptrace", CallName: "ptrace", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "req", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 16904, 8, 16903, 16, 17}}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}}},
|
||||
&Call{ID: 99, Name: "ptrace$peek", CallName: "ptrace", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "req", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2}}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 8}, Dir: DirOut}}},
|
||||
&Call{ID: 100, Name: "ptrace$poke", CallName: "ptrace", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "req", IsOptional: false}, TypeSize: 0, Vals: []uintptr{4, 5}}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 8}, Dir: DirOut}, IntType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, TypeSize: 8}}},
|
||||
&Call{ID: 101, Name: "ptrace$peekuser", CallName: "ptrace", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "req", IsOptional: false}, TypeSize: 0, Vals: []uintptr{3}}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, IntType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, TypeSize: 8}}},
|
||||
&Call{ID: 102, Name: "ptrace$pokeuser", CallName: "ptrace", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "req", IsOptional: false}, TypeSize: 0, Vals: []uintptr{3}}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, IntType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, TypeSize: 8}}},
|
||||
&Call{ID: 103, Name: "ptrace$getregs", CallName: "ptrace", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "req", IsOptional: false}, TypeSize: 0, Vals: []uintptr{12, 14}}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, IntType{TypeCommon: TypeCommon{TypeName: "ignored", IsOptional: false}, TypeSize: 8}, PtrType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, Kind: BufferBlob}}}},
|
||||
&Call{ID: 104, Name: "ptrace$getregset", CallName: "ptrace", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "req", IsOptional: false}, TypeSize: 0, Vals: []uintptr{16900}}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, FlagsType{TypeCommon: TypeCommon{TypeName: "what", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 3, 4, 6, 512, 513, 514}}, PtrType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "iovec_out", IsOptional: false}, Fields: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "addr", TypeSize: 8}}}, Dir: DirIn}}},
|
||||
&Call{ID: 105, Name: "ptrace$setregs", CallName: "ptrace", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "req", IsOptional: false}, TypeSize: 0, Vals: []uintptr{13, 15}}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, IntType{TypeCommon: TypeCommon{TypeName: "ignored", IsOptional: false}, TypeSize: 8}, PtrType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, Kind: BufferBlob}}}},
|
||||
&Call{ID: 106, Name: "ptrace$setregset", CallName: "ptrace", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "req", IsOptional: false}, TypeSize: 0, Vals: []uintptr{16901}}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, FlagsType{TypeCommon: TypeCommon{TypeName: "what", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 3, 4, 6, 512, 513, 514}}, PtrType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "iovec_in", IsOptional: false}, Fields: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "addr", TypeSize: 8}}}, Dir: DirIn}}},
|
||||
&Call{ID: 107, Name: "ptrace$getsig", CallName: "ptrace", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "req", IsOptional: false}, TypeSize: 0, Vals: []uintptr{16898}}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, IntType{TypeCommon: TypeCommon{TypeName: "ignored", IsOptional: false}, TypeSize: 8}, PtrType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "siginfo", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "signo", IsOptional: false}, TypeSize: 4, Limit: 130}, IntType{TypeCommon: TypeCommon{TypeName: "errno", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "code", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "pad3", IsOptional: false}, TypeSize: 4}}}, Dir: DirOut}}},
|
||||
&Call{ID: 108, Name: "ptrace$setsig", CallName: "ptrace", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "req", IsOptional: false}, TypeSize: 0, Vals: []uintptr{16899}}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, IntType{TypeCommon: TypeCommon{TypeName: "ignored", IsOptional: false}, TypeSize: 8}, PtrType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "siginfo", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "signo", IsOptional: false}, TypeSize: 4, Limit: 130}, IntType{TypeCommon: TypeCommon{TypeName: "errno", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "code", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "pad3", IsOptional: false}, TypeSize: 4}}}, Dir: DirIn}}},
|
||||
&Call{ID: 109, Name: "ptrace$setopts", CallName: "ptrace", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "req", IsOptional: false}, TypeSize: 0, Vals: []uintptr{16896, 16902}}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, IntType{TypeCommon: TypeCommon{TypeName: "ignored", IsOptional: false}, TypeSize: 8}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1048576, 8, 16, 64, 2, 1, 4, 32}}}},
|
||||
&Call{ID: 110, Name: "ptrace$getenv", CallName: "ptrace", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "req", IsOptional: false}, TypeSize: 0, Vals: []uintptr{16897}}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, IntType{TypeCommon: TypeCommon{TypeName: "ignored", IsOptional: false}, TypeSize: 8}, PtrType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 8}, Dir: DirOut}}},
|
||||
&Call{ID: 111, Name: "ptrace$cont", CallName: "ptrace", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "req", IsOptional: false}, TypeSize: 0, Vals: []uintptr{7, 24, 9, 31, 32}}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, IntType{TypeCommon: TypeCommon{TypeName: "ignored", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, TypeSize: 8}}},
|
||||
&Call{ID: 112, Name: "io_setup", CallName: "io_setup", Args: []Type{IntType{TypeCommon: TypeCommon{TypeName: "n", IsOptional: false}, TypeSize: 4}, PtrType{TypeCommon: TypeCommon{TypeName: "ctx", IsOptional: false}, Type: ResourceType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: ResIOCtx}, Dir: DirOut}}},
|
||||
&Call{ID: 113, Name: "io_destroy", CallName: "io_destroy", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "ctx", IsOptional: false}, Kind: ResIOCtx}}},
|
||||
&Call{ID: 114, Name: "io_getevents", CallName: "io_getevents", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "ctx", IsOptional: false}, Kind: ResIOCtx}, IntType{TypeCommon: TypeCommon{TypeName: "min_nr", IsOptional: false}, TypeSize: 8}, LenType{TypeCommon: TypeCommon{TypeName: "nr", IsOptional: false}, Buf: "events", TypeSize: 0}, PtrType{TypeCommon: TypeCommon{TypeName: "events", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "io_event", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "obj", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "res", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "res2", IsOptional: false}, TypeSize: 4}}}}, Dir: DirOut}, PtrType{TypeCommon: TypeCommon{TypeName: "timeout", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}}},
|
||||
&Call{ID: 115, Name: "io_submit", CallName: "io_submit", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "ctx", IsOptional: false}, Kind: ResIOCtx}, LenType{TypeCommon: TypeCommon{TypeName: "nr", IsOptional: false}, Buf: "iocbpp", TypeSize: 0}, PtrType{TypeCommon: TypeCommon{TypeName: "iocbpp", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: PtrType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "iocb", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "key", IsOptional: false}, TypeSize: 8}, FlagsType{TypeCommon: TypeCommon{TypeName: "op", IsOptional: false}, TypeSize: 2, Vals: []uintptr{0, 1, 2, 3, 4, 5, 6, 7, 8}}, IntType{TypeCommon: TypeCommon{TypeName: "prio", IsOptional: false}, TypeSize: 2}, ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Dir: DirInOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "nbytes", IsOptional: false}, Buf: "buf", TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "offset", IsOptional: false}, TypeSize: 8}, PtrType{TypeCommon: TypeCommon{TypeName: "reserv", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sigevent", IsOptional: false}, Fields: []Type{VmaType{TypeCommon: TypeCommon{TypeName: "val", IsOptional: false}}, IntType{TypeCommon: TypeCommon{TypeName: "signo", IsOptional: false}, TypeSize: 4, Limit: 130}, FlagsType{TypeCommon: TypeCommon{TypeName: "notify", IsOptional: false}, TypeSize: 4, Vals: []uintptr{1, 0, 2}}, IntType{TypeCommon: TypeCommon{TypeName: "pad0", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad1", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad3", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad4", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad5", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad6", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad7", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 4, Vals: []uintptr{1}}, ResourceType{TypeCommon: TypeCommon{TypeName: "resfd", IsOptional: false}, Kind: ResFD, Subkind: FdEvent}}}, Dir: DirIn}}, Dir: DirIn}}},
|
||||
&Call{ID: 116, Name: "io_cancel", CallName: "io_cancel", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "ctx", IsOptional: false}, Kind: ResIOCtx}, PtrType{TypeCommon: TypeCommon{TypeName: "iocb", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "iocb", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "key", IsOptional: false}, TypeSize: 8}, FlagsType{TypeCommon: TypeCommon{TypeName: "op", IsOptional: false}, TypeSize: 2, Vals: []uintptr{0, 1, 2, 3, 4, 5, 6, 7, 8}}, IntType{TypeCommon: TypeCommon{TypeName: "prio", IsOptional: false}, TypeSize: 2}, ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Dir: DirInOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "nbytes", IsOptional: false}, Buf: "buf", TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "offset", IsOptional: false}, TypeSize: 8}, PtrType{TypeCommon: TypeCommon{TypeName: "reserv", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sigevent", IsOptional: false}, Fields: []Type{VmaType{TypeCommon: TypeCommon{TypeName: "val", IsOptional: false}}, IntType{TypeCommon: TypeCommon{TypeName: "signo", IsOptional: false}, TypeSize: 4, Limit: 130}, FlagsType{TypeCommon: TypeCommon{TypeName: "notify", IsOptional: false}, TypeSize: 4, Vals: []uintptr{1, 0, 2}}, IntType{TypeCommon: TypeCommon{TypeName: "pad0", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad1", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad3", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad4", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad5", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad6", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad7", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 4, Vals: []uintptr{1}}, ResourceType{TypeCommon: TypeCommon{TypeName: "resfd", IsOptional: false}, Kind: ResFD, Subkind: FdEvent}}}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "res", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "io_event", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "obj", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "res", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "res2", IsOptional: false}, TypeSize: 4}}}, Dir: DirOut}}},
|
||||
&Call{ID: 117, Name: "capget", CallName: "capget", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "hdr", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "cap_header", IsOptional: false}, Fields: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "var", IsOptional: false}, TypeSize: 4, Vals: []uintptr{429392688, 537333798, 537396514}}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}}}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "cap_data", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "eff0", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "perm0", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "inher0", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "eff1", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "perm1", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "inher1", IsOptional: false}, TypeSize: 4}}}, Dir: DirIn}}},
|
||||
&Call{ID: 118, Name: "capset", CallName: "capset", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "hdr", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "cap_header", IsOptional: false}, Fields: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "var", IsOptional: false}, TypeSize: 4, Vals: []uintptr{429392688, 537333798, 537396514}}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}}}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "cap_data", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "eff0", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "perm0", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "inher0", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "eff1", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "perm1", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "inher1", IsOptional: false}, TypeSize: 4}}}, Dir: DirIn}}},
|
||||
&Call{ID: 119, Name: "prctl", CallName: "prctl", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "option", IsOptional: false}, TypeSize: 0, Vals: []uintptr{23, 24, 36, 37, 4, 3, 20, 19, 10, 9, 12, 11, 8, 7, 15, 16, 38, 39, 1, 2, 1499557217, 22, 21, 28, 27, 40, 29, 30, 14, 13, 31, 32, 26, 25, 6, 5, 33, 34, 35}}, IntType{TypeCommon: TypeCommon{TypeName: "arg2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "arg3", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "arg4", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "arg5", IsOptional: false}, TypeSize: 8}}},
|
||||
&Call{ID: 120, Name: "arch_prctl", CallName: "arch_prctl", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "code", IsOptional: false}, TypeSize: 0, Vals: []uintptr{4098, 4099, 4097, 4100}}, PtrType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "ioctl_arg", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "a0", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a1", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a3", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a4", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a5", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a6", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "a7", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}}},
|
||||
&Call{ID: 121, Name: "seccomp", CallName: "seccomp", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "op", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1}}, PtrType{TypeCommon: TypeCommon{TypeName: "prog", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sock_fprog", IsOptional: false}, Fields: []Type{LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "filter", TypeSize: 8}, PtrType{TypeCommon: TypeCommon{TypeName: "filter", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sock_filter", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "code", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "jt", IsOptional: false}, TypeSize: 1}, IntType{TypeCommon: TypeCommon{TypeName: "kf", IsOptional: false}, TypeSize: 1}, IntType{TypeCommon: TypeCommon{TypeName: "k", IsOptional: false}, TypeSize: 4}}}}, Dir: DirIn}}}, Dir: DirIn}}},
|
||||
&Call{ID: 122, Name: "add_key", CallName: "add_key", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResKey}, Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "type", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "type", IsOptional: false}, Kind: BufferString}}, PtrType{TypeCommon: TypeCommon{TypeName: "desc", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "desc", IsOptional: false}, Kind: BufferString}}, PtrType{TypeCommon: TypeCommon{TypeName: "payload", IsOptional: true}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "payload", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "paylen", IsOptional: false}, Buf: "payload", TypeSize: 0}, FlagsType{TypeCommon: TypeCommon{TypeName: "keyring", IsOptional: false}, TypeSize: 0, Vals: []uintptr{18446744073709551615, 18446744073709551614, 18446744073709551613, 18446744073709551612, 18446744073709551611}}}},
|
||||
&Call{ID: 123, Name: "request_key", CallName: "request_key", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResKey}, Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "type", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "type", IsOptional: false}, Kind: BufferString}}, PtrType{TypeCommon: TypeCommon{TypeName: "desc", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "desc", IsOptional: false}, Kind: BufferString}}, PtrType{TypeCommon: TypeCommon{TypeName: "callout", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "callout", IsOptional: false}, Kind: BufferString}}, FlagsType{TypeCommon: TypeCommon{TypeName: "keyring", IsOptional: false}, TypeSize: 0, Vals: []uintptr{18446744073709551615, 18446744073709551614, 18446744073709551613, 18446744073709551612, 18446744073709551611}}}},
|
||||
&Call{ID: 124, Name: "keyctl", CallName: "keyctl", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "code", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}}, ResourceType{TypeCommon: TypeCommon{TypeName: "key", IsOptional: false}, Kind: ResKey}, PtrType{TypeCommon: TypeCommon{TypeName: "arg2", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "arg2", IsOptional: false}, Kind: BufferString}}, IntType{TypeCommon: TypeCommon{TypeName: "arg3", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "arg4", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "arg5", IsOptional: false}, TypeSize: 8}}},
|
||||
&Call{ID: 125, Name: "mq_open", CallName: "mq_open", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: FdMq}, Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Kind: BufferString}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1, 2, 2048, 64, 128, 64}}, FlagsType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 0, Vals: []uintptr{256, 128, 64, 32, 16, 8, 4, 2, 1}}, PtrType{TypeCommon: TypeCommon{TypeName: "attr", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "mq_attr", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "maxmsg", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "msgsize", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "curmsg", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "res0", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "res1", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "res2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "res3", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}}},
|
||||
&Call{ID: 126, Name: "mq_timedsend", CallName: "mq_timedsend", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "mqd", IsOptional: false}, Kind: ResFD, Subkind: FdMq}, PtrType{TypeCommon: TypeCommon{TypeName: "msg", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "msg", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "msglen", IsOptional: false}, Buf: "msg", TypeSize: 0}, IntType{TypeCommon: TypeCommon{TypeName: "prio", IsOptional: false}, TypeSize: 8}, PtrType{TypeCommon: TypeCommon{TypeName: "timeout", IsOptional: true}, Type: StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}}},
|
||||
&Call{ID: 127, Name: "mq_timedreceive", CallName: "mq_timedreceive", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "mqd", IsOptional: false}, Kind: ResFD, Subkind: FdMq}, PtrType{TypeCommon: TypeCommon{TypeName: "msg", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "msg", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "msglen", IsOptional: false}, Buf: "msg", TypeSize: 0}, IntType{TypeCommon: TypeCommon{TypeName: "prio", IsOptional: false}, TypeSize: 8}, PtrType{TypeCommon: TypeCommon{TypeName: "timeout", IsOptional: true}, Type: StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}}},
|
||||
&Call{ID: 128, Name: "mq_notify", CallName: "mq_notify", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "mqd", IsOptional: false}, Kind: ResFD, Subkind: FdMq}, PtrType{TypeCommon: TypeCommon{TypeName: "notif", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sigevent", IsOptional: false}, Fields: []Type{VmaType{TypeCommon: TypeCommon{TypeName: "val", IsOptional: false}}, IntType{TypeCommon: TypeCommon{TypeName: "signo", IsOptional: false}, TypeSize: 4, Limit: 130}, FlagsType{TypeCommon: TypeCommon{TypeName: "notify", IsOptional: false}, TypeSize: 4, Vals: []uintptr{1, 0, 2}}, IntType{TypeCommon: TypeCommon{TypeName: "pad0", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad1", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad3", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad4", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad5", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad6", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad7", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}}},
|
||||
&Call{ID: 129, Name: "mq_getsetattr", CallName: "mq_getsetattr", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "mqd", IsOptional: false}, Kind: ResFD, Subkind: FdMq}, PtrType{TypeCommon: TypeCommon{TypeName: "attr", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "mq_attr", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "maxmsg", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "msgsize", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "curmsg", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "res0", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "res1", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "res2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "res3", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "oldattr", IsOptional: true}, Type: StructType{TypeCommon: TypeCommon{TypeName: "mq_attr", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "maxmsg", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "msgsize", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "curmsg", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "res0", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "res1", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "res2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "res3", IsOptional: false}, TypeSize: 8}}}, Dir: DirOut}}},
|
||||
&Call{ID: 130, Name: "mq_unlink", CallName: "mq_unlink", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Kind: BufferString}}}},
|
||||
&Call{ID: 131, Name: "msgget", CallName: "msgget", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResIPC, Subkind: IPCMsq}, Args: []Type{IntType{TypeCommon: TypeCommon{TypeName: "key", IsOptional: false}, TypeSize: 4}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{512, 1024, 256, 128, 64, 32, 16, 8, 4, 2, 1}}}},
|
||||
&Call{ID: 132, Name: "msgsnd", CallName: "msgsnd", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "msqid", IsOptional: false}, Kind: ResIPC, Subkind: IPCMsq}, PtrType{TypeCommon: TypeCommon{TypeName: "msgp", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "msgp", IsOptional: false}, Kind: BufferBlob}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{2048, 8192, 4096}}}},
|
||||
&Call{ID: 133, Name: "msgrcv", CallName: "msgrcv", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "msqid", IsOptional: false}, Kind: ResIPC, Subkind: IPCMsq}, PtrType{TypeCommon: TypeCommon{TypeName: "msgp", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "msgp", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "sz", IsOptional: false}, Buf: "msgp", TypeSize: 0}, IntType{TypeCommon: TypeCommon{TypeName: "typ", IsOptional: false}, TypeSize: 8}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{2048, 8192, 4096}}}},
|
||||
&Call{ID: 134, Name: "msgctl", CallName: "msgctl", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "msqid", IsOptional: false}, Kind: ResIPC, Subkind: IPCMsq}, FlagsType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Vals: []uintptr{2, 1, 0, 3, 12, 11}}, PtrType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "msqid_ds", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "key", IsOptional: false}, TypeSize: 4}, ResourceType{TypeCommon: TypeCommon{TypeName: "uid", IsOptional: false}, Kind: ResUid}, ResourceType{TypeCommon: TypeCommon{TypeName: "gid", IsOptional: false}, Kind: ResGid}, ResourceType{TypeCommon: TypeCommon{TypeName: "cuid", IsOptional: false}, Kind: ResUid}, ResourceType{TypeCommon: TypeCommon{TypeName: "cgid", IsOptional: false}, Kind: ResGid}, IntType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "seq", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "stime", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "rtime", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "ctime", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "cbytes", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "qnum", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "qbytes", IsOptional: false}, TypeSize: 8}, ResourceType{TypeCommon: TypeCommon{TypeName: "lspid", IsOptional: false}, Kind: ResPid}, ResourceType{TypeCommon: TypeCommon{TypeName: "lrpid", IsOptional: false}, Kind: ResPid}}}, Dir: DirInOut}}},
|
||||
&Call{ID: 135, Name: "semget", CallName: "semget", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResIPC, Subkind: IPCSem}, Args: []Type{IntType{TypeCommon: TypeCommon{TypeName: "key", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "nsems", IsOptional: false}, TypeSize: 8}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{512, 1024, 256, 128, 64, 32, 16, 8, 4, 2, 1}}}},
|
||||
&Call{ID: 136, Name: "semop", CallName: "semop", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "semid", IsOptional: false}, Kind: ResIPC, Subkind: IPCSem}, PtrType{TypeCommon: TypeCommon{TypeName: "ops", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sembuf", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "num", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "op", IsOptional: false}, TypeSize: 2}, FlagsType{TypeCommon: TypeCommon{TypeName: "flg", IsOptional: false}, TypeSize: 8, Vals: []uintptr{2048, 4096}}}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "nops", IsOptional: false}, Buf: "ops", TypeSize: 0}}},
|
||||
&Call{ID: 137, Name: "semtimedop", CallName: "semtimedop", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "semid", IsOptional: false}, Kind: ResIPC, Subkind: IPCSem}, PtrType{TypeCommon: TypeCommon{TypeName: "ops", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sembuf", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "num", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "op", IsOptional: false}, TypeSize: 2}, FlagsType{TypeCommon: TypeCommon{TypeName: "flg", IsOptional: false}, TypeSize: 8, Vals: []uintptr{2048, 4096}}}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "nops", IsOptional: false}, Buf: "ops", TypeSize: 0}, PtrType{TypeCommon: TypeCommon{TypeName: "timeout", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}}},
|
||||
&Call{ID: 138, Name: "semctl", CallName: "semctl", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "semid", IsOptional: false}, Kind: ResIPC, Subkind: IPCSem}, IntType{TypeCommon: TypeCommon{TypeName: "semnum", IsOptional: false}, TypeSize: 8}, FlagsType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Vals: []uintptr{2, 1, 0, 3, 19, 18, 13, 14, 11, 12, 15, 17, 16}}, PtrType{TypeCommon: TypeCommon{TypeName: "arg", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "semid_ds", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "key", IsOptional: false}, TypeSize: 4}, ResourceType{TypeCommon: TypeCommon{TypeName: "uid", IsOptional: false}, Kind: ResUid}, ResourceType{TypeCommon: TypeCommon{TypeName: "gid", IsOptional: false}, Kind: ResGid}, ResourceType{TypeCommon: TypeCommon{TypeName: "cuid", IsOptional: false}, Kind: ResUid}, ResourceType{TypeCommon: TypeCommon{TypeName: "cgid", IsOptional: false}, Kind: ResGid}, IntType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "seq", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "otime", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "ctime", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsems", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}}},
|
||||
&Call{ID: 139, Name: "shmget", CallName: "shmget", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResIPC, Subkind: IPCShm}, Args: []Type{IntType{TypeCommon: TypeCommon{TypeName: "key", IsOptional: false}, TypeSize: 4}, LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "unused", TypeSize: 0}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{512, 1024, 2048, 4096, 256, 128, 64, 32, 16, 8, 4, 2, 1}}, VmaType{TypeCommon: TypeCommon{TypeName: "unused", IsOptional: false}}}},
|
||||
&Call{ID: 140, Name: "shmat", CallName: "shmat", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "shmid", IsOptional: false}, Kind: ResIPC, Subkind: IPCShm}, VmaType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{8192, 4096, 16384}}}},
|
||||
&Call{ID: 141, Name: "shmctl", CallName: "shmctl", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "shmid", IsOptional: false}, Kind: ResIPC, Subkind: IPCShm}, FlagsType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Vals: []uintptr{2, 1, 0, 3, 14, 13, 11, 12}}, PtrType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "shmid_ds", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "key", IsOptional: false}, TypeSize: 4}, ResourceType{TypeCommon: TypeCommon{TypeName: "uid", IsOptional: false}, Kind: ResUid}, ResourceType{TypeCommon: TypeCommon{TypeName: "gid", IsOptional: false}, Kind: ResGid}, ResourceType{TypeCommon: TypeCommon{TypeName: "cuid", IsOptional: false}, Kind: ResUid}, ResourceType{TypeCommon: TypeCommon{TypeName: "cgid", IsOptional: false}, Kind: ResGid}, IntType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "seq", IsOptional: false}, TypeSize: 2}, IntType{TypeCommon: TypeCommon{TypeName: "segsz", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "atime", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "atime", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "dtime", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "ctime", IsOptional: false}, TypeSize: 8}, ResourceType{TypeCommon: TypeCommon{TypeName: "cpid", IsOptional: false}, Kind: ResPid}, ResourceType{TypeCommon: TypeCommon{TypeName: "lpid", IsOptional: false}, Kind: ResPid}, IntType{TypeCommon: TypeCommon{TypeName: "nattch", IsOptional: false}, TypeSize: 8}}}, Dir: DirInOut}}},
|
||||
&Call{ID: 142, Name: "shmdt", CallName: "shmdt", Args: []Type{VmaType{TypeCommon: TypeCommon{TypeName: "addr", IsOptional: false}}}},
|
||||
&Call{ID: 143, Name: "mknod", CallName: "mknod", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}}}, FlagsType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 0, Vals: []uintptr{32768, 8192, 24576, 4096, 49152, 256, 128, 64, 32, 16, 8, 4, 2, 1}}, IntType{TypeCommon: TypeCommon{TypeName: "dev", IsOptional: false}, TypeSize: 4}}},
|
||||
&Call{ID: 144, Name: "mknodat", CallName: "mknodat", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "dirfd", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}}}, FlagsType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 0, Vals: []uintptr{32768, 8192, 24576, 4096, 49152, 256, 128, 64, 32, 16, 8, 4, 2, 1}}, IntType{TypeCommon: TypeCommon{TypeName: "dev", IsOptional: false}, TypeSize: 4}}},
|
||||
&Call{ID: 145, Name: "chmod", CallName: "chmod", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}}}, FlagsType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 0, Vals: []uintptr{256, 128, 64, 32, 16, 8, 4, 2, 1}}}},
|
||||
&Call{ID: 146, Name: "fchmod", CallName: "fchmod", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FlagsType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 0, Vals: []uintptr{256, 128, 64, 32, 16, 8, 4, 2, 1}}}},
|
||||
&Call{ID: 147, Name: "fchmodat", CallName: "fchmodat", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "dirfd", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}}}, FlagsType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 0, Vals: []uintptr{256, 128, 64, 32, 16, 8, 4, 2, 1}}}},
|
||||
&Call{ID: 148, Name: "chown", CallName: "chown", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}}}, ResourceType{TypeCommon: TypeCommon{TypeName: "uid", IsOptional: false}, Kind: ResUid}, ResourceType{TypeCommon: TypeCommon{TypeName: "gid", IsOptional: false}, Kind: ResGid}}},
|
||||
&Call{ID: 149, Name: "lchown", CallName: "lchown", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}}}, ResourceType{TypeCommon: TypeCommon{TypeName: "uid", IsOptional: false}, Kind: ResUid}, ResourceType{TypeCommon: TypeCommon{TypeName: "gid", IsOptional: false}, Kind: ResGid}}},
|
||||
&Call{ID: 150, Name: "fchown", CallName: "fchown", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, ResourceType{TypeCommon: TypeCommon{TypeName: "uid", IsOptional: false}, Kind: ResUid}, ResourceType{TypeCommon: TypeCommon{TypeName: "gid", IsOptional: false}, Kind: ResGid}}},
|
||||
&Call{ID: 151, Name: "fchownat", CallName: "fchownat", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "dirfd", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}}}, ResourceType{TypeCommon: TypeCommon{TypeName: "uid", IsOptional: false}, Kind: ResUid}, ResourceType{TypeCommon: TypeCommon{TypeName: "gid", IsOptional: false}, Kind: ResGid}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{4096, 256}}}},
|
||||
&Call{ID: 152, Name: "fallocate", CallName: "fallocate", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FlagsType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1, 2}}, IntType{TypeCommon: TypeCommon{TypeName: "off", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, TypeSize: 8}}},
|
||||
&Call{ID: 153, Name: "faccessat", CallName: "faccessat", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "dirfd", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "pathname", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "pathname", IsOptional: false}}}, FlagsType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 0, Vals: []uintptr{256, 128, 64, 32, 16, 8, 4, 2, 1}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{512, 256}}}},
|
||||
&Call{ID: 154, Name: "utime", CallName: "utime", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "filename", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "filename", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "times", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "utimbuf", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "actime", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "modtime", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}}},
|
||||
&Call{ID: 155, Name: "utimes", CallName: "utimes", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "filename", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "filename", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "times", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "itimerval", IsOptional: false}, Fields: []Type{StructType{TypeCommon: TypeCommon{TypeName: "timeval", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "usec", IsOptional: false}, TypeSize: 8}}}, StructType{TypeCommon: TypeCommon{TypeName: "timeval", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "usec", IsOptional: false}, TypeSize: 8}}}}}, Dir: DirIn}}},
|
||||
&Call{ID: 156, Name: "futimesat", CallName: "futimesat", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "dir", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "pathname", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "pathname", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "times", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "itimerval", IsOptional: false}, Fields: []Type{StructType{TypeCommon: TypeCommon{TypeName: "timeval", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "usec", IsOptional: false}, TypeSize: 8}}}, StructType{TypeCommon: TypeCommon{TypeName: "timeval", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "usec", IsOptional: false}, TypeSize: 8}}}}}, Dir: DirIn}}},
|
||||
&Call{ID: 157, Name: "utimensat", CallName: "utimensat", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "dir", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "pathname", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "pathname", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "times", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "itimerval", IsOptional: false}, Fields: []Type{StructType{TypeCommon: TypeCommon{TypeName: "timeval", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "usec", IsOptional: false}, TypeSize: 8}}}, StructType{TypeCommon: TypeCommon{TypeName: "timeval", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "usec", IsOptional: false}, TypeSize: 8}}}}}, Dir: DirIn}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 256}}}},
|
||||
&Call{ID: 158, Name: "getgid", CallName: "getgid", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResGid}, Args: []Type{}},
|
||||
&Call{ID: 159, Name: "getegid", CallName: "getegid", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResGid}, Args: []Type{}},
|
||||
&Call{ID: 160, Name: "setuid", CallName: "setuid", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "uid", IsOptional: false}, Kind: ResUid}}},
|
||||
&Call{ID: 161, Name: "setgid", CallName: "setgid", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "gid", IsOptional: false}, Kind: ResGid}}},
|
||||
&Call{ID: 162, Name: "getuid", CallName: "getuid", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResUid}, Args: []Type{}},
|
||||
&Call{ID: 163, Name: "geteuid", CallName: "geteuid", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResUid}, Args: []Type{}},
|
||||
&Call{ID: 164, Name: "setpgid", CallName: "setpgid", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, ResourceType{TypeCommon: TypeCommon{TypeName: "pgid", IsOptional: false}, Kind: ResPid}}},
|
||||
&Call{ID: 165, Name: "getpgid", CallName: "getpgid", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResPid}, Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}}},
|
||||
&Call{ID: 166, Name: "getpgrp", CallName: "getpgrp", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResPid}, Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}}},
|
||||
&Call{ID: 167, Name: "getpid", CallName: "getpid", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResPid}, Args: []Type{}},
|
||||
&Call{ID: 168, Name: "gettid", CallName: "gettid", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResPid}, Args: []Type{}},
|
||||
&Call{ID: 169, Name: "setreuid", CallName: "setreuid", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "ruid", IsOptional: false}, Kind: ResUid}, ResourceType{TypeCommon: TypeCommon{TypeName: "euid", IsOptional: false}, Kind: ResUid}}},
|
||||
&Call{ID: 170, Name: "setregid", CallName: "setregid", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "rgid", IsOptional: false}, Kind: ResGid}, ResourceType{TypeCommon: TypeCommon{TypeName: "egid", IsOptional: false}, Kind: ResGid}}},
|
||||
&Call{ID: 171, Name: "setresuid", CallName: "setresuid", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "ruid", IsOptional: false}, Kind: ResUid}, ResourceType{TypeCommon: TypeCommon{TypeName: "euid", IsOptional: false}, Kind: ResUid}, ResourceType{TypeCommon: TypeCommon{TypeName: "suid", IsOptional: false}, Kind: ResUid}}},
|
||||
&Call{ID: 172, Name: "setresgid", CallName: "setresgid", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "rgid", IsOptional: false}, Kind: ResGid}, ResourceType{TypeCommon: TypeCommon{TypeName: "egid", IsOptional: false}, Kind: ResGid}, ResourceType{TypeCommon: TypeCommon{TypeName: "sgid", IsOptional: false}, Kind: ResGid}}},
|
||||
&Call{ID: 173, Name: "getresuid", CallName: "getresuid", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "ruid", IsOptional: false}, Type: ResourceType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: ResUid}, Dir: DirOut}, PtrType{TypeCommon: TypeCommon{TypeName: "euid", IsOptional: false}, Type: ResourceType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: ResUid}, Dir: DirOut}, PtrType{TypeCommon: TypeCommon{TypeName: "suid", IsOptional: false}, Type: ResourceType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: ResUid}, Dir: DirOut}}},
|
||||
&Call{ID: 174, Name: "getresgid", CallName: "getresgid", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "rgid", IsOptional: false}, Type: ResourceType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: ResGid}, Dir: DirOut}, PtrType{TypeCommon: TypeCommon{TypeName: "egid", IsOptional: false}, Type: ResourceType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: ResGid}, Dir: DirOut}, PtrType{TypeCommon: TypeCommon{TypeName: "sgid", IsOptional: false}, Type: ResourceType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: ResGid}, Dir: DirOut}}},
|
||||
&Call{ID: 175, Name: "setfsuid", CallName: "setfsuid", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fsuid", IsOptional: false}, Kind: ResUid}}},
|
||||
&Call{ID: 176, Name: "setfsgid", CallName: "setfsgid", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fsgid", IsOptional: false}, Kind: ResGid}}},
|
||||
&Call{ID: 177, Name: "getgroups", CallName: "getgroups", Args: []Type{LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "list", TypeSize: 0}, PtrType{TypeCommon: TypeCommon{TypeName: "list", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: ResourceType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: ResGid}}, Dir: DirInOut}}},
|
||||
&Call{ID: 178, Name: "setgroups", CallName: "setgroups", Args: []Type{LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "list", TypeSize: 0}, PtrType{TypeCommon: TypeCommon{TypeName: "list", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: ResourceType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: ResGid}}, Dir: DirIn}}},
|
||||
&Call{ID: 179, Name: "personality", CallName: "personality", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "persona", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 262144, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728}}}},
|
||||
&Call{ID: 180, Name: "inotify_init", CallName: "inotify_init", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: FdInotify}, Args: []Type{}},
|
||||
&Call{ID: 181, Name: "inotify_init1", CallName: "inotify_init1", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: FdInotify}, Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{2048, 524288}}}},
|
||||
&Call{ID: 182, Name: "inotify_add_watch", CallName: "inotify_add_watch", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResInotifyDesc}, Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdInotify}, PtrType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}}}, FlagsType{TypeCommon: TypeCommon{TypeName: "mask", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 4, 8, 16, 256, 512, 1024, 2, 2048, 64, 128, 32, 33554432, 67108864, 536870912, 2147483648, 16777216}}}},
|
||||
&Call{ID: 183, Name: "inotify_rm_watch", CallName: "inotify_rm_watch", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdInotify}, ResourceType{TypeCommon: TypeCommon{TypeName: "wd", IsOptional: false}, Kind: ResInotifyDesc}}},
|
||||
&Call{ID: 184, Name: "fanotify_init", CallName: "fanotify_init", Ret: ResourceType{TypeCommon: TypeCommon{TypeName: "ret", IsOptional: false}, Kind: ResFD, Subkind: FdFanotify}, Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{8, 4, 0, 1, 2, 16, 32}}, FlagsType{TypeCommon: TypeCommon{TypeName: "events", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1, 2, 0, 524288, 1024, 4096, 262144, 2048, 1052672}}}},
|
||||
&Call{ID: 185, Name: "fanotify_mark", CallName: "fanotify_mark", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdFanotify}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 128, 4, 8, 16, 32, 64}}, FlagsType{TypeCommon: TypeCommon{TypeName: "mask", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 8, 16, 32, 65536, 131072, 1073741824, 134217728}}, ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}}}}},
|
||||
&Call{ID: 186, Name: "link", CallName: "link", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "old", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "old", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "new", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "new", IsOptional: false}}}}},
|
||||
&Call{ID: 187, Name: "linkat", CallName: "linkat", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "oldfd", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "old", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "old", IsOptional: false}}}, ResourceType{TypeCommon: TypeCommon{TypeName: "newfd", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "new", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "new", IsOptional: false}}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{4096, 1024}}}},
|
||||
&Call{ID: 188, Name: "symlinkat", CallName: "symlinkat", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "old", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "old", IsOptional: false}}}, ResourceType{TypeCommon: TypeCommon{TypeName: "newfd", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "new", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "new", IsOptional: false}}}}},
|
||||
&Call{ID: 189, Name: "symlink", CallName: "symlink", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "old", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "old", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "new", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "new", IsOptional: false}}}}},
|
||||
&Call{ID: 190, Name: "unlink", CallName: "unlink", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}}}}},
|
||||
&Call{ID: 191, Name: "unlinkat", CallName: "unlinkat", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 512}}}},
|
||||
&Call{ID: 192, Name: "readlink", CallName: "readlink", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "siz", IsOptional: false}, Buf: "buf", TypeSize: 0}}},
|
||||
&Call{ID: 193, Name: "readlinkat", CallName: "readlinkat", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "siz", IsOptional: false}, Buf: "buf", TypeSize: 0}}},
|
||||
&Call{ID: 194, Name: "rename", CallName: "rename", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "old", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "old", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "new", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "new", IsOptional: false}}}}},
|
||||
&Call{ID: 195, Name: "renameat", CallName: "renameat", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "oldfd", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "old", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "old", IsOptional: false}}}, ResourceType{TypeCommon: TypeCommon{TypeName: "newfd", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "new", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "new", IsOptional: false}}}}},
|
||||
&Call{ID: 196, Name: "renameat2", CallName: "renameat2", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "oldfd", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "old", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "old", IsOptional: false}}}, ResourceType{TypeCommon: TypeCommon{TypeName: "newfd", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "new", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "new", IsOptional: false}}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{2, 1, 4}}}},
|
||||
&Call{ID: 197, Name: "mkdir", CallName: "mkdir", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}}}, FlagsType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 0, Vals: []uintptr{256, 128, 64, 32, 16, 8, 4, 2, 1}}}},
|
||||
&Call{ID: 198, Name: "mkdirat", CallName: "mkdirat", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}}}, FlagsType{TypeCommon: TypeCommon{TypeName: "mode", IsOptional: false}, TypeSize: 0, Vals: []uintptr{256, 128, 64, 32, 16, 8, 4, 2, 1}}}},
|
||||
&Call{ID: 199, Name: "rmdir", CallName: "rmdir", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}}}}},
|
||||
&Call{ID: 200, Name: "truncate", CallName: "truncate", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}}}, IntType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, TypeSize: 8}}},
|
||||
&Call{ID: 201, Name: "ftruncate", CallName: "ftruncate", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, IntType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, TypeSize: 8}}},
|
||||
&Call{ID: 202, Name: "flock", CallName: "flock", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FlagsType{TypeCommon: TypeCommon{TypeName: "op", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 8, 4}}}},
|
||||
&Call{ID: 203, Name: "fsync", CallName: "fsync", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}}},
|
||||
&Call{ID: 204, Name: "fdatasync", CallName: "fdatasync", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}}},
|
||||
&Call{ID: 205, Name: "sync", CallName: "sync", Args: []Type{}},
|
||||
&Call{ID: 206, Name: "syncfs", CallName: "syncfs", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}}},
|
||||
&Call{ID: 207, Name: "sync_file_range", CallName: "sync_file_range", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, IntType{TypeCommon: TypeCommon{TypeName: "off", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nbytes", IsOptional: false}, TypeSize: 8}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 4}}}},
|
||||
&Call{ID: 208, Name: "lookup_dcookie", CallName: "lookup_dcookie", Args: []Type{IntType{TypeCommon: TypeCommon{TypeName: "cookie", IsOptional: false}, TypeSize: 8}, PtrType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "buf", TypeSize: 0}}},
|
||||
&Call{ID: 209, Name: "getdents", CallName: "getdents", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "ent", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "ent", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "count", IsOptional: false}, Buf: "ent", TypeSize: 0}}},
|
||||
&Call{ID: 210, Name: "getdents64", CallName: "getdents64", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "ent", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "ent", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "count", IsOptional: false}, Buf: "ent", TypeSize: 0}}},
|
||||
&Call{ID: 211, Name: "name_to_handle_at", CallName: "name_to_handle_at", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: FdDir}, PtrType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "file", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "handle", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "file_handle", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "bytes", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "type", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "handl0", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl1", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl3", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl4", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl5", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl6", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl7", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl8", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl9", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl10", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl11", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl12", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl13", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl14", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl15", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "mnt", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 4}, Dir: DirOut}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{4096, 1024, 18446744073709551516}}}},
|
||||
&Call{ID: 212, Name: "open_by_handle_at", CallName: "open_by_handle_at", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "mountdirfd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "handle", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "file_handle", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "bytes", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "type", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "handl0", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl1", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl3", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl4", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl5", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl6", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl7", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl8", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl9", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl10", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl11", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl12", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl13", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl14", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "handl15", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1, 2, 1024, 8192, 524288, 64, 16384, 65536, 128, 0, 262144, 256, 131072, 2048, 2097152, 1052672, 512}}}},
|
||||
&Call{ID: 213, Name: "mount", CallName: "mount", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "src", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "src", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "dst", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "dst", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "type", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "type", IsOptional: false}, Kind: BufferString}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{4096, 128, 64, 8192, 1024, 4, 2048, 8, 2, 1, 2097152, 32, 32768, 16777216, 16}}, PtrType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "data", IsOptional: false}, Kind: BufferBlob}}}},
|
||||
&Call{ID: 214, Name: "umount2", CallName: "umount2", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 4, 8}}}},
|
||||
&Call{ID: 215, Name: "pivot_root", CallName: "pivot_root", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "new_root", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "new_root", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "put_old", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "put_old", IsOptional: false}}}}},
|
||||
&Call{ID: 216, Name: "sysfs", CallName: "sysfs", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "option", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 3}}, IntType{TypeCommon: TypeCommon{TypeName: "arg1", IsOptional: false}, TypeSize: 8}, PtrType{TypeCommon: TypeCommon{TypeName: "arg2", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "arg2", IsOptional: false}, Kind: BufferString}}}},
|
||||
&Call{ID: 217, Name: "statfs", CallName: "statfs", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Kind: BufferBlob}}}},
|
||||
&Call{ID: 218, Name: "fstatfs", CallName: "fstatfs", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Kind: BufferBlob}}}},
|
||||
&Call{ID: 219, Name: "uselib", CallName: "uselib", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "lib", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "lib", IsOptional: false}}}}},
|
||||
&Call{ID: 220, Name: "init_module", CallName: "init_module", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "mod", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "mod", IsOptional: false}, Kind: BufferString}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "mod", TypeSize: 0}, PtrType{TypeCommon: TypeCommon{TypeName: "args", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "args", IsOptional: false}, Kind: BufferString}}}},
|
||||
&Call{ID: 221, Name: "finit_module", CallName: "finit_module", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "args", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "args", IsOptional: false}, Kind: BufferString}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2}}}},
|
||||
&Call{ID: 222, Name: "delete_module", CallName: "delete_module", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Kind: BufferString}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{2048, 512}}}},
|
||||
&Call{ID: 223, Name: "kexec_load", CallName: "kexec_load", Args: []Type{IntType{TypeCommon: TypeCommon{TypeName: "entry", IsOptional: false}, TypeSize: 8}, LenType{TypeCommon: TypeCommon{TypeName: "nr_segments", IsOptional: false}, Buf: "segments", TypeSize: 0}, PtrType{TypeCommon: TypeCommon{TypeName: "segments", IsOptional: false}, Type: ArrayType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "kexec_segment", IsOptional: false}, Fields: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "sz", IsOptional: false}, Buf: "buf", TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "mem", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "memsz", IsOptional: false}, TypeSize: 8}}}}, Dir: DirIn}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 196608, 4063232, 1310720, 1376256, 3276800, 2621440, 1441792, 2752512, 524288, 655360}}}},
|
||||
&Call{ID: 224, Name: "get_kernel_syms", CallName: "get_kernel_syms", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "table", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "table", IsOptional: false}, Kind: BufferBlob}}}},
|
||||
&Call{ID: 225, Name: "syslog", CallName: "syslog", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "cmd", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1, 2, 3, 4, 5, 7, 9, 10}}, PtrType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: true}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "len", IsOptional: false}, Buf: "buf", TypeSize: 0}}},
|
||||
&Call{ID: 226, Name: "uname", CallName: "uname", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Kind: BufferBlob}}}},
|
||||
&Call{ID: 227, Name: "sysinfo", CallName: "sysinfo", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "info", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "info", IsOptional: false}, Kind: BufferBlob}}}},
|
||||
&Call{ID: 228, Name: "ustat", CallName: "ustat", Args: []Type{IntType{TypeCommon: TypeCommon{TypeName: "dev", IsOptional: false}, TypeSize: 8}, PtrType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "ustat", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "free", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "inode", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nampac0", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "nampac1", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "nampac2", IsOptional: false}, TypeSize: 4}}}, Dir: DirOut}}},
|
||||
&Call{ID: 229, Name: "acct", CallName: "acct", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "filename", IsOptional: true}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "filename", IsOptional: false}}}}},
|
||||
&Call{ID: 230, Name: "getrusage", CallName: "getrusage", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "who", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 18446744073709551615, 1}}, PtrType{TypeCommon: TypeCommon{TypeName: "usage", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "rusage", IsOptional: false}, Fields: []Type{StructType{TypeCommon: TypeCommon{TypeName: "timeval", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "usec", IsOptional: false}, TypeSize: 8}}}, StructType{TypeCommon: TypeCommon{TypeName: "timeval", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "usec", IsOptional: false}, TypeSize: 8}}}, IntType{TypeCommon: TypeCommon{TypeName: "maxrss", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "ixrss", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "idrss", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "isrss", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "minflt", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "majflt", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nswap", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "inblock", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "oublock", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "msgsnd", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "msgrcv", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "signals", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nvcsw", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nivcsw", IsOptional: false}, TypeSize: 8}}}, Dir: DirOut}}},
|
||||
&Call{ID: 231, Name: "getrlimit", CallName: "getrlimit", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "res", IsOptional: false}, TypeSize: 0, Vals: []uintptr{9, 4, 0, 2, 1, 10, 8, 12, 13, 7, 6, 5, 14, 15, 11, 3}}, PtrType{TypeCommon: TypeCommon{TypeName: "rlim", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "rlimit", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "soft", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "hard", IsOptional: false}, TypeSize: 8}}}, Dir: DirOut}}},
|
||||
&Call{ID: 232, Name: "setrlimit", CallName: "setrlimit", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "res", IsOptional: false}, TypeSize: 0, Vals: []uintptr{9, 4, 0, 2, 1, 10, 8, 12, 13, 7, 6, 5, 14, 15, 11, 3}}, PtrType{TypeCommon: TypeCommon{TypeName: "rlim", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "rlimit", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "soft", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "hard", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}}},
|
||||
&Call{ID: 233, Name: "prlimit64", CallName: "prlimit64", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, FlagsType{TypeCommon: TypeCommon{TypeName: "res", IsOptional: false}, TypeSize: 0, Vals: []uintptr{9, 4, 0, 2, 1, 10, 8, 12, 13, 7, 6, 5, 14, 15, 11, 3}}, PtrType{TypeCommon: TypeCommon{TypeName: "new", IsOptional: true}, Type: StructType{TypeCommon: TypeCommon{TypeName: "rlimit", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "soft", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "hard", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "old", IsOptional: true}, Type: StructType{TypeCommon: TypeCommon{TypeName: "rlimit", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "soft", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "hard", IsOptional: false}, TypeSize: 8}}}, Dir: DirOut}}},
|
||||
&Call{ID: 234, Name: "iopl", CallName: "iopl", Args: []Type{IntType{TypeCommon: TypeCommon{TypeName: "level", IsOptional: false}, TypeSize: 1}}},
|
||||
&Call{ID: 235, Name: "ioperm", CallName: "ioperm", Args: []Type{IntType{TypeCommon: TypeCommon{TypeName: "from", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "num", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "on", IsOptional: false}, TypeSize: 8}}},
|
||||
&Call{ID: 236, Name: "ioprio_get", CallName: "ioprio_get", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "which", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 3}}, ResourceType{TypeCommon: TypeCommon{TypeName: "who", IsOptional: false}, Kind: ResPid}}},
|
||||
&Call{ID: 237, Name: "ioprio_set", CallName: "ioprio_set", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "which", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 3}}, ResourceType{TypeCommon: TypeCommon{TypeName: "who", IsOptional: false}, Kind: ResPid}, IntType{TypeCommon: TypeCommon{TypeName: "prio", IsOptional: false}, TypeSize: 8}}},
|
||||
&Call{ID: 238, Name: "setns", CallName: "setns", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, FlagsType{TypeCommon: TypeCommon{TypeName: "type", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 134217728, 1073741824, 67108864}}}},
|
||||
&Call{ID: 239, Name: "setxattr", CallName: "setxattr", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Kind: BufferString}}, PtrType{TypeCommon: TypeCommon{TypeName: "val", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "val", IsOptional: false}, Kind: BufferString}}, LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "val", TypeSize: 0}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2}}}},
|
||||
&Call{ID: 240, Name: "lsetxattr", CallName: "lsetxattr", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Kind: BufferString}}, PtrType{TypeCommon: TypeCommon{TypeName: "val", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "val", IsOptional: false}, Kind: BufferString}}, LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "val", TypeSize: 0}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2}}}},
|
||||
&Call{ID: 241, Name: "fsetxattr", CallName: "fsetxattr", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Kind: BufferString}}, PtrType{TypeCommon: TypeCommon{TypeName: "val", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "val", IsOptional: false}, Kind: BufferString}}, LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "val", TypeSize: 0}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2}}}},
|
||||
&Call{ID: 242, Name: "getxattr", CallName: "getxattr", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Kind: BufferString}}, PtrType{TypeCommon: TypeCommon{TypeName: "val", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "val", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "val", TypeSize: 0}}},
|
||||
&Call{ID: 243, Name: "lgetxattr", CallName: "lgetxattr", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Kind: BufferString}}, PtrType{TypeCommon: TypeCommon{TypeName: "val", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "val", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "val", TypeSize: 0}}},
|
||||
&Call{ID: 244, Name: "fgetxattr", CallName: "fgetxattr", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Kind: BufferString}}, PtrType{TypeCommon: TypeCommon{TypeName: "val", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "val", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "val", TypeSize: 0}}},
|
||||
&Call{ID: 245, Name: "listxattr", CallName: "listxattr", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "list", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "list", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "list", TypeSize: 0}}},
|
||||
&Call{ID: 246, Name: "llistxattr", CallName: "llistxattr", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "list", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "list", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "list", TypeSize: 0}}},
|
||||
&Call{ID: 247, Name: "flistxattr", CallName: "flistxattr", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "list", IsOptional: false}, Dir: DirOut, Type: BufferType{TypeCommon: TypeCommon{TypeName: "list", IsOptional: false}, Kind: BufferBlob}}, LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "list", TypeSize: 0}}},
|
||||
&Call{ID: 248, Name: "removexattr", CallName: "removexattr", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Kind: BufferString}}}},
|
||||
&Call{ID: 249, Name: "lremovexattr", CallName: "lremovexattr", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}, Dir: DirIn, Type: FilenameType{TypeCommon: TypeCommon{TypeName: "path", IsOptional: false}}}, PtrType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Kind: BufferString}}}},
|
||||
&Call{ID: 250, Name: "fremovexattr", CallName: "fremovexattr", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "fd", IsOptional: false}, Kind: ResFD, Subkind: ResAny}, PtrType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Dir: DirIn, Type: BufferType{TypeCommon: TypeCommon{TypeName: "name", IsOptional: false}, Kind: BufferString}}}},
|
||||
&Call{ID: 251, Name: "time", CallName: "time", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "t", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 8}, Dir: DirOut}}},
|
||||
&Call{ID: 252, Name: "clock_gettime", CallName: "clock_gettime", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "id", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 5, 1, 6, 4, 7, 2, 3}}, PtrType{TypeCommon: TypeCommon{TypeName: "tp", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, Dir: DirOut}}},
|
||||
&Call{ID: 253, Name: "clock_settime", CallName: "clock_settime", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "id", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 5, 1, 6, 4, 7, 2, 3}}, PtrType{TypeCommon: TypeCommon{TypeName: "tp", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}}},
|
||||
&Call{ID: 254, Name: "clock_adjtime", CallName: "clock_adjtime", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "id", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 5, 1, 6, 4, 7, 2, 3}}, PtrType{TypeCommon: TypeCommon{TypeName: "tx", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "timex", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "stuff0", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff1", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff3", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff4", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff5", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff6", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff7", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff8", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff9", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff10", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff11", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff12", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff13", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff14", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff15", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff16", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff17", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff18", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff19", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff20", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff21", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff22", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff23", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff24", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stuff25", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}}},
|
||||
&Call{ID: 255, Name: "clock_getres", CallName: "clock_getres", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "id", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 5, 1, 6, 4, 7, 2, 3}}, PtrType{TypeCommon: TypeCommon{TypeName: "tp", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, Dir: DirOut}}},
|
||||
&Call{ID: 256, Name: "clock_nanosleep", CallName: "clock_nanosleep", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "id", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 5, 1, 6, 4, 7, 2, 3}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1}}, PtrType{TypeCommon: TypeCommon{TypeName: "rqtp", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "rmtp", IsOptional: true}, Type: StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, Dir: DirOut}}},
|
||||
&Call{ID: 257, Name: "timer_create", CallName: "timer_create", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "id", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 5, 1, 6, 4, 7, 2, 3}}, PtrType{TypeCommon: TypeCommon{TypeName: "ev", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sigevent", IsOptional: false}, Fields: []Type{VmaType{TypeCommon: TypeCommon{TypeName: "val", IsOptional: false}}, IntType{TypeCommon: TypeCommon{TypeName: "signo", IsOptional: false}, TypeSize: 4, Limit: 130}, FlagsType{TypeCommon: TypeCommon{TypeName: "notify", IsOptional: false}, TypeSize: 4, Vals: []uintptr{1, 0, 2}}, IntType{TypeCommon: TypeCommon{TypeName: "pad0", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad1", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad2", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad3", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad4", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad5", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad6", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "pad7", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "timerid", IsOptional: false}, Type: ResourceType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, Kind: ResTimerid}, Dir: DirOut}}},
|
||||
&Call{ID: 258, Name: "timer_gettime", CallName: "timer_gettime", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "timerid", IsOptional: false}, Kind: ResTimerid}, PtrType{TypeCommon: TypeCommon{TypeName: "setting", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "itimerspec", IsOptional: false}, Fields: []Type{StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}}}, Dir: DirOut}}},
|
||||
&Call{ID: 259, Name: "timer_getoverrun", CallName: "timer_getoverrun", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "timerid", IsOptional: false}, Kind: ResTimerid}}},
|
||||
&Call{ID: 260, Name: "timer_settime", CallName: "timer_settime", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "timerid", IsOptional: false}, Kind: ResTimerid}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1}}, PtrType{TypeCommon: TypeCommon{TypeName: "new", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "itimerspec", IsOptional: false}, Fields: []Type{StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}}}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "old", IsOptional: true}, Type: StructType{TypeCommon: TypeCommon{TypeName: "itimerspec", IsOptional: false}, Fields: []Type{StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}}}, Dir: DirOut}}},
|
||||
&Call{ID: 261, Name: "timer_delete", CallName: "timer_delete", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "timerid", IsOptional: false}, Kind: ResTimerid}}},
|
||||
&Call{ID: 262, Name: "rt_sigaction", CallName: "rt_sigaction", Args: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sig", IsOptional: false}, TypeSize: 4, Limit: 130}, PtrType{TypeCommon: TypeCommon{TypeName: "act", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sigaction", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "handler", IsOptional: false}, TypeSize: 8}, StructType{TypeCommon: TypeCommon{TypeName: "sigset", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "mask", IsOptional: false}, TypeSize: 8}}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 8, Vals: []uintptr{1, 2, 1073741824, 134217728, 2147483648, 268435456, 4}}, IntType{TypeCommon: TypeCommon{TypeName: "restor", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "oact", IsOptional: true}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sigaction", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "handler", IsOptional: false}, TypeSize: 8}, StructType{TypeCommon: TypeCommon{TypeName: "sigset", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "mask", IsOptional: false}, TypeSize: 8}}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 8, Vals: []uintptr{1, 2, 1073741824, 134217728, 2147483648, 268435456, 4}}, IntType{TypeCommon: TypeCommon{TypeName: "restor", IsOptional: false}, TypeSize: 8}}}, Dir: DirOut}, LenType{TypeCommon: TypeCommon{TypeName: "sigsetsize", IsOptional: false}, Buf: "fake", TypeSize: 0}, PtrType{TypeCommon: TypeCommon{TypeName: "fake", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sigset", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "mask", IsOptional: false}, TypeSize: 8}}}, Dir: DirOut}}},
|
||||
&Call{ID: 263, Name: "rt_sigprocmask", CallName: "rt_sigprocmask", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "how", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1, 2}}, PtrType{TypeCommon: TypeCommon{TypeName: "nset", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sigset", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "mask", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "oset", IsOptional: true}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sigset", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "mask", IsOptional: false}, TypeSize: 8}}}, Dir: DirOut}, LenType{TypeCommon: TypeCommon{TypeName: "sigsetsize", IsOptional: false}, Buf: "nset", TypeSize: 0}}},
|
||||
&Call{ID: 264, Name: "rt_sigreturn", CallName: "rt_sigreturn", Args: []Type{}},
|
||||
&Call{ID: 265, Name: "rt_sigpending", CallName: "rt_sigpending", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "set", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sigset", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "mask", IsOptional: false}, TypeSize: 8}}}, Dir: DirOut}, LenType{TypeCommon: TypeCommon{TypeName: "sigsetsize", IsOptional: false}, Buf: "set", TypeSize: 0}}},
|
||||
&Call{ID: 266, Name: "rt_sigtimedwait", CallName: "rt_sigtimedwait", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "these", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sigset", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "mask", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "info", IsOptional: true}, Type: StructType{TypeCommon: TypeCommon{TypeName: "siginfo", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "signo", IsOptional: false}, TypeSize: 4, Limit: 130}, IntType{TypeCommon: TypeCommon{TypeName: "errno", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "code", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "pad3", IsOptional: false}, TypeSize: 4}}}, Dir: DirOut}, PtrType{TypeCommon: TypeCommon{TypeName: "ts", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "sigsetsize", IsOptional: false}, Buf: "these", TypeSize: 0}}},
|
||||
&Call{ID: 267, Name: "rt_sigsuspend", CallName: "rt_sigsuspend", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "new", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sigset", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "mask", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, LenType{TypeCommon: TypeCommon{TypeName: "sigsetsize", IsOptional: false}, Buf: "new", TypeSize: 0}}},
|
||||
&Call{ID: 268, Name: "rt_sigqueueinfo", CallName: "rt_sigqueueinfo", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, IntType{TypeCommon: TypeCommon{TypeName: "sig", IsOptional: false}, TypeSize: 4, Limit: 130}, PtrType{TypeCommon: TypeCommon{TypeName: "info", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "siginfo", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "signo", IsOptional: false}, TypeSize: 4, Limit: 130}, IntType{TypeCommon: TypeCommon{TypeName: "errno", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "code", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "pad3", IsOptional: false}, TypeSize: 4}}}, Dir: DirIn}}},
|
||||
&Call{ID: 269, Name: "rt_tgsigqueueinfo", CallName: "rt_tgsigqueueinfo", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "gid", IsOptional: false}, Kind: ResPid}, ResourceType{TypeCommon: TypeCommon{TypeName: "tid", IsOptional: false}, Kind: ResPid}, IntType{TypeCommon: TypeCommon{TypeName: "sig", IsOptional: false}, TypeSize: 4, Limit: 130}, PtrType{TypeCommon: TypeCommon{TypeName: "info", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "siginfo", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "signo", IsOptional: false}, TypeSize: 4, Limit: 130}, IntType{TypeCommon: TypeCommon{TypeName: "errno", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "code", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "pad3", IsOptional: false}, TypeSize: 4}}}, Dir: DirIn}}},
|
||||
&Call{ID: 270, Name: "sigaltstack", CallName: "sigaltstack", Args: []Type{VmaType{TypeCommon: TypeCommon{TypeName: "ss", IsOptional: false}}, PtrType{TypeCommon: TypeCommon{TypeName: "oss", IsOptional: true}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 8}, Dir: DirOut}}},
|
||||
&Call{ID: 271, Name: "tgkill", CallName: "tgkill", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "gid", IsOptional: false}, Kind: ResPid}, ResourceType{TypeCommon: TypeCommon{TypeName: "tid", IsOptional: false}, Kind: ResPid}, IntType{TypeCommon: TypeCommon{TypeName: "sig", IsOptional: false}, TypeSize: 4, Limit: 130}}},
|
||||
&Call{ID: 272, Name: "tkill", CallName: "tkill", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "tid", IsOptional: false}, Kind: ResPid}, IntType{TypeCommon: TypeCommon{TypeName: "sig", IsOptional: false}, TypeSize: 4, Limit: 130}}},
|
||||
&Call{ID: 273, Name: "pause", CallName: "pause", Args: []Type{}},
|
||||
&Call{ID: 274, Name: "alarm", CallName: "alarm", Args: []Type{IntType{TypeCommon: TypeCommon{TypeName: "seconds", IsOptional: false}, TypeSize: 8}}},
|
||||
&Call{ID: 275, Name: "nanosleep", CallName: "nanosleep", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "req", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "rem", IsOptional: true}, Type: StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, Dir: DirOut}}},
|
||||
&Call{ID: 276, Name: "getitimer", CallName: "getitimer", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "which", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1, 2}}, PtrType{TypeCommon: TypeCommon{TypeName: "cur", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "itimerval", IsOptional: false}, Fields: []Type{StructType{TypeCommon: TypeCommon{TypeName: "timeval", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "usec", IsOptional: false}, TypeSize: 8}}}, StructType{TypeCommon: TypeCommon{TypeName: "timeval", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "usec", IsOptional: false}, TypeSize: 8}}}}}, Dir: DirOut}}},
|
||||
&Call{ID: 277, Name: "setitimer", CallName: "setitimer", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "which", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1, 2}}, PtrType{TypeCommon: TypeCommon{TypeName: "new", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "itimerval", IsOptional: false}, Fields: []Type{StructType{TypeCommon: TypeCommon{TypeName: "timeval", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "usec", IsOptional: false}, TypeSize: 8}}}, StructType{TypeCommon: TypeCommon{TypeName: "timeval", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "usec", IsOptional: false}, TypeSize: 8}}}}}, Dir: DirIn}, PtrType{TypeCommon: TypeCommon{TypeName: "old", IsOptional: true}, Type: StructType{TypeCommon: TypeCommon{TypeName: "itimerval", IsOptional: false}, Fields: []Type{StructType{TypeCommon: TypeCommon{TypeName: "timeval", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "usec", IsOptional: false}, TypeSize: 8}}}, StructType{TypeCommon: TypeCommon{TypeName: "timeval", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "usec", IsOptional: false}, TypeSize: 8}}}}}, Dir: DirOut}}},
|
||||
&Call{ID: 278, Name: "exit", CallName: "exit", Args: []Type{IntType{TypeCommon: TypeCommon{TypeName: "code", IsOptional: false}, TypeSize: 8}}},
|
||||
&Call{ID: 279, Name: "exit_group", CallName: "exit_group", Args: []Type{IntType{TypeCommon: TypeCommon{TypeName: "code", IsOptional: false}, TypeSize: 8}}},
|
||||
&Call{ID: 280, Name: "waitid", CallName: "waitid", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "which", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 0}}, ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, PtrType{TypeCommon: TypeCommon{TypeName: "infop", IsOptional: true}, Type: StructType{TypeCommon: TypeCommon{TypeName: "siginfo", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "signo", IsOptional: false}, TypeSize: 4, Limit: 130}, IntType{TypeCommon: TypeCommon{TypeName: "errno", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "code", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "pad3", IsOptional: false}, TypeSize: 4}}}, Dir: DirOut}, FlagsType{TypeCommon: TypeCommon{TypeName: "options", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 8, 4, 2, 8, 1, 16777216, 2147483648, 1073741824, 536870912}}, PtrType{TypeCommon: TypeCommon{TypeName: "ru", IsOptional: true}, Type: StructType{TypeCommon: TypeCommon{TypeName: "rusage", IsOptional: false}, Fields: []Type{StructType{TypeCommon: TypeCommon{TypeName: "timeval", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "usec", IsOptional: false}, TypeSize: 8}}}, StructType{TypeCommon: TypeCommon{TypeName: "timeval", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "usec", IsOptional: false}, TypeSize: 8}}}, IntType{TypeCommon: TypeCommon{TypeName: "maxrss", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "ixrss", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "idrss", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "isrss", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "minflt", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "majflt", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nswap", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "inblock", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "oublock", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "msgsnd", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "msgrcv", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "signals", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nvcsw", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nivcsw", IsOptional: false}, TypeSize: 8}}}, Dir: DirOut}}},
|
||||
&Call{ID: 281, Name: "wait4", CallName: "wait4", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, PtrType{TypeCommon: TypeCommon{TypeName: "status", IsOptional: true}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 4}, Dir: DirOut}, FlagsType{TypeCommon: TypeCommon{TypeName: "options", IsOptional: false}, TypeSize: 0, Vals: []uintptr{1, 2, 8, 4, 2, 8, 1, 16777216, 2147483648, 1073741824, 536870912}}, PtrType{TypeCommon: TypeCommon{TypeName: "ru", IsOptional: true}, Type: StructType{TypeCommon: TypeCommon{TypeName: "rusage", IsOptional: false}, Fields: []Type{StructType{TypeCommon: TypeCommon{TypeName: "timeval", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "usec", IsOptional: false}, TypeSize: 8}}}, StructType{TypeCommon: TypeCommon{TypeName: "timeval", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "usec", IsOptional: false}, TypeSize: 8}}}, IntType{TypeCommon: TypeCommon{TypeName: "maxrss", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "ixrss", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "idrss", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "isrss", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "minflt", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "majflt", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nswap", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "inblock", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "oublock", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "msgsnd", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "msgrcv", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "signals", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nvcsw", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nivcsw", IsOptional: false}, TypeSize: 8}}}, Dir: DirOut}}},
|
||||
&Call{ID: 282, Name: "times", CallName: "times", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "buf", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "tms", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "utime", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "stime", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "cutime", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "cstime", IsOptional: false}, TypeSize: 8}}}, Dir: DirOut}}},
|
||||
&Call{ID: 283, Name: "set_thread_area", CallName: "set_thread_area", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "info", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "user_desc", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "entry", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "base", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "limit", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 1}}}, Dir: DirIn}}},
|
||||
&Call{ID: 284, Name: "get_thread_area", CallName: "get_thread_area", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "info", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "user_desc", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "entry", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "base", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "limit", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 1}}}, Dir: DirIn}}},
|
||||
&Call{ID: 285, Name: "set_tid_address", CallName: "set_tid_address", Args: []Type{PtrType{TypeCommon: TypeCommon{TypeName: "tidptr", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 4}, Dir: DirOut}}},
|
||||
&Call{ID: 286, Name: "getpriority", CallName: "getpriority", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "which", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1, 2}}, ResourceType{TypeCommon: TypeCommon{TypeName: "who", IsOptional: false}, Kind: ResPid}}},
|
||||
&Call{ID: 287, Name: "setpriority", CallName: "setpriority", Args: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "which", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 1, 2}}, ResourceType{TypeCommon: TypeCommon{TypeName: "who", IsOptional: false}, Kind: ResPid}, IntType{TypeCommon: TypeCommon{TypeName: "prio", IsOptional: false}, TypeSize: 8}}},
|
||||
&Call{ID: 288, Name: "sched_getscheduler", CallName: "sched_getscheduler", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}}},
|
||||
&Call{ID: 289, Name: "sched_setscheduler", CallName: "sched_setscheduler", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, FlagsType{TypeCommon: TypeCommon{TypeName: "policy", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0, 3, 5, 1, 2, 6}}, PtrType{TypeCommon: TypeCommon{TypeName: "prio", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 4}, Dir: DirIn}}},
|
||||
&Call{ID: 290, Name: "sched_rr_get_interval", CallName: "sched_rr_get_interval", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, PtrType{TypeCommon: TypeCommon{TypeName: "tp", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "timespec", IsOptional: false}, Fields: []Type{IntType{TypeCommon: TypeCommon{TypeName: "sec", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "nsec", IsOptional: false}, TypeSize: 8}}}, Dir: DirOut}}},
|
||||
&Call{ID: 291, Name: "sched_getparam", CallName: "sched_getparam", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, PtrType{TypeCommon: TypeCommon{TypeName: "prio", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 4}, Dir: DirOut}}},
|
||||
&Call{ID: 292, Name: "sched_setparam", CallName: "sched_setparam", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, PtrType{TypeCommon: TypeCommon{TypeName: "prio", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 4}, Dir: DirIn}}},
|
||||
&Call{ID: 293, Name: "sched_getaffinity", CallName: "sched_getaffinity", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, LenType{TypeCommon: TypeCommon{TypeName: "cpusetsize", IsOptional: false}, Buf: "mask", TypeSize: 0}, PtrType{TypeCommon: TypeCommon{TypeName: "mask", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 8}, Dir: DirOut}}},
|
||||
&Call{ID: 294, Name: "sched_setaffinity", CallName: "sched_setaffinity", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, LenType{TypeCommon: TypeCommon{TypeName: "cpusetsize", IsOptional: false}, Buf: "mask", TypeSize: 0}, PtrType{TypeCommon: TypeCommon{TypeName: "mask", IsOptional: false}, Type: IntType{TypeCommon: TypeCommon{TypeName: "", IsOptional: false}, TypeSize: 8}, Dir: DirIn}}},
|
||||
&Call{ID: 295, Name: "sched_getattr", CallName: "sched_getattr", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, PtrType{TypeCommon: TypeCommon{TypeName: "attr", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sched_attr", IsOptional: false}, Fields: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, TypeSize: 4, Vals: []uintptr{48}}, FlagsType{TypeCommon: TypeCommon{TypeName: "policy", IsOptional: false}, TypeSize: 4, Vals: []uintptr{0, 3, 5, 1, 2, 6}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 8, Vals: []uintptr{0, 1}}, IntType{TypeCommon: TypeCommon{TypeName: "nice", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "prio", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "runtime", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "deadlin", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "period", IsOptional: false}, TypeSize: 8}}}, Dir: DirOut}, LenType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, Buf: "attr", TypeSize: 0}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0}}}},
|
||||
&Call{ID: 296, Name: "sched_setattr", CallName: "sched_setattr", Args: []Type{ResourceType{TypeCommon: TypeCommon{TypeName: "pid", IsOptional: false}, Kind: ResPid}, PtrType{TypeCommon: TypeCommon{TypeName: "attr", IsOptional: false}, Type: StructType{TypeCommon: TypeCommon{TypeName: "sched_attr", IsOptional: false}, Fields: []Type{FlagsType{TypeCommon: TypeCommon{TypeName: "size", IsOptional: false}, TypeSize: 4, Vals: []uintptr{48}}, FlagsType{TypeCommon: TypeCommon{TypeName: "policy", IsOptional: false}, TypeSize: 4, Vals: []uintptr{0, 3, 5, 1, 2, 6}}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 8, Vals: []uintptr{0, 1}}, IntType{TypeCommon: TypeCommon{TypeName: "nice", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "prio", IsOptional: false}, TypeSize: 4}, IntType{TypeCommon: TypeCommon{TypeName: "runtime", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "deadlin", IsOptional: false}, TypeSize: 8}, IntType{TypeCommon: TypeCommon{TypeName: "period", IsOptional: false}, TypeSize: 8}}}, Dir: DirIn}, FlagsType{TypeCommon: TypeCommon{TypeName: "flags", IsOptional: false}, TypeSize: 0, Vals: []uintptr{0}}}},
|
||||
&Call{ID: 297, Name: "sched_yield", CallName: "sched_yield", Args: []Type{}},
|
||||
}
|
1134
sys/sys.txt
Normal file
1134
sys/sys.txt
Normal file
File diff suppressed because it is too large
Load Diff
92
sysgen/parser.go
Normal file
92
sysgen/parser.go
Normal file
@ -0,0 +1,92 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Parser struct {
|
||||
r *bufio.Scanner
|
||||
s string
|
||||
i int
|
||||
l int
|
||||
}
|
||||
|
||||
func NewParser(r io.Reader) *Parser {
|
||||
return &Parser{r: bufio.NewScanner(r)}
|
||||
}
|
||||
|
||||
func (p *Parser) Scan() bool {
|
||||
if !p.r.Scan() {
|
||||
if err := p.r.Err(); err != nil {
|
||||
failf("failed to read input file: %v", err)
|
||||
}
|
||||
return false
|
||||
}
|
||||
p.s = p.r.Text()
|
||||
p.i = 0
|
||||
p.l++
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *Parser) Str() string {
|
||||
return p.s
|
||||
}
|
||||
|
||||
func (p *Parser) EOF() bool {
|
||||
return p.i == len(p.s)
|
||||
}
|
||||
|
||||
func (p *Parser) Char() byte {
|
||||
if p.EOF() {
|
||||
p.failf("unexpected eof")
|
||||
}
|
||||
return p.s[p.i]
|
||||
}
|
||||
|
||||
func (p *Parser) Parse(ch byte) {
|
||||
if p.EOF() {
|
||||
p.failf("want %s, got EOF", string(ch))
|
||||
}
|
||||
if p.s[p.i] != ch {
|
||||
p.failf("want '%v', got '%v'", string(ch), string(p.s[p.i]))
|
||||
}
|
||||
p.i++
|
||||
p.SkipWs()
|
||||
}
|
||||
|
||||
func (p *Parser) SkipWs() {
|
||||
for p.i < len(p.s) && (p.s[p.i] == ' ' || p.s[p.i] == '\t') {
|
||||
p.i++
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) Ident() string {
|
||||
i := p.i
|
||||
for p.i < len(p.s) &&
|
||||
(p.s[p.i] >= 'a' && p.s[p.i] <= 'z' ||
|
||||
p.s[p.i] >= 'A' && p.s[p.i] <= 'Z' ||
|
||||
p.s[p.i] >= '0' && p.s[p.i] <= '9' ||
|
||||
p.s[p.i] == '_' || p.s[p.i] == '$') { // $ is for n-way syscalls (like ptrace$peek)
|
||||
p.i++
|
||||
}
|
||||
if i == p.i {
|
||||
p.failf("failed to parse identifier at pos %v", i)
|
||||
}
|
||||
if ch := p.s[i]; ch >= '0' && ch <= '9' {
|
||||
// p.failf("identifier starts with a digit at pos %v", i)
|
||||
}
|
||||
s := p.s[i:p.i]
|
||||
p.SkipWs()
|
||||
return s
|
||||
}
|
||||
|
||||
func (p *Parser) failf(msg string, args ...interface{}) {
|
||||
fmt.Fprintf(os.Stderr, "line #%v: %v\n", p.l, p.s)
|
||||
failf(msg, args...)
|
||||
}
|
649
sysgen/sysgen.go
Normal file
649
sysgen/sysgen.go
Normal file
@ -0,0 +1,649 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 2 {
|
||||
failf("usage: gen input_file")
|
||||
}
|
||||
inf, err := os.Open(os.Args[1])
|
||||
if err != nil {
|
||||
failf("failed to open input file: %v", err)
|
||||
}
|
||||
defer inf.Close()
|
||||
|
||||
includes, defines, syscalls, structs, unnamed, flags := parse(bufio.NewReader(inf))
|
||||
intFlags, flagVals := compileFlags(includes, defines, flags)
|
||||
|
||||
out := new(bytes.Buffer)
|
||||
generate(syscalls, structs, unnamed, intFlags, out)
|
||||
writeSource("sys.go", out.Bytes())
|
||||
|
||||
out = new(bytes.Buffer)
|
||||
generateConsts(flagVals, out)
|
||||
writeSource("../prog/consts.go", out.Bytes())
|
||||
|
||||
out = new(bytes.Buffer)
|
||||
generateHeader(syscalls, out)
|
||||
writeFile("../executor/syscalls.h", out.Bytes())
|
||||
}
|
||||
|
||||
type Syscall struct {
|
||||
Name string
|
||||
CallName string
|
||||
Args [][]string
|
||||
Ret []string
|
||||
}
|
||||
|
||||
type Struct struct {
|
||||
Name string
|
||||
Flds [][]string
|
||||
}
|
||||
|
||||
type Flag struct {
|
||||
Name string
|
||||
Values []string
|
||||
}
|
||||
|
||||
func generate(syscalls []Syscall, structs map[string]Struct, unnamed map[string][]string, flags map[string][]string, out io.Writer) {
|
||||
fmt.Fprintf(out, "// AUTOGENERATED FILE\n")
|
||||
fmt.Fprintf(out, "package sys\n\n")
|
||||
|
||||
fmt.Fprintf(out, "var Calls = []*Call {\n")
|
||||
for i, s := range syscalls {
|
||||
fmt.Fprintf(out, "&Call{ID: %v, Name: \"%v\", CallName: \"%v\"", i, s.Name, s.CallName)
|
||||
if len(s.Ret) != 0 {
|
||||
fmt.Fprintf(out, ", Ret: ")
|
||||
generateArg("ret", s.Ret[0], s.Ret[1:], structs, unnamed, flags, false, out)
|
||||
}
|
||||
fmt.Fprintf(out, ", Args: []Type{")
|
||||
for i, a := range s.Args {
|
||||
if i != 0 {
|
||||
fmt.Fprintf(out, ", ")
|
||||
}
|
||||
generateArg(a[0], a[1], a[2:], structs, unnamed, flags, false, out)
|
||||
}
|
||||
fmt.Fprintf(out, "}},\n")
|
||||
}
|
||||
fmt.Fprintf(out, "}\n")
|
||||
}
|
||||
|
||||
func generateArg(name, typ string, a []string, structs map[string]Struct, unnamed map[string][]string, flags map[string][]string, isField bool, out io.Writer) {
|
||||
name = "\"" + name + "\""
|
||||
opt := false
|
||||
for i, v := range a {
|
||||
if v == "opt" {
|
||||
opt = true
|
||||
copy(a[i:], a[i+1:])
|
||||
a = a[:len(a)-1]
|
||||
break
|
||||
}
|
||||
}
|
||||
common := func() string {
|
||||
return fmt.Sprintf("TypeCommon: TypeCommon{TypeName: %v, IsOptional: %v}", name, opt)
|
||||
}
|
||||
switch typ {
|
||||
case "fd":
|
||||
if len(a) == 0 {
|
||||
a = append(a, "")
|
||||
}
|
||||
if want := 1; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
fmt.Fprintf(out, "ResourceType{%v, Kind: ResFD, Subkind: %v}", common(), fmtFdKind(a[0]))
|
||||
case "io_ctx":
|
||||
if want := 0; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
fmt.Fprintf(out, "ResourceType{%v, Kind: ResIOCtx}", common())
|
||||
case "ipc":
|
||||
if want := 1; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
fmt.Fprintf(out, "ResourceType{%v, Kind: ResIPC, Subkind: %v}", common(), fmtIPCKind(a[0]))
|
||||
case "key":
|
||||
if want := 0; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
fmt.Fprintf(out, "ResourceType{%v, Kind: ResKey}", common())
|
||||
case "inotifydesc":
|
||||
if want := 0; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
fmt.Fprintf(out, "ResourceType{%v, Kind: ResInotifyDesc}", common())
|
||||
case "timerid":
|
||||
if want := 0; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
fmt.Fprintf(out, "ResourceType{%v, Kind: ResTimerid}", common())
|
||||
case "pid":
|
||||
if want := 0; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
fmt.Fprintf(out, "ResourceType{%v, Kind: ResPid}", common())
|
||||
case "uid":
|
||||
if want := 0; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
fmt.Fprintf(out, "ResourceType{%v, Kind: ResUid}", common())
|
||||
case "gid":
|
||||
if want := 0; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
fmt.Fprintf(out, "ResourceType{%v, Kind: ResGid}", common())
|
||||
case "fileoff":
|
||||
var size uint64
|
||||
if isField {
|
||||
if want := 2; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
size = typeToSize(a[1])
|
||||
} else {
|
||||
if want := 1; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(out, "FileoffType{%v, File: \"%v\", TypeSize: %v}", common(), a[0], size)
|
||||
case "buffer":
|
||||
if want := 1; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
commonHdr := common()
|
||||
opt = false
|
||||
fmt.Fprintf(out, "PtrType{%v, Dir: %v, Type: BufferType{%v, Kind: BufferBlob}}", commonHdr, fmtDir(a[0]), 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))
|
||||
}
|
||||
commonHdr := common()
|
||||
opt = false
|
||||
fmt.Fprintf(out, "PtrType{%v, Dir: %v, Type: BufferType{%v, Kind: BufferString}}", commonHdr, fmtDir("in"), common())
|
||||
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))
|
||||
}
|
||||
fmt.Fprintf(out, "BufferType{%v, Kind: BufferSockaddr}", common())
|
||||
case "vma":
|
||||
if want := 0; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
fmt.Fprintf(out, "VmaType{%v}", common())
|
||||
case "len":
|
||||
var size uint64
|
||||
if isField {
|
||||
if want := 2; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
size = typeToSize(a[1])
|
||||
} else {
|
||||
if want := 1; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(out, "LenType{%v, Buf: \"%v\", TypeSize: %v}", common(), a[0], size)
|
||||
case "flags":
|
||||
var size uint64
|
||||
if isField {
|
||||
if want := 2; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
size = typeToSize(a[1])
|
||||
} else {
|
||||
if want := 1; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
}
|
||||
vals := flags[a[0]]
|
||||
if len(vals) == 0 {
|
||||
failf("unknown flag %v", a[0])
|
||||
}
|
||||
fmt.Fprintf(out, "FlagsType{%v, TypeSize: %v, Vals: []uintptr{%v}}", common(), size, strings.Join(vals, ","))
|
||||
case "int8", "int16", "int32", "int64", "intptr":
|
||||
if want := 0; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
fmt.Fprintf(out, "IntType{%v, TypeSize: %v}", common(), typeToSize(typ))
|
||||
case "signalno":
|
||||
if want := 0; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
fmt.Fprintf(out, "IntType{%v, TypeSize: 4, Limit: 130}", common())
|
||||
case "filename":
|
||||
if want := 0; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
commonHdr := common()
|
||||
opt = false
|
||||
fmt.Fprintf(out, "PtrType{%v, Dir: DirIn, Type: FilenameType{%v}}", commonHdr, common())
|
||||
case "array":
|
||||
if want := 1; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
fmt.Fprintf(out, "ArrayType{%v, Type: %v}", common(), generateType(a[0], structs, unnamed, flags))
|
||||
case "ptr":
|
||||
if want := 2; len(a) != want {
|
||||
failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a))
|
||||
}
|
||||
fmt.Fprintf(out, "PtrType{%v, Type: %v, Dir: %v}", common(), generateType(a[1], structs, unnamed, flags), fmtDir(a[0]))
|
||||
default:
|
||||
if strings.HasPrefix(typ, "unnamed") {
|
||||
if inner, ok := unnamed[typ]; ok {
|
||||
generateArg("", inner[0], inner[1:], structs, unnamed, flags, isField, out)
|
||||
return
|
||||
}
|
||||
failf("unknown unnamed type '%v'", typ)
|
||||
}
|
||||
if str, ok := structs[typ]; ok {
|
||||
fmt.Fprintf(out, "StructType{TypeCommon: TypeCommon{TypeName: \"%v\", IsOptional: %v}, Fields: []Type{", str.Name, false)
|
||||
for i, a := range str.Flds {
|
||||
if i != 0 {
|
||||
fmt.Fprintf(out, ", ")
|
||||
}
|
||||
generateArg(a[0], a[1], a[2:], structs, unnamed, flags, true, out)
|
||||
}
|
||||
fmt.Fprintf(out, "}}")
|
||||
return
|
||||
}
|
||||
failf("unknown arg type \"%v\" for %v", typ, name)
|
||||
}
|
||||
}
|
||||
|
||||
func generateType(typ string, structs map[string]Struct, unnamed map[string][]string, flags map[string][]string) string {
|
||||
buf := new(bytes.Buffer)
|
||||
generateArg("", typ, nil, structs, unnamed, flags, true, buf)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func fmtFdKind(s string) string {
|
||||
switch s {
|
||||
case "":
|
||||
return "ResAny"
|
||||
case "file":
|
||||
return "FdFile"
|
||||
case "sock":
|
||||
return "FdSock"
|
||||
case "pipe":
|
||||
return "FdPipe"
|
||||
case "signal":
|
||||
return "FdSignal"
|
||||
case "event":
|
||||
return "FdEvent"
|
||||
case "timer":
|
||||
return "FdTimer"
|
||||
case "epoll":
|
||||
return "FdEpoll"
|
||||
case "dir":
|
||||
return "FdDir"
|
||||
case "mq":
|
||||
return "FdMq"
|
||||
case "inotify":
|
||||
return "FdInotify"
|
||||
case "fanotify":
|
||||
return "FdFanotify"
|
||||
default:
|
||||
failf("bad fd type %v", s)
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func fmtIPCKind(s string) string {
|
||||
switch s {
|
||||
case "msq":
|
||||
return "IPCMsq"
|
||||
case "sem":
|
||||
return "IPCSem"
|
||||
case "shm":
|
||||
return "IPCShm"
|
||||
default:
|
||||
failf("bad ipc type %v", s)
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func fmtDir(s string) string {
|
||||
switch s {
|
||||
case "in":
|
||||
return "DirIn"
|
||||
case "out":
|
||||
return "DirOut"
|
||||
case "inout":
|
||||
return "DirInOut"
|
||||
default:
|
||||
failf("bad direction %v", s)
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func typeToSize(typ string) uint64 {
|
||||
switch typ {
|
||||
case "int8", "int16", "int32", "int64", "intptr":
|
||||
default:
|
||||
failf("unknown type %v", typ)
|
||||
}
|
||||
sz := int64(64) // TODO: assume that pointer is 8 bytes for now
|
||||
if typ != "intptr" {
|
||||
sz, _ = strconv.ParseInt(typ[3:], 10, 64)
|
||||
}
|
||||
return uint64(sz / 8)
|
||||
}
|
||||
|
||||
type F struct {
|
||||
name string
|
||||
val string
|
||||
}
|
||||
|
||||
type FlagArray []F
|
||||
|
||||
func (a FlagArray) Len() int { return len(a) }
|
||||
func (a FlagArray) Less(i, j int) bool { return a[i].name < a[j].name }
|
||||
func (a FlagArray) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
|
||||
func generateConsts(flags map[string]string, out io.Writer) {
|
||||
var ff []F
|
||||
for k, v := range flags {
|
||||
ff = append(ff, F{k, v})
|
||||
}
|
||||
sort.Sort(FlagArray(ff))
|
||||
|
||||
fmt.Fprintf(out, "// AUTOGENERATED FILE\n")
|
||||
fmt.Fprintf(out, "package prog\n\n")
|
||||
fmt.Fprintf(out, "const (\n")
|
||||
for _, f := range ff {
|
||||
fmt.Fprintf(out, " %v = %v\n", f.name, f.val)
|
||||
}
|
||||
fmt.Fprintf(out, ")\n")
|
||||
}
|
||||
|
||||
func generateHeader(syscalls []Syscall, out io.Writer) {
|
||||
fmt.Fprint(out, `// AUTOGENERATED FILE
|
||||
|
||||
struct call_t {
|
||||
const char* name;
|
||||
int sys_nr;
|
||||
};
|
||||
|
||||
call_t syscalls[] = {
|
||||
`)
|
||||
for _, s := range syscalls {
|
||||
fmt.Fprintf(out, "\t{\"%v\", __NR_%v},\n", s.Name, s.CallName)
|
||||
}
|
||||
fmt.Fprintf(out, "};\n")
|
||||
}
|
||||
|
||||
func compileFlags(includes []string, defines map[string]string, flags []Flag) (map[string][]string, map[string]string) {
|
||||
vals := make(map[string]string)
|
||||
for _, f := range flags {
|
||||
for _, v := range f.Values {
|
||||
vals[v] = ""
|
||||
}
|
||||
}
|
||||
for k := range defines {
|
||||
vals[k] = ""
|
||||
}
|
||||
valArray := make([]string, 0, len(vals))
|
||||
for k := range vals {
|
||||
valArray = append(valArray, k)
|
||||
}
|
||||
flagVals := fetchValues(valArray, includes, defines)
|
||||
for i, f := range valArray {
|
||||
vals[f] = flagVals[i]
|
||||
}
|
||||
res := make(map[string][]string)
|
||||
for _, f := range flags {
|
||||
var arr []string
|
||||
for _, v := range f.Values {
|
||||
arr = append(arr, vals[v])
|
||||
}
|
||||
if res[f.Name] != nil {
|
||||
failf("flag %v is defined multiple times", f.Name)
|
||||
}
|
||||
res[f.Name] = arr
|
||||
}
|
||||
ids := make(map[string]string)
|
||||
for k, v := range vals {
|
||||
if isIdentifier(k) {
|
||||
ids[k] = v
|
||||
}
|
||||
}
|
||||
return res, ids
|
||||
}
|
||||
|
||||
func fetchValues(vals []string, includes []string, defines map[string]string) []string {
|
||||
includeText := ""
|
||||
for _, inc := range includes {
|
||||
includeText += fmt.Sprintf("#include <%v>\n", inc)
|
||||
}
|
||||
definesText := ""
|
||||
for k, v := range defines {
|
||||
definesText += fmt.Sprintf("#ifndef %v\n#define %v %v\n#endif\n", k, k, v)
|
||||
}
|
||||
src := strings.Replace(fetchSrc, "[[INCLUDES]]", includeText, 1)
|
||||
src = strings.Replace(src, "[[DEFAULTS]]", definesText, 1)
|
||||
src = strings.Replace(src, "[[VALS]]", strings.Join(vals, ","), 1)
|
||||
bin, err := ioutil.TempFile("", "")
|
||||
if err != nil {
|
||||
failf("failed to create temp file: %v", err)
|
||||
}
|
||||
bin.Close()
|
||||
defer os.Remove(bin.Name())
|
||||
|
||||
cmd := exec.Command("gcc", "-x", "c", "-", "-o", bin.Name())
|
||||
cmd.Stdin = strings.NewReader(src)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
failf("failed to run gcc: %v\n%v", err, string(out))
|
||||
}
|
||||
|
||||
out, err = exec.Command(bin.Name()).CombinedOutput()
|
||||
if err != nil {
|
||||
failf("failed to flags binary: %v\n%v", err, string(out))
|
||||
}
|
||||
|
||||
flagVals := strings.Split(string(out), " ")
|
||||
if len(flagVals) != len(vals) {
|
||||
failf("fetched wrong number of values")
|
||||
}
|
||||
for _, v := range flagVals {
|
||||
_, err := strconv.ParseUint(v, 10, 64)
|
||||
if err != nil {
|
||||
failf("failed to parse value: %v (%v)", err, v)
|
||||
}
|
||||
}
|
||||
return flagVals
|
||||
}
|
||||
|
||||
func isIdentifier(s string) bool {
|
||||
for i, c := range s {
|
||||
if c == '_' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || i > 0 && (c >= '0' && c <= '9') {
|
||||
continue
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func parse(in io.Reader) (includes []string, defines map[string]string, syscalls []Syscall, structs map[string]Struct, unnamed map[string][]string, flags []Flag) {
|
||||
p := NewParser(in)
|
||||
defines = make(map[string]string)
|
||||
structs = make(map[string]Struct)
|
||||
unnamed = make(map[string][]string)
|
||||
var str *Struct
|
||||
for p.Scan() {
|
||||
if p.EOF() || p.Char() == '#' {
|
||||
continue
|
||||
}
|
||||
if str != nil {
|
||||
// Parsing a struct.
|
||||
if p.Char() == '}' {
|
||||
p.Parse('}')
|
||||
if _, ok := structs[str.Name]; ok {
|
||||
failf("%v struct is defined multiple times", str.Name)
|
||||
}
|
||||
structs[str.Name] = *str
|
||||
str = nil
|
||||
} else {
|
||||
p.SkipWs()
|
||||
fld := []string{p.Ident()}
|
||||
fld = append(fld, parseType(p, unnamed)...)
|
||||
str.Flds = append(str.Flds, fld)
|
||||
}
|
||||
} else {
|
||||
name := p.Ident()
|
||||
if name == "include" {
|
||||
p.Parse('<')
|
||||
var include []byte
|
||||
for {
|
||||
ch := p.Char()
|
||||
if ch == '>' {
|
||||
break
|
||||
}
|
||||
p.Parse(ch)
|
||||
include = append(include, ch)
|
||||
}
|
||||
p.Parse('>')
|
||||
includes = append(includes, string(include))
|
||||
} else if name == "define" {
|
||||
key := p.Ident()
|
||||
var val []byte
|
||||
for !p.EOF() {
|
||||
ch := p.Char()
|
||||
p.Parse(ch)
|
||||
val = append(val, ch)
|
||||
}
|
||||
if defines[key] != "" {
|
||||
failf("%v define is defined multiple times", key)
|
||||
}
|
||||
defines[key] = string(val)
|
||||
} else {
|
||||
switch p.Char() {
|
||||
case '(':
|
||||
// syscall
|
||||
p.Parse('(')
|
||||
var args [][]string
|
||||
for p.Char() != ')' {
|
||||
arg := []string{p.Ident()}
|
||||
arg = append(arg, parseType(p, unnamed)...)
|
||||
args = append(args, arg)
|
||||
if p.Char() != ')' {
|
||||
p.Parse(',')
|
||||
}
|
||||
}
|
||||
p.Parse(')')
|
||||
var ret []string
|
||||
if !p.EOF() {
|
||||
ret = parseType(p, unnamed)
|
||||
}
|
||||
callName := name
|
||||
if idx := strings.IndexByte(callName, '$'); idx != -1 {
|
||||
callName = callName[:idx]
|
||||
}
|
||||
syscalls = append(syscalls, Syscall{name, callName, args, ret})
|
||||
case '=':
|
||||
// flag
|
||||
p.Parse('=')
|
||||
vals := []string{p.Ident()}
|
||||
for !p.EOF() {
|
||||
p.Parse(',')
|
||||
vals = append(vals, p.Ident())
|
||||
}
|
||||
flags = append(flags, Flag{name, vals})
|
||||
case '{':
|
||||
p.Parse('{')
|
||||
str = &Struct{Name: name}
|
||||
default:
|
||||
failf("bad line (%v)", p.Str())
|
||||
}
|
||||
}
|
||||
}
|
||||
if !p.EOF() {
|
||||
failf("trailing data (%v)", p.Str())
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func parseType(p *Parser, unnamed map[string][]string) []string {
|
||||
return parseType1(p, unnamed, p.Ident())
|
||||
}
|
||||
|
||||
var unnamedSeq int
|
||||
|
||||
func parseType1(p *Parser, unnamed map[string][]string, name string) []string {
|
||||
typ := []string{name}
|
||||
if !p.EOF() && p.Char() == '[' {
|
||||
p.Parse('[')
|
||||
for {
|
||||
id := p.Ident()
|
||||
if p.Char() == '[' {
|
||||
inner := parseType1(p, unnamed, id)
|
||||
id = fmt.Sprintf("unnamed%v", unnamedSeq)
|
||||
unnamedSeq++
|
||||
unnamed[id] = inner
|
||||
}
|
||||
typ = append(typ, id)
|
||||
if p.Char() == ']' {
|
||||
break
|
||||
}
|
||||
p.Parse(',')
|
||||
}
|
||||
p.Parse(']')
|
||||
}
|
||||
return typ
|
||||
}
|
||||
|
||||
func writeSource(file string, data []byte) {
|
||||
src, err := format.Source(data)
|
||||
if err != nil {
|
||||
fmt.Printf("%s\n", data)
|
||||
failf("failed to format output: %v", err)
|
||||
}
|
||||
writeFile(file, src)
|
||||
}
|
||||
|
||||
func writeFile(file string, data []byte) {
|
||||
outf, err := os.Create(file)
|
||||
if err != nil {
|
||||
failf("failed to create output file: %v", err)
|
||||
}
|
||||
defer outf.Close()
|
||||
outf.Write(data)
|
||||
}
|
||||
|
||||
func failf(msg string, args ...interface{}) {
|
||||
fmt.Fprintf(os.Stderr, msg+"\n", args...)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var fetchSrc = `
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
[[INCLUDES]]
|
||||
|
||||
[[DEFAULTS]]
|
||||
|
||||
int main() {
|
||||
int i;
|
||||
unsigned long vals[] = {[[VALS]]};
|
||||
for (i = 0; i < sizeof(vals)/sizeof(vals[0]); i++) {
|
||||
if (i != 0)
|
||||
printf(" ");
|
||||
printf("%lu", vals[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
`
|
83
tools/execlog/execlog.go
Normal file
83
tools/execlog/execlog.go
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
// execlog executes all programs from a log (for non-reproducible crashes).
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"flag"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/google/syzkaller/ipc"
|
||||
"github.com/google/syzkaller/prog"
|
||||
)
|
||||
|
||||
var (
|
||||
flagExecutor = flag.String("executor", "", "path to executor binary")
|
||||
flagLog = flag.String("log", "", "comma-delimited list of log files to execute")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
var progs [][]byte
|
||||
for _, fn := range strings.Split(*flagLog, ",") {
|
||||
logf, err := os.Open(fn)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to open log file: %v", err)
|
||||
}
|
||||
log.Printf("parsing log %v", fn)
|
||||
s := bufio.NewScanner(logf)
|
||||
var cur []byte
|
||||
var last *prog.Prog
|
||||
for s.Scan() {
|
||||
ln := s.Text()
|
||||
tmp := append(cur, ln...)
|
||||
tmp = append(tmp, '\n')
|
||||
p, err := prog.Deserialize(tmp)
|
||||
if err == nil {
|
||||
cur = tmp
|
||||
last = p
|
||||
continue
|
||||
}
|
||||
if last != nil {
|
||||
progs = append(progs, last.SerializeForExec())
|
||||
last = nil
|
||||
cur = cur[:0]
|
||||
}
|
||||
}
|
||||
if last != nil {
|
||||
progs = append(progs, last.SerializeForExec())
|
||||
}
|
||||
}
|
||||
log.Printf("parsed %v programs", len(progs))
|
||||
if len(progs) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var pos uint32
|
||||
for p := 0; p < 16; p++ {
|
||||
go func() {
|
||||
env, err := ipc.MakeEnv(*flagExecutor, 5*time.Second, 0)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to create ipc env: %v", err)
|
||||
}
|
||||
for {
|
||||
idx := int(atomic.AddUint32(&pos, 1) - 1)
|
||||
if idx%1000 == 0 {
|
||||
log.Printf("executing %v\n", idx)
|
||||
}
|
||||
copy(env.In, progs[idx%len(progs)])
|
||||
_, _, _, _, err := env.Exec()
|
||||
if err != nil {
|
||||
log.Printf("failed to execute program: %v", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
select {}
|
||||
}
|
62
tools/execprog/execprog.go
Normal file
62
tools/execprog/execprog.go
Normal file
@ -0,0 +1,62 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/google/syzkaller/ipc"
|
||||
"github.com/google/syzkaller/prog"
|
||||
)
|
||||
|
||||
var (
|
||||
flagExecutor = flag.String("executor", "", "path to executor binary")
|
||||
flagProg = flag.String("prog", "", "file with a program to execute")
|
||||
flagThreaded = flag.Bool("threaded", false, "use threaded mode in executor")
|
||||
flagDebug = flag.Bool("debug", true, "debug output from executor")
|
||||
flagStrace = flag.Bool("strace", false, "run executor under strace")
|
||||
flagCover = flag.Bool("cover", false, "collect coverage")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
data, err := ioutil.ReadFile(*flagProg)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to read prog file: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
p, err := prog.Deserialize(data)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to deserialize the program: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
var flags uint64
|
||||
if *flagThreaded {
|
||||
flags |= ipc.FlagThreaded
|
||||
}
|
||||
if *flagDebug {
|
||||
flags |= ipc.FlagDebug
|
||||
}
|
||||
if *flagStrace {
|
||||
flags |= ipc.FlagStrace
|
||||
}
|
||||
if *flagCover {
|
||||
flags |= ipc.FlagCover
|
||||
}
|
||||
env, err := ipc.MakeEnv(*flagExecutor, 3*time.Second, flags)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to create execution environment: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
copy(env.In, p.SerializeForExec())
|
||||
output, strace, failed, hanged, err := env.Exec()
|
||||
fmt.Printf("result: failed=%v hanged=%v err=%v\n\n%s", failed, hanged, err, output)
|
||||
if *flagStrace {
|
||||
fmt.Printf("strace output:\n%s", strace)
|
||||
}
|
||||
}
|
31
tools/prog2c/prog2c.go
Normal file
31
tools/prog2c/prog2c.go
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/google/syzkaller/prog"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 2 {
|
||||
fmt.Fprintf(os.Stderr, "usage: prog2c prog_file\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
data, err := ioutil.ReadFile(os.Args[1])
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to read prog file: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
p, err := prog.Deserialize(data)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to deserialize the program: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
src := p.WriteCSource()
|
||||
os.Stdout.Write(src)
|
||||
}
|
104
tools/stress/stress.go
Normal file
104
tools/stress/stress.go
Normal file
@ -0,0 +1,104 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math/rand"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"github.com/google/syzkaller/ipc"
|
||||
"github.com/google/syzkaller/prog"
|
||||
)
|
||||
|
||||
var (
|
||||
flagCorpus = flag.String("corpus", "", "corpus directory")
|
||||
flagExecutor = flag.String("executor", "", "path to executor binary")
|
||||
flagOutput = flag.Bool("output", false, "print executor output to console")
|
||||
flagDebug = flag.Bool("debug", false, "executor debug output")
|
||||
|
||||
failedRe = regexp.MustCompile("runtime error: |panic: ")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
corpus := readCorpus()
|
||||
flags := ipc.FlagThreaded
|
||||
if *flagDebug {
|
||||
flags |= ipc.FlagDebug
|
||||
}
|
||||
env, err := ipc.MakeEnv(*flagExecutor, 5*time.Second, flags)
|
||||
if err != nil {
|
||||
failf("failed to create execution environment: %v", err)
|
||||
}
|
||||
rs := rand.NewSource(time.Now().UnixNano())
|
||||
rnd := rand.New(rs)
|
||||
for i := 0; ; i++ {
|
||||
var p *prog.Prog
|
||||
if len(corpus) == 0 || i%10 != 0 {
|
||||
p = prog.Generate(rs, 50, nil)
|
||||
execute(env, p)
|
||||
p.Mutate(rs, 50, nil)
|
||||
execute(env, p)
|
||||
} else {
|
||||
p = corpus[rnd.Intn(len(corpus))].Clone()
|
||||
p.Mutate(rs, 50, nil)
|
||||
execute(env, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func execute(env *ipc.Env, p *prog.Prog) {
|
||||
if *flagExecutor == "" {
|
||||
return
|
||||
}
|
||||
copy(env.In, p.SerializeForExec())
|
||||
output, _, _, _, err := env.Exec()
|
||||
if err != nil {
|
||||
fmt.Printf("failed to execute executor: %v\n", err)
|
||||
}
|
||||
failed := failedRe.Match(output)
|
||||
if failed {
|
||||
fmt.Printf("PROGRAM:\n%s\n", p.Serialize())
|
||||
}
|
||||
if failed || *flagOutput {
|
||||
os.Stdout.Write(output)
|
||||
}
|
||||
}
|
||||
|
||||
func readCorpus() []*prog.Prog {
|
||||
if *flagCorpus == "" {
|
||||
return nil
|
||||
}
|
||||
files, err := ioutil.ReadDir(*flagCorpus)
|
||||
if err != nil {
|
||||
failf("failed to read corpus dir: %v", err)
|
||||
}
|
||||
var progs []*prog.Prog
|
||||
for _, f := range files {
|
||||
if f.IsDir() {
|
||||
continue
|
||||
}
|
||||
data, err := ioutil.ReadFile(filepath.Join(*flagCorpus, f.Name()))
|
||||
if err != nil {
|
||||
failf("failed to read corpus file: %v", err)
|
||||
}
|
||||
p, err := prog.Deserialize(data)
|
||||
if err != nil {
|
||||
failf("failed to deserialize corpus program: %v", err)
|
||||
}
|
||||
progs = append(progs, p)
|
||||
}
|
||||
return progs
|
||||
}
|
||||
|
||||
func failf(msg string, args ...interface{}) {
|
||||
log.Fatalf(msg, args...)
|
||||
}
|
117
vm/local/local.go
Normal file
117
vm/local/local.go
Normal file
@ -0,0 +1,117 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package qemu
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/google/syzkaller/vm"
|
||||
)
|
||||
|
||||
func init() {
|
||||
vm.Register("local", ctor)
|
||||
}
|
||||
|
||||
type local struct {
|
||||
params
|
||||
workdir string
|
||||
syscalls map[int]bool
|
||||
id int
|
||||
mgrPort int
|
||||
}
|
||||
|
||||
type params struct {
|
||||
Fuzzer string
|
||||
Executor string
|
||||
Parallel int
|
||||
}
|
||||
|
||||
func ctor(workdir string, syscalls map[int]bool, port, index int, paramsData []byte) (vm.Instance, error) {
|
||||
p := new(params)
|
||||
if err := json.Unmarshal(paramsData, p); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal local params: %v", err)
|
||||
}
|
||||
if _, err := os.Stat(p.Fuzzer); err != nil {
|
||||
return nil, fmt.Errorf("fuzzer binary '%v' does not exist: %v", p.Fuzzer, err)
|
||||
}
|
||||
if _, err := os.Stat(p.Executor); err != nil {
|
||||
return nil, fmt.Errorf("executor binary '%v' does not exist: %v", p.Executor, err)
|
||||
}
|
||||
if p.Parallel == 0 {
|
||||
p.Parallel = 1
|
||||
}
|
||||
if p.Parallel <= 0 || p.Parallel > 100 {
|
||||
return nil, fmt.Errorf("bad parallel param: %v, want [1-100]", p.Parallel)
|
||||
}
|
||||
|
||||
os.MkdirAll(workdir, 0770)
|
||||
|
||||
// Disable annoying segfault dmesg messages, fuzzer is going to crash a lot.
|
||||
etrace, err := os.Open("/proc/sys/debug/exception-trace")
|
||||
if err == nil {
|
||||
etrace.Write([]byte{'0'})
|
||||
etrace.Close()
|
||||
}
|
||||
|
||||
// Don't write executor core files.
|
||||
syscall.Setrlimit(syscall.RLIMIT_CORE, &syscall.Rlimit{0, 0})
|
||||
|
||||
loc := &local{
|
||||
params: *p,
|
||||
workdir: workdir,
|
||||
syscalls: syscalls,
|
||||
id: index,
|
||||
mgrPort: port,
|
||||
}
|
||||
return loc, nil
|
||||
}
|
||||
|
||||
func (loc *local) Run() {
|
||||
name := fmt.Sprintf("local-%v", loc.id)
|
||||
log.Printf("%v: started\n", name)
|
||||
for run := 0; ; run++ {
|
||||
cmd := exec.Command(loc.Fuzzer, "-name", name, "-saveprog", "-executor", loc.Executor,
|
||||
"-manager", fmt.Sprintf("localhost:%v", loc.mgrPort), "-parallel", fmt.Sprintf("%v", loc.Parallel))
|
||||
if len(loc.syscalls) != 0 {
|
||||
buf := new(bytes.Buffer)
|
||||
for c := range loc.syscalls {
|
||||
fmt.Fprintf(buf, ",%v", c)
|
||||
}
|
||||
cmd.Args = append(cmd.Args, "-calls="+buf.String()[1:])
|
||||
}
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Dir = loc.workdir
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
if err := cmd.Start(); err != nil {
|
||||
log.Printf("failed to start fuzzer binary: %v", err)
|
||||
time.Sleep(10 * time.Second)
|
||||
continue
|
||||
}
|
||||
pid := cmd.Process.Pid
|
||||
done := make(chan bool)
|
||||
go func() {
|
||||
select {
|
||||
case <-done:
|
||||
case <-time.After(time.Hour):
|
||||
log.Printf("%v: running for long enough, restarting", name)
|
||||
syscall.Kill(-pid, syscall.SIGKILL)
|
||||
syscall.Kill(-pid, syscall.SIGKILL)
|
||||
syscall.Kill(pid, syscall.SIGKILL)
|
||||
syscall.Kill(pid, syscall.SIGKILL)
|
||||
}
|
||||
}()
|
||||
err := cmd.Wait()
|
||||
close(done)
|
||||
log.Printf("fuzzer binary exited: %v", err)
|
||||
time.Sleep(10 * time.Second)
|
||||
}
|
||||
}
|
478
vm/qemu/qemu.go
Normal file
478
vm/qemu/qemu.go
Normal file
@ -0,0 +1,478 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package qemu
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/google/syzkaller/vm"
|
||||
)
|
||||
|
||||
const hostAddr = "10.0.2.10"
|
||||
const logOutput = false
|
||||
|
||||
func init() {
|
||||
vm.Register("qemu", ctor)
|
||||
}
|
||||
|
||||
type qemu struct {
|
||||
params
|
||||
workdir string
|
||||
crashdir string
|
||||
callsFlag string
|
||||
id int
|
||||
mgrPort int
|
||||
}
|
||||
|
||||
type params struct {
|
||||
Qemu string
|
||||
Kernel string
|
||||
Image string
|
||||
Sshkey string
|
||||
Fuzzer string
|
||||
Executor string
|
||||
Port int
|
||||
Cpu int
|
||||
Mem int
|
||||
Parallel int
|
||||
}
|
||||
|
||||
func ctor(workdir string, syscalls map[int]bool, port, index int, paramsData []byte) (vm.Instance, error) {
|
||||
p := new(params)
|
||||
if err := json.Unmarshal(paramsData, p); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal qemu params: %v", err)
|
||||
}
|
||||
if _, err := os.Stat(p.Image); err != nil {
|
||||
return nil, fmt.Errorf("image file '%v' does not exist: %v", p.Image, err)
|
||||
}
|
||||
if _, err := os.Stat(p.Kernel); err != nil {
|
||||
return nil, fmt.Errorf("kernel file '%v' does not exist: %v", p.Kernel, err)
|
||||
}
|
||||
if _, err := os.Stat(p.Sshkey); err != nil {
|
||||
return nil, fmt.Errorf("ssh key '%v' does not exist: %v", p.Sshkey, err)
|
||||
}
|
||||
if _, err := os.Stat(p.Fuzzer); err != nil {
|
||||
return nil, fmt.Errorf("fuzzer binary '%v' does not exist: %v", p.Fuzzer, err)
|
||||
}
|
||||
if _, err := os.Stat(p.Executor); err != nil {
|
||||
return nil, fmt.Errorf("executor binary '%v' does not exist: %v", p.Executor, err)
|
||||
}
|
||||
if p.Qemu == "" {
|
||||
p.Qemu = "qemu-system-x86_64"
|
||||
}
|
||||
if p.Port <= 1024 || p.Port >= 64<<10 {
|
||||
return nil, fmt.Errorf("bad qemu port: %v, want (1024-65536)", p.Port)
|
||||
}
|
||||
p.Port += index
|
||||
if p.Cpu <= 0 || p.Cpu > 1024 {
|
||||
return nil, fmt.Errorf("bad qemu cpu: %v, want [1-1024]", p.Cpu)
|
||||
}
|
||||
if p.Mem < 128 || p.Mem > 1048576 {
|
||||
return nil, fmt.Errorf("bad qemu mem: %v, want [128-1048576]", p.Mem)
|
||||
}
|
||||
if p.Parallel == 0 {
|
||||
p.Parallel = 1
|
||||
}
|
||||
if p.Parallel <= 0 || p.Parallel > 100 {
|
||||
return nil, fmt.Errorf("bad parallel param: %v, want [1-100]", p.Parallel)
|
||||
}
|
||||
|
||||
crashdir := filepath.Join(workdir, "crashes")
|
||||
os.MkdirAll(crashdir, 0770)
|
||||
|
||||
workdir = filepath.Join(workdir, "qemu")
|
||||
os.MkdirAll(workdir, 0770)
|
||||
|
||||
q := &qemu{
|
||||
params: *p,
|
||||
workdir: workdir,
|
||||
crashdir: crashdir,
|
||||
id: index,
|
||||
mgrPort: port,
|
||||
}
|
||||
|
||||
if len(syscalls) != 0 {
|
||||
buf := new(bytes.Buffer)
|
||||
for c := range syscalls {
|
||||
fmt.Fprintf(buf, ",%v", c)
|
||||
}
|
||||
q.callsFlag = "-calls=" + buf.String()[1:]
|
||||
}
|
||||
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (q *qemu) Run() {
|
||||
log.Printf("qemu/%v: started\n", q.id)
|
||||
imagename := filepath.Join(q.workdir, fmt.Sprintf("image%v", q.id))
|
||||
for run := 0; ; run++ {
|
||||
logname := filepath.Join(q.workdir, fmt.Sprintf("log%v-%v-%v", q.id, run, time.Now().Unix()))
|
||||
var logf *os.File
|
||||
if logOutput {
|
||||
var err error
|
||||
logf, err = os.Create(logname)
|
||||
if err != nil {
|
||||
log.Printf("failed to create log file: %v", err)
|
||||
time.Sleep(10 * time.Second)
|
||||
continue
|
||||
}
|
||||
}
|
||||
rpipe, wpipe, err := os.Pipe()
|
||||
if err != nil {
|
||||
log.Printf("failed to create pipe: %v", err)
|
||||
if logf != nil {
|
||||
logf.Close()
|
||||
}
|
||||
time.Sleep(10 * time.Second)
|
||||
continue
|
||||
}
|
||||
os.Remove(imagename)
|
||||
if err := copyFile(q.Image, imagename); err != nil {
|
||||
log.Printf("failed to copy image file: %v", err)
|
||||
if logf != nil {
|
||||
logf.Close()
|
||||
}
|
||||
rpipe.Close()
|
||||
wpipe.Close()
|
||||
time.Sleep(10 * time.Second)
|
||||
continue
|
||||
}
|
||||
inst := &Instance{
|
||||
id: q.id,
|
||||
crashdir: q.crashdir,
|
||||
params: q.params,
|
||||
name: fmt.Sprintf("qemu/%v-%v", q.id, run),
|
||||
image: imagename,
|
||||
callsFlag: q.callsFlag,
|
||||
log: logf,
|
||||
rpipe: rpipe,
|
||||
wpipe: wpipe,
|
||||
mgrPort: q.mgrPort,
|
||||
cmds: make(map[*Command]bool),
|
||||
}
|
||||
inst.Run()
|
||||
inst.Shutdown()
|
||||
time.Sleep(10 * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
type Instance struct {
|
||||
params
|
||||
sync.Mutex
|
||||
id int
|
||||
crashdir string
|
||||
name string
|
||||
image string
|
||||
callsFlag string
|
||||
log *os.File
|
||||
rpipe *os.File
|
||||
wpipe *os.File
|
||||
mgrPort int
|
||||
cmds map[*Command]bool
|
||||
qemu *Command
|
||||
}
|
||||
|
||||
type Command struct {
|
||||
sync.Mutex
|
||||
cmd *exec.Cmd
|
||||
done chan struct{}
|
||||
failed bool
|
||||
out []byte
|
||||
outpos int
|
||||
}
|
||||
|
||||
func (inst *Instance) Run() {
|
||||
var outputMu sync.Mutex
|
||||
var output []byte
|
||||
go func() {
|
||||
var buf [64 << 10]byte
|
||||
for {
|
||||
n, err := inst.rpipe.Read(buf[:])
|
||||
if n != 0 {
|
||||
outputMu.Lock()
|
||||
output = append(output, buf[:n]...)
|
||||
outputMu.Unlock()
|
||||
if inst.log != nil {
|
||||
inst.log.Write(buf[:n])
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Start the instance.
|
||||
// TODO: ignores inst.Cpu
|
||||
inst.qemu = inst.CreateCommand(inst.Qemu,
|
||||
"-hda", inst.image,
|
||||
"-m", strconv.Itoa(inst.Mem),
|
||||
"-net", "nic",
|
||||
"-net", fmt.Sprintf("user,host=%v,hostfwd=tcp::%v-:22", hostAddr, inst.Port),
|
||||
"-nographic",
|
||||
"-kernel", inst.Kernel,
|
||||
"-append", "console=ttyS0 root=/dev/sda debug earlyprintk=serial slub_debug=UZ",
|
||||
"-enable-kvm",
|
||||
"-numa", "node,nodeid=0,cpus=0-1", "-numa", "node,nodeid=1,cpus=2-3",
|
||||
"-smp", "sockets=2,cores=2,threads=1",
|
||||
"-usb", "-usbdevice", "mouse", "-usbdevice", "tablet",
|
||||
)
|
||||
// Wait for ssh server.
|
||||
time.Sleep(10 * time.Second)
|
||||
start := time.Now()
|
||||
for {
|
||||
c, err := net.DialTimeout("tcp", fmt.Sprintf("localhost:%v", inst.Port), 3*time.Second)
|
||||
if err == nil {
|
||||
c.SetDeadline(time.Now().Add(3 * time.Second))
|
||||
var tmp [1]byte
|
||||
n, err := c.Read(tmp[:])
|
||||
c.Close()
|
||||
if err == nil && n > 0 {
|
||||
// ssh is up and responding.
|
||||
break
|
||||
}
|
||||
c.Close()
|
||||
time.Sleep(3 * time.Second)
|
||||
}
|
||||
if inst.qemu.Exited() {
|
||||
output = append(output, "qemu stopped\n"...)
|
||||
inst.SaveCrasher(output)
|
||||
inst.Logf("qemu stopped")
|
||||
return
|
||||
}
|
||||
if time.Since(start) > 10*time.Minute {
|
||||
outputMu.Lock()
|
||||
output = append(output, "ssh server did not start\n"...)
|
||||
inst.SaveCrasher(output)
|
||||
outputMu.Unlock()
|
||||
inst.Logf("ssh server did not start")
|
||||
return
|
||||
}
|
||||
}
|
||||
inst.Logf("started vm")
|
||||
|
||||
// Copy the binaries into the instance.
|
||||
if !inst.CreateSCPCommand(inst.Fuzzer, "/syzkaller_fuzzer").Wait(1*time.Minute) ||
|
||||
!inst.CreateSCPCommand(inst.Executor, "/syzkaller_executor").Wait(1*time.Minute) {
|
||||
inst.Logf("failed to scp binaries into the instance")
|
||||
return
|
||||
}
|
||||
|
||||
// Disable annoying segfault dmesg messages, fuzzer is going to crash a lot.
|
||||
inst.CreateSSHCommand("echo -n 0 > /proc/sys/debug/exception-trace").Wait(10 * time.Second)
|
||||
|
||||
// Run the binary.
|
||||
cmd := inst.CreateSSHCommand(fmt.Sprintf("/syzkaller_fuzzer -name %v -executor /syzkaller_executor -manager %v:%v -parallel %v %v",
|
||||
inst.name, hostAddr, inst.mgrPort, inst.Parallel, inst.callsFlag))
|
||||
|
||||
deadline := start.Add(time.Hour)
|
||||
lastOutput := time.Now()
|
||||
lastOutputLen := 0
|
||||
matchPos := 0
|
||||
crashRe := regexp.MustCompile("\\[ cut here \\]|Kernel panic| BUG: | WARNING: | INFO: |unable to handle kernel NULL pointer dereference|general protection fault")
|
||||
const contextSize = 64 << 10
|
||||
for range time.NewTicker(5 * time.Second).C {
|
||||
outputMu.Lock()
|
||||
if lastOutputLen != len(output) {
|
||||
lastOutput = time.Now()
|
||||
}
|
||||
if loc := crashRe.FindAllIndex(output[matchPos:], -1); len(loc) != 0 {
|
||||
// Give it some time to finish writing the error message.
|
||||
outputMu.Unlock()
|
||||
time.Sleep(5 * time.Second)
|
||||
outputMu.Lock()
|
||||
loc = crashRe.FindAllIndex(output[matchPos:], -1)
|
||||
start := loc[0][0] - contextSize
|
||||
if start < 0 {
|
||||
start = 0
|
||||
}
|
||||
end := loc[len(loc)-1][1] + contextSize
|
||||
if end > len(output) {
|
||||
end = len(output)
|
||||
}
|
||||
inst.SaveCrasher(output[start:end])
|
||||
}
|
||||
if len(output) > 2*contextSize {
|
||||
copy(output, output[len(output)-contextSize:])
|
||||
output = output[:contextSize]
|
||||
}
|
||||
matchPos = len(output) - 128
|
||||
if matchPos < 0 {
|
||||
matchPos = 0
|
||||
}
|
||||
lastOutputLen = len(output)
|
||||
outputMu.Unlock()
|
||||
|
||||
if time.Since(lastOutput) > 3*time.Minute {
|
||||
time.Sleep(time.Second)
|
||||
outputMu.Lock()
|
||||
output = append(output, "no output from fuzzer, restarting\n"...)
|
||||
inst.SaveCrasher(output)
|
||||
outputMu.Unlock()
|
||||
inst.Logf("no output from fuzzer, restarting")
|
||||
cmd.cmd.Process.Kill()
|
||||
cmd.cmd.Process.Kill()
|
||||
return
|
||||
}
|
||||
if cmd.Exited() {
|
||||
time.Sleep(time.Second)
|
||||
outputMu.Lock()
|
||||
output = append(output, "fuzzer binary stopped or lost connection\n"...)
|
||||
inst.SaveCrasher(output)
|
||||
inst.Logf("fuzzer binary stopped or lost connection")
|
||||
outputMu.Unlock()
|
||||
return
|
||||
}
|
||||
if time.Now().After(deadline) {
|
||||
inst.Logf("running for long enough, restarting")
|
||||
cmd.cmd.Process.Kill()
|
||||
cmd.cmd.Process.Kill()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (inst *Instance) SaveCrasher(output []byte) {
|
||||
ioutil.WriteFile(filepath.Join(inst.crashdir, fmt.Sprintf("crash%v-%v", inst.id, time.Now().UnixNano())), output, 0660)
|
||||
}
|
||||
|
||||
func (inst *Instance) Shutdown() {
|
||||
defer func() {
|
||||
os.Remove(inst.image)
|
||||
inst.rpipe.Close()
|
||||
inst.wpipe.Close()
|
||||
if inst.log != nil {
|
||||
inst.log.Close()
|
||||
}
|
||||
}()
|
||||
if inst.qemu.cmd == nil {
|
||||
// CreateCommand should have been failed very early.
|
||||
return
|
||||
}
|
||||
for try := 0; try < 10; try++ {
|
||||
inst.qemu.cmd.Process.Kill()
|
||||
time.Sleep(time.Second)
|
||||
inst.Lock()
|
||||
n := len(inst.cmds)
|
||||
inst.Unlock()
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
}
|
||||
inst.Logf("hanged processes after kill")
|
||||
inst.Lock()
|
||||
for cmd := range inst.cmds {
|
||||
cmd.cmd.Process.Kill()
|
||||
cmd.cmd.Process.Kill()
|
||||
}
|
||||
inst.Unlock()
|
||||
time.Sleep(3 * time.Second)
|
||||
}
|
||||
|
||||
func (inst *Instance) CreateCommand(args ...string) *Command {
|
||||
if inst.log != nil {
|
||||
fmt.Fprintf(inst.log, "executing command: %v\n", args)
|
||||
}
|
||||
cmd := &Command{}
|
||||
cmd.done = make(chan struct{})
|
||||
cmd.cmd = exec.Command(args[0], args[1:]...)
|
||||
cmd.cmd.Stdout = inst.wpipe
|
||||
cmd.cmd.Stderr = inst.wpipe
|
||||
if err := cmd.cmd.Start(); err != nil {
|
||||
inst.Logf("failed to start command '%v': %v\n", args, err)
|
||||
cmd.failed = true
|
||||
close(cmd.done)
|
||||
return cmd
|
||||
}
|
||||
inst.Lock()
|
||||
inst.cmds[cmd] = true
|
||||
inst.Unlock()
|
||||
go func() {
|
||||
err := cmd.cmd.Wait()
|
||||
inst.Lock()
|
||||
delete(inst.cmds, cmd)
|
||||
inst.Unlock()
|
||||
if inst.log != nil {
|
||||
fmt.Fprintf(inst.log, "command '%v' exited: %v\n", args, err)
|
||||
}
|
||||
cmd.failed = err != nil
|
||||
close(cmd.done)
|
||||
}()
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (inst *Instance) CreateSSHCommand(args ...string) *Command {
|
||||
args1 := []string{"ssh", "-i", inst.Sshkey, "-p", strconv.Itoa(inst.Port),
|
||||
"-o", "ConnectionAttempts=10", "-o", "ConnectTimeout=10",
|
||||
"-o", "BatchMode=yes", "-o", "UserKnownHostsFile=/dev/null",
|
||||
"-o", "StrictHostKeyChecking=no", "root@localhost"}
|
||||
return inst.CreateCommand(append(args1, args...)...)
|
||||
}
|
||||
|
||||
func (inst *Instance) CreateSCPCommand(from, to string) *Command {
|
||||
return inst.CreateCommand("scp", "-i", inst.Sshkey, "-P", strconv.Itoa(inst.Port),
|
||||
"-o", "ConnectionAttempts=10", "-o", "ConnectTimeout=10",
|
||||
"-o", "BatchMode=yes", "-o", "UserKnownHostsFile=/dev/null",
|
||||
"-o", "StrictHostKeyChecking=no",
|
||||
from, "root@localhost:"+to)
|
||||
}
|
||||
|
||||
func (inst *Instance) Logf(str string, args ...interface{}) {
|
||||
fmt.Fprintf(inst.wpipe, str+"\n", args...)
|
||||
log.Printf("%v: "+str, append([]interface{}{inst.name}, args...)...)
|
||||
}
|
||||
|
||||
func (cmd *Command) Wait(max time.Duration) bool {
|
||||
select {
|
||||
case <-cmd.done:
|
||||
return !cmd.failed
|
||||
case <-time.After(max):
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (cmd *Command) Exited() bool {
|
||||
select {
|
||||
case <-cmd.done:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
var copySem sync.Mutex
|
||||
|
||||
func copyFile(oldfn, newfn string) error {
|
||||
copySem.Lock()
|
||||
defer copySem.Unlock()
|
||||
|
||||
oldf, err := os.Open(oldfn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer oldf.Close()
|
||||
newf, err := os.Create(newfn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer newf.Close()
|
||||
_, err = io.Copy(newf, oldf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
28
vm/vm.go
Normal file
28
vm/vm.go
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright 2015 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package vm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Instance interface {
|
||||
Run()
|
||||
}
|
||||
|
||||
type ctorFunc func(workdir string, syscalls map[int]bool, port, index int, params []byte) (Instance, error)
|
||||
|
||||
var ctors = make(map[string]ctorFunc)
|
||||
|
||||
func Register(typ string, ctor ctorFunc) {
|
||||
ctors[typ] = ctor
|
||||
}
|
||||
|
||||
func Create(typ string, workdir string, syscalls map[int]bool, port, index int, params []byte) (Instance, error) {
|
||||
ctor := ctors[typ]
|
||||
if ctor == nil {
|
||||
return nil, fmt.Errorf("unknown instance type '%v'", typ)
|
||||
}
|
||||
return ctor(workdir, syscalls, port, index, params)
|
||||
}
|
Loading…
Reference in New Issue
Block a user