xref: /freebsd/lib/libsysdecode/tests/sysdecode_test.c (revision 4d846d260e2b9a3d4d0a701462568268cbfe7a5b)
1d0f245d2SMark Johnston /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3d0f245d2SMark Johnston  *
4d0f245d2SMark Johnston  * Copyright (c) 2022 The FreeBSD Foundation
5d0f245d2SMark Johnston  *
6d0f245d2SMark Johnston  * This software was developed by Mark Johnston under sponsorship from
7d0f245d2SMark Johnston  * the FreeBSD Foundation.
8d0f245d2SMark Johnston  *
9d0f245d2SMark Johnston  * Redistribution and use in source and binary forms, with or without
10d0f245d2SMark Johnston  * modification, are permitted provided that the following conditions are
11d0f245d2SMark Johnston  * met:
12d0f245d2SMark Johnston  * 1. Redistributions of source code must retain the above copyright
13d0f245d2SMark Johnston  *    notice, this list of conditions and the following disclaimer.
14d0f245d2SMark Johnston  * 2. Redistributions in binary form must reproduce the above copyright
15d0f245d2SMark Johnston  *    notice, this list of conditions and the following disclaimer in
16d0f245d2SMark Johnston  *    the documentation and/or other materials provided with the distribution.
17d0f245d2SMark Johnston  *
18d0f245d2SMark Johnston  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19d0f245d2SMark Johnston  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20d0f245d2SMark Johnston  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21d0f245d2SMark Johnston  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22d0f245d2SMark Johnston  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23d0f245d2SMark Johnston  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24d0f245d2SMark Johnston  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25d0f245d2SMark Johnston  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26d0f245d2SMark Johnston  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27d0f245d2SMark Johnston  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28d0f245d2SMark Johnston  * SUCH DAMAGE.
29d0f245d2SMark Johnston  */
30d0f245d2SMark Johnston 
31d0f245d2SMark Johnston #include <sys/capsicum.h>
32d0f245d2SMark Johnston #include <stdio.h>
33d0f245d2SMark Johnston #include <stdlib.h>
34d0f245d2SMark Johnston 
35d0f245d2SMark Johnston #include <atf-c.h>
36d0f245d2SMark Johnston #include <sysdecode.h>
37d0f245d2SMark Johnston 
38d0f245d2SMark Johnston /*
39d0f245d2SMark Johnston  * Take a comma-separated list of capability rights and verify that all rights
40d0f245d2SMark Johnston  * are present in the specified table, and that all rights in the table are
41d0f245d2SMark Johnston  * present in the list.
42d0f245d2SMark Johnston  */
43d0f245d2SMark Johnston static void
check_sysdecode_cap_rights(FILE * fp,char ** bufp,size_t * szp,cap_rights_t * rightsp,const char * tab[])44d0f245d2SMark Johnston check_sysdecode_cap_rights(FILE *fp, char **bufp, size_t *szp,
45d0f245d2SMark Johnston     cap_rights_t *rightsp, const char *tab[])
46d0f245d2SMark Johnston {
47d0f245d2SMark Johnston 	const char *next, *tok;
48d0f245d2SMark Johnston 	char *buf;
49d0f245d2SMark Johnston 	int i;
50d0f245d2SMark Johnston 
51d0f245d2SMark Johnston 	sysdecode_cap_rights(fp, rightsp);
52d0f245d2SMark Johnston 
53d0f245d2SMark Johnston 	ATF_REQUIRE(fflush(fp) == 0);
54d0f245d2SMark Johnston 	(*bufp)[*szp] = '\0';
55d0f245d2SMark Johnston 
56d0f245d2SMark Johnston 	buf = strdup(*bufp);
57d0f245d2SMark Johnston 	for (tok = buf; (next = strsep(&buf, ",")), tok != NULL; tok = next) {
58d0f245d2SMark Johnston 		for (i = 0; tab[i] != NULL; i++) {
59d0f245d2SMark Johnston 			if (strcmp(tok, tab[i]) == 0)
60d0f245d2SMark Johnston 				break;
61d0f245d2SMark Johnston 		}
62d0f245d2SMark Johnston 		ATF_REQUIRE_MSG(tab[i] != NULL,
63d0f245d2SMark Johnston 		    "did not find '%s' in table", tok);
64d0f245d2SMark Johnston 	}
65d0f245d2SMark Johnston 	free(buf);
66d0f245d2SMark Johnston 
67d0f245d2SMark Johnston 	for (i = 0; tab[i] != NULL; i++) {
68d0f245d2SMark Johnston 		buf = strdup(*bufp);
69d0f245d2SMark Johnston 		for (tok = buf; (next = strsep(&buf, ",")), tok != NULL;
70d0f245d2SMark Johnston 		    tok = next) {
71d0f245d2SMark Johnston 			if (strcmp(tok, tab[i]) == 0)
72d0f245d2SMark Johnston 				break;
73d0f245d2SMark Johnston 		}
74d0f245d2SMark Johnston 		free(buf);
75d0f245d2SMark Johnston 		ATF_REQUIRE_MSG(tok != NULL,
76d0f245d2SMark Johnston 		    "did not find '%s' in output stream", tab[i]);
77d0f245d2SMark Johnston 	}
78d0f245d2SMark Johnston 
79d0f245d2SMark Johnston 	ATF_REQUIRE(fseek(fp, 0, SEEK_SET) == 0);
80d0f245d2SMark Johnston }
81d0f245d2SMark Johnston 
82d0f245d2SMark Johnston /*
83d0f245d2SMark Johnston  * Regression tests for sysdecode_cap_rights(3).
84d0f245d2SMark Johnston  */
85d0f245d2SMark Johnston ATF_TC_WITHOUT_HEAD(cap_rights);
ATF_TC_BODY(cap_rights,tc)86d0f245d2SMark Johnston ATF_TC_BODY(cap_rights, tc)
87d0f245d2SMark Johnston {
88d0f245d2SMark Johnston 	char *buf;
89d0f245d2SMark Johnston 	FILE *fp;
90d0f245d2SMark Johnston 	size_t sz;
91d0f245d2SMark Johnston 	cap_rights_t rights;
92d0f245d2SMark Johnston 
93d0f245d2SMark Johnston 	fp = open_memstream(&buf, &sz);
94d0f245d2SMark Johnston 	ATF_REQUIRE(fp != NULL);
95d0f245d2SMark Johnston 
96d0f245d2SMark Johnston 	/*
97d0f245d2SMark Johnston 	 * libsysdecode emits a pseudo-right, CAP_NONE, when no rights are
98d0f245d2SMark Johnston 	 * present.
99d0f245d2SMark Johnston 	 */
100d0f245d2SMark Johnston 	check_sysdecode_cap_rights(fp, &buf, &sz,
101d0f245d2SMark Johnston 	    cap_rights_init(&rights),
102d0f245d2SMark Johnston 	    (const char *[]){ "CAP_NONE", NULL, });
103d0f245d2SMark Johnston 
104d0f245d2SMark Johnston 	check_sysdecode_cap_rights(fp, &buf, &sz,
105d0f245d2SMark Johnston 	    cap_rights_init(&rights, CAP_READ, CAP_SEEK),
106d0f245d2SMark Johnston 	    (const char *[]){ "CAP_PREAD", NULL, });
107d0f245d2SMark Johnston 
108d0f245d2SMark Johnston 	check_sysdecode_cap_rights(fp, &buf, &sz,
109d0f245d2SMark Johnston 	    cap_rights_init(&rights, CAP_READ, CAP_MMAP, CAP_SEEK_TELL),
110d0f245d2SMark Johnston 	    (const char *[]){ "CAP_READ", "CAP_MMAP", "CAP_SEEK_TELL", NULL, });
111d0f245d2SMark Johnston 
112d0f245d2SMark Johnston 	check_sysdecode_cap_rights(fp, &buf, &sz,
113d0f245d2SMark Johnston 	    cap_rights_init(&rights, CAP_MMAP, CAP_READ, CAP_WRITE, CAP_SEEK),
114d0f245d2SMark Johnston 	    (const char *[]){ "CAP_MMAP_RW", NULL, });
115d0f245d2SMark Johnston 
116d0f245d2SMark Johnston 	check_sysdecode_cap_rights(fp, &buf, &sz,
117d0f245d2SMark Johnston 	    cap_rights_init(&rights, CAP_READ, CAP_MMAP_X),
118d0f245d2SMark Johnston 	    (const char *[]){ "CAP_MMAP_RX", NULL, });
119d0f245d2SMark Johnston 
120d0f245d2SMark Johnston 	/* Aliases map back to the main definition. */
121d0f245d2SMark Johnston 	check_sysdecode_cap_rights(fp, &buf, &sz,
122d0f245d2SMark Johnston 	    cap_rights_init(&rights, CAP_RECV, CAP_SEND),
123d0f245d2SMark Johnston 	    (const char *[]){ "CAP_READ", "CAP_WRITE", NULL, });
124d0f245d2SMark Johnston 
125d0f245d2SMark Johnston 	/* This set straddles both indices. */
126d0f245d2SMark Johnston 	check_sysdecode_cap_rights(fp, &buf, &sz,
127d0f245d2SMark Johnston 	    cap_rights_init(&rights, CAP_READ, CAP_KQUEUE),
128d0f245d2SMark Johnston 	    (const char *[]){ "CAP_READ", "CAP_KQUEUE", NULL, });
129d0f245d2SMark Johnston 
130d0f245d2SMark Johnston 	/* Create a rights set with an unnamed flag. */
131d0f245d2SMark Johnston 	cap_rights_init(&rights, CAP_SEEK);
132d0f245d2SMark Johnston 	cap_rights_clear(&rights, CAP_SEEK_TELL);
133d0f245d2SMark Johnston 	check_sysdecode_cap_rights(fp, &buf, &sz,
134d0f245d2SMark Johnston 	    &rights,
135d0f245d2SMark Johnston 	    (const char *[]){ "CAP_NONE", "unknown rights", NULL, });
136d0f245d2SMark Johnston 
137d0f245d2SMark Johnston 	cap_rights_init(&rights, CAP_SEEK, CAP_KQUEUE_CHANGE);
138d0f245d2SMark Johnston 	cap_rights_clear(&rights, CAP_SEEK_TELL);
139d0f245d2SMark Johnston 	check_sysdecode_cap_rights(fp, &buf, &sz,
140d0f245d2SMark Johnston 	    &rights,
141d0f245d2SMark Johnston 	    (const char *[]){ "CAP_KQUEUE_CHANGE", "unknown rights", NULL, });
142d0f245d2SMark Johnston 
143d0f245d2SMark Johnston 	ATF_REQUIRE(fclose(fp) == 0);
144d0f245d2SMark Johnston 	free(buf);
145d0f245d2SMark Johnston }
146d0f245d2SMark Johnston 
ATF_TP_ADD_TCS(tp)147d0f245d2SMark Johnston ATF_TP_ADD_TCS(tp)
148d0f245d2SMark Johnston {
149d0f245d2SMark Johnston 	ATF_TP_ADD_TC(tp, cap_rights);
150d0f245d2SMark Johnston 
151d0f245d2SMark Johnston 	return (atf_no_error());
152d0f245d2SMark Johnston }
153