1 /*- 2 * Copyright (c) 2018 Kristof Provost <kp@FreeBSD.org> 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26 #include <sys/param.h> 27 #include <sys/module.h> 28 #include <sys/types.h> 29 #include <sys/ioctl.h> 30 #include <sys/socket.h> 31 32 #include <net/if.h> 33 #include <net/pfvar.h> 34 35 #include <errno.h> 36 #include <fcntl.h> 37 #include <stdio.h> 38 39 #include <atf-c.h> 40 41 static int dev; 42 43 #define COMMON_HEAD() \ 44 if (modfind("pf") == -1) \ 45 atf_tc_skip("pf not loaded"); \ 46 dev = open("/dev/pf", O_RDWR); \ 47 if (dev == -1) \ 48 atf_tc_skip("Failed to open /dev/pf"); 49 50 #define COMMON_CLEANUP() \ 51 close(dev); 52 53 static void 54 common_init_tbl(struct pfr_table *tbl) 55 { 56 bzero(tbl, sizeof(struct pfr_table)); 57 strcpy(tbl->pfrt_anchor, "anchor"); 58 strcpy(tbl->pfrt_name, "name"); 59 tbl->pfrt_flags = 0; 60 tbl->pfrt_fback = 0; 61 } 62 63 ATF_TC_WITH_CLEANUP(addtables); 64 ATF_TC_HEAD(addtables, tc) 65 { 66 atf_tc_set_md_var(tc, "require.user", "root"); 67 } 68 69 ATF_TC_BODY(addtables, tc) 70 { 71 struct pfioc_table io; 72 struct pfr_table tbl; 73 struct pfr_table tbls[4]; 74 int flags; 75 76 COMMON_HEAD(); 77 78 flags = 0; 79 80 bzero(&io, sizeof(io)); 81 io.pfrio_flags = flags; 82 io.pfrio_buffer = &tbl; 83 io.pfrio_esize = sizeof(tbl); 84 85 /* Negative size */ 86 io.pfrio_size = -1; 87 if (ioctl(dev, DIOCRADDTABLES, &io) == 0) 88 atf_tc_fail("Request with size -1 succeeded"); 89 90 /* Overly large size */ 91 io.pfrio_size = 1 << 24; 92 if (ioctl(dev, DIOCRADDTABLES, &io) == 0) 93 atf_tc_fail("Request with size 1 << 24 succeeded"); 94 95 /* NULL buffer */ 96 io.pfrio_size = 1; 97 io.pfrio_buffer = NULL; 98 if (ioctl(dev, DIOCRADDTABLES, &io) == 0) 99 atf_tc_fail("Request with NULL buffer succeeded"); 100 101 /* This can provoke a memory leak, see r331225. */ 102 io.pfrio_size = 4; 103 for (int i = 0; i < io.pfrio_size; i++) 104 common_init_tbl(&tbls[i]); 105 106 io.pfrio_buffer = &tbls; 107 ioctl(dev, DIOCRADDTABLES, &io); 108 } 109 110 ATF_TC_CLEANUP(addtables, tc) 111 { 112 COMMON_CLEANUP(); 113 } 114 115 ATF_TC_WITH_CLEANUP(deltables); 116 ATF_TC_HEAD(deltables, tc) 117 { 118 atf_tc_set_md_var(tc, "require.user", "root"); 119 } 120 121 ATF_TC_BODY(deltables, tc) 122 { 123 struct pfioc_table io; 124 struct pfr_table tbl; 125 int flags; 126 127 COMMON_HEAD(); 128 129 flags = 0; 130 131 bzero(&io, sizeof(io)); 132 io.pfrio_flags = flags; 133 io.pfrio_buffer = &tbl; 134 io.pfrio_esize = sizeof(tbl); 135 136 /* Negative size */ 137 io.pfrio_size = -1; 138 if (ioctl(dev, DIOCRDELTABLES, &io) == 0) 139 atf_tc_fail("Request with size -1 succeeded"); 140 141 /* Overly large size */ 142 io.pfrio_size = 1 << 24; 143 if (ioctl(dev, DIOCRDELTABLES, &io) == 0) 144 atf_tc_fail("Request with size 1 << 24 succeeded"); 145 146 /* NULL buffer */ 147 io.pfrio_size = 1; 148 io.pfrio_buffer = NULL; 149 if (ioctl(dev, DIOCRDELTABLES, &io) == 0) 150 atf_tc_fail("Request with NULL buffer succeeded"); 151 } 152 153 ATF_TC_CLEANUP(deltables, tc) 154 { 155 COMMON_CLEANUP(); 156 } 157 158 ATF_TC_WITH_CLEANUP(gettables); 159 ATF_TC_HEAD(gettables, tc) 160 { 161 atf_tc_set_md_var(tc, "require.user", "root"); 162 } 163 164 ATF_TC_BODY(gettables, tc) 165 { 166 struct pfioc_table io; 167 struct pfr_table tbl; 168 int flags; 169 170 COMMON_HEAD(); 171 172 flags = 0; 173 174 bzero(&io, sizeof(io)); 175 io.pfrio_flags = flags; 176 io.pfrio_buffer = &tbl; 177 io.pfrio_esize = sizeof(tbl); 178 179 /* Negative size. This will succeed, because the kernel will not copy 180 * tables than it has. */ 181 io.pfrio_size = -1; 182 if (ioctl(dev, DIOCRGETTABLES, &io) != 0) 183 atf_tc_fail("Request with size -1 failed"); 184 185 /* Overly large size. See above. */ 186 io.pfrio_size = 1 << 24; 187 if (ioctl(dev, DIOCRGETTABLES, &io) != 0) 188 atf_tc_fail("Request with size 1 << 24 failed"); 189 } 190 191 ATF_TC_CLEANUP(gettables, tc) 192 { 193 COMMON_CLEANUP(); 194 } 195 196 ATF_TC_WITH_CLEANUP(gettstats); 197 ATF_TC_HEAD(gettstats, tc) 198 { 199 atf_tc_set_md_var(tc, "require.user", "root"); 200 } 201 202 ATF_TC_BODY(gettstats, tc) 203 { 204 struct pfioc_table io; 205 struct pfr_tstats stats; 206 int flags; 207 208 COMMON_HEAD(); 209 210 flags = 0; 211 212 bzero(&io, sizeof(io)); 213 io.pfrio_flags = flags; 214 io.pfrio_buffer = &stats; 215 io.pfrio_esize = sizeof(stats); 216 217 /* Negative size. This will succeed, because the kernel will not copy 218 * tables than it has. */ 219 io.pfrio_size = -1; 220 if (ioctl(dev, DIOCRGETTSTATS, &io) != 0) 221 atf_tc_fail("Request with size -1 failed"); 222 223 /* Overly large size. See above. */ 224 io.pfrio_size = 1 << 24; 225 if (ioctl(dev, DIOCRGETTSTATS, &io) != 0) 226 atf_tc_fail("Request with size 1 << 24 failed"); 227 } 228 229 ATF_TC_CLEANUP(gettstats, tc) 230 { 231 COMMON_CLEANUP(); 232 } 233 234 ATF_TC_WITH_CLEANUP(clrtstats); 235 ATF_TC_HEAD(clrtstats, tc) 236 { 237 atf_tc_set_md_var(tc, "require.user", "root"); 238 } 239 240 ATF_TC_BODY(clrtstats, tc) 241 { 242 struct pfioc_table io; 243 struct pfr_table tbl; 244 int flags; 245 246 COMMON_HEAD(); 247 248 flags = 0; 249 250 common_init_tbl(&tbl); 251 252 bzero(&io, sizeof(io)); 253 io.pfrio_flags = flags; 254 io.pfrio_buffer = &tbl; 255 io.pfrio_esize = sizeof(tbl); 256 257 /* Negative size. This will succeed, because the kernel will not copy 258 * tables than it has. */ 259 io.pfrio_size = -1; 260 if (ioctl(dev, DIOCRCLRTSTATS, &io) != 0) 261 atf_tc_fail("Request with size -1 failed "); 262 263 /* Overly large size. See above. */ 264 io.pfrio_size = 1 << 24; 265 if (ioctl(dev, DIOCRCLRTSTATS, &io) != 0) 266 atf_tc_fail("Request with size 1 << 24 failed"); 267 268 io.pfrio_size = sizeof(tbl); 269 io.pfrio_buffer = NULL; 270 if (ioctl(dev, DIOCRCLRTSTATS, &io) == 0) 271 atf_tc_fail("Request with NULL buffer succeeded"); 272 } 273 274 ATF_TC_CLEANUP(clrtstats, tc) 275 { 276 COMMON_CLEANUP(); 277 } 278 279 ATF_TC_WITH_CLEANUP(settflags); 280 ATF_TC_HEAD(settflags, tc) 281 { 282 atf_tc_set_md_var(tc, "require.user", "root"); 283 } 284 285 ATF_TC_BODY(settflags, tc) 286 { 287 struct pfioc_table io; 288 struct pfr_table tbl; 289 int flags; 290 291 COMMON_HEAD(); 292 293 flags = 0; 294 295 common_init_tbl(&tbl); 296 297 bzero(&io, sizeof(io)); 298 io.pfrio_flags = flags; 299 io.pfrio_buffer = &tbl; 300 io.pfrio_esize = sizeof(tbl); 301 302 /* Negative size. This will succeed, because the kernel will not copy 303 * tables than it has. */ 304 io.pfrio_size = -1; 305 if (ioctl(dev, DIOCRSETTFLAGS, &io) != 0) 306 atf_tc_fail("Request with size -1 failed"); 307 308 /* Overly large size. See above. */ 309 io.pfrio_size = 1 << 28; 310 if (ioctl(dev, DIOCRSETTFLAGS, &io) != 0) 311 atf_tc_fail("Request with size 1 << 24 failed"); 312 313 /* NULL buffer */ 314 io.pfrio_buffer = NULL; 315 if (ioctl(dev, DIOCRSETTFLAGS, &io) != -1) 316 atf_tc_fail("Request with NULL buffer succeeded"); 317 } 318 319 ATF_TC_CLEANUP(settflags, tc) 320 { 321 COMMON_CLEANUP(); 322 } 323 324 ATF_TC_WITH_CLEANUP(addaddrs); 325 ATF_TC_HEAD(addaddrs, tc) 326 { 327 atf_tc_set_md_var(tc, "require.user", "root"); 328 } 329 330 ATF_TC_BODY(addaddrs, tc) 331 { 332 struct pfioc_table io; 333 struct pfr_addr addr; 334 335 COMMON_HEAD(); 336 337 bzero(&addr, sizeof(addr)); 338 bzero(&io, sizeof(io)); 339 io.pfrio_flags = 0; 340 io.pfrio_buffer = &addr; 341 io.pfrio_esize = sizeof(addr); 342 343 /* Negative size. */ 344 io.pfrio_size = -1; 345 if (ioctl(dev, DIOCRADDADDRS, &io) == 0) 346 atf_tc_fail("Request with size -1 succeeded"); 347 348 /* Overly large size. */ 349 io.pfrio_size = 1 << 28; 350 if (ioctl(dev, DIOCRADDADDRS, &io) == 0) 351 atf_tc_fail("Reuqest with size 1 << 28 failed"); 352 } 353 354 ATF_TC_CLEANUP(addaddrs, tc) 355 { 356 COMMON_CLEANUP(); 357 } 358 359 ATF_TC_WITH_CLEANUP(deladdrs); 360 ATF_TC_HEAD(deladdrs, tc) 361 { 362 atf_tc_set_md_var(tc, "require.user", "root"); 363 } 364 365 ATF_TC_BODY(deladdrs, tc) 366 { 367 struct pfioc_table io; 368 struct pfr_addr addr; 369 370 COMMON_HEAD(); 371 372 bzero(&addr, sizeof(addr)); 373 bzero(&io, sizeof(io)); 374 io.pfrio_flags = 0; 375 io.pfrio_buffer = &addr; 376 io.pfrio_esize = sizeof(addr); 377 378 /* Negative size. */ 379 io.pfrio_size = -1; 380 if (ioctl(dev, DIOCRDELADDRS, &io) == 0) 381 atf_tc_fail("Request with size -1 succeeded"); 382 383 /* Overly large size. */ 384 io.pfrio_size = 1 << 28; 385 if (ioctl(dev, DIOCRDELADDRS, &io) == 0) 386 atf_tc_fail("Reuqest with size 1 << 28 failed"); 387 } 388 389 ATF_TC_CLEANUP(deladdrs, tc) 390 { 391 COMMON_CLEANUP(); 392 } 393 394 ATF_TC_WITH_CLEANUP(setaddrs); 395 ATF_TC_HEAD(setaddrs, tc) 396 { 397 atf_tc_set_md_var(tc, "require.user", "root"); 398 } 399 400 ATF_TC_BODY(setaddrs, tc) 401 { 402 struct pfioc_table io; 403 struct pfr_addr addr; 404 405 COMMON_HEAD(); 406 407 bzero(&addr, sizeof(addr)); 408 bzero(&io, sizeof(io)); 409 io.pfrio_flags = 0; 410 io.pfrio_buffer = &addr; 411 io.pfrio_esize = sizeof(addr); 412 413 /* Negative size. */ 414 io.pfrio_size = -1; 415 if (ioctl(dev, DIOCRSETADDRS, &io) == 0) 416 atf_tc_fail("Request with size -1 succeeded"); 417 418 /* Overly large size. */ 419 io.pfrio_size = 1 << 28; 420 if (ioctl(dev, DIOCRSETADDRS, &io) == 0) 421 atf_tc_fail("Reuqest with size 1 << 28 failed"); 422 } 423 424 ATF_TC_CLEANUP(setaddrs, tc) 425 { 426 COMMON_CLEANUP(); 427 } 428 429 ATF_TC_WITH_CLEANUP(getaddrs); 430 ATF_TC_HEAD(getaddrs, tc) 431 { 432 atf_tc_set_md_var(tc, "require.user", "root"); 433 } 434 435 ATF_TC_BODY(getaddrs, tc) 436 { 437 struct pfioc_table io; 438 struct pfr_addr addr; 439 440 COMMON_HEAD(); 441 442 bzero(&addr, sizeof(addr)); 443 bzero(&io, sizeof(io)); 444 io.pfrio_flags = 0; 445 io.pfrio_buffer = &addr; 446 io.pfrio_esize = sizeof(addr); 447 448 common_init_tbl(&io.pfrio_table); 449 450 /* Negative size. */ 451 io.pfrio_size = -1; 452 if (ioctl(dev, DIOCRGETADDRS, &io) == 0) 453 atf_tc_fail("Request with size -1 succeeded"); 454 455 /* Overly large size. */ 456 io.pfrio_size = 1 << 24; 457 if (ioctl(dev, DIOCRGETADDRS, &io) == 0) 458 atf_tc_fail("Request with size 1 << 24 failed"); 459 } 460 461 ATF_TC_CLEANUP(getaddrs, tc) 462 { 463 COMMON_CLEANUP(); 464 } 465 466 ATF_TC_WITH_CLEANUP(getastats); 467 ATF_TC_HEAD(getastats, tc) 468 { 469 atf_tc_set_md_var(tc, "require.user", "root"); 470 } 471 472 ATF_TC_BODY(getastats, tc) 473 { 474 struct pfioc_table io; 475 struct pfr_astats astats; 476 477 COMMON_HEAD(); 478 479 bzero(&astats, sizeof(astats)); 480 bzero(&io, sizeof(io)); 481 io.pfrio_flags = 0; 482 io.pfrio_buffer = &astats; 483 io.pfrio_esize = sizeof(astats); 484 485 common_init_tbl(&io.pfrio_table); 486 487 /* Negative size. */ 488 io.pfrio_size = -1; 489 if (ioctl(dev, DIOCRGETASTATS, &io) == 0) 490 atf_tc_fail("Request with size -1 succeeded"); 491 492 /* Overly large size. */ 493 io.pfrio_size = 1 << 24; 494 if (ioctl(dev, DIOCRGETASTATS, &io) == 0) 495 atf_tc_fail("Request with size 1 << 24 failed"); 496 } 497 498 ATF_TC_CLEANUP(getastats, tc) 499 { 500 COMMON_CLEANUP(); 501 } 502 503 ATF_TC_WITH_CLEANUP(clrastats); 504 ATF_TC_HEAD(clrastats, tc) 505 { 506 atf_tc_set_md_var(tc, "require.user", "root"); 507 } 508 509 ATF_TC_BODY(clrastats, tc) 510 { 511 struct pfioc_table io; 512 struct pfr_addr addr; 513 514 COMMON_HEAD(); 515 516 bzero(&addr, sizeof(addr)); 517 bzero(&io, sizeof(io)); 518 io.pfrio_flags = 0; 519 io.pfrio_buffer = &addr; 520 io.pfrio_esize = sizeof(addr); 521 522 common_init_tbl(&io.pfrio_table); 523 524 /* Negative size. */ 525 io.pfrio_size = -1; 526 if (ioctl(dev, DIOCRCLRASTATS, &io) == 0) 527 atf_tc_fail("Request with size -1 succeeded"); 528 529 /* Overly large size. */ 530 io.pfrio_size = 1 << 24; 531 if (ioctl(dev, DIOCRCLRASTATS, &io) == 0) 532 atf_tc_fail("Request with size 1 << 24 failed"); 533 } 534 535 ATF_TC_CLEANUP(clrastats, tc) 536 { 537 COMMON_CLEANUP(); 538 } 539 540 ATF_TC_WITH_CLEANUP(tstaddrs); 541 ATF_TC_HEAD(tstaddrs, tc) 542 { 543 atf_tc_set_md_var(tc, "require.user", "root"); 544 } 545 546 ATF_TC_BODY(tstaddrs, tc) 547 { 548 struct pfioc_table io; 549 struct pfr_addr addr; 550 551 COMMON_HEAD(); 552 553 bzero(&addr, sizeof(addr)); 554 bzero(&io, sizeof(io)); 555 io.pfrio_flags = 0; 556 io.pfrio_buffer = &addr; 557 io.pfrio_esize = sizeof(addr); 558 559 common_init_tbl(&io.pfrio_table); 560 561 /* Negative size. */ 562 io.pfrio_size = -1; 563 if (ioctl(dev, DIOCRTSTADDRS, &io) == 0) 564 atf_tc_fail("Request with size -1 succeeded"); 565 566 /* Overly large size. */ 567 io.pfrio_size = 1 << 24; 568 if (ioctl(dev, DIOCRTSTADDRS, &io) == 0) 569 atf_tc_fail("Request with size 1 << 24 failed"); 570 } 571 572 ATF_TC_CLEANUP(tstaddrs, tc) 573 { 574 COMMON_CLEANUP(); 575 } 576 577 ATF_TC_WITH_CLEANUP(inadefine); 578 ATF_TC_HEAD(inadefine, tc) 579 { 580 atf_tc_set_md_var(tc, "require.user", "root"); 581 } 582 583 ATF_TC_BODY(inadefine, tc) 584 { 585 struct pfioc_table io; 586 struct pfr_addr addr; 587 588 COMMON_HEAD(); 589 590 bzero(&addr, sizeof(addr)); 591 bzero(&io, sizeof(io)); 592 io.pfrio_flags = 0; 593 io.pfrio_buffer = &addr; 594 io.pfrio_esize = sizeof(addr); 595 596 common_init_tbl(&io.pfrio_table); 597 598 /* Negative size. */ 599 io.pfrio_size = -1; 600 if (ioctl(dev, DIOCRINADEFINE, &io) == 0) 601 atf_tc_fail("Request with size -1 succeeded"); 602 603 /* Overly large size. */ 604 io.pfrio_size = 1 << 24; 605 if (ioctl(dev, DIOCRINADEFINE, &io) == 0) 606 atf_tc_fail("Request with size 1 << 24 failed"); 607 } 608 609 ATF_TC_CLEANUP(inadefine, tc) 610 { 611 COMMON_CLEANUP(); 612 } 613 614 ATF_TC_WITH_CLEANUP(igetifaces); 615 ATF_TC_HEAD(igetifaces, tc) 616 { 617 atf_tc_set_md_var(tc, "require.user", "root"); 618 } 619 620 ATF_TC_BODY(igetifaces, tc) 621 { 622 struct pfioc_iface io; 623 struct pfi_kif kif; 624 625 COMMON_HEAD(); 626 627 bzero(&io, sizeof(io)); 628 io.pfiio_flags = 0; 629 io.pfiio_buffer = &kif; 630 io.pfiio_esize = sizeof(kif); 631 632 /* Negative size */ 633 io.pfiio_size = -1; 634 if (ioctl(dev, DIOCIGETIFACES, &io) == 0) 635 atf_tc_fail("request with size -1 succeeded"); 636 637 /* Overflow size */ 638 io.pfiio_size = 1 << 31; 639 if (ioctl(dev, DIOCIGETIFACES, &io) == 0) 640 atf_tc_fail("request with size 1 << 31 succeeded"); 641 } 642 643 ATF_TC_CLEANUP(igetifaces, tc) 644 { 645 COMMON_CLEANUP(); 646 } 647 648 ATF_TC_WITH_CLEANUP(cxbegin); 649 ATF_TC_HEAD(cxbegin, tc) 650 { 651 atf_tc_set_md_var(tc, "require.user", "root"); 652 } 653 654 ATF_TC_BODY(cxbegin, tc) 655 { 656 struct pfioc_trans io; 657 struct pfioc_trans_e ioe; 658 659 COMMON_HEAD(); 660 661 bzero(&io, sizeof(io)); 662 io.esize = sizeof(ioe); 663 io.array = &ioe; 664 665 /* Negative size */ 666 io.size = -1; 667 if (ioctl(dev, DIOCXBEGIN, &io) == 0) 668 atf_tc_fail("request with size -1 succeeded"); 669 670 /* Overflow size */ 671 io.size = 1 << 30; 672 if (ioctl(dev, DIOCXBEGIN, &io) == 0) 673 atf_tc_fail("request with size 1 << 30 succeeded"); 674 675 /* NULL buffer */ 676 io.size = 1; 677 io.array = NULL; 678 if (ioctl(dev, DIOCXBEGIN, &io) == 0) 679 atf_tc_fail("request with size -1 succeeded"); 680 } 681 682 ATF_TC_CLEANUP(cxbegin, tc) 683 { 684 COMMON_CLEANUP(); 685 } 686 687 ATF_TC_WITH_CLEANUP(cxrollback); 688 ATF_TC_HEAD(cxrollback, tc) 689 { 690 atf_tc_set_md_var(tc, "require.user", "root"); 691 } 692 693 ATF_TC_BODY(cxrollback, tc) 694 { 695 struct pfioc_trans io; 696 struct pfioc_trans_e ioe; 697 698 COMMON_HEAD(); 699 700 bzero(&io, sizeof(io)); 701 io.esize = sizeof(ioe); 702 io.array = &ioe; 703 704 /* Negative size */ 705 io.size = -1; 706 if (ioctl(dev, DIOCXROLLBACK, &io) == 0) 707 atf_tc_fail("request with size -1 succeeded"); 708 709 /* Overflow size */ 710 io.size = 1 << 30; 711 if (ioctl(dev, DIOCXROLLBACK, &io) == 0) 712 atf_tc_fail("request with size 1 << 30 succeeded"); 713 714 /* NULL buffer */ 715 io.size = 1; 716 io.array = NULL; 717 if (ioctl(dev, DIOCXROLLBACK, &io) == 0) 718 atf_tc_fail("request with size -1 succeeded"); 719 } 720 721 ATF_TC_CLEANUP(cxrollback, tc) 722 { 723 COMMON_CLEANUP(); 724 } 725 726 ATF_TC_WITH_CLEANUP(commit); 727 ATF_TC_HEAD(commit, tc) 728 { 729 atf_tc_set_md_var(tc, "require.user", "root"); 730 } 731 732 ATF_TC_BODY(commit, tc) 733 { 734 struct pfioc_trans io; 735 struct pfioc_trans_e ioe; 736 737 COMMON_HEAD(); 738 739 bzero(&io, sizeof(io)); 740 io.esize = sizeof(ioe); 741 io.array = &ioe; 742 743 /* Negative size */ 744 io.size = -1; 745 if (ioctl(dev, DIOCXCOMMIT, &io) == 0) 746 atf_tc_fail("request with size -1 succeeded"); 747 748 /* Overflow size */ 749 io.size = 1 << 30; 750 if (ioctl(dev, DIOCXCOMMIT, &io) == 0) 751 atf_tc_fail("request with size 1 << 30 succeeded"); 752 753 /* NULL buffer */ 754 io.size = 1; 755 io.array = NULL; 756 if (ioctl(dev, DIOCXCOMMIT, &io) == 0) 757 atf_tc_fail("request with size -1 succeeded"); 758 } 759 760 ATF_TC_CLEANUP(commit, tc) 761 { 762 COMMON_CLEANUP(); 763 } 764 765 ATF_TC_WITH_CLEANUP(getsrcnodes); 766 ATF_TC_HEAD(getsrcnodes, tc) 767 { 768 atf_tc_set_md_var(tc, "require.user", "root"); 769 } 770 771 ATF_TC_BODY(getsrcnodes, tc) 772 { 773 struct pfioc_src_nodes psn; 774 775 COMMON_HEAD(); 776 777 bzero(&psn, sizeof(psn)); 778 779 psn.psn_len = -1; 780 if (ioctl(dev, DIOCGETSRCNODES, &psn) != 0) 781 atf_tc_fail("request with size -1 failed"); 782 783 psn.psn_len = 1 << 30; 784 if (ioctl(dev, DIOCGETSRCNODES, &psn) != 0) 785 atf_tc_fail("request with size << 30 failed"); 786 787 psn.psn_len = 1 << 31; 788 if (ioctl(dev, DIOCGETSRCNODES, &psn) != 0) 789 atf_tc_fail("request with size << 30 failed"); 790 } 791 792 ATF_TC_CLEANUP(getsrcnodes, tc) 793 { 794 COMMON_CLEANUP(); 795 } 796 797 ATF_TC_WITH_CLEANUP(tag); 798 ATF_TC_HEAD(tag, tc) 799 { 800 atf_tc_set_md_var(tc, "require.user", "root"); 801 } 802 803 ATF_TC_BODY(tag, tc) 804 { 805 struct pfioc_rule rule; 806 807 COMMON_HEAD(); 808 809 memset(&rule, 0x42, sizeof(rule)); 810 811 rule.ticket = 0; 812 rule.pool_ticket = 0; 813 rule.anchor[0] = 0; 814 815 rule.rule.return_icmp = 0; 816 bzero(&rule.rule.src, sizeof(rule.rule.src)); 817 bzero(&rule.rule.dst, sizeof(rule.rule.dst)); 818 819 rule.rule.ifname[0] = 0; 820 rule.rule.action = 0; 821 rule.rule.rtableid = 0; 822 823 rule.rule.tagname[0] = 0; 824 825 for (int i = 0; i < 10; i++) 826 ioctl(dev, DIOCADDRULE, &rule); 827 } 828 829 ATF_TC_CLEANUP(tag, tc) 830 { 831 COMMON_CLEANUP(); 832 } 833 834 ATF_TC_WITH_CLEANUP(rpool_mtx); 835 ATF_TC_HEAD(rpool_mtx, tc) 836 { 837 atf_tc_set_md_var(tc, "require.user", "root"); 838 } 839 840 ATF_TC_BODY(rpool_mtx, tc) 841 { 842 struct pfioc_rule rule; 843 844 COMMON_HEAD(); 845 846 memset(&rule, 0, sizeof(rule)); 847 848 rule.ticket = 0; 849 rule.pool_ticket = 0; 850 rule.anchor[0] = 0; 851 852 rule.rule.return_icmp = 0; 853 bzero(&rule.rule.src, sizeof(rule.rule.src)); 854 bzero(&rule.rule.dst, sizeof(rule.rule.dst)); 855 856 rule.rule.ifname[0] = 0; 857 rule.rule.action = 0; 858 rule.rule.rtableid = 0; 859 860 rule.rule.tagname[0] = 0; 861 rule.rule.action = 42; 862 863 ioctl(dev, DIOCADDRULE, &rule); 864 } 865 866 ATF_TC_CLEANUP(rpool_mtx, tc) 867 { 868 COMMON_CLEANUP(); 869 } 870 871 ATF_TC_WITH_CLEANUP(rpool_mtx2); 872 ATF_TC_HEAD(rpool_mtx2, tc) 873 { 874 atf_tc_set_md_var(tc, "require.user", "root"); 875 } 876 877 ATF_TC_BODY(rpool_mtx2, tc) 878 { 879 struct pfioc_rule rule; 880 881 COMMON_HEAD(); 882 883 memset(&rule, 0, sizeof(rule)); 884 885 rule.pool_ticket = 1000000; 886 rule.action = PF_CHANGE_ADD_HEAD; 887 rule.rule.af = AF_INET; 888 889 ioctl(dev, DIOCCHANGERULE, &rule); 890 } 891 892 ATF_TC_CLEANUP(rpool_mtx2, tc) 893 { 894 COMMON_CLEANUP(); 895 } 896 897 ATF_TC_WITH_CLEANUP(natlook); 898 ATF_TC_HEAD(natlook, tc) 899 { 900 atf_tc_set_md_var(tc, "require.user", "root"); 901 } 902 903 ATF_TC_BODY(natlook, tc) 904 { 905 struct pfioc_natlook nl = { 0 }; 906 907 COMMON_HEAD(); 908 909 nl.af = AF_INET; 910 nl.proto = IPPROTO_ICMP; 911 nl.saddr.v4.s_addr = 0x01020304; 912 nl.daddr.v4.s_addr = 0x05060708; 913 914 /* Invalid direction */ 915 nl.direction = 42; 916 917 ATF_CHECK_ERRNO(EINVAL, ioctl(dev, DIOCNATLOOK, &nl) == -1); 918 919 /* Invalid af */ 920 nl.direction = PF_IN; 921 nl.af = 99; 922 923 ATF_CHECK_ERRNO(EAFNOSUPPORT, ioctl(dev, DIOCNATLOOK, &nl) == -1); 924 } 925 926 ATF_TC_CLEANUP(natlook, tc) 927 { 928 COMMON_CLEANUP(); 929 } 930 931 ATF_TP_ADD_TCS(tp) 932 { 933 ATF_TP_ADD_TC(tp, addtables); 934 ATF_TP_ADD_TC(tp, deltables); 935 ATF_TP_ADD_TC(tp, gettables); 936 ATF_TP_ADD_TC(tp, getastats); 937 ATF_TP_ADD_TC(tp, gettstats); 938 ATF_TP_ADD_TC(tp, clrtstats); 939 ATF_TP_ADD_TC(tp, settflags); 940 ATF_TP_ADD_TC(tp, addaddrs); 941 ATF_TP_ADD_TC(tp, deladdrs); 942 ATF_TP_ADD_TC(tp, setaddrs); 943 ATF_TP_ADD_TC(tp, getaddrs); 944 ATF_TP_ADD_TC(tp, clrastats); 945 ATF_TP_ADD_TC(tp, tstaddrs); 946 ATF_TP_ADD_TC(tp, inadefine); 947 ATF_TP_ADD_TC(tp, igetifaces); 948 ATF_TP_ADD_TC(tp, cxbegin); 949 ATF_TP_ADD_TC(tp, cxrollback); 950 ATF_TP_ADD_TC(tp, commit); 951 ATF_TP_ADD_TC(tp, getsrcnodes); 952 ATF_TP_ADD_TC(tp, tag); 953 ATF_TP_ADD_TC(tp, rpool_mtx); 954 ATF_TP_ADD_TC(tp, rpool_mtx2); 955 ATF_TP_ADD_TC(tp, natlook); 956 957 return (atf_no_error()); 958 } 959