initial commit

This commit is contained in:
Dmitry Vyukov 2015-10-12 10:16:57 +02:00
commit 874c5754bb
46 changed files with 10240 additions and 0 deletions

9
AUTHORS Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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(">", "&gt;", "<", "&lt;", "&", "&amp;", "\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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

92
sysgen/parser.go Normal file
View 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
View 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
View 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 {}
}

View 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
View 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
View 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
View 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
View 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
View 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)
}