github.com/lianghucheng/zrddz@v0.0.0-20200923083010-c71f680932e2/src/golang.org/x/net/bpf/vm_aluop_test.go (about) 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 "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 // Load byte 0 into X 153 bpf.LoadAbsolute{ 154 Off: 8, 155 Size: 1, 156 }, 157 bpf.TAX{}, 158 // Load byte 1 into A 159 bpf.LoadAbsolute{ 160 Off: 9, 161 Size: 1, 162 }, 163 // Attempt to perform 1/0 164 bpf.ALUOpX{ 165 Op: bpf.ALUOpDiv, 166 }, 167 // Return 4 bytes if program does not terminate 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 // Load byte 0 into X 389 bpf.LoadAbsolute{ 390 Off: 8, 391 Size: 1, 392 }, 393 bpf.TAX{}, 394 // Load byte 1 into A 395 bpf.LoadAbsolute{ 396 Off: 9, 397 Size: 1, 398 }, 399 // Attempt to perform 1%0 400 bpf.ALUOpX{ 401 Op: bpf.ALUOpMod, 402 }, 403 // Return 4 bytes if program does not terminate 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 // Verify that an unknown operation is a no-op 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 }