mirror of
https://github.com/reactos/syzkaller.git
synced 2024-12-13 14:25:59 +00:00
216 lines
5.2 KiB
Go
216 lines
5.2 KiB
Go
// Copyright 2017 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.
|
|
|
|
// +build linux
|
|
|
|
package linux
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"math/rand"
|
|
"strings"
|
|
"syscall"
|
|
"testing"
|
|
"unsafe"
|
|
)
|
|
|
|
// AF_ALG tests won't generally pass and intended for manual testing.
|
|
// First, they require fresh kernel with _all_ crypto algorithms enabled.
|
|
// Second, they require the newest hardware with all of SSE/AVX.
|
|
// Finally, they still won't pass because some algorithms are arch-dependent.
|
|
var flagRunAlgTests = flag.Bool("algtests", false, "run AF_ALG tests")
|
|
|
|
func algTest(t *testing.T) {
|
|
if !*flagRunAlgTests {
|
|
t.Skip()
|
|
}
|
|
t.Parallel()
|
|
}
|
|
|
|
// TestAlgDescriptions checks that there are no duplicate names and that
|
|
// templates mentioned in complete algorithms are also present as standalone templates.
|
|
func TestAlgDescriptions(t *testing.T) {
|
|
algTest(t)
|
|
allall := make(map[string]bool)
|
|
for typ, algList := range allAlgs {
|
|
algs := make(map[string]bool)
|
|
templates := make(map[string]bool)
|
|
for _, alg := range algList {
|
|
allall[alg.name] = true
|
|
if algs[alg.name] {
|
|
t.Errorf("duplicate: %v", alg.name)
|
|
}
|
|
algs[alg.name] = true
|
|
if len(alg.args) > 0 {
|
|
templates[alg.name] = true
|
|
}
|
|
}
|
|
for _, alg := range algList {
|
|
if len(alg.args) > 0 || strings.HasPrefix(alg.name, "__") {
|
|
continue
|
|
}
|
|
brace := strings.IndexByte(alg.name, '(')
|
|
if brace == -1 {
|
|
continue
|
|
}
|
|
templ := alg.name[:brace]
|
|
if !templates[templ] {
|
|
t.Errorf("template %v is missing for type %v", templ, typ)
|
|
}
|
|
templates[templ] = true
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestSingleAlg tests creation of all algorithms (not templates).
|
|
func TestSingleAlg(t *testing.T) {
|
|
algTest(t)
|
|
for _, typ := range allTypes {
|
|
for _, alg := range allAlgs[typ.typ] {
|
|
if len(alg.args) != 0 {
|
|
continue
|
|
}
|
|
ok, skip := testAlg(t, typ.name, alg.name)
|
|
if skip {
|
|
t.Errorf("SKIP\t%10v\t%v", typ.name, alg.name)
|
|
continue
|
|
}
|
|
if !ok {
|
|
t.Errorf("FAIL\t%10v\t%v", typ.name, alg.name)
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestTemplateAlg1 tests creation of all templates with 1 argument.
|
|
func TestTemplateAlg1(t *testing.T) {
|
|
algTest(t)
|
|
for _, typ := range allTypes {
|
|
for _, alg := range allAlgs[typ.typ] {
|
|
if len(alg.args) != 1 {
|
|
continue
|
|
}
|
|
var works []int
|
|
nextType:
|
|
for typ1, algs1 := range allAlgs {
|
|
var selection []algDesc
|
|
for _, x := range rand.Perm(len(algs1)) {
|
|
if len(algs1[x].args) != 0 {
|
|
continue
|
|
}
|
|
selection = append(selection, algs1[x])
|
|
if len(selection) == 10 {
|
|
break
|
|
}
|
|
}
|
|
for _, alg1 := range selection {
|
|
name := fmt.Sprintf("%v(%v)", alg.name, alg1.name)
|
|
ok, _ := testAlg(t, typ.name, name)
|
|
if ok {
|
|
works = append(works, typ1)
|
|
continue nextType
|
|
}
|
|
}
|
|
}
|
|
if len(works) == 1 && works[0] == alg.args[0] {
|
|
continue
|
|
}
|
|
t.Errorf("FAIL\t%10v\t%v\tclaimed %v works with %v",
|
|
typ.name, alg.name, alg.args[0], works)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestTemplateAlg2 tests creation of all templates with 2 argument.
|
|
func TestTemplateAlg2(t *testing.T) {
|
|
algTest(t)
|
|
// Can't affort to test all permutations of 2 algorithms,
|
|
// 20 algorithm pairs for each type pair and use them.
|
|
selections := make(map[int][]int)
|
|
for typ1, algs1 := range allAlgs {
|
|
for typ2, algs2 := range allAlgs {
|
|
var pairs []int
|
|
for i1, alg1 := range algs1 {
|
|
if len(alg1.args) != 0 {
|
|
continue
|
|
}
|
|
for i2, alg2 := range algs2 {
|
|
if len(alg2.args) != 0 {
|
|
continue
|
|
}
|
|
pairs = append(pairs, i1*1000+i2)
|
|
}
|
|
}
|
|
var selection []int
|
|
for _, x := range rand.Perm(len(pairs)) {
|
|
selection = append(selection, pairs[x])
|
|
if len(selection) > 20 {
|
|
break
|
|
}
|
|
}
|
|
selections[typ1*1000+typ2] = selection
|
|
}
|
|
}
|
|
for _, typ := range allTypes {
|
|
for _, alg := range allAlgs[typ.typ] {
|
|
if len(alg.args) != 2 {
|
|
continue
|
|
}
|
|
for typ1, algs1 := range allAlgs {
|
|
for typ2, algs2 := range allAlgs {
|
|
selection := selections[typ1*1000+typ2]
|
|
for _, x := range selection {
|
|
alg1 := algs1[x/1000]
|
|
alg2 := algs2[x%1000]
|
|
name := fmt.Sprintf("%v(%v,%v)",
|
|
alg.name, alg1.name, alg2.name)
|
|
if ok, _ := testAlg(t, typ.name, name); ok {
|
|
t.Logf("%10v\t%v\tclaimed %v works with %v/%v (%v)",
|
|
typ.name, alg.name, alg.args, typ1, typ2, name)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
type sockaddrAlg struct {
|
|
family uint16
|
|
typ [14]byte
|
|
feat uint32
|
|
mask uint32
|
|
name [64]byte
|
|
}
|
|
|
|
func testAlg(t *testing.T, typ, name string) (ok, skip bool) {
|
|
const AF_ALG = 0x26
|
|
addr := &sockaddrAlg{
|
|
family: AF_ALG,
|
|
}
|
|
if len(typ) >= int(unsafe.Sizeof(addr.typ)) ||
|
|
len(name) >= int(unsafe.Sizeof(addr.name)) {
|
|
return false, true
|
|
}
|
|
for i := 0; i < len(typ); i++ {
|
|
addr.typ[i] = typ[i]
|
|
}
|
|
for i := 0; i < len(name); i++ {
|
|
addr.name[i] = name[i]
|
|
}
|
|
sock, err := syscall.Socket(AF_ALG, syscall.SOCK_SEQPACKET, 0)
|
|
if err != nil {
|
|
t.Fatalf("failed to create AF_ALG socket: %v", err)
|
|
}
|
|
defer syscall.Close(sock)
|
|
_, _, errno := syscall.Syscall(syscall.SYS_BIND, uintptr(sock),
|
|
uintptr(unsafe.Pointer(addr)), unsafe.Sizeof(*addr))
|
|
if errno != 0 {
|
|
return false, false
|
|
}
|
|
return true, false
|
|
}
|