OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / bpf / vm_load_test.go
1 // Copyright 2016 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package bpf_test
6
7 import (
8         "net"
9         "testing"
10
11         "golang.org/x/net/bpf"
12         "golang.org/x/net/ipv4"
13 )
14
15 func TestVMLoadAbsoluteOffsetOutOfBounds(t *testing.T) {
16         vm, done, err := testVM(t, []bpf.Instruction{
17                 bpf.LoadAbsolute{
18                         Off:  100,
19                         Size: 2,
20                 },
21                 bpf.RetA{},
22         })
23         if err != nil {
24                 t.Fatalf("failed to load BPF program: %v", err)
25         }
26         defer done()
27
28         out, err := vm.Run([]byte{
29                 0xff, 0xff, 0xff, 0xff,
30                 0xff, 0xff, 0xff, 0xff,
31                 0, 1, 2, 3,
32         })
33         if err != nil {
34                 t.Fatalf("unexpected error while running program: %v", err)
35         }
36         if want, got := 0, out; want != got {
37                 t.Fatalf("unexpected number of output bytes:\n- want: %d\n-  got: %d",
38                         want, got)
39         }
40 }
41
42 func TestVMLoadAbsoluteOffsetPlusSizeOutOfBounds(t *testing.T) {
43         vm, done, err := testVM(t, []bpf.Instruction{
44                 bpf.LoadAbsolute{
45                         Off:  8,
46                         Size: 2,
47                 },
48                 bpf.RetA{},
49         })
50         if err != nil {
51                 t.Fatalf("failed to load BPF program: %v", err)
52         }
53         defer done()
54
55         out, err := vm.Run([]byte{
56                 0xff, 0xff, 0xff, 0xff,
57                 0xff, 0xff, 0xff, 0xff,
58                 0,
59         })
60         if err != nil {
61                 t.Fatalf("unexpected error while running program: %v", err)
62         }
63         if want, got := 0, out; want != got {
64                 t.Fatalf("unexpected number of output bytes:\n- want: %d\n-  got: %d",
65                         want, got)
66         }
67 }
68
69 func TestVMLoadAbsoluteBadInstructionSize(t *testing.T) {
70         _, _, err := testVM(t, []bpf.Instruction{
71                 bpf.LoadAbsolute{
72                         Size: 5,
73                 },
74                 bpf.RetA{},
75         })
76         if errStr(err) != "assembling instruction 1: invalid load byte length 0" {
77                 t.Fatalf("unexpected error: %v", err)
78         }
79 }
80
81 func TestVMLoadConstantOK(t *testing.T) {
82         vm, done, err := testVM(t, []bpf.Instruction{
83                 bpf.LoadConstant{
84                         Dst: bpf.RegX,
85                         Val: 9,
86                 },
87                 bpf.TXA{},
88                 bpf.RetA{},
89         })
90         if err != nil {
91                 t.Fatalf("failed to load BPF program: %v", err)
92         }
93         defer done()
94
95         out, err := vm.Run([]byte{
96                 0xff, 0xff, 0xff, 0xff,
97                 0xff, 0xff, 0xff, 0xff,
98                 0,
99         })
100         if err != nil {
101                 t.Fatalf("unexpected error while running program: %v", err)
102         }
103         if want, got := 1, out; want != got {
104                 t.Fatalf("unexpected number of output bytes:\n- want: %d\n-  got: %d",
105                         want, got)
106         }
107 }
108
109 func TestVMLoadIndirectOutOfBounds(t *testing.T) {
110         vm, done, err := testVM(t, []bpf.Instruction{
111                 bpf.LoadIndirect{
112                         Off:  100,
113                         Size: 1,
114                 },
115                 bpf.RetA{},
116         })
117         if err != nil {
118                 t.Fatalf("failed to load BPF program: %v", err)
119         }
120         defer done()
121
122         out, err := vm.Run([]byte{
123                 0xff, 0xff, 0xff, 0xff,
124                 0xff, 0xff, 0xff, 0xff,
125                 0,
126         })
127         if err != nil {
128                 t.Fatalf("unexpected error while running program: %v", err)
129         }
130         if want, got := 0, out; want != got {
131                 t.Fatalf("unexpected number of output bytes:\n- want: %d\n-  got: %d",
132                         want, got)
133         }
134 }
135
136 func TestVMLoadMemShiftOutOfBounds(t *testing.T) {
137         vm, done, err := testVM(t, []bpf.Instruction{
138                 bpf.LoadMemShift{
139                         Off: 100,
140                 },
141                 bpf.RetA{},
142         })
143         if err != nil {
144                 t.Fatalf("failed to load BPF program: %v", err)
145         }
146         defer done()
147
148         out, err := vm.Run([]byte{
149                 0xff, 0xff, 0xff, 0xff,
150                 0xff, 0xff, 0xff, 0xff,
151                 0,
152         })
153         if err != nil {
154                 t.Fatalf("unexpected error while running program: %v", err)
155         }
156         if want, got := 0, out; want != got {
157                 t.Fatalf("unexpected number of output bytes:\n- want: %d\n-  got: %d",
158                         want, got)
159         }
160 }
161
162 const (
163         dhcp4Port = 53
164 )
165
166 func TestVMLoadMemShiftLoadIndirectNoResult(t *testing.T) {
167         vm, in, done := testDHCPv4(t)
168         defer done()
169
170         // Append mostly empty UDP header with incorrect DHCPv4 port
171         in = append(in, []byte{
172                 0, 0,
173                 0, dhcp4Port + 1,
174                 0, 0,
175                 0, 0,
176         }...)
177
178         out, err := vm.Run(in)
179         if err != nil {
180                 t.Fatalf("unexpected error while running program: %v", err)
181         }
182         if want, got := 0, out; want != got {
183                 t.Fatalf("unexpected number of output bytes:\n- want: %d\n-  got: %d",
184                         want, got)
185         }
186 }
187
188 func TestVMLoadMemShiftLoadIndirectOK(t *testing.T) {
189         vm, in, done := testDHCPv4(t)
190         defer done()
191
192         // Append mostly empty UDP header with correct DHCPv4 port
193         in = append(in, []byte{
194                 0, 0,
195                 0, dhcp4Port,
196                 0, 0,
197                 0, 0,
198         }...)
199
200         out, err := vm.Run(in)
201         if err != nil {
202                 t.Fatalf("unexpected error while running program: %v", err)
203         }
204         if want, got := len(in)-8, out; want != got {
205                 t.Fatalf("unexpected number of output bytes:\n- want: %d\n-  got: %d",
206                         want, got)
207         }
208 }
209
210 func testDHCPv4(t *testing.T) (virtualMachine, []byte, func()) {
211         // DHCPv4 test data courtesy of David Anderson:
212         // https://github.com/google/netboot/blob/master/dhcp4/conn_linux.go#L59-L70
213         vm, done, err := testVM(t, []bpf.Instruction{
214                 // Load IPv4 packet length
215                 bpf.LoadMemShift{Off: 8},
216                 // Get UDP dport
217                 bpf.LoadIndirect{Off: 8 + 2, Size: 2},
218                 // Correct dport?
219                 bpf.JumpIf{Cond: bpf.JumpEqual, Val: dhcp4Port, SkipFalse: 1},
220                 // Accept
221                 bpf.RetConstant{Val: 1500},
222                 // Ignore
223                 bpf.RetConstant{Val: 0},
224         })
225         if err != nil {
226                 t.Fatalf("failed to load BPF program: %v", err)
227         }
228
229         // Minimal requirements to make a valid IPv4 header
230         h := &ipv4.Header{
231                 Len: ipv4.HeaderLen,
232                 Src: net.IPv4(192, 168, 1, 1),
233                 Dst: net.IPv4(192, 168, 1, 2),
234         }
235         hb, err := h.Marshal()
236         if err != nil {
237                 t.Fatalf("failed to marshal IPv4 header: %v", err)
238         }
239
240         hb = append([]byte{
241                 0xff, 0xff, 0xff, 0xff,
242                 0xff, 0xff, 0xff, 0xff,
243         }, hb...)
244
245         return vm, hb, done
246 }