Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tools/regression/security/cap_test/cap_test.h
48266 views
1
/*-
2
* Copyright (c) 2008-2011 Robert N. M. Watson
3
* Copyright (c) 2011 Jonathan Anderson
4
* All rights reserved.
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
* 1. Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* 2. Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
* SUCH DAMAGE.
26
*/
27
28
#ifndef CAP_TEST_H
29
#define CAP_TEST_H
30
31
#include <err.h>
32
33
/*
34
* Define a file required by a test. The test can't complete without the file,
35
* so if we don't have it, just die.
36
*/
37
#define REQUIRE(fd) do { \
38
if ((fd) < 0) \
39
err(-1, "%s:%d: Missing required file '%s'", \
40
__FILE__, __LINE__, #fd); \
41
} while (0)
42
43
/* Whether a test passed or failed. */
44
#define PASSED 0
45
#define FAILED 1
46
47
/* A test has failed; print a message and clear the 'success' flag. */
48
#define FAIL(...) do { \
49
warn(__VA_ARGS__); \
50
success = FAILED; \
51
} while (0)
52
53
/* As above, but do not print the errno message. */
54
#define FAILX(...) do { \
55
warnx(__VA_ARGS__); \
56
success = FAILED; \
57
} while (0)
58
59
/* Like an assertion, but don't kill the test, just fail and keep going. */
60
#define CHECK(condition) do { \
61
if (!(condition)) \
62
FAILX("%s:%d: Assertion '%s' failed", \
63
__func__, __LINE__, #condition); \
64
} while (0)
65
66
/* Make sure that a system call's return value is >= 0. */
67
#define CHECK_SYSCALL_SUCCEEDS(syscall, ...) do { \
68
if (syscall(__VA_ARGS__) < 0) \
69
FAIL("%s() at line %d: %s failed", \
70
__func__, __LINE__, #syscall); \
71
} while (0)
72
73
/* Make sure that a system call fails with the correct errno. */
74
#define CHECK_SYSCALL_FAILS(expected_errno, syscall, ...) do { \
75
if (syscall(__VA_ARGS__) < 0) { \
76
if (errno != expected_errno) \
77
FAIL("%s() at line %d: %s", \
78
__func__, __LINE__, #syscall); \
79
} else { \
80
FAILX("%s() at line %d: %s succeeded; it should've failed", \
81
__func__, __LINE__, #syscall); \
82
} \
83
} while (0)
84
85
/* Make sure that a system call fails, but not with a particular errno. */
86
#define CHECK_SYSCALL_FAILS_BUT_NOT_WITH(bad_errno, syscall, ...) do { \
87
if (syscall(__VA_ARGS__) < 0) { \
88
if (errno == bad_errno) \
89
FAIL("%s() at line %d: %s", \
90
__func__, __LINE__, #syscall); \
91
} else { \
92
FAILX("%s() at line %d: %s succeeded; it should've failed", \
93
__func__, __LINE__, #syscall); \
94
} \
95
} while (0)
96
97
/* A system call should fail with ECAPMODE. */
98
#define CHECK_CAPMODE(...) \
99
CHECK_SYSCALL_FAILS(ECAPMODE, __VA_ARGS__)
100
101
/* A system call should fail, but not with ECAPMODE. */
102
#define CHECK_NOT_CAPMODE(...) \
103
CHECK_SYSCALL_FAILS_BUT_NOT_WITH(ECAPMODE, __VA_ARGS__)
104
105
/* A system call should fail with ENOTCAPABLE. */
106
#define CHECK_NOTCAPABLE(...) \
107
CHECK_SYSCALL_FAILS(ENOTCAPABLE, __VA_ARGS__)
108
109
/* Ensure that 'rights' are a subset of 'max'. */
110
#define CHECK_RIGHTS(rights, max) do { \
111
if ((success == PASSED) && (rights != max)) \
112
FAILX("Rights of opened file (%jx) > maximum (%jx)", \
113
(cap_rights_t) rights, (cap_rights_t) max); \
114
} while (0)
115
116
/* Create a capability from a file descriptor, make sure it succeeds. */
117
#define MAKE_CAPABILITY(to, from, rights) do { \
118
cap_rights_t _rights; \
119
REQUIRE(to = cap_new(from, rights)); \
120
CHECK_SYSCALL_SUCCEEDS(cap_getrights, to, &_rights); \
121
if ((success == PASSED) && (_rights != (rights))) \
122
FAILX("New capability's rights (%jx) != %jx", \
123
_rights, (cap_rights_t) (rights)); \
124
} while (0)
125
126
/*
127
* A top-level test should take no arguments and return an integer value,
128
* either PASSED or FAILED.
129
*
130
* Errors such as SIGSEGV will be caught and interpreted as FAILED.
131
*/
132
typedef int (*test_function)(void);
133
134
/* Information about a test. */
135
struct test {
136
char *t_name;
137
test_function t_run;
138
int t_result;
139
};
140
141
/*
142
* Run a test in a child process so that cap_enter(2) doesn't mess up
143
* subsequent tests.
144
*/
145
int execute(int id, struct test*);
146
147
int test_capmode(void);
148
int test_capabilities(void);
149
int test_fcntl(void);
150
int test_pdfork(void);
151
int test_pdkill(void);
152
int test_pdwait(void);
153
int test_relative(void);
154
int test_sysctl(void);
155
156
#endif /* CAP_TEST_H */
157
158