1
2
3
4
5 package bpf_test
6
7 import (
8 "testing"
9
10 "golang.org/x/net/bpf"
11 )
12
13 func TestVMALUOpAdd(t *testing.T) {
14 vm, done, err := testVM(t, []bpf.Instruction{
15 bpf.LoadAbsolute{
16 Off: 8,
17 Size: 1,
18 },
19 bpf.ALUOpConstant{
20 Op: bpf.ALUOpAdd,
21 Val: 3,
22 },
23 bpf.RetA{},
24 })
25 if err != nil {
26 t.Fatalf("failed to load BPF program: %v", err)
27 }
28 defer done()
29
30 out, err := vm.Run([]byte{
31 0xff, 0xff, 0xff, 0xff,
32 0xff, 0xff, 0xff, 0xff,
33 8, 2, 3,
34 })
35 if err != nil {
36 t.Fatalf("unexpected error while running program: %v", err)
37 }
38 if want, got := 3, out; want != got {
39 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
40 want, got)
41 }
42 }
43
44 func TestVMALUOpSub(t *testing.T) {
45 vm, done, err := testVM(t, []bpf.Instruction{
46 bpf.LoadAbsolute{
47 Off: 8,
48 Size: 1,
49 },
50 bpf.TAX{},
51 bpf.ALUOpX{
52 Op: bpf.ALUOpSub,
53 },
54 bpf.RetA{},
55 })
56 if err != nil {
57 t.Fatalf("failed to load BPF program: %v", err)
58 }
59 defer done()
60
61 out, err := vm.Run([]byte{
62 0xff, 0xff, 0xff, 0xff,
63 0xff, 0xff, 0xff, 0xff,
64 1, 2, 3,
65 })
66 if err != nil {
67 t.Fatalf("unexpected error while running program: %v", err)
68 }
69 if want, got := 0, out; want != got {
70 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
71 want, got)
72 }
73 }
74
75 func TestVMALUOpMul(t *testing.T) {
76 vm, done, err := testVM(t, []bpf.Instruction{
77 bpf.LoadAbsolute{
78 Off: 8,
79 Size: 1,
80 },
81 bpf.ALUOpConstant{
82 Op: bpf.ALUOpMul,
83 Val: 2,
84 },
85 bpf.RetA{},
86 })
87 if err != nil {
88 t.Fatalf("failed to load BPF program: %v", err)
89 }
90 defer done()
91
92 out, err := vm.Run([]byte{
93 0xff, 0xff, 0xff, 0xff,
94 0xff, 0xff, 0xff, 0xff,
95 6, 2, 3, 4,
96 })
97 if err != nil {
98 t.Fatalf("unexpected error while running program: %v", err)
99 }
100 if want, got := 4, out; want != got {
101 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
102 want, got)
103 }
104 }
105
106 func TestVMALUOpDiv(t *testing.T) {
107 vm, done, err := testVM(t, []bpf.Instruction{
108 bpf.LoadAbsolute{
109 Off: 8,
110 Size: 1,
111 },
112 bpf.ALUOpConstant{
113 Op: bpf.ALUOpDiv,
114 Val: 2,
115 },
116 bpf.RetA{},
117 })
118 if err != nil {
119 t.Fatalf("failed to load BPF program: %v", err)
120 }
121 defer done()
122
123 out, err := vm.Run([]byte{
124 0xff, 0xff, 0xff, 0xff,
125 0xff, 0xff, 0xff, 0xff,
126 20, 2, 3, 4,
127 })
128 if err != nil {
129 t.Fatalf("unexpected error while running program: %v", err)
130 }
131 if want, got := 2, out; want != got {
132 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
133 want, got)
134 }
135 }
136
137 func TestVMALUOpDivByZeroALUOpConstant(t *testing.T) {
138 _, _, err := testVM(t, []bpf.Instruction{
139 bpf.ALUOpConstant{
140 Op: bpf.ALUOpDiv,
141 Val: 0,
142 },
143 bpf.RetA{},
144 })
145 if errStr(err) != "cannot divide by zero using ALUOpConstant" {
146 t.Fatalf("unexpected error: %v", err)
147 }
148 }
149
150 func TestVMALUOpDivByZeroALUOpX(t *testing.T) {
151 vm, done, err := testVM(t, []bpf.Instruction{
152
153 bpf.LoadAbsolute{
154 Off: 8,
155 Size: 1,
156 },
157 bpf.TAX{},
158
159 bpf.LoadAbsolute{
160 Off: 9,
161 Size: 1,
162 },
163
164 bpf.ALUOpX{
165 Op: bpf.ALUOpDiv,
166 },
167
168 bpf.LoadConstant{
169 Val: 12,
170 },
171 bpf.RetA{},
172 })
173 if err != nil {
174 t.Fatalf("failed to load BPF program: %v", err)
175 }
176 defer done()
177
178 out, err := vm.Run([]byte{
179 0xff, 0xff, 0xff, 0xff,
180 0xff, 0xff, 0xff, 0xff,
181 0, 1, 3, 4,
182 })
183 if err != nil {
184 t.Fatalf("unexpected error while running program: %v", err)
185 }
186 if want, got := 0, out; want != got {
187 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
188 want, got)
189 }
190 }
191
192 func TestVMALUOpOr(t *testing.T) {
193 vm, done, err := testVM(t, []bpf.Instruction{
194 bpf.LoadAbsolute{
195 Off: 8,
196 Size: 2,
197 },
198 bpf.ALUOpConstant{
199 Op: bpf.ALUOpOr,
200 Val: 0x01,
201 },
202 bpf.RetA{},
203 })
204 if err != nil {
205 t.Fatalf("failed to load BPF program: %v", err)
206 }
207 defer done()
208
209 out, err := vm.Run([]byte{
210 0xff, 0xff, 0xff, 0xff,
211 0xff, 0xff, 0xff, 0xff,
212 0x00, 0x10, 0x03, 0x04,
213 0x05, 0x06, 0x07, 0x08,
214 0x09, 0xff,
215 })
216 if err != nil {
217 t.Fatalf("unexpected error while running program: %v", err)
218 }
219 if want, got := 9, out; want != got {
220 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
221 want, got)
222 }
223 }
224
225 func TestVMALUOpAnd(t *testing.T) {
226 vm, done, err := testVM(t, []bpf.Instruction{
227 bpf.LoadAbsolute{
228 Off: 8,
229 Size: 2,
230 },
231 bpf.ALUOpConstant{
232 Op: bpf.ALUOpAnd,
233 Val: 0x0019,
234 },
235 bpf.RetA{},
236 })
237 if err != nil {
238 t.Fatalf("failed to load BPF program: %v", err)
239 }
240 defer done()
241
242 out, err := vm.Run([]byte{
243 0xff, 0xff, 0xff, 0xff,
244 0xff, 0xff, 0xff, 0xff,
245 0xaa, 0x09,
246 })
247 if err != nil {
248 t.Fatalf("unexpected error while running program: %v", err)
249 }
250 if want, got := 1, out; want != got {
251 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
252 want, got)
253 }
254 }
255
256 func TestVMALUOpShiftLeft(t *testing.T) {
257 vm, done, err := testVM(t, []bpf.Instruction{
258 bpf.LoadAbsolute{
259 Off: 8,
260 Size: 1,
261 },
262 bpf.ALUOpConstant{
263 Op: bpf.ALUOpShiftLeft,
264 Val: 0x01,
265 },
266 bpf.JumpIf{
267 Cond: bpf.JumpEqual,
268 Val: 0x02,
269 SkipTrue: 1,
270 },
271 bpf.RetConstant{
272 Val: 0,
273 },
274 bpf.RetConstant{
275 Val: 9,
276 },
277 })
278 if err != nil {
279 t.Fatalf("failed to load BPF program: %v", err)
280 }
281 defer done()
282
283 out, err := vm.Run([]byte{
284 0xff, 0xff, 0xff, 0xff,
285 0xff, 0xff, 0xff, 0xff,
286 0x01, 0xaa,
287 })
288 if err != nil {
289 t.Fatalf("unexpected error while running program: %v", err)
290 }
291 if want, got := 1, out; want != got {
292 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
293 want, got)
294 }
295 }
296
297 func TestVMALUOpShiftRight(t *testing.T) {
298 vm, done, err := testVM(t, []bpf.Instruction{
299 bpf.LoadAbsolute{
300 Off: 8,
301 Size: 1,
302 },
303 bpf.ALUOpConstant{
304 Op: bpf.ALUOpShiftRight,
305 Val: 0x01,
306 },
307 bpf.JumpIf{
308 Cond: bpf.JumpEqual,
309 Val: 0x04,
310 SkipTrue: 1,
311 },
312 bpf.RetConstant{
313 Val: 0,
314 },
315 bpf.RetConstant{
316 Val: 9,
317 },
318 })
319 if err != nil {
320 t.Fatalf("failed to load BPF program: %v", err)
321 }
322 defer done()
323
324 out, err := vm.Run([]byte{
325 0xff, 0xff, 0xff, 0xff,
326 0xff, 0xff, 0xff, 0xff,
327 0x08, 0xff, 0xff,
328 })
329 if err != nil {
330 t.Fatalf("unexpected error while running program: %v", err)
331 }
332 if want, got := 1, out; want != got {
333 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
334 want, got)
335 }
336 }
337
338 func TestVMALUOpMod(t *testing.T) {
339 vm, done, err := testVM(t, []bpf.Instruction{
340 bpf.LoadAbsolute{
341 Off: 8,
342 Size: 1,
343 },
344 bpf.ALUOpConstant{
345 Op: bpf.ALUOpMod,
346 Val: 20,
347 },
348 bpf.RetA{},
349 })
350 if err != nil {
351 t.Fatalf("failed to load BPF program: %v", err)
352 }
353 defer done()
354
355 out, err := vm.Run([]byte{
356 0xff, 0xff, 0xff, 0xff,
357 0xff, 0xff, 0xff, 0xff,
358 30, 0, 0,
359 })
360 if err != nil {
361 t.Fatalf("unexpected error while running program: %v", err)
362 }
363 if want, got := 2, out; want != got {
364 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
365 want, got)
366 }
367 }
368
369 func TestVMALUOpModByZeroALUOpConstant(t *testing.T) {
370 _, _, err := testVM(t, []bpf.Instruction{
371 bpf.LoadAbsolute{
372 Off: 8,
373 Size: 1,
374 },
375 bpf.ALUOpConstant{
376 Op: bpf.ALUOpMod,
377 Val: 0,
378 },
379 bpf.RetA{},
380 })
381 if errStr(err) != "cannot divide by zero using ALUOpConstant" {
382 t.Fatalf("unexpected error: %v", err)
383 }
384 }
385
386 func TestVMALUOpModByZeroALUOpX(t *testing.T) {
387 vm, done, err := testVM(t, []bpf.Instruction{
388
389 bpf.LoadAbsolute{
390 Off: 8,
391 Size: 1,
392 },
393 bpf.TAX{},
394
395 bpf.LoadAbsolute{
396 Off: 9,
397 Size: 1,
398 },
399
400 bpf.ALUOpX{
401 Op: bpf.ALUOpMod,
402 },
403
404 bpf.LoadConstant{
405 Val: 12,
406 },
407 bpf.RetA{},
408 })
409 if err != nil {
410 t.Fatalf("failed to load BPF program: %v", err)
411 }
412 defer done()
413
414 out, err := vm.Run([]byte{
415 0xff, 0xff, 0xff, 0xff,
416 0xff, 0xff, 0xff, 0xff,
417 0, 1, 3, 4,
418 })
419 if err != nil {
420 t.Fatalf("unexpected error while running program: %v", err)
421 }
422 if want, got := 0, out; want != got {
423 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
424 want, got)
425 }
426 }
427
428 func TestVMALUOpXor(t *testing.T) {
429 vm, done, err := testVM(t, []bpf.Instruction{
430 bpf.LoadAbsolute{
431 Off: 8,
432 Size: 1,
433 },
434 bpf.ALUOpConstant{
435 Op: bpf.ALUOpXor,
436 Val: 0x0a,
437 },
438 bpf.JumpIf{
439 Cond: bpf.JumpEqual,
440 Val: 0x01,
441 SkipTrue: 1,
442 },
443 bpf.RetConstant{
444 Val: 0,
445 },
446 bpf.RetConstant{
447 Val: 9,
448 },
449 })
450 if err != nil {
451 t.Fatalf("failed to load BPF program: %v", err)
452 }
453 defer done()
454
455 out, err := vm.Run([]byte{
456 0xff, 0xff, 0xff, 0xff,
457 0xff, 0xff, 0xff, 0xff,
458 0x0b, 0x00, 0x00, 0x00,
459 })
460 if err != nil {
461 t.Fatalf("unexpected error while running program: %v", err)
462 }
463 if want, got := 1, out; want != got {
464 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
465 want, got)
466 }
467 }
468
469 func TestVMALUOpUnknown(t *testing.T) {
470 vm, done, err := testVM(t, []bpf.Instruction{
471 bpf.LoadAbsolute{
472 Off: 8,
473 Size: 1,
474 },
475 bpf.ALUOpConstant{
476 Op: bpf.ALUOpAdd,
477 Val: 1,
478 },
479
480 bpf.ALUOpConstant{
481 Op: 100,
482 },
483 bpf.JumpIf{
484 Cond: bpf.JumpEqual,
485 Val: 0x02,
486 SkipTrue: 1,
487 },
488 bpf.RetConstant{
489 Val: 0,
490 },
491 bpf.RetConstant{
492 Val: 9,
493 },
494 })
495 if err != nil {
496 t.Fatalf("failed to load BPF program: %v", err)
497 }
498 defer done()
499
500 out, err := vm.Run([]byte{
501 0xff, 0xff, 0xff, 0xff,
502 0xff, 0xff, 0xff, 0xff,
503 1,
504 })
505 if err != nil {
506 t.Fatalf("unexpected error while running program: %v", err)
507 }
508 if want, got := 1, out; want != got {
509 t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
510 want, got)
511 }
512 }
513
View as plain text