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