Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libcapsicum/capsicum_helpers.h
39475 views
1
/*-
2
* Copyright (c) 2016 Mariusz Zaborski <[email protected]>
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
* SUCH DAMAGE.
25
*/
26
27
#ifndef _CAPSICUM_HELPERS_H_
28
#define _CAPSICUM_HELPERS_H_
29
30
#include <sys/param.h>
31
#include <sys/capsicum.h>
32
#include <sys/ioctl.h>
33
34
#include <errno.h>
35
#include <nl_types.h>
36
#include <termios.h>
37
#include <time.h>
38
#include <unistd.h>
39
40
#include <libcasper.h>
41
42
#define CAPH_IGNORE_EBADF 0x0001
43
#define CAPH_READ 0x0002
44
#define CAPH_WRITE 0x0004
45
#define CAPH_LOOKUP 0x0008
46
47
__BEGIN_DECLS
48
49
static const unsigned long caph_stream_cmds[] =
50
{
51
#ifdef TIOCGETA
52
TIOCGETA,
53
#endif
54
#ifdef TIOCGWINSZ
55
TIOCGWINSZ,
56
#endif
57
#ifdef FIODTYPE
58
FIODTYPE,
59
#endif
60
};
61
static const uint32_t caph_stream_fcntls = CAP_FCNTL_GETFL;
62
63
static __inline void
64
caph_stream_rights(cap_rights_t *rights, int flags)
65
{
66
67
cap_rights_init(rights, CAP_EVENT, CAP_FCNTL, CAP_FSTAT,
68
CAP_IOCTL, CAP_SEEK);
69
70
if ((flags & CAPH_READ) != 0)
71
cap_rights_set(rights, CAP_READ);
72
if ((flags & CAPH_WRITE) != 0)
73
cap_rights_set(rights, CAP_WRITE);
74
if ((flags & CAPH_LOOKUP) != 0)
75
cap_rights_set(rights, CAP_LOOKUP);
76
}
77
78
static __inline int
79
caph_limit_stream(int fd, int flags)
80
{
81
cap_rights_t rights;
82
83
caph_stream_rights(&rights, flags);
84
if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS) {
85
if (errno == EBADF && (flags & CAPH_IGNORE_EBADF) != 0)
86
return (0);
87
return (-1);
88
}
89
90
if (cap_ioctls_limit(fd, caph_stream_cmds,
91
nitems(caph_stream_cmds)) < 0 && errno != ENOSYS)
92
return (-1);
93
94
if (cap_fcntls_limit(fd, caph_stream_fcntls) < 0 && errno != ENOSYS)
95
return (-1);
96
97
return (0);
98
}
99
100
static __inline int
101
caph_limit_stdin(void)
102
{
103
104
return (caph_limit_stream(STDIN_FILENO, CAPH_READ));
105
}
106
107
static __inline int
108
caph_limit_stderr(void)
109
{
110
111
return (caph_limit_stream(STDERR_FILENO, CAPH_WRITE));
112
}
113
114
static __inline int
115
caph_limit_stdout(void)
116
{
117
118
return (caph_limit_stream(STDOUT_FILENO, CAPH_WRITE));
119
}
120
121
static __inline int
122
caph_limit_stdio(void)
123
{
124
const int iebadf = CAPH_IGNORE_EBADF;
125
126
if (caph_limit_stream(STDIN_FILENO, CAPH_READ | iebadf) == -1 ||
127
caph_limit_stream(STDOUT_FILENO, CAPH_WRITE | iebadf) == -1 ||
128
caph_limit_stream(STDERR_FILENO, CAPH_WRITE | iebadf) == -1)
129
return (-1);
130
return (0);
131
}
132
133
static __inline void
134
caph_cache_tzdata(void)
135
{
136
time_t delta;
137
138
tzset();
139
140
/*
141
* The tzset() function does not cache all time zones.
142
* Some functions, such as gmtime(), require a GMT time zone.
143
* The only way to cache them is to call the function directly.
144
*/
145
delta = 0;
146
(void)gmtime(&delta);
147
}
148
149
static __inline void
150
caph_cache_catpages(void)
151
{
152
153
(void)catopen("libc", NL_CAT_LOCALE);
154
}
155
156
static __inline int
157
caph_enter(void)
158
{
159
160
if (cap_enter() < 0 && errno != ENOSYS)
161
return (-1);
162
163
return (0);
164
}
165
166
static __inline int
167
caph_rights_limit(int fd, const cap_rights_t *rights)
168
{
169
170
if (cap_rights_limit(fd, rights) < 0 && errno != ENOSYS)
171
return (-1);
172
173
return (0);
174
}
175
176
static __inline int
177
caph_ioctls_limit(int fd, const unsigned long *cmds, size_t ncmds)
178
{
179
180
if (cap_ioctls_limit(fd, cmds, ncmds) < 0 && errno != ENOSYS)
181
return (-1);
182
183
return (0);
184
}
185
186
static __inline int
187
caph_fcntls_limit(int fd, uint32_t fcntlrights)
188
{
189
190
if (cap_fcntls_limit(fd, fcntlrights) < 0 && errno != ENOSYS)
191
return (-1);
192
193
return (0);
194
}
195
196
static __inline int
197
caph_enter_casper(void)
198
{
199
200
return (CASPER_SUPPORT == 0 ? 0 : caph_enter());
201
}
202
203
__END_DECLS
204
205
#endif /* _CAPSICUM_HELPERS_H_ */
206
207