2 * Copyright (c) 2018 Kristof Provost <kp@FreeBSD.org>
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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
28 #include <sys/param.h>
29 #include <sys/module.h>
30 #include <sys/types.h>
31 #include <sys/ioctl.h>
32 #include <sys/socket.h>
35 #include <net/pfvar.h>
44 #define COMMON_HEAD() \
45 if (modfind("pf") == -1) \
46 atf_tc_skip("pf not loaded"); \
47 dev = open("/dev/pf", O_RDWR); \
49 atf_tc_skip("Failed to open /dev/pf");
51 #define COMMON_CLEANUP() \
55 common_init_tbl(struct pfr_table *tbl)
57 bzero(tbl, sizeof(struct pfr_table));
58 strcpy(tbl->pfrt_anchor, "anchor");
59 strcpy(tbl->pfrt_name, "name");
64 ATF_TC_WITH_CLEANUP(addtables);
65 ATF_TC_HEAD(addtables, tc)
67 atf_tc_set_md_var(tc, "require.user", "root");
70 ATF_TC_BODY(addtables, tc)
72 struct pfioc_table io;
74 struct pfr_table tbls[4];
81 bzero(&io, sizeof(io));
82 io.pfrio_flags = flags;
83 io.pfrio_buffer = &tbl;
84 io.pfrio_esize = sizeof(tbl);
88 if (ioctl(dev, DIOCRADDTABLES, &io) == 0)
89 atf_tc_fail("Request with size -1 succeeded");
91 /* Overly large size */
92 io.pfrio_size = 1 << 24;
93 if (ioctl(dev, DIOCRADDTABLES, &io) == 0)
94 atf_tc_fail("Request with size 1 << 24 succeeded");
98 io.pfrio_buffer = NULL;
99 if (ioctl(dev, DIOCRADDTABLES, &io) == 0)
100 atf_tc_fail("Request with NULL buffer succeeded");
102 /* This can provoke a memory leak, see r331225. */
104 for (int i = 0; i < io.pfrio_size; i++)
105 common_init_tbl(&tbls[i]);
107 io.pfrio_buffer = &tbls;
108 ioctl(dev, DIOCRADDTABLES, &io);
111 ATF_TC_CLEANUP(addtables, tc)
116 ATF_TC_WITH_CLEANUP(deltables);
117 ATF_TC_HEAD(deltables, tc)
119 atf_tc_set_md_var(tc, "require.user", "root");
122 ATF_TC_BODY(deltables, tc)
124 struct pfioc_table io;
125 struct pfr_table tbl;
132 bzero(&io, sizeof(io));
133 io.pfrio_flags = flags;
134 io.pfrio_buffer = &tbl;
135 io.pfrio_esize = sizeof(tbl);
139 if (ioctl(dev, DIOCRDELTABLES, &io) == 0)
140 atf_tc_fail("Request with size -1 succeeded");
142 /* Overly large size */
143 io.pfrio_size = 1 << 24;
144 if (ioctl(dev, DIOCRDELTABLES, &io) == 0)
145 atf_tc_fail("Request with size 1 << 24 succeeded");
149 io.pfrio_buffer = NULL;
150 if (ioctl(dev, DIOCRDELTABLES, &io) == 0)
151 atf_tc_fail("Request with NULL buffer succeeded");
154 ATF_TC_CLEANUP(deltables, tc)
159 ATF_TC_WITH_CLEANUP(gettables);
160 ATF_TC_HEAD(gettables, tc)
162 atf_tc_set_md_var(tc, "require.user", "root");
165 ATF_TC_BODY(gettables, tc)
167 struct pfioc_table io;
168 struct pfr_table tbl;
175 bzero(&io, sizeof(io));
176 io.pfrio_flags = flags;
177 io.pfrio_buffer = &tbl;
178 io.pfrio_esize = sizeof(tbl);
180 /* Negative size. This will succeed, because the kernel will not copy
181 * tables than it has. */
183 if (ioctl(dev, DIOCRGETTABLES, &io) != 0)
184 atf_tc_fail("Request with size -1 failed");
186 /* Overly large size. See above. */
187 io.pfrio_size = 1 << 24;
188 if (ioctl(dev, DIOCRGETTABLES, &io) != 0)
189 atf_tc_fail("Request with size 1 << 24 failed");
192 ATF_TC_CLEANUP(gettables, tc)
197 ATF_TC_WITH_CLEANUP(gettstats);
198 ATF_TC_HEAD(gettstats, tc)
200 atf_tc_set_md_var(tc, "require.user", "root");
203 ATF_TC_BODY(gettstats, tc)
205 struct pfioc_table io;
206 struct pfr_tstats stats;
213 bzero(&io, sizeof(io));
214 io.pfrio_flags = flags;
215 io.pfrio_buffer = &stats;
216 io.pfrio_esize = sizeof(stats);
218 /* Negative size. This will succeed, because the kernel will not copy
219 * tables than it has. */
221 if (ioctl(dev, DIOCRGETTSTATS, &io) != 0)
222 atf_tc_fail("Request with size -1 failed");
224 /* Overly large size. See above. */
225 io.pfrio_size = 1 << 24;
226 if (ioctl(dev, DIOCRGETTSTATS, &io) != 0)
227 atf_tc_fail("Request with size 1 << 24 failed");
230 ATF_TC_CLEANUP(gettstats, tc)
235 ATF_TC_WITH_CLEANUP(clrtstats);
236 ATF_TC_HEAD(clrtstats, tc)
238 atf_tc_set_md_var(tc, "require.user", "root");
241 ATF_TC_BODY(clrtstats, tc)
243 struct pfioc_table io;
244 struct pfr_table tbl;
251 common_init_tbl(&tbl);
253 bzero(&io, sizeof(io));
254 io.pfrio_flags = flags;
255 io.pfrio_buffer = &tbl;
256 io.pfrio_esize = sizeof(tbl);
258 /* Negative size. This will succeed, because the kernel will not copy
259 * tables than it has. */
261 if (ioctl(dev, DIOCRCLRTSTATS, &io) != 0)
262 atf_tc_fail("Request with size -1 failed ");
264 /* Overly large size. See above. */
265 io.pfrio_size = 1 << 24;
266 if (ioctl(dev, DIOCRCLRTSTATS, &io) != 0)
267 atf_tc_fail("Request with size 1 << 24 failed");
270 ATF_TC_CLEANUP(clrtstats, tc)
275 ATF_TC_WITH_CLEANUP(settflags);
276 ATF_TC_HEAD(settflags, tc)
278 atf_tc_set_md_var(tc, "require.user", "root");
281 ATF_TC_BODY(settflags, tc)
283 struct pfioc_table io;
284 struct pfr_table tbl;
291 common_init_tbl(&tbl);
293 bzero(&io, sizeof(io));
294 io.pfrio_flags = flags;
295 io.pfrio_buffer = &tbl;
296 io.pfrio_esize = sizeof(tbl);
298 /* Negative size. This will succeed, because the kernel will not copy
299 * tables than it has. */
301 if (ioctl(dev, DIOCRSETTFLAGS, &io) != 0)
302 atf_tc_fail("Request with size -1 failed");
304 /* Overly large size. See above. */
305 io.pfrio_size = 1 << 28;
306 if (ioctl(dev, DIOCRSETTFLAGS, &io) != 0)
307 atf_tc_fail("Request with size 1 << 24 failed");
310 ATF_TC_CLEANUP(settflags, tc)
315 ATF_TC_WITH_CLEANUP(addaddrs);
316 ATF_TC_HEAD(addaddrs, tc)
318 atf_tc_set_md_var(tc, "require.user", "root");
321 ATF_TC_BODY(addaddrs, tc)
323 struct pfioc_table io;
324 struct pfr_addr addr;
328 bzero(&addr, sizeof(addr));
329 bzero(&io, sizeof(io));
331 io.pfrio_buffer = &addr;
332 io.pfrio_esize = sizeof(addr);
336 if (ioctl(dev, DIOCRADDADDRS, &io) == 0)
337 atf_tc_fail("Request with size -1 succeeded");
339 /* Overly large size. */
340 io.pfrio_size = 1 << 28;
341 if (ioctl(dev, DIOCRADDADDRS, &io) == 0)
342 atf_tc_fail("Reuqest with size 1 << 28 failed");
345 ATF_TC_CLEANUP(addaddrs, tc)
350 ATF_TC_WITH_CLEANUP(deladdrs);
351 ATF_TC_HEAD(deladdrs, tc)
353 atf_tc_set_md_var(tc, "require.user", "root");
356 ATF_TC_BODY(deladdrs, tc)
358 struct pfioc_table io;
359 struct pfr_addr addr;
363 bzero(&addr, sizeof(addr));
364 bzero(&io, sizeof(io));
366 io.pfrio_buffer = &addr;
367 io.pfrio_esize = sizeof(addr);
371 if (ioctl(dev, DIOCRDELADDRS, &io) == 0)
372 atf_tc_fail("Request with size -1 succeeded");
374 /* Overly large size. */
375 io.pfrio_size = 1 << 28;
376 if (ioctl(dev, DIOCRDELADDRS, &io) == 0)
377 atf_tc_fail("Reuqest with size 1 << 28 failed");
380 ATF_TC_CLEANUP(deladdrs, tc)
385 ATF_TC_WITH_CLEANUP(setaddrs);
386 ATF_TC_HEAD(setaddrs, tc)
388 atf_tc_set_md_var(tc, "require.user", "root");
391 ATF_TC_BODY(setaddrs, tc)
393 struct pfioc_table io;
394 struct pfr_addr addr;
398 bzero(&addr, sizeof(addr));
399 bzero(&io, sizeof(io));
401 io.pfrio_buffer = &addr;
402 io.pfrio_esize = sizeof(addr);
406 if (ioctl(dev, DIOCRSETADDRS, &io) == 0)
407 atf_tc_fail("Request with size -1 succeeded");
409 /* Overly large size. */
410 io.pfrio_size = 1 << 28;
411 if (ioctl(dev, DIOCRSETADDRS, &io) == 0)
412 atf_tc_fail("Reuqest with size 1 << 28 failed");
415 ATF_TC_CLEANUP(setaddrs, tc)
420 ATF_TC_WITH_CLEANUP(getaddrs);
421 ATF_TC_HEAD(getaddrs, tc)
423 atf_tc_set_md_var(tc, "require.user", "root");
426 ATF_TC_BODY(getaddrs, tc)
428 struct pfioc_table io;
429 struct pfr_addr addr;
433 bzero(&addr, sizeof(addr));
434 bzero(&io, sizeof(io));
436 io.pfrio_buffer = &addr;
437 io.pfrio_esize = sizeof(addr);
439 common_init_tbl(&io.pfrio_table);
443 if (ioctl(dev, DIOCRGETADDRS, &io) == 0)
444 atf_tc_fail("Request with size -1 succeeded");
446 /* Overly large size. */
447 io.pfrio_size = 1 << 24;
448 if (ioctl(dev, DIOCRGETADDRS, &io) == 0)
449 atf_tc_fail("Request with size 1 << 24 failed");
452 ATF_TC_CLEANUP(getaddrs, tc)
457 ATF_TC_WITH_CLEANUP(getastats);
458 ATF_TC_HEAD(getastats, tc)
460 atf_tc_set_md_var(tc, "require.user", "root");
463 ATF_TC_BODY(getastats, tc)
465 struct pfioc_table io;
466 struct pfr_astats astats;
470 bzero(&astats, sizeof(astats));
471 bzero(&io, sizeof(io));
473 io.pfrio_buffer = &astats;
474 io.pfrio_esize = sizeof(astats);
476 common_init_tbl(&io.pfrio_table);
480 if (ioctl(dev, DIOCRGETASTATS, &io) == 0)
481 atf_tc_fail("Request with size -1 succeeded");
483 /* Overly large size. */
484 io.pfrio_size = 1 << 24;
485 if (ioctl(dev, DIOCRGETASTATS, &io) == 0)
486 atf_tc_fail("Request with size 1 << 24 failed");
489 ATF_TC_CLEANUP(getastats, tc)
494 ATF_TC_WITH_CLEANUP(clrastats);
495 ATF_TC_HEAD(clrastats, tc)
497 atf_tc_set_md_var(tc, "require.user", "root");
500 ATF_TC_BODY(clrastats, tc)
502 struct pfioc_table io;
503 struct pfr_addr addr;
507 bzero(&addr, sizeof(addr));
508 bzero(&io, sizeof(io));
510 io.pfrio_buffer = &addr;
511 io.pfrio_esize = sizeof(addr);
513 common_init_tbl(&io.pfrio_table);
517 if (ioctl(dev, DIOCRCLRASTATS, &io) == 0)
518 atf_tc_fail("Request with size -1 succeeded");
520 /* Overly large size. */
521 io.pfrio_size = 1 << 24;
522 if (ioctl(dev, DIOCRCLRASTATS, &io) == 0)
523 atf_tc_fail("Request with size 1 << 24 failed");
526 ATF_TC_CLEANUP(clrastats, tc)
531 ATF_TC_WITH_CLEANUP(tstaddrs);
532 ATF_TC_HEAD(tstaddrs, tc)
534 atf_tc_set_md_var(tc, "require.user", "root");
537 ATF_TC_BODY(tstaddrs, tc)
539 struct pfioc_table io;
540 struct pfr_addr addr;
544 bzero(&addr, sizeof(addr));
545 bzero(&io, sizeof(io));
547 io.pfrio_buffer = &addr;
548 io.pfrio_esize = sizeof(addr);
550 common_init_tbl(&io.pfrio_table);
554 if (ioctl(dev, DIOCRTSTADDRS, &io) == 0)
555 atf_tc_fail("Request with size -1 succeeded");
557 /* Overly large size. */
558 io.pfrio_size = 1 << 24;
559 if (ioctl(dev, DIOCRTSTADDRS, &io) == 0)
560 atf_tc_fail("Request with size 1 << 24 failed");
563 ATF_TC_CLEANUP(tstaddrs, tc)
568 ATF_TC_WITH_CLEANUP(inadefine);
569 ATF_TC_HEAD(inadefine, tc)
571 atf_tc_set_md_var(tc, "require.user", "root");
574 ATF_TC_BODY(inadefine, tc)
576 struct pfioc_table io;
577 struct pfr_addr addr;
581 bzero(&addr, sizeof(addr));
582 bzero(&io, sizeof(io));
584 io.pfrio_buffer = &addr;
585 io.pfrio_esize = sizeof(addr);
587 common_init_tbl(&io.pfrio_table);
591 if (ioctl(dev, DIOCRINADEFINE, &io) == 0)
592 atf_tc_fail("Request with size -1 succeeded");
594 /* Overly large size. */
595 io.pfrio_size = 1 << 24;
596 if (ioctl(dev, DIOCRINADEFINE, &io) == 0)
597 atf_tc_fail("Request with size 1 << 24 failed");
600 ATF_TC_CLEANUP(inadefine, tc)
605 ATF_TC_WITH_CLEANUP(igetifaces);
606 ATF_TC_HEAD(igetifaces, tc)
608 atf_tc_set_md_var(tc, "require.user", "root");
611 ATF_TC_BODY(igetifaces, tc)
613 struct pfioc_iface io;
618 bzero(&io, sizeof(io));
620 io.pfiio_buffer = &kif;
621 io.pfiio_esize = sizeof(kif);
625 if (ioctl(dev, DIOCIGETIFACES, &io) == 0)
626 atf_tc_fail("request with size -1 succeeded");
629 io.pfiio_size = 1 << 31;
630 if (ioctl(dev, DIOCIGETIFACES, &io) == 0)
631 atf_tc_fail("request with size 1 << 31 succeeded");
634 ATF_TC_CLEANUP(igetifaces, tc)
639 ATF_TC_WITH_CLEANUP(cxbegin);
640 ATF_TC_HEAD(cxbegin, tc)
642 atf_tc_set_md_var(tc, "require.user", "root");
645 ATF_TC_BODY(cxbegin, tc)
647 struct pfioc_trans io;
648 struct pfioc_trans_e ioe;
652 bzero(&io, sizeof(io));
653 io.esize = sizeof(ioe);
658 if (ioctl(dev, DIOCXBEGIN, &io) == 0)
659 atf_tc_fail("request with size -1 succeeded");
663 if (ioctl(dev, DIOCXBEGIN, &io) == 0)
664 atf_tc_fail("request with size 1 << 30 succeeded");
669 if (ioctl(dev, DIOCXBEGIN, &io) == 0)
670 atf_tc_fail("request with size -1 succeeded");
673 ATF_TC_CLEANUP(cxbegin, tc)
678 ATF_TC_WITH_CLEANUP(cxrollback);
679 ATF_TC_HEAD(cxrollback, tc)
681 atf_tc_set_md_var(tc, "require.user", "root");
684 ATF_TC_BODY(cxrollback, tc)
686 struct pfioc_trans io;
687 struct pfioc_trans_e ioe;
691 bzero(&io, sizeof(io));
692 io.esize = sizeof(ioe);
697 if (ioctl(dev, DIOCXROLLBACK, &io) == 0)
698 atf_tc_fail("request with size -1 succeeded");
702 if (ioctl(dev, DIOCXROLLBACK, &io) == 0)
703 atf_tc_fail("request with size 1 << 30 succeeded");
708 if (ioctl(dev, DIOCXROLLBACK, &io) == 0)
709 atf_tc_fail("request with size -1 succeeded");
712 ATF_TC_CLEANUP(cxrollback, tc)
717 ATF_TC_WITH_CLEANUP(commit);
718 ATF_TC_HEAD(commit, tc)
720 atf_tc_set_md_var(tc, "require.user", "root");
723 ATF_TC_BODY(commit, tc)
725 struct pfioc_trans io;
726 struct pfioc_trans_e ioe;
730 bzero(&io, sizeof(io));
731 io.esize = sizeof(ioe);
736 if (ioctl(dev, DIOCXCOMMIT, &io) == 0)
737 atf_tc_fail("request with size -1 succeeded");
741 if (ioctl(dev, DIOCXCOMMIT, &io) == 0)
742 atf_tc_fail("request with size 1 << 30 succeeded");
747 if (ioctl(dev, DIOCXCOMMIT, &io) == 0)
748 atf_tc_fail("request with size -1 succeeded");
751 ATF_TC_CLEANUP(commit, tc)
758 ATF_TP_ADD_TC(tp, addtables);
759 ATF_TP_ADD_TC(tp, deltables);
760 ATF_TP_ADD_TC(tp, gettables);
761 ATF_TP_ADD_TC(tp, gettstats);
762 ATF_TP_ADD_TC(tp, clrtstats);
763 ATF_TP_ADD_TC(tp, settflags);
764 ATF_TP_ADD_TC(tp, addaddrs);
765 ATF_TP_ADD_TC(tp, deladdrs);
766 ATF_TP_ADD_TC(tp, setaddrs);
767 ATF_TP_ADD_TC(tp, getaddrs);
768 ATF_TP_ADD_TC(tp, clrastats);
769 ATF_TP_ADD_TC(tp, tstaddrs);
770 ATF_TP_ADD_TC(tp, inadefine);
771 ATF_TP_ADD_TC(tp, igetifaces);
772 ATF_TP_ADD_TC(tp, cxbegin);
773 ATF_TP_ADD_TC(tp, cxrollback);
774 ATF_TP_ADD_TC(tp, commit);
776 return (atf_no_error());