vm_jump_test.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  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. package bpf_test
  5. import (
  6. "testing"
  7. "golang.org/x/net/bpf"
  8. )
  9. func TestVMJumpOne(t *testing.T) {
  10. vm, done, err := testVM(t, []bpf.Instruction{
  11. bpf.LoadAbsolute{
  12. Off: 8,
  13. Size: 1,
  14. },
  15. bpf.Jump{
  16. Skip: 1,
  17. },
  18. bpf.RetConstant{
  19. Val: 0,
  20. },
  21. bpf.RetConstant{
  22. Val: 9,
  23. },
  24. })
  25. if err != nil {
  26. t.Fatalf("failed to load BPF program: %v", err)
  27. }
  28. defer done()
  29. out, err := vm.Run([]byte{
  30. 0xff, 0xff, 0xff, 0xff,
  31. 0xff, 0xff, 0xff, 0xff,
  32. 1,
  33. })
  34. if err != nil {
  35. t.Fatalf("unexpected error while running program: %v", err)
  36. }
  37. if want, got := 1, out; want != got {
  38. t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
  39. want, got)
  40. }
  41. }
  42. func TestVMJumpOutOfProgram(t *testing.T) {
  43. _, _, err := testVM(t, []bpf.Instruction{
  44. bpf.Jump{
  45. Skip: 1,
  46. },
  47. bpf.RetA{},
  48. })
  49. if errStr(err) != "cannot jump 1 instructions; jumping past program bounds" {
  50. t.Fatalf("unexpected error: %v", err)
  51. }
  52. }
  53. func TestVMJumpIfTrueOutOfProgram(t *testing.T) {
  54. _, _, err := testVM(t, []bpf.Instruction{
  55. bpf.JumpIf{
  56. Cond: bpf.JumpEqual,
  57. SkipTrue: 2,
  58. },
  59. bpf.RetA{},
  60. })
  61. if errStr(err) != "cannot jump 2 instructions in true case; jumping past program bounds" {
  62. t.Fatalf("unexpected error: %v", err)
  63. }
  64. }
  65. func TestVMJumpIfFalseOutOfProgram(t *testing.T) {
  66. _, _, err := testVM(t, []bpf.Instruction{
  67. bpf.JumpIf{
  68. Cond: bpf.JumpEqual,
  69. SkipFalse: 3,
  70. },
  71. bpf.RetA{},
  72. })
  73. if errStr(err) != "cannot jump 3 instructions in false case; jumping past program bounds" {
  74. t.Fatalf("unexpected error: %v", err)
  75. }
  76. }
  77. func TestVMJumpIfXTrueOutOfProgram(t *testing.T) {
  78. _, _, err := testVM(t, []bpf.Instruction{
  79. bpf.JumpIfX{
  80. Cond: bpf.JumpEqual,
  81. SkipTrue: 2,
  82. },
  83. bpf.RetA{},
  84. })
  85. if errStr(err) != "cannot jump 2 instructions in true case; jumping past program bounds" {
  86. t.Fatalf("unexpected error: %v", err)
  87. }
  88. }
  89. func TestVMJumpIfXFalseOutOfProgram(t *testing.T) {
  90. _, _, err := testVM(t, []bpf.Instruction{
  91. bpf.JumpIfX{
  92. Cond: bpf.JumpEqual,
  93. SkipFalse: 3,
  94. },
  95. bpf.RetA{},
  96. })
  97. if errStr(err) != "cannot jump 3 instructions in false case; jumping past program bounds" {
  98. t.Fatalf("unexpected error: %v", err)
  99. }
  100. }
  101. func TestVMJumpIfEqual(t *testing.T) {
  102. vm, done, err := testVM(t, []bpf.Instruction{
  103. bpf.LoadAbsolute{
  104. Off: 8,
  105. Size: 1,
  106. },
  107. bpf.JumpIf{
  108. Cond: bpf.JumpEqual,
  109. Val: 1,
  110. SkipTrue: 1,
  111. },
  112. bpf.RetConstant{
  113. Val: 0,
  114. },
  115. bpf.RetConstant{
  116. Val: 9,
  117. },
  118. })
  119. if err != nil {
  120. t.Fatalf("failed to load BPF program: %v", err)
  121. }
  122. defer done()
  123. out, err := vm.Run([]byte{
  124. 0xff, 0xff, 0xff, 0xff,
  125. 0xff, 0xff, 0xff, 0xff,
  126. 1,
  127. })
  128. if err != nil {
  129. t.Fatalf("unexpected error while running program: %v", err)
  130. }
  131. if want, got := 1, out; want != got {
  132. t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
  133. want, got)
  134. }
  135. }
  136. func TestVMJumpIfNotEqual(t *testing.T) {
  137. vm, done, err := testVM(t, []bpf.Instruction{
  138. bpf.LoadAbsolute{
  139. Off: 8,
  140. Size: 1,
  141. },
  142. bpf.JumpIf{
  143. Cond: bpf.JumpNotEqual,
  144. Val: 1,
  145. SkipFalse: 1,
  146. },
  147. bpf.RetConstant{
  148. Val: 0,
  149. },
  150. bpf.RetConstant{
  151. Val: 9,
  152. },
  153. })
  154. if err != nil {
  155. t.Fatalf("failed to load BPF program: %v", err)
  156. }
  157. defer done()
  158. out, err := vm.Run([]byte{
  159. 0xff, 0xff, 0xff, 0xff,
  160. 0xff, 0xff, 0xff, 0xff,
  161. 1,
  162. })
  163. if err != nil {
  164. t.Fatalf("unexpected error while running program: %v", err)
  165. }
  166. if want, got := 1, out; want != got {
  167. t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
  168. want, got)
  169. }
  170. }
  171. func TestVMJumpIfGreaterThan(t *testing.T) {
  172. vm, done, err := testVM(t, []bpf.Instruction{
  173. bpf.LoadAbsolute{
  174. Off: 8,
  175. Size: 4,
  176. },
  177. bpf.JumpIf{
  178. Cond: bpf.JumpGreaterThan,
  179. Val: 0x00010202,
  180. SkipTrue: 1,
  181. },
  182. bpf.RetConstant{
  183. Val: 0,
  184. },
  185. bpf.RetConstant{
  186. Val: 12,
  187. },
  188. })
  189. if err != nil {
  190. t.Fatalf("failed to load BPF program: %v", err)
  191. }
  192. defer done()
  193. out, err := vm.Run([]byte{
  194. 0xff, 0xff, 0xff, 0xff,
  195. 0xff, 0xff, 0xff, 0xff,
  196. 0, 1, 2, 3,
  197. })
  198. if err != nil {
  199. t.Fatalf("unexpected error while running program: %v", err)
  200. }
  201. if want, got := 4, out; want != got {
  202. t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
  203. want, got)
  204. }
  205. }
  206. func TestVMJumpIfLessThan(t *testing.T) {
  207. vm, done, err := testVM(t, []bpf.Instruction{
  208. bpf.LoadAbsolute{
  209. Off: 8,
  210. Size: 4,
  211. },
  212. bpf.JumpIf{
  213. Cond: bpf.JumpLessThan,
  214. Val: 0xff010203,
  215. SkipTrue: 1,
  216. },
  217. bpf.RetConstant{
  218. Val: 0,
  219. },
  220. bpf.RetConstant{
  221. Val: 12,
  222. },
  223. })
  224. if err != nil {
  225. t.Fatalf("failed to load BPF program: %v", err)
  226. }
  227. defer done()
  228. out, err := vm.Run([]byte{
  229. 0xff, 0xff, 0xff, 0xff,
  230. 0xff, 0xff, 0xff, 0xff,
  231. 0, 1, 2, 3,
  232. })
  233. if err != nil {
  234. t.Fatalf("unexpected error while running program: %v", err)
  235. }
  236. if want, got := 4, out; want != got {
  237. t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
  238. want, got)
  239. }
  240. }
  241. func TestVMJumpIfGreaterOrEqual(t *testing.T) {
  242. vm, done, err := testVM(t, []bpf.Instruction{
  243. bpf.LoadAbsolute{
  244. Off: 8,
  245. Size: 4,
  246. },
  247. bpf.JumpIf{
  248. Cond: bpf.JumpGreaterOrEqual,
  249. Val: 0x00010203,
  250. SkipTrue: 1,
  251. },
  252. bpf.RetConstant{
  253. Val: 0,
  254. },
  255. bpf.RetConstant{
  256. Val: 12,
  257. },
  258. })
  259. if err != nil {
  260. t.Fatalf("failed to load BPF program: %v", err)
  261. }
  262. defer done()
  263. out, err := vm.Run([]byte{
  264. 0xff, 0xff, 0xff, 0xff,
  265. 0xff, 0xff, 0xff, 0xff,
  266. 0, 1, 2, 3,
  267. })
  268. if err != nil {
  269. t.Fatalf("unexpected error while running program: %v", err)
  270. }
  271. if want, got := 4, out; want != got {
  272. t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
  273. want, got)
  274. }
  275. }
  276. func TestVMJumpIfLessOrEqual(t *testing.T) {
  277. vm, done, err := testVM(t, []bpf.Instruction{
  278. bpf.LoadAbsolute{
  279. Off: 8,
  280. Size: 4,
  281. },
  282. bpf.JumpIf{
  283. Cond: bpf.JumpLessOrEqual,
  284. Val: 0xff010203,
  285. SkipTrue: 1,
  286. },
  287. bpf.RetConstant{
  288. Val: 0,
  289. },
  290. bpf.RetConstant{
  291. Val: 12,
  292. },
  293. })
  294. if err != nil {
  295. t.Fatalf("failed to load BPF program: %v", err)
  296. }
  297. defer done()
  298. out, err := vm.Run([]byte{
  299. 0xff, 0xff, 0xff, 0xff,
  300. 0xff, 0xff, 0xff, 0xff,
  301. 0, 1, 2, 3,
  302. })
  303. if err != nil {
  304. t.Fatalf("unexpected error while running program: %v", err)
  305. }
  306. if want, got := 4, out; want != got {
  307. t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
  308. want, got)
  309. }
  310. }
  311. func TestVMJumpIfBitsSet(t *testing.T) {
  312. vm, done, err := testVM(t, []bpf.Instruction{
  313. bpf.LoadAbsolute{
  314. Off: 8,
  315. Size: 2,
  316. },
  317. bpf.JumpIf{
  318. Cond: bpf.JumpBitsSet,
  319. Val: 0x1122,
  320. SkipTrue: 1,
  321. },
  322. bpf.RetConstant{
  323. Val: 0,
  324. },
  325. bpf.RetConstant{
  326. Val: 10,
  327. },
  328. })
  329. if err != nil {
  330. t.Fatalf("failed to load BPF program: %v", err)
  331. }
  332. defer done()
  333. out, err := vm.Run([]byte{
  334. 0xff, 0xff, 0xff, 0xff,
  335. 0xff, 0xff, 0xff, 0xff,
  336. 0x01, 0x02,
  337. })
  338. if err != nil {
  339. t.Fatalf("unexpected error while running program: %v", err)
  340. }
  341. if want, got := 2, out; want != got {
  342. t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
  343. want, got)
  344. }
  345. }
  346. func TestVMJumpIfBitsNotSet(t *testing.T) {
  347. vm, done, err := testVM(t, []bpf.Instruction{
  348. bpf.LoadAbsolute{
  349. Off: 8,
  350. Size: 2,
  351. },
  352. bpf.JumpIf{
  353. Cond: bpf.JumpBitsNotSet,
  354. Val: 0x1221,
  355. SkipTrue: 1,
  356. },
  357. bpf.RetConstant{
  358. Val: 0,
  359. },
  360. bpf.RetConstant{
  361. Val: 10,
  362. },
  363. })
  364. if err != nil {
  365. t.Fatalf("failed to load BPF program: %v", err)
  366. }
  367. defer done()
  368. out, err := vm.Run([]byte{
  369. 0xff, 0xff, 0xff, 0xff,
  370. 0xff, 0xff, 0xff, 0xff,
  371. 0x01, 0x02,
  372. })
  373. if err != nil {
  374. t.Fatalf("unexpected error while running program: %v", err)
  375. }
  376. if want, got := 2, out; want != got {
  377. t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
  378. want, got)
  379. }
  380. }
  381. func TestVMJumpIfXEqual(t *testing.T) {
  382. vm, done, err := testVM(t, []bpf.Instruction{
  383. bpf.LoadAbsolute{
  384. Off: 8,
  385. Size: 1,
  386. },
  387. bpf.LoadConstant{
  388. Dst: bpf.RegX,
  389. Val: 1,
  390. },
  391. bpf.JumpIfX{
  392. Cond: bpf.JumpEqual,
  393. SkipTrue: 1,
  394. },
  395. bpf.RetConstant{
  396. Val: 0,
  397. },
  398. bpf.RetConstant{
  399. Val: 9,
  400. },
  401. })
  402. if err != nil {
  403. t.Fatalf("failed to load BPF program: %v", err)
  404. }
  405. defer done()
  406. out, err := vm.Run([]byte{
  407. 0xff, 0xff, 0xff, 0xff,
  408. 0xff, 0xff, 0xff, 0xff,
  409. 1,
  410. })
  411. if err != nil {
  412. t.Fatalf("unexpected error while running program: %v", err)
  413. }
  414. if want, got := 1, out; want != got {
  415. t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
  416. want, got)
  417. }
  418. }
  419. func TestVMJumpIfXNotEqual(t *testing.T) {
  420. vm, done, err := testVM(t, []bpf.Instruction{
  421. bpf.LoadAbsolute{
  422. Off: 8,
  423. Size: 1,
  424. },
  425. bpf.LoadConstant{
  426. Dst: bpf.RegX,
  427. Val: 1,
  428. },
  429. bpf.JumpIfX{
  430. Cond: bpf.JumpNotEqual,
  431. SkipFalse: 1,
  432. },
  433. bpf.RetConstant{
  434. Val: 0,
  435. },
  436. bpf.RetConstant{
  437. Val: 9,
  438. },
  439. })
  440. if err != nil {
  441. t.Fatalf("failed to load BPF program: %v", err)
  442. }
  443. defer done()
  444. out, err := vm.Run([]byte{
  445. 0xff, 0xff, 0xff, 0xff,
  446. 0xff, 0xff, 0xff, 0xff,
  447. 1,
  448. })
  449. if err != nil {
  450. t.Fatalf("unexpected error while running program: %v", err)
  451. }
  452. if want, got := 1, out; want != got {
  453. t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
  454. want, got)
  455. }
  456. }
  457. func TestVMJumpIfXGreaterThan(t *testing.T) {
  458. vm, done, err := testVM(t, []bpf.Instruction{
  459. bpf.LoadAbsolute{
  460. Off: 8,
  461. Size: 4,
  462. },
  463. bpf.LoadConstant{
  464. Dst: bpf.RegX,
  465. Val: 0x00010202,
  466. },
  467. bpf.JumpIfX{
  468. Cond: bpf.JumpGreaterThan,
  469. SkipTrue: 1,
  470. },
  471. bpf.RetConstant{
  472. Val: 0,
  473. },
  474. bpf.RetConstant{
  475. Val: 12,
  476. },
  477. })
  478. if err != nil {
  479. t.Fatalf("failed to load BPF program: %v", err)
  480. }
  481. defer done()
  482. out, err := vm.Run([]byte{
  483. 0xff, 0xff, 0xff, 0xff,
  484. 0xff, 0xff, 0xff, 0xff,
  485. 0, 1, 2, 3,
  486. })
  487. if err != nil {
  488. t.Fatalf("unexpected error while running program: %v", err)
  489. }
  490. if want, got := 4, out; want != got {
  491. t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
  492. want, got)
  493. }
  494. }
  495. func TestVMJumpIfXLessThan(t *testing.T) {
  496. vm, done, err := testVM(t, []bpf.Instruction{
  497. bpf.LoadAbsolute{
  498. Off: 8,
  499. Size: 4,
  500. },
  501. bpf.LoadConstant{
  502. Dst: bpf.RegX,
  503. Val: 0xff010203,
  504. },
  505. bpf.JumpIfX{
  506. Cond: bpf.JumpLessThan,
  507. SkipTrue: 1,
  508. },
  509. bpf.RetConstant{
  510. Val: 0,
  511. },
  512. bpf.RetConstant{
  513. Val: 12,
  514. },
  515. })
  516. if err != nil {
  517. t.Fatalf("failed to load BPF program: %v", err)
  518. }
  519. defer done()
  520. out, err := vm.Run([]byte{
  521. 0xff, 0xff, 0xff, 0xff,
  522. 0xff, 0xff, 0xff, 0xff,
  523. 0, 1, 2, 3,
  524. })
  525. if err != nil {
  526. t.Fatalf("unexpected error while running program: %v", err)
  527. }
  528. if want, got := 4, out; want != got {
  529. t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
  530. want, got)
  531. }
  532. }
  533. func TestVMJumpIfXGreaterOrEqual(t *testing.T) {
  534. vm, done, err := testVM(t, []bpf.Instruction{
  535. bpf.LoadAbsolute{
  536. Off: 8,
  537. Size: 4,
  538. },
  539. bpf.LoadConstant{
  540. Dst: bpf.RegX,
  541. Val: 0x00010203,
  542. },
  543. bpf.JumpIfX{
  544. Cond: bpf.JumpGreaterOrEqual,
  545. SkipTrue: 1,
  546. },
  547. bpf.RetConstant{
  548. Val: 0,
  549. },
  550. bpf.RetConstant{
  551. Val: 12,
  552. },
  553. })
  554. if err != nil {
  555. t.Fatalf("failed to load BPF program: %v", err)
  556. }
  557. defer done()
  558. out, err := vm.Run([]byte{
  559. 0xff, 0xff, 0xff, 0xff,
  560. 0xff, 0xff, 0xff, 0xff,
  561. 0, 1, 2, 3,
  562. })
  563. if err != nil {
  564. t.Fatalf("unexpected error while running program: %v", err)
  565. }
  566. if want, got := 4, out; want != got {
  567. t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
  568. want, got)
  569. }
  570. }
  571. func TestVMJumpIfXLessOrEqual(t *testing.T) {
  572. vm, done, err := testVM(t, []bpf.Instruction{
  573. bpf.LoadAbsolute{
  574. Off: 8,
  575. Size: 4,
  576. },
  577. bpf.LoadConstant{
  578. Dst: bpf.RegX,
  579. Val: 0xff010203,
  580. },
  581. bpf.JumpIfX{
  582. Cond: bpf.JumpLessOrEqual,
  583. SkipTrue: 1,
  584. },
  585. bpf.RetConstant{
  586. Val: 0,
  587. },
  588. bpf.RetConstant{
  589. Val: 12,
  590. },
  591. })
  592. if err != nil {
  593. t.Fatalf("failed to load BPF program: %v", err)
  594. }
  595. defer done()
  596. out, err := vm.Run([]byte{
  597. 0xff, 0xff, 0xff, 0xff,
  598. 0xff, 0xff, 0xff, 0xff,
  599. 0, 1, 2, 3,
  600. })
  601. if err != nil {
  602. t.Fatalf("unexpected error while running program: %v", err)
  603. }
  604. if want, got := 4, out; want != got {
  605. t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
  606. want, got)
  607. }
  608. }
  609. func TestVMJumpIfXBitsSet(t *testing.T) {
  610. vm, done, err := testVM(t, []bpf.Instruction{
  611. bpf.LoadAbsolute{
  612. Off: 8,
  613. Size: 2,
  614. },
  615. bpf.LoadConstant{
  616. Dst: bpf.RegX,
  617. Val: 0x1122,
  618. },
  619. bpf.JumpIfX{
  620. Cond: bpf.JumpBitsSet,
  621. SkipTrue: 1,
  622. },
  623. bpf.RetConstant{
  624. Val: 0,
  625. },
  626. bpf.RetConstant{
  627. Val: 10,
  628. },
  629. })
  630. if err != nil {
  631. t.Fatalf("failed to load BPF program: %v", err)
  632. }
  633. defer done()
  634. out, err := vm.Run([]byte{
  635. 0xff, 0xff, 0xff, 0xff,
  636. 0xff, 0xff, 0xff, 0xff,
  637. 0x01, 0x02,
  638. })
  639. if err != nil {
  640. t.Fatalf("unexpected error while running program: %v", err)
  641. }
  642. if want, got := 2, out; want != got {
  643. t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
  644. want, got)
  645. }
  646. }
  647. func TestVMJumpIfXBitsNotSet(t *testing.T) {
  648. vm, done, err := testVM(t, []bpf.Instruction{
  649. bpf.LoadAbsolute{
  650. Off: 8,
  651. Size: 2,
  652. },
  653. bpf.LoadConstant{
  654. Dst: bpf.RegX,
  655. Val: 0x1221,
  656. },
  657. bpf.JumpIfX{
  658. Cond: bpf.JumpBitsNotSet,
  659. SkipTrue: 1,
  660. },
  661. bpf.RetConstant{
  662. Val: 0,
  663. },
  664. bpf.RetConstant{
  665. Val: 10,
  666. },
  667. })
  668. if err != nil {
  669. t.Fatalf("failed to load BPF program: %v", err)
  670. }
  671. defer done()
  672. out, err := vm.Run([]byte{
  673. 0xff, 0xff, 0xff, 0xff,
  674. 0xff, 0xff, 0xff, 0xff,
  675. 0x01, 0x02,
  676. })
  677. if err != nil {
  678. t.Fatalf("unexpected error while running program: %v", err)
  679. }
  680. if want, got := 2, out; want != got {
  681. t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
  682. want, got)
  683. }
  684. }