Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/security/mac/mac_cred.c
39476 views
1
/*-
2
* Copyright (c) 1999-2002, 2008-2009 Robert N. M. Watson
3
* Copyright (c) 2001 Ilmar S. Habibulin
4
* Copyright (c) 2001-2003 Networks Associates Technology, Inc.
5
* Copyright (c) 2005 Samy Al Bahra
6
* Copyright (c) 2006 SPARTA, Inc.
7
* Copyright (c) 2008 Apple Inc.
8
* All rights reserved.
9
*
10
* This software was developed by Robert Watson and Ilmar Habibulin for the
11
* TrustedBSD Project.
12
*
13
* This software was developed for the FreeBSD Project in part by Network
14
* Associates Laboratories, the Security Research Division of Network
15
* Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
16
* as part of the DARPA CHATS research program.
17
*
18
* This software was enhanced by SPARTA ISSO under SPAWAR contract
19
* N66001-04-C-6019 ("SEFOS").
20
*
21
* This software was developed at the University of Cambridge Computer
22
* Laboratory with support from a grant from Google, Inc.
23
*
24
* Redistribution and use in source and binary forms, with or without
25
* modification, are permitted provided that the following conditions
26
* are met:
27
* 1. Redistributions of source code must retain the above copyright
28
* notice, this list of conditions and the following disclaimer.
29
* 2. Redistributions in binary form must reproduce the above copyright
30
* notice, this list of conditions and the following disclaimer in the
31
* documentation and/or other materials provided with the distribution.
32
*
33
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
34
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
37
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43
* SUCH DAMAGE.
44
*/
45
46
#include <sys/cdefs.h>
47
#include "opt_mac.h"
48
49
#include <sys/param.h>
50
#include <sys/condvar.h>
51
#include <sys/imgact.h>
52
#include <sys/kernel.h>
53
#include <sys/lock.h>
54
#include <sys/malloc.h>
55
#include <sys/mutex.h>
56
#include <sys/mac.h>
57
#include <sys/proc.h>
58
#include <sys/sbuf.h>
59
#include <sys/sdt.h>
60
#include <sys/systm.h>
61
#include <sys/vnode.h>
62
#include <sys/mount.h>
63
#include <sys/file.h>
64
#include <sys/namei.h>
65
#include <sys/sysctl.h>
66
67
#include <vm/vm.h>
68
#include <vm/pmap.h>
69
#include <vm/vm_map.h>
70
#include <vm/vm_object.h>
71
72
#include <security/mac/mac_framework.h>
73
#include <security/mac/mac_internal.h>
74
#include <security/mac/mac_policy.h>
75
76
struct label *
77
mac_cred_label_alloc(void)
78
{
79
struct label *label;
80
81
label = mac_labelzone_alloc(M_WAITOK);
82
MAC_POLICY_PERFORM(cred_init_label, label);
83
return (label);
84
}
85
86
void
87
mac_cred_init(struct ucred *cred)
88
{
89
90
if (mac_labeled & MPC_OBJECT_CRED)
91
cred->cr_label = mac_cred_label_alloc();
92
else
93
cred->cr_label = NULL;
94
}
95
96
void
97
mac_cred_label_free(struct label *label)
98
{
99
100
MAC_POLICY_PERFORM_NOSLEEP(cred_destroy_label, label);
101
mac_labelzone_free(label);
102
}
103
104
void
105
mac_cred_destroy(struct ucred *cred)
106
{
107
108
if (cred->cr_label != NULL) {
109
mac_cred_label_free(cred->cr_label);
110
cred->cr_label = NULL;
111
}
112
}
113
114
/*
115
* When a thread becomes an NFS server daemon, its credential may need to be
116
* updated to reflect this so that policies can recognize when file system
117
* operations originate from the network.
118
*
119
* At some point, it would be desirable if the credential used for each NFS
120
* RPC could be set based on the RPC context (i.e., source system, etc) to
121
* provide more fine-grained access control.
122
*/
123
void
124
mac_cred_associate_nfsd(struct ucred *cred)
125
{
126
127
MAC_POLICY_PERFORM_NOSLEEP(cred_associate_nfsd, cred);
128
}
129
130
/*
131
* Initialize MAC label for the first kernel process, from which other kernel
132
* processes and threads are spawned.
133
*/
134
void
135
mac_cred_create_swapper(struct ucred *cred)
136
{
137
138
MAC_POLICY_PERFORM_NOSLEEP(cred_create_swapper, cred);
139
}
140
141
/*
142
* Initialize MAC label for the first userland process, from which other
143
* userland processes and threads are spawned.
144
*/
145
void
146
mac_cred_create_init(struct ucred *cred)
147
{
148
149
MAC_POLICY_PERFORM_NOSLEEP(cred_create_init, cred);
150
}
151
152
int
153
mac_cred_externalize_label(struct label *label, char *elements,
154
char *outbuf, size_t outbuflen)
155
{
156
int error;
157
158
MAC_POLICY_EXTERNALIZE(cred, label, elements, outbuf, outbuflen);
159
160
return (error);
161
}
162
163
int
164
mac_cred_internalize_label(struct label *label, char *string)
165
{
166
int error;
167
168
MAC_POLICY_INTERNALIZE(cred, label, string);
169
170
return (error);
171
}
172
173
/*
174
* When a new process is created, its label must be initialized. Generally,
175
* this involves inheritance from the parent process, modulo possible deltas.
176
* This function allows that processing to take place.
177
*/
178
void
179
mac_cred_copy(struct ucred *src, struct ucred *dest)
180
{
181
182
MAC_POLICY_PERFORM_NOSLEEP(cred_copy_label, src->cr_label,
183
dest->cr_label);
184
}
185
186
/*
187
* When the subject's label changes, it may require revocation of privilege
188
* to mapped objects. This can't be done on-the-fly later with a unified
189
* buffer cache.
190
*/
191
void
192
mac_cred_relabel(struct ucred *cred, struct label *newlabel)
193
{
194
195
MAC_POLICY_PERFORM_NOSLEEP(cred_relabel, cred, newlabel);
196
}
197
198
MAC_CHECK_PROBE_DEFINE2(cred_check_relabel, "struct ucred *",
199
"struct label *");
200
201
int
202
mac_cred_check_relabel(struct ucred *cred, struct label *newlabel)
203
{
204
int error;
205
206
MAC_POLICY_CHECK_NOSLEEP(cred_check_relabel, cred, newlabel);
207
MAC_CHECK_PROBE2(cred_check_relabel, error, cred, newlabel);
208
209
return (error);
210
}
211
212
/*
213
* Entry hook for setcred().
214
*
215
* Called with no lock held by setcred() so that MAC modules may allocate memory
216
* in preparation for checking privileges. A call to this hook is always
217
* followed by a matching call to mac_cred_setcred_exit(). Between these two,
218
* setcred() may or may not call mac_cred_check_setcred().
219
*/
220
void
221
mac_cred_setcred_enter(void)
222
{
223
MAC_POLICY_PERFORM_NOSLEEP(cred_setcred_enter);
224
}
225
226
MAC_CHECK_PROBE_DEFINE3(cred_check_setcred, "unsigned int", "struct ucred *",
227
"struct ucred *");
228
229
/*
230
* Check hook for setcred().
231
*
232
* When called, the current process' lock is held. It thus cannot perform
233
* memory allocations, which must be done in advance in
234
* mac_cred_setcred_enter(). It *MUST NOT* tamper with the process' lock.
235
*/
236
int
237
mac_cred_check_setcred(u_int flags, const struct ucred *old_cred,
238
struct ucred *new_cred)
239
{
240
int error;
241
242
MAC_POLICY_CHECK_NOSLEEP(cred_check_setcred, flags, old_cred, new_cred);
243
MAC_CHECK_PROBE3(cred_check_setcred, error, flags, old_cred, new_cred);
244
245
return (error);
246
}
247
248
/*
249
* Exit hook for setcred().
250
*
251
* Called with no lock held, exactly once per call to mac_cred_setcred_enter().
252
*/
253
void
254
mac_cred_setcred_exit(void)
255
{
256
MAC_POLICY_PERFORM_NOSLEEP(cred_setcred_exit);
257
}
258
259
MAC_CHECK_PROBE_DEFINE2(cred_check_setuid, "struct ucred *", "uid_t");
260
261
int
262
mac_cred_check_setuid(struct ucred *cred, uid_t uid)
263
{
264
int error;
265
266
MAC_POLICY_CHECK_NOSLEEP(cred_check_setuid, cred, uid);
267
MAC_CHECK_PROBE2(cred_check_setuid, error, cred, uid);
268
269
return (error);
270
}
271
272
MAC_CHECK_PROBE_DEFINE2(cred_check_seteuid, "struct ucred *", "uid_t");
273
274
int
275
mac_cred_check_seteuid(struct ucred *cred, uid_t euid)
276
{
277
int error;
278
279
MAC_POLICY_CHECK_NOSLEEP(cred_check_seteuid, cred, euid);
280
MAC_CHECK_PROBE2(cred_check_seteuid, error, cred, euid);
281
282
return (error);
283
}
284
285
MAC_CHECK_PROBE_DEFINE2(cred_check_setgid, "struct ucred *", "gid_t");
286
287
int
288
mac_cred_check_setgid(struct ucred *cred, gid_t gid)
289
{
290
int error;
291
292
MAC_POLICY_CHECK_NOSLEEP(cred_check_setgid, cred, gid);
293
MAC_CHECK_PROBE2(cred_check_setgid, error, cred, gid);
294
295
return (error);
296
}
297
298
MAC_CHECK_PROBE_DEFINE2(cred_check_setegid, "struct ucred *", "gid_t");
299
300
int
301
mac_cred_check_setegid(struct ucred *cred, gid_t egid)
302
{
303
int error;
304
305
MAC_POLICY_CHECK_NOSLEEP(cred_check_setegid, cred, egid);
306
MAC_CHECK_PROBE2(cred_check_setegid, error, cred, egid);
307
308
return (error);
309
}
310
311
MAC_CHECK_PROBE_DEFINE3(cred_check_setgroups, "struct ucred *", "int",
312
"gid_t *");
313
314
int
315
mac_cred_check_setgroups(struct ucred *cred, int ngroups, gid_t *gidset)
316
{
317
int error;
318
319
MAC_POLICY_CHECK_NOSLEEP(cred_check_setgroups, cred, ngroups, gidset);
320
MAC_CHECK_PROBE3(cred_check_setgroups, error, cred, ngroups, gidset);
321
322
return (error);
323
}
324
325
MAC_CHECK_PROBE_DEFINE3(cred_check_setreuid, "struct ucred *", "uid_t",
326
"uid_t");
327
328
int
329
mac_cred_check_setreuid(struct ucred *cred, uid_t ruid, uid_t euid)
330
{
331
int error;
332
333
MAC_POLICY_CHECK_NOSLEEP(cred_check_setreuid, cred, ruid, euid);
334
MAC_CHECK_PROBE3(cred_check_setreuid, error, cred, ruid, euid);
335
336
return (error);
337
}
338
339
MAC_CHECK_PROBE_DEFINE3(cred_check_setregid, "struct ucred *", "gid_t",
340
"gid_t");
341
342
int
343
mac_cred_check_setregid(struct ucred *cred, gid_t rgid, gid_t egid)
344
{
345
int error;
346
347
MAC_POLICY_CHECK_NOSLEEP(cred_check_setregid, cred, rgid, egid);
348
MAC_CHECK_PROBE3(cred_check_setregid, error, cred, rgid, egid);
349
350
return (error);
351
}
352
353
MAC_CHECK_PROBE_DEFINE4(cred_check_setresuid, "struct ucred *", "uid_t",
354
"uid_t", "uid_t");
355
356
int
357
mac_cred_check_setresuid(struct ucred *cred, uid_t ruid, uid_t euid,
358
uid_t suid)
359
{
360
int error;
361
362
MAC_POLICY_CHECK_NOSLEEP(cred_check_setresuid, cred, ruid, euid, suid);
363
MAC_CHECK_PROBE4(cred_check_setresuid, error, cred, ruid, euid,
364
suid);
365
366
return (error);
367
}
368
369
MAC_CHECK_PROBE_DEFINE4(cred_check_setresgid, "struct ucred *", "gid_t",
370
"gid_t", "gid_t");
371
372
int
373
mac_cred_check_setresgid(struct ucred *cred, gid_t rgid, gid_t egid,
374
gid_t sgid)
375
{
376
int error;
377
378
MAC_POLICY_CHECK_NOSLEEP(cred_check_setresgid, cred, rgid, egid, sgid);
379
MAC_CHECK_PROBE4(cred_check_setresgid, error, cred, rgid, egid,
380
sgid);
381
382
return (error);
383
}
384
385
MAC_CHECK_PROBE_DEFINE2(cred_check_visible, "struct ucred *",
386
"struct ucred *");
387
388
int
389
mac_cred_check_visible(struct ucred *cr1, struct ucred *cr2)
390
{
391
int error;
392
393
MAC_POLICY_CHECK_NOSLEEP(cred_check_visible, cr1, cr2);
394
MAC_CHECK_PROBE2(cred_check_visible, error, cr1, cr2);
395
396
return (error);
397
}
398
399