prog: export deserialization test helper for sys/{linux,openbsd}

sys/{linux,openbsd} duplicate deserialization test logic as well.
Export and reuse the existing helper function.
This commit is contained in:
Dmitry Vyukov 2020-03-17 10:44:38 +01:00
parent 0a4d69469b
commit a2f9a44649
6 changed files with 306 additions and 338 deletions

View File

@ -9,7 +9,6 @@ import (
"math/rand"
"reflect"
"sort"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
@ -140,227 +139,174 @@ func TestCallSetRandom(t *testing.T) {
}
func TestDeserialize(t *testing.T) {
testDeserialize(t, nil, []deserializeTest{
TestDeserializeHelper(t, "test", "64", nil, []DeserializeTest{
{
input: `test$struct(&(0x7f0000000000)={0x0, {0x0}})`,
In: `test$struct(&(0x7f0000000000)={0x0, {0x0}})`,
},
{
input: `test$struct(&(0x7f0000000000)=0x0)`,
output: `test$struct(&(0x7f0000000000))`,
strictErr: "wrong int arg",
In: `test$struct(&(0x7f0000000000)=0x0)`,
Out: `test$struct(&(0x7f0000000000))`,
StrictErr: "wrong int arg",
},
{
input: `test$regression1(&(0x7f0000000000)=[{"000000"}, {"0000000000"}])`,
In: `test$regression1(&(0x7f0000000000)=[{"000000"}, {"0000000000"}])`,
},
{
input: `test$regression2(&(0x7f0000000000)=[0x1, 0x2, 0x3, 0x4, 0x5, 0x6])`,
In: `test$regression2(&(0x7f0000000000)=[0x1, 0x2, 0x3, 0x4, 0x5, 0x6])`,
},
{
input: `test_excessive_args1(0x0, 0x1, {0x1, &(0x7f0000000000)=[0x1, 0x2]})`,
strictErr: "excessive syscall arguments",
In: `test_excessive_args1(0x0, 0x1, {0x1, &(0x7f0000000000)=[0x1, 0x2]})`,
StrictErr: "excessive syscall arguments",
},
{
input: `test_excessive_args2(0x0, 0x1, {0x1, &(0x7f0000000000)={0x1, 0x2}})`,
strictErr: "excessive syscall arguments",
In: `test_excessive_args2(0x0, 0x1, {0x1, &(0x7f0000000000)={0x1, 0x2}})`,
StrictErr: "excessive syscall arguments",
},
{
input: `test_excessive_args2(0x0, 0x1, {0x1, &(0x7f0000000000)=nil})`,
strictErr: "excessive syscall arguments",
In: `test_excessive_args2(0x0, 0x1, {0x1, &(0x7f0000000000)=nil})`,
StrictErr: "excessive syscall arguments",
},
{
input: `test_excessive_args2(0x0, &(0x7f0000000000), 0x0)`,
strictErr: "excessive syscall arguments",
In: `test_excessive_args2(0x0, &(0x7f0000000000), 0x0)`,
StrictErr: "excessive syscall arguments",
},
{
input: `test$excessive_fields1(&(0x7f0000000000)={0x1, &(0x7f0000000000)=[{0x0}, 0x2]}, {0x1, 0x2, [0x1, 0x2]})`,
strictErr: "excessive struct excessive_fields fields",
In: `test$excessive_fields1(&(0x7f0000000000)={0x1, &(0x7f0000000000)=[{0x0}, 0x2]}, {0x1, 0x2, [0x1, 0x2]})`,
StrictErr: "excessive struct excessive_fields fields",
},
{
input: `test$excessive_fields1(0x0)`,
output: `test$excessive_fields1(0x0)`,
In: `test$excessive_fields1(0x0)`,
Out: `test$excessive_fields1(0x0)`,
},
{
input: `test$excessive_fields1(r0)`,
output: `test$excessive_fields1(&(0x7f0000000000))`,
strictErr: "undeclared variable r0",
In: `test$excessive_fields1(r0)`,
Out: `test$excessive_fields1(&(0x7f0000000000))`,
StrictErr: "undeclared variable r0",
},
{
input: `test_excessive_args2(r1)`,
output: `test_excessive_args2(0x0)`,
strictErr: "undeclared variable r1",
In: `test_excessive_args2(r1)`,
Out: `test_excessive_args2(0x0)`,
StrictErr: "undeclared variable r1",
},
{
input: `test_excessive_args2({0x0, 0x1})`,
output: `test_excessive_args2(0x0)`,
strictErr: "wrong struct arg",
In: `test_excessive_args2({0x0, 0x1})`,
Out: `test_excessive_args2(0x0)`,
StrictErr: "wrong struct arg",
},
{
input: `test_excessive_args2([0x0], 0x0)`,
output: `test_excessive_args2(0x0)`,
strictErr: "wrong array arg",
In: `test_excessive_args2([0x0], 0x0)`,
Out: `test_excessive_args2(0x0)`,
StrictErr: "wrong array arg",
},
{
input: `test_excessive_args2(@foo)`,
output: `test_excessive_args2(0x0)`,
strictErr: "wrong union arg",
In: `test_excessive_args2(@foo)`,
Out: `test_excessive_args2(0x0)`,
StrictErr: "wrong union arg",
},
{
input: `test_excessive_args2('foo')`,
output: `test_excessive_args2(0x0)`,
strictErr: "wrong string arg",
In: `test_excessive_args2('foo')`,
Out: `test_excessive_args2(0x0)`,
StrictErr: "wrong string arg",
},
{
input: `test_excessive_args2(&(0x7f0000000000)={0x0, 0x1})`,
output: `test_excessive_args2(0x0)`,
strictErr: "wrong addr arg",
In: `test_excessive_args2(&(0x7f0000000000)={0x0, 0x1})`,
Out: `test_excessive_args2(0x0)`,
StrictErr: "wrong addr arg",
},
{
input: `test_excessive_args2(nil)`,
output: `test_excessive_args2(0x0)`,
In: `test_excessive_args2(nil)`,
Out: `test_excessive_args2(0x0)`,
},
{
input: `test$type_confusion1(&(0x7f0000000000)=@unknown)`,
output: `test$type_confusion1(&(0x7f0000000000))`,
strictErr: "wrong union option",
In: `test$type_confusion1(&(0x7f0000000000)=@unknown)`,
Out: `test$type_confusion1(&(0x7f0000000000))`,
StrictErr: "wrong union option",
},
{
input: `test$type_confusion1(&(0x7f0000000000)=@unknown={0x0, 'abc'}, 0x0)`,
output: `test$type_confusion1(&(0x7f0000000000))`,
strictErr: "wrong union option",
In: `test$type_confusion1(&(0x7f0000000000)=@unknown={0x0, 'abc'}, 0x0)`,
Out: `test$type_confusion1(&(0x7f0000000000))`,
StrictErr: "wrong union option",
},
{
input: `test$excessive_fields1(&(0x7f0000000000)=0x0)`,
output: `test$excessive_fields1(&(0x7f0000000000))`,
strictErr: "wrong int arg",
In: `test$excessive_fields1(&(0x7f0000000000)=0x0)`,
Out: `test$excessive_fields1(&(0x7f0000000000))`,
StrictErr: "wrong int arg",
},
{
input: `test$excessive_fields1(0x0)`,
output: `test$excessive_fields1(0x0)`,
In: `test$excessive_fields1(0x0)`,
Out: `test$excessive_fields1(0x0)`,
},
{
input: `test$excessive_fields1(0xffffffffffffffff)`,
output: `test$excessive_fields1(0xffffffffffffffff)`,
In: `test$excessive_fields1(0xffffffffffffffff)`,
Out: `test$excessive_fields1(0xffffffffffffffff)`,
},
{
input: `test$excessive_fields1(0xfffffffffffffffe)`,
output: `test$excessive_fields1(0xfffffffffffffffe)`,
In: `test$excessive_fields1(0xfffffffffffffffe)`,
Out: `test$excessive_fields1(0xfffffffffffffffe)`,
},
{
input: `test$excessive_fields1(0xfffffffffffffffd)`,
output: `test$excessive_fields1(0x0)`,
In: `test$excessive_fields1(0xfffffffffffffffd)`,
Out: `test$excessive_fields1(0x0)`,
},
{
input: `test$excessive_fields1(0xfffffffffffffffc)`,
output: `test$excessive_fields1(0xffffffffffffffff)`,
In: `test$excessive_fields1(0xfffffffffffffffc)`,
Out: `test$excessive_fields1(0xffffffffffffffff)`,
},
{
input: `test$auto0(AUTO, &AUTO={AUTO, AUTO, 0x1}, AUTO, 0x0)`,
output: `test$auto0(0x42, &(0x7f0000000040)={0xc, 0x43, 0x1}, 0xc, 0x0)`,
In: `test$auto0(AUTO, &AUTO={AUTO, AUTO, 0x1}, AUTO, 0x0)`,
Out: `test$auto0(0x42, &(0x7f0000000040)={0xc, 0x43, 0x1}, 0xc, 0x0)`,
},
{
input: `test$auto0(AUTO, &AUTO={AUTO, AUTO, AUTO}, AUTO, 0x0)`,
err: `wrong type *prog.IntType for AUTO`,
In: `test$auto0(AUTO, &AUTO={AUTO, AUTO, AUTO}, AUTO, 0x0)`,
Err: `wrong type *prog.IntType for AUTO`,
},
{
input: `test$str0(&AUTO="303100090a0d7022273a")`,
output: `test$str0(&(0x7f0000000040)='01\x00\t\n\rp\"\':')`,
In: `test$str0(&AUTO="303100090a0d7022273a")`,
Out: `test$str0(&(0x7f0000000040)='01\x00\t\n\rp\"\':')`,
},
{
input: `test$blob0(&AUTO="303100090a0d7022273a")`,
output: `test$blob0(&(0x7f0000000040)='01\x00\t\n\rp\"\':')`,
In: `test$blob0(&AUTO="303100090a0d7022273a")`,
Out: `test$blob0(&(0x7f0000000040)='01\x00\t\n\rp\"\':')`,
},
{
input: `test$blob0(&AUTO="3031000a0d7022273a01")`,
output: `test$blob0(&(0x7f0000000040)="3031000a0d7022273a01")`,
In: `test$blob0(&AUTO="3031000a0d7022273a01")`,
Out: `test$blob0(&(0x7f0000000040)="3031000a0d7022273a01")`,
},
{
input: `test$out_const(&(0x7f0000000000)=0x2)`,
output: `test$out_const(&(0x7f0000000000))`,
strictErr: `out arg const[1, const] has non-default value: 2`,
In: `test$out_const(&(0x7f0000000000)=0x2)`,
Out: `test$out_const(&(0x7f0000000000))`,
StrictErr: `out arg const[1, const] has non-default value: 2`,
},
{
input: `test$str1(&(0x7f0000000000)='foo\x00')`,
output: `test$str1(&(0x7f0000000000)='foo\x00')`,
In: `test$str1(&(0x7f0000000000)='foo\x00')`,
Out: `test$str1(&(0x7f0000000000)='foo\x00')`,
},
{
input: `test$str1(&(0x7f0000000000)='bar\x00')`,
output: `test$str1(&(0x7f0000000000)='foo\x00')`,
strictErr: `bad string value "bar\x00", expect ["foo\x00"]`,
In: `test$str1(&(0x7f0000000000)='bar\x00')`,
Out: `test$str1(&(0x7f0000000000)='foo\x00')`,
StrictErr: `bad string value "bar\x00", expect ["foo\x00"]`,
},
{
input: `test$str2(&(0x7f0000000000)='bar\x00')`,
output: `test$str2(&(0x7f0000000000)='bar\x00')`,
In: `test$str2(&(0x7f0000000000)='bar\x00')`,
Out: `test$str2(&(0x7f0000000000)='bar\x00')`,
},
{
input: `test$str2(&(0x7f0000000000)='baz\x00')`,
output: `test$str2(&(0x7f0000000000)='foo\x00')`,
strictErr: `bad string value "baz\x00", expect ["foo\x00" "bar\x00"]`,
In: `test$str2(&(0x7f0000000000)='baz\x00')`,
Out: `test$str2(&(0x7f0000000000)='foo\x00')`,
StrictErr: `bad string value "baz\x00", expect ["foo\x00" "bar\x00"]`,
},
})
}
type deserializeTest struct {
input string
output string
err string
strictErr string
}
func testDeserialize(t *testing.T, transform func(*Target, *Prog), tests []deserializeTest) {
target := initTargetTest(t, "test", "64")
buf := make([]byte, ExecBufferSize)
for testidx, test := range tests {
t.Run(fmt.Sprint(testidx), func(t *testing.T) {
if test.strictErr == "" {
test.strictErr = test.err
}
if test.err != "" && test.output != "" {
t.Fatalf("both err and output are set")
}
for _, mode := range []DeserializeMode{NonStrict, Strict} {
p, err := target.Deserialize([]byte(test.input), mode)
wantErr := test.err
if mode == Strict {
wantErr = test.strictErr
}
if err != nil {
if wantErr == "" {
t.Fatalf("deserialization failed with\n%s\ndata:\n%s\n",
err, test.input)
}
if !strings.Contains(err.Error(), wantErr) {
t.Fatalf("deserialization failed with\n%s\nwhich doesn't match\n%s\ndata:\n%s",
err, wantErr, test.input)
}
} else {
if wantErr != "" {
t.Fatalf("deserialization should have failed with:\n%s\ndata:\n%s\n",
wantErr, test.input)
}
if transform != nil {
transform(target, p)
}
output := strings.TrimSpace(string(p.Serialize()))
if test.output != "" && test.output != output {
t.Fatalf("wrong serialized data:\n%s\nexpect:\n%s\n",
output, test.output)
}
p.SerializeForExec(buf)
}
}
})
}
}
func TestSerializeDeserialize(t *testing.T) {
testDeserialize(t, nil, []deserializeTest{
TestDeserializeHelper(t, "test", "64", nil, []DeserializeTest{
{
input: `serialize0(&(0x7f0000408000)={"6861736800000000000000000000", "48490000"})`,
output: `serialize0(&(0x7f0000408000)={'hash\x00', 'HI\x00'})`,
In: `serialize0(&(0x7f0000408000)={"6861736800000000000000000000", "48490000"})`,
Out: `serialize0(&(0x7f0000408000)={'hash\x00', 'HI\x00'})`,
},
{
input: `serialize1(&(0x7f0000000000)="0000000000000000", 0x8)`,
output: `serialize1(&(0x7f0000000000)=""/8, 0x8)`,
In: `serialize1(&(0x7f0000000000)="0000000000000000", 0x8)`,
Out: `serialize1(&(0x7f0000000000)=""/8, 0x8)`,
},
})
}

View File

@ -20,17 +20,9 @@ func init() {
var (
CalcChecksumsCall = calcChecksumsCall
InitTest = initTest
initTargetTest = InitTargetTest
)
func initTargetTest(t *testing.T, os, arch string) *Target {
t.Parallel()
target, err := GetTarget(os, arch)
if err != nil {
t.Fatal(err)
}
return target
}
func randSource(t *testing.T) rand.Source {
seed := time.Now().UnixNano()
if os.Getenv("TRAVIS") != "" {

View File

@ -29,134 +29,134 @@ func TestAssignSizeRandom(t *testing.T) {
func TestAssignSize(t *testing.T) {
// nolint: lll
testDeserialize(t, func(target *Target, p *Prog) {
TestDeserializeHelper(t, "test", "64", func(target *Target, p *Prog) {
for _, call := range p.Calls {
target.assignSizesCall(call)
}
}, []deserializeTest{
}, []DeserializeTest{
{
input: "test$length0(&(0x7f0000000000)={0xff, 0x0})",
output: "test$length0(&(0x7f0000000000)={0xff, 0x2})",
In: "test$length0(&(0x7f0000000000)={0xff, 0x0})",
Out: "test$length0(&(0x7f0000000000)={0xff, 0x2})",
},
{
input: "test$length1(&(0x7f0000001000)={0xff, 0x0})",
output: "test$length1(&(0x7f0000001000)={0xff, 0x4})",
In: "test$length1(&(0x7f0000001000)={0xff, 0x0})",
Out: "test$length1(&(0x7f0000001000)={0xff, 0x4})",
},
{
input: "test$length2(&(0x7f0000001000)={0xff, 0x0})",
output: "test$length2(&(0x7f0000001000)={0xff, 0x8})",
In: "test$length2(&(0x7f0000001000)={0xff, 0x0})",
Out: "test$length2(&(0x7f0000001000)={0xff, 0x8})",
},
{
input: "test$length3(&(0x7f0000005000)={0xff, 0x0, 0x0})",
output: "test$length3(&(0x7f0000005000)={0xff, 0x4, 0x2})",
In: "test$length3(&(0x7f0000005000)={0xff, 0x0, 0x0})",
Out: "test$length3(&(0x7f0000005000)={0xff, 0x4, 0x2})",
},
{
input: "test$length4(&(0x7f0000003000)={0x0, 0x0})",
output: "test$length4(&(0x7f0000003000)={0x2, 0x2})",
In: "test$length4(&(0x7f0000003000)={0x0, 0x0})",
Out: "test$length4(&(0x7f0000003000)={0x2, 0x2})",
},
{
input: "test$length5(&(0x7f0000002000)={0xff, 0x0})",
output: "test$length5(&(0x7f0000002000)={0xff, 0x4})",
In: "test$length5(&(0x7f0000002000)={0xff, 0x0})",
Out: "test$length5(&(0x7f0000002000)={0xff, 0x4})",
},
{
input: "test$length6(&(0x7f0000002000)={[0xff, 0xff, 0xff, 0xff], 0x0})",
output: "test$length6(&(0x7f0000002000)={[0xff, 0xff, 0xff, 0xff], 0x4})",
In: "test$length6(&(0x7f0000002000)={[0xff, 0xff, 0xff, 0xff], 0x0})",
Out: "test$length6(&(0x7f0000002000)={[0xff, 0xff, 0xff, 0xff], 0x4})",
},
{
input: "test$length7(&(0x7f0000003000)={[0xff, 0xff, 0xff, 0xff], 0x0})",
output: "test$length7(&(0x7f0000003000)={[0xff, 0xff, 0xff, 0xff], 0x8})",
In: "test$length7(&(0x7f0000003000)={[0xff, 0xff, 0xff, 0xff], 0x0})",
Out: "test$length7(&(0x7f0000003000)={[0xff, 0xff, 0xff, 0xff], 0x8})",
},
{
input: "test$length8(&(0x7f000001f000)={0x00, {0xff, 0x0, 0x00, [0xff, 0xff, 0xff]}, [{0xff, 0x0, 0x00, [0xff, 0xff, 0xff]}], 0x00, 0x0, [0xff, 0xff]})",
output: "test$length8(&(0x7f000001f000)={0x32, {0xff, 0x1, 0x10, [0xff, 0xff, 0xff]}, [{0xff, 0x1, 0x10, [0xff, 0xff, 0xff]}], 0x10, 0x1, [0xff, 0xff]})",
In: "test$length8(&(0x7f000001f000)={0x00, {0xff, 0x0, 0x00, [0xff, 0xff, 0xff]}, [{0xff, 0x0, 0x00, [0xff, 0xff, 0xff]}], 0x00, 0x0, [0xff, 0xff]})",
Out: "test$length8(&(0x7f000001f000)={0x32, {0xff, 0x1, 0x10, [0xff, 0xff, 0xff]}, [{0xff, 0x1, 0x10, [0xff, 0xff, 0xff]}], 0x10, 0x1, [0xff, 0xff]})",
},
{
input: "test$length9(&(0x7f000001f000)={&(0x7f0000000000/0x5000)=nil, 0x0000})",
output: "test$length9(&(0x7f000001f000)={&(0x7f0000000000/0x5000)=nil, 0x5000})",
In: "test$length9(&(0x7f000001f000)={&(0x7f0000000000/0x5000)=nil, 0x0000})",
Out: "test$length9(&(0x7f000001f000)={&(0x7f0000000000/0x5000)=nil, 0x5000})",
},
{
input: "test$length10(&(0x7f0000000000/0x5000)=nil, 0x0000, 0x0000, 0x0000, 0x0000)",
output: "test$length10(&(0x7f0000000000/0x5000)=nil, 0x5000, 0x5000, 0x2800, 0x1400)",
In: "test$length10(&(0x7f0000000000/0x5000)=nil, 0x0000, 0x0000, 0x0000, 0x0000)",
Out: "test$length10(&(0x7f0000000000/0x5000)=nil, 0x5000, 0x5000, 0x2800, 0x1400)",
},
{
input: "test$length11(&(0x7f0000000000)={0xff, 0xff, [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]}, 0x00)",
output: "test$length11(&(0x7f0000000000)={0xff, 0xff, [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]}, 0x30)",
In: "test$length11(&(0x7f0000000000)={0xff, 0xff, [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]}, 0x00)",
Out: "test$length11(&(0x7f0000000000)={0xff, 0xff, [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]}, 0x30)",
},
{
input: "test$length12(&(0x7f0000000000)={0xff, 0xff, [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]}, 0x00)",
output: "test$length12(&(0x7f0000000000)={0xff, 0xff, [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]}, 0x30)",
In: "test$length12(&(0x7f0000000000)={0xff, 0xff, [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]}, 0x00)",
Out: "test$length12(&(0x7f0000000000)={0xff, 0xff, [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]}, 0x30)",
},
{
input: "test$length13(&(0x7f0000000000)={0xff, 0xff, [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]}, &(0x7f0000001000)=0x00)",
output: "test$length13(&(0x7f0000000000)={0xff, 0xff, [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]}, &(0x7f0000001000)=0x30)",
In: "test$length13(&(0x7f0000000000)={0xff, 0xff, [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]}, &(0x7f0000001000)=0x00)",
Out: "test$length13(&(0x7f0000000000)={0xff, 0xff, [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]}, &(0x7f0000001000)=0x30)",
},
{
input: "test$length14(&(0x7f0000000000)={0xff, 0xff, [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]}, &(0x7f0000001000)=0x00)",
output: "test$length14(&(0x7f0000000000)={0xff, 0xff, [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]}, &(0x7f0000001000)=0x30)",
In: "test$length14(&(0x7f0000000000)={0xff, 0xff, [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]}, &(0x7f0000001000)=0x00)",
Out: "test$length14(&(0x7f0000000000)={0xff, 0xff, [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]}, &(0x7f0000001000)=0x30)",
},
{
input: "test_length15(0xff, 0x0)",
output: "test_length15(0xff, 0x2)",
In: "test_length15(0xff, 0x0)",
Out: "test_length15(0xff, 0x2)",
},
{
input: "test$length16(&(0x7f0000000000)={[0x42, 0x42], 0xff, 0xff, 0xff, 0xff, 0xff})",
output: "test$length16(&(0x7f0000000000)={[0x42, 0x42], 0x2, 0x10, 0x8, 0x4, 0x2})",
In: "test$length16(&(0x7f0000000000)={[0x42, 0x42], 0xff, 0xff, 0xff, 0xff, 0xff})",
Out: "test$length16(&(0x7f0000000000)={[0x42, 0x42], 0x2, 0x10, 0x8, 0x4, 0x2})",
},
{
input: "test$length17(&(0x7f0000000000)={0x42, 0xff, 0xff, 0xff, 0xff})",
output: "test$length17(&(0x7f0000000000)={0x42, 0x8, 0x4, 0x2, 0x1})",
In: "test$length17(&(0x7f0000000000)={0x42, 0xff, 0xff, 0xff, 0xff})",
Out: "test$length17(&(0x7f0000000000)={0x42, 0x8, 0x4, 0x2, 0x1})",
},
{
input: "test$length18(&(0x7f0000000000)={0x42, 0xff, 0xff, 0xff, 0xff})",
output: "test$length18(&(0x7f0000000000)={0x42, 0x8, 0x4, 0x2, 0x1})",
In: "test$length18(&(0x7f0000000000)={0x42, 0xff, 0xff, 0xff, 0xff})",
Out: "test$length18(&(0x7f0000000000)={0x42, 0x8, 0x4, 0x2, 0x1})",
},
{
input: "test$length19(&(0x7f0000000000)={{0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0xff}, 0xff, 0xff, 0xff})",
output: "test$length19(&(0x7f0000000000)={{0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x14}, 0x14, 0x14, 0x5})",
In: "test$length19(&(0x7f0000000000)={{0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0xff}, 0xff, 0xff, 0xff})",
Out: "test$length19(&(0x7f0000000000)={{0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x14}, 0x14, 0x14, 0x5})",
},
{
input: "test$length20(&(0x7f0000000000)={{{0xff, 0xff, 0xff, 0xff}, 0xff, 0xff, 0xff}, 0xff, 0xff})",
output: "test$length20(&(0x7f0000000000)={{{0x4, 0x4, 0x7, 0x9}, 0x7, 0x7, 0x9}, 0x9, 0x9})",
In: "test$length20(&(0x7f0000000000)={{{0xff, 0xff, 0xff, 0xff}, 0xff, 0xff, 0xff}, 0xff, 0xff})",
Out: "test$length20(&(0x7f0000000000)={{{0x4, 0x4, 0x7, 0x9}, 0x7, 0x7, 0x9}, 0x9, 0x9})",
},
{
input: "test$length21(&(0x7f0000000000)=0x0, 0x0)",
output: "test$length21(&(0x7f0000000000), 0x40)",
In: "test$length21(&(0x7f0000000000)=0x0, 0x0)",
Out: "test$length21(&(0x7f0000000000), 0x40)",
},
{
input: "test$length22(&(0x7f0000000000)='12345', 0x0)",
output: "test$length22(&(0x7f0000000000)='12345', 0x28)",
In: "test$length22(&(0x7f0000000000)='12345', 0x0)",
Out: "test$length22(&(0x7f0000000000)='12345', 0x28)",
},
{
input: "test$length23(&(0x7f0000000000)={0x1, {0x2, 0x0}})",
output: "test$length23(&(0x7f0000000000)={0x1, {0x2, 0x6}})",
In: "test$length23(&(0x7f0000000000)={0x1, {0x2, 0x0}})",
Out: "test$length23(&(0x7f0000000000)={0x1, {0x2, 0x6}})",
},
{
input: "test$length24(&(0x7f0000000000)={{0x0, {0x0}}, {0x0, {0x0}}})",
output: "test$length24(&(0x7f0000000000)={{0x0, {0x8}}, {0x0, {0x10}}})",
In: "test$length24(&(0x7f0000000000)={{0x0, {0x0}}, {0x0, {0x0}}})",
Out: "test$length24(&(0x7f0000000000)={{0x0, {0x8}}, {0x0, {0x10}}})",
},
{
input: "test$length26(&(0x7f0000000000), 0x0)",
output: "test$length26(&(0x7f0000000000), 0x8)",
In: "test$length26(&(0x7f0000000000), 0x0)",
Out: "test$length26(&(0x7f0000000000), 0x8)",
},
{
input: "test$length27(&(0x7f0000000000), 0x0)",
output: "test$length27(&(0x7f0000000000), 0x2a)",
In: "test$length27(&(0x7f0000000000), 0x0)",
Out: "test$length27(&(0x7f0000000000), 0x2a)",
},
{
input: "test$length28(&(0x7f0000000000), 0x0)",
output: "test$length28(&(0x7f0000000000), 0x2a)",
In: "test$length28(&(0x7f0000000000), 0x0)",
Out: "test$length28(&(0x7f0000000000), 0x2a)",
},
{
input: "test$length29(&(0x7f0000000000)={'./a\\x00', './b/c\\x00', 0x0, 0x0, 0x0})",
output: "test$length29(&(0x7f0000000000)={'./a\\x00', './b/c\\x00', 0xa, 0x14, 0x21})",
In: "test$length29(&(0x7f0000000000)={'./a\\x00', './b/c\\x00', 0x0, 0x0, 0x0})",
Out: "test$length29(&(0x7f0000000000)={'./a\\x00', './b/c\\x00', 0xa, 0x14, 0x21})",
},
{
input: "test$length30(&(0x7f0000000000)={{{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, {'a', 'aaa', 'aaaaa', 'aaaaaa'}, &(0x7f0000000000)={'a', 'aaa', 'aaaaa', 'aaaaaa'}, &(0x7f0000000000)=&(0x7f0000000000)={'a', 'aaa', 'aaaaa', 'aaaaaa'}, 0x0}, 0x0}, 0x0, &(0x7f0000000000)=0x0, 0x0)",
output: "test$length30(&(0x7f0000000000)={{{0x0, 0x18, 0x1, 0x3, 0x5, 0x6}, {'a', 'aaa', 'aaaaa', 'aaaaaa'}, &(0x7f0000000000)={'a', 'aaa', 'aaaaa', 'aaaaaa'}, &(0x7f0000000000)=&(0x7f0000000000)={'a', 'aaa', 'aaaaa', 'aaaaaa'}, 0x2}, 0x4}, 0x40, &(0x7f0000000000)=0x18, 0x2)",
In: "test$length30(&(0x7f0000000000)={{{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, {'a', 'aaa', 'aaaaa', 'aaaaaa'}, &(0x7f0000000000)={'a', 'aaa', 'aaaaa', 'aaaaaa'}, &(0x7f0000000000)=&(0x7f0000000000)={'a', 'aaa', 'aaaaa', 'aaaaaa'}, 0x0}, 0x0}, 0x0, &(0x7f0000000000)=0x0, 0x0)",
Out: "test$length30(&(0x7f0000000000)={{{0x0, 0x18, 0x1, 0x3, 0x5, 0x6}, {'a', 'aaa', 'aaaaa', 'aaaaaa'}, &(0x7f0000000000)={'a', 'aaa', 'aaaaa', 'aaaaaa'}, &(0x7f0000000000)=&(0x7f0000000000)={'a', 'aaa', 'aaaaa', 'aaaaaa'}, 0x2}, 0x4}, 0x40, &(0x7f0000000000)=0x18, 0x2)",
},
{
input: "test$offsetof0(&(0x7f0000000000)={0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0})",
output: "test$offsetof0(&(0x7f0000000000)={0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x6, 0x8, 0x10, 0x18, 0x18, 0x20})",
In: "test$offsetof0(&(0x7f0000000000)={0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0})",
Out: "test$offsetof0(&(0x7f0000000000)={0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x6, 0x8, 0x10, 0x18, 0x18, 0x20})",
},
})
}

72
prog/test_util.go Normal file
View File

@ -0,0 +1,72 @@
// Copyright 2020 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"
"strings"
"testing"
)
func InitTargetTest(t *testing.T, os, arch string) *Target {
t.Parallel()
target, err := GetTarget(os, arch)
if err != nil {
t.Fatal(err)
}
return target
}
type DeserializeTest struct {
In string
Out string
Err string
StrictErr string
}
func TestDeserializeHelper(t *testing.T, OS, arch string, transform func(*Target, *Prog), tests []DeserializeTest) {
target := InitTargetTest(t, OS, arch)
buf := make([]byte, ExecBufferSize)
for testidx, test := range tests {
t.Run(fmt.Sprint(testidx), func(t *testing.T) {
if test.StrictErr == "" {
test.StrictErr = test.Err
}
if test.Err != "" && test.Out != "" {
t.Fatalf("both Err and Out are set")
}
for _, mode := range []DeserializeMode{NonStrict, Strict} {
p, err := target.Deserialize([]byte(test.In), mode)
wantErr := test.Err
if mode == Strict {
wantErr = test.StrictErr
}
if err != nil {
if wantErr == "" {
t.Fatalf("deserialization failed with\n%s\ndata:\n%s\n",
err, test.In)
}
if !strings.Contains(err.Error(), wantErr) {
t.Fatalf("deserialization failed with\n%s\nwhich doesn't match\n%s\ndata:\n%s",
err, wantErr, test.In)
}
} else {
if wantErr != "" {
t.Fatalf("deserialization should have failed with:\n%s\ndata:\n%s\n",
wantErr, test.In)
}
if transform != nil {
transform(target, p)
}
output := strings.TrimSpace(string(p.Serialize()))
want := strings.TrimSpace(test.Out)
if want != "" && want != output {
t.Fatalf("wrong serialized data:\n%s\nexpect:\n%s\n", output, want)
}
p.SerializeForExec(buf)
}
}
})
}
}

View File

@ -4,8 +4,6 @@
package linux_test
import (
"fmt"
"strings"
"testing"
"github.com/google/syzkaller/prog"
@ -13,100 +11,94 @@ import (
)
func TestSanitize(t *testing.T) {
target, err := prog.GetTarget("linux", "amd64")
if err != nil {
t.Fatal(err)
}
tests := []struct {
input string
output string
}{
prog.TestDeserializeHelper(t, "linux", "amd64", nil, []prog.DeserializeTest{
{
`syslog(0x10000000006, 0x0, 0x0)`,
`syslog(0x9, 0x0, 0x0)`,
In: `syslog(0x10000000006, 0x0, 0x0)`,
Out: `syslog(0x9, 0x0, 0x0)`,
},
{
`syslog(0x10000000007, 0x0, 0x0)`,
`syslog(0x9, 0x0, 0x0)`,
In: `syslog(0x10000000007, 0x0, 0x0)`,
Out: `syslog(0x9, 0x0, 0x0)`,
},
{
`syslog(0x1, 0x0, 0x0)`,
`syslog(0x1, 0x0, 0x0)`,
In: `syslog(0x1, 0x0, 0x0)`,
Out: `syslog(0x1, 0x0, 0x0)`,
},
{
`ptrace(0xf000000000, 0x0)`,
`ptrace(0xffffffffffffffff, 0x0)`,
In: `ptrace(0xf000000000, 0x0)`,
Out: `ptrace(0xffffffffffffffff, 0x0)`,
},
{
`ptrace$peek(0x0, 0x0, &(0x7f0000000000))`,
`ptrace$peek(0xffffffffffffffff, 0x0, &(0x7f0000000000))`,
In: `ptrace$peek(0x0, 0x0, &(0x7f0000000000))`,
Out: `ptrace$peek(0xffffffffffffffff, 0x0, &(0x7f0000000000))`,
},
{
`ptrace(0x1, 0x0)`,
`ptrace(0x1, 0x0)`,
In: `ptrace(0x1, 0x0)`,
Out: `ptrace(0x1, 0x0)`,
},
{
`arch_prctl$ARCH_SET_GS(0xf00000001002, 0x0)`,
`arch_prctl$ARCH_SET_GS(0x1001, 0x0)`,
In: `arch_prctl$ARCH_SET_GS(0xf00000001002, 0x0)`,
Out: `arch_prctl$ARCH_SET_GS(0x1001, 0x0)`,
},
{
`arch_prctl$ARCH_SET_GS(0x1003, 0x0)`,
`arch_prctl$ARCH_SET_GS(0x1003, 0x0)`,
In: `arch_prctl$ARCH_SET_GS(0x1003, 0x0)`,
Out: `arch_prctl$ARCH_SET_GS(0x1003, 0x0)`,
},
{
`ioctl(0x0, 0x200000c0045877, 0x0)`,
`ioctl(0x0, 0xc0045878, 0x0)`,
In: `ioctl(0x0, 0x200000c0045877, 0x0)`,
Out: `ioctl(0x0, 0xc0045878, 0x0)`,
},
{
`ioctl$int_in(0x0, 0x2000008004587d, 0x0)`,
`ioctl$int_in(0x0, 0x6609, 0x0)`,
In: `ioctl$int_in(0x0, 0x2000008004587d, 0x0)`,
Out: `ioctl$int_in(0x0, 0x6609, 0x0)`,
},
{
`fanotify_mark(0x1, 0x2, 0x407fe029, 0x3, 0x0)`,
`fanotify_mark(0x1, 0x2, 0x4078e029, 0x3, 0x0)`,
In: `fanotify_mark(0x1, 0x2, 0x407fe029, 0x3, 0x0)`,
Out: `fanotify_mark(0x1, 0x2, 0x4078e029, 0x3, 0x0)`,
},
{
`fanotify_mark(0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffff8ffff, 0xffffffffffffffff, 0x0)`,
`fanotify_mark(0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffff8ffff, 0xffffffffffffffff, 0x0)`,
In: `fanotify_mark(0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffff8ffff, 0xffffffffffffffff, 0x0)`,
Out: `fanotify_mark(0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffff8ffff, 0xffffffffffffffff, 0x0)`,
},
{
`syz_init_net_socket$bt_hci(0x1, 0x0, 0x0)`,
`syz_init_net_socket$bt_hci(0xffffffffffffffff, 0x0, 0x0)`,
In: `syz_init_net_socket$bt_hci(0x1, 0x0, 0x0)`,
Out: `syz_init_net_socket$bt_hci(0xffffffffffffffff, 0x0, 0x0)`,
},
{
`syz_init_net_socket$bt_hci(0x27, 0x0, 0x0)`,
`syz_init_net_socket$bt_hci(0x27, 0x0, 0x0)`,
In: `syz_init_net_socket$bt_hci(0x27, 0x0, 0x0)`,
Out: `syz_init_net_socket$bt_hci(0x27, 0x0, 0x0)`,
},
{
`syz_init_net_socket$bt_hci(0x1a, 0x0, 0x0)`,
`syz_init_net_socket$bt_hci(0x1a, 0x0, 0x0)`,
In: `syz_init_net_socket$bt_hci(0x1a, 0x0, 0x0)`,
Out: `syz_init_net_socket$bt_hci(0x1a, 0x0, 0x0)`,
},
{
`syz_init_net_socket$bt_hci(0x1f, 0x0, 0x0)`,
`syz_init_net_socket$bt_hci(0x1f, 0x0, 0x0)`,
In: `syz_init_net_socket$bt_hci(0x1f, 0x0, 0x0)`,
Out: `syz_init_net_socket$bt_hci(0x1f, 0x0, 0x0)`,
},
{
`mmap(0x0, 0x0, 0x0, 0x0, 0x0, 0x0)`,
`mmap(0x0, 0x0, 0x0, 0x10, 0x0, 0x0)`,
In: `mmap(0x0, 0x0, 0x0, 0x0, 0x0, 0x0)`,
Out: `mmap(0x0, 0x0, 0x0, 0x10, 0x0, 0x0)`,
},
{
`mremap(0x0, 0x0, 0x0, 0xcc, 0x0)`,
`mremap(0x0, 0x0, 0x0, 0xcc, 0x0)`,
In: `mremap(0x0, 0x0, 0x0, 0xcc, 0x0)`,
Out: `mremap(0x0, 0x0, 0x0, 0xcc, 0x0)`,
},
{
`mremap(0x0, 0x0, 0x0, 0xcd, 0x0)`,
`mremap(0x0, 0x0, 0x0, 0xcf, 0x0)`,
In: `mremap(0x0, 0x0, 0x0, 0xcd, 0x0)`,
Out: `mremap(0x0, 0x0, 0x0, 0xcf, 0x0)`,
},
{
`
In: `
mknod(0x0, 0x1000, 0x0)
mknod(0x0, 0x8000, 0x0)
mknod(0x0, 0xc000, 0x0)
mknod(0x0, 0x2000, 0x0)
mknod(0x0, 0x6000, 0x0)
mknod(0x0, 0x6000, 0x700)
`, `
`,
Out: `
mknod(0x0, 0x1000, 0x0)
mknod(0x0, 0x8000, 0x0)
mknod(0x0, 0xc000, 0x0)
@ -116,7 +108,7 @@ mknod(0x0, 0x6000, 0x700)
`,
},
{
`
In: `
exit(0x3)
exit(0x43)
exit(0xc3)
@ -124,7 +116,8 @@ exit(0xc3)
exit_group(0x5a)
exit_group(0x43)
exit_group(0x443)
`, `
`,
Out: `
exit(0x3)
exit(0x1)
exit(0x1)
@ -135,33 +128,20 @@ exit_group(0x1)
`,
},
{
`
In: `
syz_open_dev$tty1(0xc, 0x4, 0x4)
syz_open_dev$tty1(0xb, 0x2, 0x4)
syz_open_dev$tty1(0xc, 0x4, 0x5)
`,
`
Out: `
syz_open_dev$tty1(0xc, 0x4, 0x4)
syz_open_dev$tty1(0xc, 0x4, 0x4)
syz_open_dev$tty1(0xc, 0x4, 0x1)
`,
},
{
`ioctl$TIOCSSERIAL(0x0, 0x541f, 0x0)`,
`ioctl$TIOCSSERIAL(0x0, 0x541e, 0x0)`,
In: `ioctl$TIOCSSERIAL(0x0, 0x541f, 0x0)`,
Out: `ioctl$TIOCSSERIAL(0x0, 0x541e, 0x0)`,
},
}
for i, test := range tests {
t.Run(fmt.Sprint(i), func(t *testing.T) {
p, err := target.Deserialize([]byte(test.input), prog.Strict)
if err != nil {
t.Fatal(err)
}
got := strings.TrimSpace(string(p.Serialize()))
want := strings.TrimSpace(test.output)
if got != want {
t.Fatalf("input:\n%v\ngot:\n%v\nwant:\n%s", test.input, got, want)
}
})
}
})
}

View File

@ -4,8 +4,6 @@
package openbsd_test
import (
"fmt"
"strings"
"testing"
"github.com/google/syzkaller/prog"
@ -13,93 +11,73 @@ import (
)
func TestSanitizeCall(t *testing.T) {
target, err := prog.GetTarget("openbsd", "amd64")
if err != nil {
t.Fatal(err)
}
tests := []struct {
input string
output string
}{
prog.TestDeserializeHelper(t, "openbsd", "amd64", nil, []prog.DeserializeTest{
{
`chflagsat(0x0, 0x0, 0x60004, 0x0)`,
`chflagsat(0x0, 0x0, 0x0, 0x0)`,
In: `chflagsat(0x0, 0x0, 0x60004, 0x0)`,
Out: `chflagsat(0x0, 0x0, 0x0, 0x0)`,
},
{
`fchflags(0x0, 0x60004)`,
`fchflags(0x0, 0x0)`,
In: `fchflags(0x0, 0x60004)`,
Out: `fchflags(0x0, 0x0)`,
},
{
`ioctl$BIOCSDIRFILT(0x0, 0xc0e04429, 0x0)`,
`ioctl$BIOCSDIRFILT(0x0, 0x0, 0x0)`,
In: `ioctl$BIOCSDIRFILT(0x0, 0xc0e04429, 0x0)`,
Out: `ioctl$BIOCSDIRFILT(0x0, 0x0, 0x0)`,
},
{
// major=22, minor=232
`mknodat(0x0, 0x0, 0x0, 0x16e8)`,
`mknodat(0x0, 0x0, 0x0, 0x202)`,
In: `mknodat(0x0, 0x0, 0x0, 0x16e8)`,
Out: `mknodat(0x0, 0x0, 0x0, 0x202)`,
},
{
// major=22, minor=232
`mknod(0x0, 0x0, 0x16e8)`,
`mknod(0x0, 0x0, 0x202)`,
In: `mknod(0x0, 0x0, 0x16e8)`,
Out: `mknod(0x0, 0x0, 0x202)`,
},
{
// major=22, minor=0
`mknod(0x0, 0x0, 0x1600)`,
`mknod(0x0, 0x0, 0x1600)`,
In: `mknod(0x0, 0x0, 0x1600)`,
Out: `mknod(0x0, 0x0, 0x1600)`,
},
{
// major=4, minor=0
`mknod(0x0, 0x0, 0x400)`,
`mknod(0x0, 0x0, 0x400)`,
In: `mknod(0x0, 0x0, 0x400)`,
Out: `mknod(0x0, 0x0, 0x400)`,
},
{
// major=4, minor=1
`mknod(0x0, 0x0, 0x401)`,
`mknod(0x0, 0x0, 0x202)`,
In: `mknod(0x0, 0x0, 0x401)`,
Out: `mknod(0x0, 0x0, 0x202)`,
},
{
// major=4, minor=2
`mknod(0x0, 0x0, 0x402)`,
`mknod(0x0, 0x0, 0x202)`,
In: `mknod(0x0, 0x0, 0x402)`,
Out: `mknod(0x0, 0x0, 0x202)`,
},
{
// MCL_CURRENT | MCL_FUTURE
`mlockall(0x3)`,
`mlockall(0x1)`,
In: `mlockall(0x3)`,
Out: `mlockall(0x1)`,
},
{
// RLIMIT_DATA
`setrlimit(0x2, &(0x7f0000cc0ff0)={0x0, 0x80000000})`,
`setrlimit(0x2, &(0x7f0000cc0ff0)={0x60000000, 0x80000000})`,
In: `setrlimit(0x2, &(0x7f0000cc0ff0)={0x0, 0x80000000})`,
Out: `setrlimit(0x2, &(0x7f0000cc0ff0)={0x60000000, 0x80000000})`,
},
{
// RLIMIT_DATA
`setrlimit(0x10000000000002, &(0x7f0000cc0ff0)={0x0, 0x80000000})`,
`setrlimit(0x10000000000002, &(0x7f0000cc0ff0)={0x60000000, 0x80000000})`,
In: `setrlimit(0x10000000000002, &(0x7f0000cc0ff0)={0x0, 0x80000000})`,
Out: `setrlimit(0x10000000000002, &(0x7f0000cc0ff0)={0x60000000, 0x80000000})`,
},
{
// RLIMIT_STACK
`setrlimit(0x3, &(0x7f0000cc0ff0)={0x1000000000, 0x1000000000})`,
`setrlimit(0x3, &(0x7f0000cc0ff0)={0x100000, 0x100000})`,
In: `setrlimit(0x3, &(0x7f0000cc0ff0)={0x1000000000, 0x1000000000})`,
Out: `setrlimit(0x3, &(0x7f0000cc0ff0)={0x100000, 0x100000})`,
},
{
// RLIMIT_CPU
`setrlimit(0x0, &(0x7f0000cc0ff0)={0x1, 0x1})`,
`setrlimit(0x0, &(0x7f0000cc0ff0)={0x1, 0x1})`,
In: `setrlimit(0x0, &(0x7f0000cc0ff0)={0x1, 0x1})`,
Out: `setrlimit(0x0, &(0x7f0000cc0ff0)={0x1, 0x1})`,
},
}
for i, test := range tests {
t.Run(fmt.Sprint(i), func(t *testing.T) {
p, err := target.Deserialize([]byte(test.input), prog.Strict)
if err != nil {
t.Fatal(err)
}
got := strings.TrimSpace(string(p.Serialize()))
want := strings.TrimSpace(test.output)
if got != want {
t.Fatalf("input:\n%v\ngot:\n%v\nwant:\n%s", test.input, got, want)
}
})
}
})
}