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