xref: /freebsd/contrib/capsicum-test/capsicum.h (revision a466cc55373fc3cf86837f09da729535b57e69a1)
1 /*
2  * Minimal portability layer for Capsicum-related features.
3  */
4 #ifndef __CAPSICUM_H__
5 #define __CAPSICUM_H__
6 
7 #ifdef __FreeBSD__
8 #include "capsicum-freebsd.h"
9 #endif
10 
11 #ifdef __linux__
12 #include "capsicum-linux.h"
13 #endif
14 
15 /*
16  * CAP_ALL/CAP_NONE is a value in FreeBSD9.x Capsicum, but a functional macro
17  * in FreeBSD10.x Capsicum.  Always use CAP_SET_ALL/CAP_SET_NONE instead.
18  */
19 #ifndef CAP_SET_ALL
20 #ifdef CAP_RIGHTS_VERSION
21 #define CAP_SET_ALL(rights) CAP_ALL(rights)
22 #else
23 #define CAP_SET_ALL(rights) *(rights) = CAP_MASK_VALID
24 #endif
25 #endif
26 
27 #ifndef CAP_SET_NONE
28 #ifdef CAP_RIGHTS_VERSION
29 #define CAP_SET_NONE(rights) CAP_NONE(rights)
30 #else
31 #define CAP_SET_NONE(rights) *(rights) = 0
32 #endif
33 #endif
34 
35 
36 /************************************************************
37  * Define new-style rights in terms of old-style rights if
38  * absent.
39  ************************************************************/
40 #include "capsicum-rights.h"
41 
42 /*
43  * Cope with systems (e.g. FreeBSD 10.x) where CAP_RENAMEAT hasn't been split out.
44  *  (src, dest): RENAMEAT, LINKAT => RENAMEAT_SOURCE, RENAMEAT_TARGET
45  */
46 #ifndef CAP_RENAMEAT_SOURCE
47 #define CAP_RENAMEAT_SOURCE CAP_RENAMEAT
48 #endif
49 #ifndef CAP_RENAMEAT_TARGET
50 #define CAP_RENAMEAT_TARGET CAP_LINKAT
51 #endif
52 /*
53  * Cope with systems (e.g. FreeBSD 10.x) where CAP_RENAMEAT hasn't been split out.
54  *  (src, dest): 0, LINKAT => LINKAT_SOURCE, LINKAT_TARGET
55  */
56 #ifndef CAP_LINKAT_SOURCE
57 #define CAP_LINKAT_SOURCE CAP_LOOKUP
58 #endif
59 #ifndef CAP_LINKAT_TARGET
60 #define CAP_LINKAT_TARGET CAP_LINKAT
61 #endif
62 
63 #ifdef CAP_PREAD
64 /* Existence of CAP_PREAD implies new-style CAP_SEEK semantics */
65 #define CAP_SEEK_ASWAS 0
66 #else
67 /* Old-style CAP_SEEK semantics */
68 #define CAP_SEEK_ASWAS CAP_SEEK
69 #define CAP_PREAD CAP_READ
70 #define CAP_PWRITE CAP_WRITE
71 #endif
72 
73 #ifndef CAP_MMAP_R
74 #define CAP_MMAP_R (CAP_READ|CAP_MMAP)
75 #define CAP_MMAP_W (CAP_WRITE|CAP_MMAP)
76 #define CAP_MMAP_X (CAP_MAPEXEC|CAP_MMAP)
77 #define CAP_MMAP_RW (CAP_MMAP_R|CAP_MMAP_W)
78 #define CAP_MMAP_RX (CAP_MMAP_R|CAP_MMAP_X)
79 #define CAP_MMAP_WX (CAP_MMAP_W|CAP_MMAP_X)
80 #define CAP_MMAP_RWX (CAP_MMAP_R|CAP_MMAP_W|CAP_MMAP_X)
81 #endif
82 
83 #ifndef CAP_MKFIFOAT
84 #define CAP_MKFIFOAT CAP_MKFIFO
85 #endif
86 
87 #ifndef CAP_MKNODAT
88 #define CAP_MKNODAT CAP_MKFIFOAT
89 #endif
90 
91 #ifndef CAP_MKDIRAT
92 #define CAP_MKDIRAT CAP_MKDIR
93 #endif
94 
95 #ifndef CAP_UNLINKAT
96 #define CAP_UNLINKAT CAP_RMDIR
97 #endif
98 
99 #ifndef CAP_SOCK_CLIENT
100 #define CAP_SOCK_CLIENT \
101         (CAP_CONNECT | CAP_GETPEERNAME | CAP_GETSOCKNAME | CAP_GETSOCKOPT | \
102          CAP_PEELOFF | CAP_READ | CAP_WRITE | CAP_SETSOCKOPT | CAP_SHUTDOWN)
103 #endif
104 
105 #ifndef CAP_SOCK_SERVER
106 #define CAP_SOCK_SERVER \
107         (CAP_ACCEPT | CAP_BIND | CAP_GETPEERNAME | CAP_GETSOCKNAME | \
108          CAP_GETSOCKOPT | CAP_LISTEN | CAP_PEELOFF | CAP_READ | CAP_WRITE | \
109          CAP_SETSOCKOPT | CAP_SHUTDOWN)
110 #endif
111 
112 #ifndef CAP_EVENT
113 #define CAP_EVENT CAP_POLL_EVENT
114 #endif
115 
116 /************************************************************
117  * Define new-style API functions in terms of old-style API
118  * functions if absent.
119  ************************************************************/
120 #ifndef HAVE_CAP_RIGHTS_GET
121 /* Define cap_rights_get() in terms of old-style cap_getrights() */
122 inline int cap_rights_get(int fd, cap_rights_t *rights) {
123   return cap_getrights(fd, rights);
124 }
125 #endif
126 
127 #ifndef HAVE_CAP_RIGHTS_LIMIT
128 /* Define cap_rights_limit() in terms of old-style cap_new() and dup2() */
129 #include <unistd.h>
130 inline int cap_rights_limit(int fd, const cap_rights_t *rights) {
131   int cap = cap_new(fd, *rights);
132   if (cap < 0) return cap;
133   int rc = dup2(cap, fd);
134   if (rc < 0) return rc;
135   close(cap);
136   return rc;
137 }
138 #endif
139 
140 #include <stdio.h>
141 #ifdef CAP_RIGHTS_VERSION
142 /* New-style Capsicum API extras for debugging */
143 static inline void cap_rights_describe(const cap_rights_t *rights, char *buffer) {
144   int ii;
145   for (ii = 0; ii < (CAP_RIGHTS_VERSION+2); ii++) {
146     int len = sprintf(buffer, "0x%016llx ", (unsigned long long)rights->cr_rights[ii]);
147     buffer += len;
148   }
149 }
150 
151 #ifdef __cplusplus
152 #include <iostream>
153 #include <iomanip>
154 inline std::ostream& operator<<(std::ostream& os, cap_rights_t rights) {
155   for (int ii = 0; ii < (CAP_RIGHTS_VERSION+2); ii++) {
156     os << std::hex << std::setw(16) << std::setfill('0') << (unsigned long long)rights.cr_rights[ii] << " ";
157   }
158   return os;
159 }
160 #endif
161 
162 #else
163 
164 static inline void cap_rights_describe(const cap_rights_t *rights, char *buffer) {
165   sprintf(buffer, "0x%016llx", (*rights));
166 }
167 
168 #endif  /* new/old style rights manipulation */
169 
170 #ifdef __cplusplus
171 #include <string>
172 extern std::string capsicum_test_bindir;
173 #endif
174 
175 #endif /*__CAPSICUM_H__*/
176