• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2017 syzkaller project authors. All rights reserved.
2// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
3
4// +build linux
5
6package linux
7
8import (
9	"flag"
10	"fmt"
11	"math/rand"
12	"strings"
13	"syscall"
14	"testing"
15	"unsafe"
16)
17
18// AF_ALG tests won't generally pass and intended for manual testing.
19// First, they require fresh kernel with _all_ crypto algorithms enabled.
20// Second, they require the newest hardware with all of SSE/AVX.
21// Finally, they still won't pass because some algorithms are arch-dependent.
22var flagRunAlgTests = flag.Bool("algtests", false, "run AF_ALG tests")
23
24func algTest(t *testing.T) {
25	if !*flagRunAlgTests {
26		t.Skip()
27	}
28	t.Parallel()
29}
30
31// TestAlgDescriptions checks that there are no duplicate names and that
32// templates mentioned in complete algorithms are also present as standalone templates.
33func TestAlgDescriptions(t *testing.T) {
34	algTest(t)
35	allall := make(map[string]bool)
36	for typ, algList := range allAlgs {
37		algs := make(map[string]bool)
38		templates := make(map[string]bool)
39		for _, alg := range algList {
40			allall[alg.name] = true
41			if algs[alg.name] {
42				t.Errorf("duplicate: %v", alg.name)
43			}
44			algs[alg.name] = true
45			if len(alg.args) > 0 {
46				templates[alg.name] = true
47			}
48		}
49		for _, alg := range algList {
50			if len(alg.args) > 0 || strings.HasPrefix(alg.name, "__") {
51				continue
52			}
53			brace := strings.IndexByte(alg.name, '(')
54			if brace == -1 {
55				continue
56			}
57			templ := alg.name[:brace]
58			if !templates[templ] {
59				t.Errorf("template %v is missing for type %v", templ, typ)
60			}
61			templates[templ] = true
62		}
63	}
64}
65
66// TestSingleAlg tests creation of all algorithms (not templates).
67func TestSingleAlg(t *testing.T) {
68	algTest(t)
69	for _, typ := range allTypes {
70		for _, alg := range allAlgs[typ.typ] {
71			if len(alg.args) != 0 {
72				continue
73			}
74			ok, skip := testAlg(t, typ.name, alg.name)
75			if skip {
76				t.Errorf("SKIP\t%10v\t%v", typ.name, alg.name)
77				continue
78			}
79			if !ok {
80				t.Errorf("FAIL\t%10v\t%v", typ.name, alg.name)
81				continue
82			}
83		}
84	}
85}
86
87// TestTemplateAlg1 tests creation of all templates with 1 argument.
88func TestTemplateAlg1(t *testing.T) {
89	algTest(t)
90	for _, typ := range allTypes {
91		for _, alg := range allAlgs[typ.typ] {
92			if len(alg.args) != 1 {
93				continue
94			}
95			var works []int
96		nextType:
97			for typ1, algs1 := range allAlgs {
98				var selection []algDesc
99				for _, x := range rand.Perm(len(algs1)) {
100					if len(algs1[x].args) != 0 {
101						continue
102					}
103					selection = append(selection, algs1[x])
104					if len(selection) == 10 {
105						break
106					}
107				}
108				for _, alg1 := range selection {
109					name := fmt.Sprintf("%v(%v)", alg.name, alg1.name)
110					ok, _ := testAlg(t, typ.name, name)
111					if ok {
112						works = append(works, typ1)
113						continue nextType
114					}
115				}
116			}
117			if len(works) == 1 && works[0] == alg.args[0] {
118				continue
119			}
120			t.Errorf("FAIL\t%10v\t%v\tclaimed %v works with %v",
121				typ.name, alg.name, alg.args[0], works)
122		}
123	}
124}
125
126// TestTemplateAlg2 tests creation of all templates with 2 argument.
127func TestTemplateAlg2(t *testing.T) {
128	algTest(t)
129	// Can't afford to test all permutations of 2 algorithms,
130	// 20 algorithm pairs for each type pair and use them.
131	selections := make(map[int][]int)
132	for typ1, algs1 := range allAlgs {
133		for typ2, algs2 := range allAlgs {
134			var pairs []int
135			for i1, alg1 := range algs1 {
136				if len(alg1.args) != 0 {
137					continue
138				}
139				for i2, alg2 := range algs2 {
140					if len(alg2.args) != 0 {
141						continue
142					}
143					pairs = append(pairs, i1*1000+i2)
144				}
145			}
146			var selection []int
147			for _, x := range rand.Perm(len(pairs)) {
148				selection = append(selection, pairs[x])
149				if len(selection) > 20 {
150					break
151				}
152			}
153			selections[typ1*1000+typ2] = selection
154		}
155	}
156	for _, typ := range allTypes {
157		for _, alg := range allAlgs[typ.typ] {
158			if len(alg.args) != 2 {
159				continue
160			}
161			for typ1, algs1 := range allAlgs {
162				for typ2, algs2 := range allAlgs {
163					selection := selections[typ1*1000+typ2]
164					for _, x := range selection {
165						alg1 := algs1[x/1000]
166						alg2 := algs2[x%1000]
167						name := fmt.Sprintf("%v(%v,%v)",
168							alg.name, alg1.name, alg2.name)
169						if ok, _ := testAlg(t, typ.name, name); ok {
170							t.Logf("%10v\t%v\tclaimed %v works with %v/%v (%v)",
171								typ.name, alg.name, alg.args, typ1, typ2, name)
172							break
173						}
174					}
175				}
176			}
177		}
178	}
179}
180
181type sockaddrAlg struct {
182	family uint16
183	typ    [14]byte
184	feat   uint32
185	mask   uint32
186	name   [64]byte
187}
188
189func testAlg(t *testing.T, typ, name string) (ok, skip bool) {
190	const AF_ALG = 0x26
191	addr := &sockaddrAlg{
192		family: AF_ALG,
193		feat:   0,
194		mask:   0,
195	}
196	if len(typ) >= int(unsafe.Sizeof(addr.typ)) ||
197		len(name) >= int(unsafe.Sizeof(addr.name)) {
198		return false, true
199	}
200	for i := 0; i < len(typ); i++ {
201		addr.typ[i] = typ[i]
202	}
203	for i := 0; i < len(name); i++ {
204		addr.name[i] = name[i]
205	}
206	sock, err := syscall.Socket(AF_ALG, syscall.SOCK_SEQPACKET, 0)
207	if err != nil {
208		t.Fatalf("failed to create AF_ALG socket: %v", err)
209	}
210	defer syscall.Close(sock)
211	_, _, errno := syscall.Syscall(syscall.SYS_BIND, uintptr(sock),
212		uintptr(unsafe.Pointer(addr)), unsafe.Sizeof(*addr))
213	if errno != 0 {
214		return false, false
215	}
216	return true, false
217}
218