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