]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/sys/netpfil/pf/ioctl/validation.c
MFC r341835:
[FreeBSD/FreeBSD.git] / tests / sys / netpfil / pf / ioctl / validation.c
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  * $FreeBSD$
26  */
27
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>
33
34 #include <net/if.h>
35 #include <net/pfvar.h>
36
37 #include <fcntl.h>
38 #include <stdio.h>
39
40 #include <atf-c.h>
41
42 static int dev;
43
44 #define COMMON_HEAD() \
45         if (modfind("pf") == -1) \
46                 atf_tc_skip("pf not loaded"); \
47         dev = open("/dev/pf", O_RDWR); \
48         if (dev == -1) \
49                 atf_tc_skip("Failed to open /dev/pf");
50
51 #define COMMON_CLEANUP() \
52         close(dev);
53
54 void
55 common_init_tbl(struct pfr_table *tbl)
56 {
57         bzero(tbl, sizeof(struct pfr_table));
58         strcpy(tbl->pfrt_anchor, "anchor");
59         strcpy(tbl->pfrt_name, "name");
60         tbl->pfrt_flags = 0;
61         tbl->pfrt_fback = 0;
62 }
63
64 ATF_TC_WITH_CLEANUP(addtables);
65 ATF_TC_HEAD(addtables, tc)
66 {
67         atf_tc_set_md_var(tc, "require.user", "root");
68 }
69
70 ATF_TC_BODY(addtables, tc)
71 {
72         struct pfioc_table io;
73         struct pfr_table tbl;
74         struct pfr_table tbls[4];
75         int flags;
76
77         COMMON_HEAD();
78
79         flags = 0;
80
81         bzero(&io, sizeof(io));
82         io.pfrio_flags = flags;
83         io.pfrio_buffer = &tbl;
84         io.pfrio_esize = sizeof(tbl);
85
86         /* Negative size */
87         io.pfrio_size = -1;
88         if (ioctl(dev, DIOCRADDTABLES, &io) == 0)
89                 atf_tc_fail("Request with size -1 succeeded");
90
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");
95
96         /* NULL buffer */
97         io.pfrio_size = 1;
98         io.pfrio_buffer = NULL;
99         if (ioctl(dev, DIOCRADDTABLES, &io) == 0)
100                 atf_tc_fail("Request with NULL buffer succeeded");
101
102         /* This can provoke a memory leak, see r331225. */
103         io.pfrio_size = 4;
104         for (int i = 0; i < io.pfrio_size; i++)
105                 common_init_tbl(&tbls[i]);
106
107         io.pfrio_buffer = &tbls;
108         ioctl(dev, DIOCRADDTABLES, &io);
109 }
110
111 ATF_TC_CLEANUP(addtables, tc)
112 {
113         COMMON_CLEANUP();
114 }
115
116 ATF_TC_WITH_CLEANUP(deltables);
117 ATF_TC_HEAD(deltables, tc)
118 {
119         atf_tc_set_md_var(tc, "require.user", "root");
120 }
121
122 ATF_TC_BODY(deltables, tc)
123 {
124         struct pfioc_table io;
125         struct pfr_table tbl;
126         int flags;
127
128         COMMON_HEAD();
129
130         flags = 0;
131
132         bzero(&io, sizeof(io));
133         io.pfrio_flags = flags;
134         io.pfrio_buffer = &tbl;
135         io.pfrio_esize = sizeof(tbl);
136
137         /* Negative size */
138         io.pfrio_size = -1;
139         if (ioctl(dev, DIOCRDELTABLES, &io) == 0)
140                 atf_tc_fail("Request with size -1 succeeded");
141
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");
146
147         /* NULL buffer */
148         io.pfrio_size = 1;
149         io.pfrio_buffer = NULL;
150         if (ioctl(dev, DIOCRDELTABLES, &io) == 0)
151                 atf_tc_fail("Request with NULL buffer succeeded");
152 }
153
154 ATF_TC_CLEANUP(deltables, tc)
155 {
156         COMMON_CLEANUP();
157 }
158
159 ATF_TC_WITH_CLEANUP(gettables);
160 ATF_TC_HEAD(gettables, tc)
161 {
162         atf_tc_set_md_var(tc, "require.user", "root");
163 }
164
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
192 ATF_TC_CLEANUP(gettables, tc)
193 {
194         COMMON_CLEANUP();
195 }
196
197 ATF_TC_WITH_CLEANUP(gettstats);
198 ATF_TC_HEAD(gettstats, tc)
199 {
200         atf_tc_set_md_var(tc, "require.user", "root");
201 }
202
203 ATF_TC_BODY(gettstats, tc)
204 {
205         struct pfioc_table io;
206         struct pfr_tstats stats;
207         int flags;
208
209         COMMON_HEAD();
210
211         flags = 0;
212
213         bzero(&io, sizeof(io));
214         io.pfrio_flags = flags;
215         io.pfrio_buffer = &stats;
216         io.pfrio_esize = sizeof(stats);
217
218         /* Negative size. This will succeed, because the kernel will not copy
219          * tables than it has. */
220         io.pfrio_size = -1;
221         if (ioctl(dev, DIOCRGETTSTATS, &io) != 0)
222                 atf_tc_fail("Request with size -1 failed");
223
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");
228 }
229
230 ATF_TC_CLEANUP(gettstats, tc)
231 {
232         COMMON_CLEANUP();
233 }
234
235 ATF_TC_WITH_CLEANUP(clrtstats);
236 ATF_TC_HEAD(clrtstats, tc)
237 {
238         atf_tc_set_md_var(tc, "require.user", "root");
239 }
240
241 ATF_TC_BODY(clrtstats, tc)
242 {
243         struct pfioc_table io;
244         struct pfr_table tbl;
245         int flags;
246
247         COMMON_HEAD();
248
249         flags = 0;
250
251         common_init_tbl(&tbl);
252
253         bzero(&io, sizeof(io));
254         io.pfrio_flags = flags;
255         io.pfrio_buffer = &tbl;
256         io.pfrio_esize = sizeof(tbl);
257
258         /* Negative size. This will succeed, because the kernel will not copy
259          * tables than it has. */
260         io.pfrio_size = -1;
261         if (ioctl(dev, DIOCRCLRTSTATS, &io) != 0)
262                 atf_tc_fail("Request with size -1 failed ");
263
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");
268 }
269
270 ATF_TC_CLEANUP(clrtstats, tc)
271 {
272         COMMON_CLEANUP();
273 }
274
275 ATF_TC_WITH_CLEANUP(settflags);
276 ATF_TC_HEAD(settflags, tc)
277 {
278         atf_tc_set_md_var(tc, "require.user", "root");
279 }
280
281 ATF_TC_BODY(settflags, tc)
282 {
283         struct pfioc_table io;
284         struct pfr_table tbl;
285         int flags;
286
287         COMMON_HEAD();
288
289         flags = 0;
290
291         common_init_tbl(&tbl);
292
293         bzero(&io, sizeof(io));
294         io.pfrio_flags = flags;
295         io.pfrio_buffer = &tbl;
296         io.pfrio_esize = sizeof(tbl);
297
298         /* Negative size. This will succeed, because the kernel will not copy
299          * tables than it has. */
300         io.pfrio_size = -1;
301         if (ioctl(dev, DIOCRSETTFLAGS, &io) != 0)
302                 atf_tc_fail("Request with size -1 failed");
303
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");
308 }
309
310 ATF_TC_CLEANUP(settflags, tc)
311 {
312         COMMON_CLEANUP();
313 }
314
315 ATF_TC_WITH_CLEANUP(addaddrs);
316 ATF_TC_HEAD(addaddrs, tc)
317 {
318         atf_tc_set_md_var(tc, "require.user", "root");
319 }
320
321 ATF_TC_BODY(addaddrs, tc)
322 {
323         struct pfioc_table io;
324         struct pfr_addr addr;
325
326         COMMON_HEAD();
327
328         bzero(&addr, sizeof(addr));
329         bzero(&io, sizeof(io));
330         io.pfrio_flags = 0;
331         io.pfrio_buffer = &addr;
332         io.pfrio_esize = sizeof(addr);
333
334         /* Negative size. */
335         io.pfrio_size = -1;
336         if (ioctl(dev, DIOCRADDADDRS, &io) == 0)
337                 atf_tc_fail("Request with size -1 succeeded");
338
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");
343 }
344
345 ATF_TC_CLEANUP(addaddrs, tc)
346 {
347         COMMON_CLEANUP();
348 }
349
350 ATF_TC_WITH_CLEANUP(deladdrs);
351 ATF_TC_HEAD(deladdrs, tc)
352 {
353         atf_tc_set_md_var(tc, "require.user", "root");
354 }
355
356 ATF_TC_BODY(deladdrs, tc)
357 {
358         struct pfioc_table io;
359         struct pfr_addr addr;
360
361         COMMON_HEAD();
362
363         bzero(&addr, sizeof(addr));
364         bzero(&io, sizeof(io));
365         io.pfrio_flags = 0;
366         io.pfrio_buffer = &addr;
367         io.pfrio_esize = sizeof(addr);
368
369         /* Negative size. */
370         io.pfrio_size = -1;
371         if (ioctl(dev, DIOCRDELADDRS, &io) == 0)
372                 atf_tc_fail("Request with size -1 succeeded");
373
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");
378 }
379
380 ATF_TC_CLEANUP(deladdrs, tc)
381 {
382         COMMON_CLEANUP();
383 }
384
385 ATF_TC_WITH_CLEANUP(setaddrs);
386 ATF_TC_HEAD(setaddrs, tc)
387 {
388         atf_tc_set_md_var(tc, "require.user", "root");
389 }
390
391 ATF_TC_BODY(setaddrs, tc)
392 {
393         struct pfioc_table io;
394         struct pfr_addr addr;
395
396         COMMON_HEAD();
397
398         bzero(&addr, sizeof(addr));
399         bzero(&io, sizeof(io));
400         io.pfrio_flags = 0;
401         io.pfrio_buffer = &addr;
402         io.pfrio_esize = sizeof(addr);
403
404         /* Negative size. */
405         io.pfrio_size = -1;
406         if (ioctl(dev, DIOCRSETADDRS, &io) == 0)
407                 atf_tc_fail("Request with size -1 succeeded");
408
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");
413 }
414
415 ATF_TC_CLEANUP(setaddrs, tc)
416 {
417         COMMON_CLEANUP();
418 }
419
420 ATF_TC_WITH_CLEANUP(getaddrs);
421 ATF_TC_HEAD(getaddrs, tc)
422 {
423         atf_tc_set_md_var(tc, "require.user", "root");
424 }
425
426 ATF_TC_BODY(getaddrs, tc)
427 {
428         struct pfioc_table io;
429         struct pfr_addr addr;
430
431         COMMON_HEAD();
432
433         bzero(&addr, sizeof(addr));
434         bzero(&io, sizeof(io));
435         io.pfrio_flags = 0;
436         io.pfrio_buffer = &addr;
437         io.pfrio_esize = sizeof(addr);
438
439         common_init_tbl(&io.pfrio_table);
440
441         /* Negative size. */
442         io.pfrio_size = -1;
443         if (ioctl(dev, DIOCRGETADDRS, &io) == 0)
444                 atf_tc_fail("Request with size -1 succeeded");
445
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");
450 }
451
452 ATF_TC_CLEANUP(getaddrs, tc)
453 {
454         COMMON_CLEANUP();
455 }
456
457 ATF_TC_WITH_CLEANUP(getastats);
458 ATF_TC_HEAD(getastats, tc)
459 {
460         atf_tc_set_md_var(tc, "require.user", "root");
461 }
462
463 ATF_TC_BODY(getastats, tc)
464 {
465         struct pfioc_table io;
466         struct pfr_astats astats;
467
468         COMMON_HEAD();
469
470         bzero(&astats, sizeof(astats));
471         bzero(&io, sizeof(io));
472         io.pfrio_flags = 0;
473         io.pfrio_buffer = &astats;
474         io.pfrio_esize = sizeof(astats);
475
476         common_init_tbl(&io.pfrio_table);
477
478         /* Negative size. */
479         io.pfrio_size = -1;
480         if (ioctl(dev, DIOCRGETASTATS, &io) == 0)
481                 atf_tc_fail("Request with size -1 succeeded");
482
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");
487 }
488
489 ATF_TC_CLEANUP(getastats, tc)
490 {
491         COMMON_CLEANUP();
492 }
493
494 ATF_TC_WITH_CLEANUP(clrastats);
495 ATF_TC_HEAD(clrastats, tc)
496 {
497         atf_tc_set_md_var(tc, "require.user", "root");
498 }
499
500 ATF_TC_BODY(clrastats, tc)
501 {
502         struct pfioc_table io;
503         struct pfr_addr addr;
504
505         COMMON_HEAD();
506
507         bzero(&addr, sizeof(addr));
508         bzero(&io, sizeof(io));
509         io.pfrio_flags = 0;
510         io.pfrio_buffer = &addr;
511         io.pfrio_esize = sizeof(addr);
512
513         common_init_tbl(&io.pfrio_table);
514
515         /* Negative size. */
516         io.pfrio_size = -1;
517         if (ioctl(dev, DIOCRCLRASTATS, &io) == 0)
518                 atf_tc_fail("Request with size -1 succeeded");
519
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");
524 }
525
526 ATF_TC_CLEANUP(clrastats, tc)
527 {
528         COMMON_CLEANUP();
529 }
530
531 ATF_TC_WITH_CLEANUP(tstaddrs);
532 ATF_TC_HEAD(tstaddrs, tc)
533 {
534         atf_tc_set_md_var(tc, "require.user", "root");
535 }
536
537 ATF_TC_BODY(tstaddrs, tc)
538 {
539         struct pfioc_table io;
540         struct pfr_addr addr;
541
542         COMMON_HEAD();
543
544         bzero(&addr, sizeof(addr));
545         bzero(&io, sizeof(io));
546         io.pfrio_flags = 0;
547         io.pfrio_buffer = &addr;
548         io.pfrio_esize = sizeof(addr);
549
550         common_init_tbl(&io.pfrio_table);
551
552         /* Negative size. */
553         io.pfrio_size = -1;
554         if (ioctl(dev, DIOCRTSTADDRS, &io) == 0)
555                 atf_tc_fail("Request with size -1 succeeded");
556
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");
561 }
562
563 ATF_TC_CLEANUP(tstaddrs, tc)
564 {
565         COMMON_CLEANUP();
566 }
567
568 ATF_TC_WITH_CLEANUP(inadefine);
569 ATF_TC_HEAD(inadefine, tc)
570 {
571         atf_tc_set_md_var(tc, "require.user", "root");
572 }
573
574 ATF_TC_BODY(inadefine, tc)
575 {
576         struct pfioc_table io;
577         struct pfr_addr addr;
578
579         COMMON_HEAD();
580
581         bzero(&addr, sizeof(addr));
582         bzero(&io, sizeof(io));
583         io.pfrio_flags = 0;
584         io.pfrio_buffer = &addr;
585         io.pfrio_esize = sizeof(addr);
586
587         common_init_tbl(&io.pfrio_table);
588
589         /* Negative size. */
590         io.pfrio_size = -1;
591         if (ioctl(dev, DIOCRINADEFINE, &io) == 0)
592                 atf_tc_fail("Request with size -1 succeeded");
593
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");
598 }
599
600 ATF_TC_CLEANUP(inadefine, tc)
601 {
602         COMMON_CLEANUP();
603 }
604
605 ATF_TC_WITH_CLEANUP(igetifaces);
606 ATF_TC_HEAD(igetifaces, tc)
607 {
608         atf_tc_set_md_var(tc, "require.user", "root");
609 }
610
611 ATF_TC_BODY(igetifaces, tc)
612 {
613         struct pfioc_iface io;
614         struct pfi_kif kif;
615
616         COMMON_HEAD();
617
618         bzero(&io, sizeof(io));
619         io.pfiio_flags = 0;
620         io.pfiio_buffer = &kif;
621         io.pfiio_esize = sizeof(kif);
622
623         /* Negative size */
624         io.pfiio_size = -1;
625         if (ioctl(dev, DIOCIGETIFACES, &io) == 0)
626                 atf_tc_fail("request with size -1 succeeded");
627
628         /* Overflow size */
629         io.pfiio_size = 1 << 31;
630         if (ioctl(dev, DIOCIGETIFACES, &io) == 0)
631                 atf_tc_fail("request with size 1 << 31 succeeded");
632 }
633
634 ATF_TC_CLEANUP(igetifaces, tc)
635 {
636         COMMON_CLEANUP();
637 }
638
639 ATF_TC_WITH_CLEANUP(cxbegin);
640 ATF_TC_HEAD(cxbegin, tc)
641 {
642         atf_tc_set_md_var(tc, "require.user", "root");
643 }
644
645 ATF_TC_BODY(cxbegin, tc)
646 {
647         struct pfioc_trans io;
648         struct pfioc_trans_e ioe;
649
650         COMMON_HEAD();
651
652         bzero(&io, sizeof(io));
653         io.esize = sizeof(ioe);
654         io.array = &ioe;
655
656         /* Negative size */
657         io.size = -1;
658         if (ioctl(dev, DIOCXBEGIN, &io) == 0)
659                 atf_tc_fail("request with size -1 succeeded");
660
661         /* Overflow size */
662         io.size = 1 << 30;
663         if (ioctl(dev, DIOCXBEGIN, &io) == 0)
664                 atf_tc_fail("request with size 1 << 30 succeeded");
665
666         /* NULL buffer */
667         io.size = 1;
668         io.array = NULL;
669         if (ioctl(dev, DIOCXBEGIN, &io) == 0)
670                 atf_tc_fail("request with size -1 succeeded");
671 }
672
673 ATF_TC_CLEANUP(cxbegin, tc)
674 {
675         COMMON_CLEANUP();
676 }
677
678 ATF_TC_WITH_CLEANUP(cxrollback);
679 ATF_TC_HEAD(cxrollback, tc)
680 {
681         atf_tc_set_md_var(tc, "require.user", "root");
682 }
683
684 ATF_TC_BODY(cxrollback, tc)
685 {
686         struct pfioc_trans io;
687         struct pfioc_trans_e ioe;
688
689         COMMON_HEAD();
690
691         bzero(&io, sizeof(io));
692         io.esize = sizeof(ioe);
693         io.array = &ioe;
694
695         /* Negative size */
696         io.size = -1;
697         if (ioctl(dev, DIOCXROLLBACK, &io) == 0)
698                 atf_tc_fail("request with size -1 succeeded");
699
700         /* Overflow size */
701         io.size = 1 << 30;
702         if (ioctl(dev, DIOCXROLLBACK, &io) == 0)
703                 atf_tc_fail("request with size 1 << 30 succeeded");
704
705         /* NULL buffer */
706         io.size = 1;
707         io.array = NULL;
708         if (ioctl(dev, DIOCXROLLBACK, &io) == 0)
709                 atf_tc_fail("request with size -1 succeeded");
710 }
711
712 ATF_TC_CLEANUP(cxrollback, tc)
713 {
714         COMMON_CLEANUP();
715 }
716
717 ATF_TC_WITH_CLEANUP(commit);
718 ATF_TC_HEAD(commit, tc)
719 {
720         atf_tc_set_md_var(tc, "require.user", "root");
721 }
722
723 ATF_TC_BODY(commit, tc)
724 {
725         struct pfioc_trans io;
726         struct pfioc_trans_e ioe;
727
728         COMMON_HEAD();
729
730         bzero(&io, sizeof(io));
731         io.esize = sizeof(ioe);
732         io.array = &ioe;
733
734         /* Negative size */
735         io.size = -1;
736         if (ioctl(dev, DIOCXCOMMIT, &io) == 0)
737                 atf_tc_fail("request with size -1 succeeded");
738
739         /* Overflow size */
740         io.size = 1 << 30;
741         if (ioctl(dev, DIOCXCOMMIT, &io) == 0)
742                 atf_tc_fail("request with size 1 << 30 succeeded");
743
744         /* NULL buffer */
745         io.size = 1;
746         io.array = NULL;
747         if (ioctl(dev, DIOCXCOMMIT, &io) == 0)
748                 atf_tc_fail("request with size -1 succeeded");
749 }
750
751 ATF_TC_CLEANUP(commit, tc)
752 {
753         COMMON_CLEANUP();
754 }
755
756 ATF_TP_ADD_TCS(tp)
757 {
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);
775
776         return (atf_no_error());
777 }