Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/security/mac/mac_vfs.c
39476 views
1
/*-
2
* Copyright (c) 1999-2002, 2009 Robert N. M. Watson
3
* Copyright (c) 2001 Ilmar S. Habibulin
4
* Copyright (c) 2001-2005 McAfee, Inc.
5
* Copyright (c) 2005-2006 SPARTA, Inc.
6
* Copyright (c) 2008 Apple Inc.
7
* All rights reserved.
8
*
9
* This software was developed by Robert Watson and Ilmar Habibulin for the
10
* TrustedBSD Project.
11
*
12
* This software was developed for the FreeBSD Project in part by McAfee
13
* Research, the Security Research Division of McAfee, Inc. under
14
* DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
15
* CHATS research program.
16
*
17
* This software was enhanced by SPARTA ISSO under SPAWAR contract
18
* N66001-04-C-6019 ("SEFOS").
19
*
20
* This software was developed at the University of Cambridge Computer
21
* Laboratory with support from a grant from Google, Inc.
22
*
23
* Redistribution and use in source and binary forms, with or without
24
* modification, are permitted provided that the following conditions
25
* are met:
26
* 1. Redistributions of source code must retain the above copyright
27
* notice, this list of conditions and the following disclaimer.
28
* 2. Redistributions in binary form must reproduce the above copyright
29
* notice, this list of conditions and the following disclaimer in the
30
* documentation and/or other materials provided with the distribution.
31
*
32
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
33
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
36
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
40
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
41
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42
* SUCH DAMAGE.
43
*/
44
45
#include <sys/cdefs.h>
46
#include "opt_mac.h"
47
48
#include <sys/param.h>
49
#include <sys/condvar.h>
50
#include <sys/extattr.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/proc.h>
57
#include <sys/sbuf.h>
58
#include <sys/systm.h>
59
#include <sys/vnode.h>
60
#include <sys/mount.h>
61
#include <sys/file.h>
62
#include <sys/namei.h>
63
#include <sys/sdt.h>
64
#include <sys/sysctl.h>
65
66
#include <vm/vm.h>
67
#include <vm/pmap.h>
68
#include <vm/vm_map.h>
69
#include <vm/vm_object.h>
70
71
#include <fs/devfs/devfs.h>
72
73
#include <security/mac/mac_framework.h>
74
#include <security/mac/mac_internal.h>
75
#include <security/mac/mac_policy.h>
76
77
/*
78
* Warn about EA transactions only the first time they happen. No locking on
79
* this variable.
80
*/
81
static int ea_warn_once = 0;
82
83
static int mac_vnode_setlabel_extattr(struct ucred *cred,
84
struct vnode *vp, struct label *intlabel);
85
86
static struct label *
87
mac_devfs_label_alloc(void)
88
{
89
struct label *label;
90
91
label = mac_labelzone_alloc(M_WAITOK);
92
MAC_POLICY_PERFORM(devfs_init_label, label);
93
return (label);
94
}
95
96
void
97
mac_devfs_init(struct devfs_dirent *de)
98
{
99
100
if (mac_labeled & MPC_OBJECT_DEVFS)
101
de->de_label = mac_devfs_label_alloc();
102
else
103
de->de_label = NULL;
104
}
105
106
static struct label *
107
mac_mount_label_alloc(void)
108
{
109
struct label *label;
110
111
label = mac_labelzone_alloc(M_WAITOK);
112
MAC_POLICY_PERFORM(mount_init_label, label);
113
return (label);
114
}
115
116
void
117
mac_mount_init(struct mount *mp)
118
{
119
120
if (mac_labeled & MPC_OBJECT_MOUNT)
121
mp->mnt_label = mac_mount_label_alloc();
122
else
123
mp->mnt_label = NULL;
124
}
125
126
struct label *
127
mac_vnode_label_alloc(void)
128
{
129
struct label *label;
130
131
label = mac_labelzone_alloc(M_WAITOK);
132
MAC_POLICY_PERFORM(vnode_init_label, label);
133
return (label);
134
}
135
136
void
137
mac_vnode_init(struct vnode *vp)
138
{
139
140
if (mac_labeled & MPC_OBJECT_VNODE)
141
vp->v_label = mac_vnode_label_alloc();
142
else
143
vp->v_label = NULL;
144
}
145
146
static void
147
mac_devfs_label_free(struct label *label)
148
{
149
150
MAC_POLICY_PERFORM_NOSLEEP(devfs_destroy_label, label);
151
mac_labelzone_free(label);
152
}
153
154
void
155
mac_devfs_destroy(struct devfs_dirent *de)
156
{
157
158
if (de->de_label != NULL) {
159
mac_devfs_label_free(de->de_label);
160
de->de_label = NULL;
161
}
162
}
163
164
static void
165
mac_mount_label_free(struct label *label)
166
{
167
168
MAC_POLICY_PERFORM_NOSLEEP(mount_destroy_label, label);
169
mac_labelzone_free(label);
170
}
171
172
void
173
mac_mount_destroy(struct mount *mp)
174
{
175
176
if (mp->mnt_label != NULL) {
177
mac_mount_label_free(mp->mnt_label);
178
mp->mnt_label = NULL;
179
}
180
}
181
182
void
183
mac_vnode_label_free(struct label *label)
184
{
185
186
MAC_POLICY_PERFORM_NOSLEEP(vnode_destroy_label, label);
187
mac_labelzone_free(label);
188
}
189
190
void
191
mac_vnode_destroy(struct vnode *vp)
192
{
193
194
if (vp->v_label != NULL) {
195
mac_vnode_label_free(vp->v_label);
196
vp->v_label = NULL;
197
}
198
}
199
200
void
201
mac_vnode_copy_label(struct label *src, struct label *dest)
202
{
203
204
MAC_POLICY_PERFORM_NOSLEEP(vnode_copy_label, src, dest);
205
}
206
207
int
208
mac_vnode_externalize_label(struct label *label, char *elements,
209
char *outbuf, size_t outbuflen)
210
{
211
int error;
212
213
MAC_POLICY_EXTERNALIZE(vnode, label, elements, outbuf, outbuflen);
214
215
return (error);
216
}
217
218
int
219
mac_vnode_internalize_label(struct label *label, char *string)
220
{
221
int error;
222
223
MAC_POLICY_INTERNALIZE(vnode, label, string);
224
225
return (error);
226
}
227
228
void
229
mac_devfs_update(struct mount *mp, struct devfs_dirent *de, struct vnode *vp)
230
{
231
232
MAC_POLICY_PERFORM_NOSLEEP(devfs_update, mp, de, de->de_label, vp,
233
vp->v_label);
234
}
235
236
void
237
mac_devfs_vnode_associate(struct mount *mp, struct devfs_dirent *de,
238
struct vnode *vp)
239
{
240
241
MAC_POLICY_PERFORM_NOSLEEP(devfs_vnode_associate, mp, mp->mnt_label,
242
de, de->de_label, vp, vp->v_label);
243
}
244
245
int
246
mac_vnode_associate_extattr(struct mount *mp, struct vnode *vp)
247
{
248
int error;
249
250
ASSERT_VOP_LOCKED(vp, "mac_vnode_associate_extattr");
251
252
MAC_POLICY_CHECK(vnode_associate_extattr, mp, mp->mnt_label, vp,
253
vp->v_label);
254
255
return (error);
256
}
257
258
void
259
mac_vnode_associate_singlelabel(struct mount *mp, struct vnode *vp)
260
{
261
262
MAC_POLICY_PERFORM_NOSLEEP(vnode_associate_singlelabel, mp,
263
mp->mnt_label, vp, vp->v_label);
264
}
265
266
/*
267
* Functions implementing extended-attribute backed labels for file systems
268
* that support it.
269
*
270
* Where possible, we use EA transactions to make writes to multiple
271
* attributes across difference policies mutually atomic. We allow work to
272
* continue on file systems not supporting EA transactions, but generate a
273
* printf warning.
274
*/
275
int
276
mac_vnode_create_extattr(struct ucred *cred, struct mount *mp,
277
struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
278
{
279
int error;
280
281
ASSERT_VOP_LOCKED(dvp, "mac_vnode_create_extattr");
282
ASSERT_VOP_LOCKED(vp, "mac_vnode_create_extattr");
283
284
error = VOP_OPENEXTATTR(vp, cred, curthread);
285
if (error == EOPNOTSUPP) {
286
if (ea_warn_once == 0) {
287
printf("Warning: transactions not supported "
288
"in EA write.\n");
289
ea_warn_once = 1;
290
}
291
} else if (error)
292
return (error);
293
294
MAC_POLICY_CHECK(vnode_create_extattr, cred, mp, mp->mnt_label, dvp,
295
dvp->v_label, vp, vp->v_label, cnp);
296
297
if (error) {
298
VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
299
return (error);
300
}
301
302
error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
303
if (error == EOPNOTSUPP)
304
error = 0;
305
306
return (error);
307
}
308
309
static int
310
mac_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp,
311
struct label *intlabel)
312
{
313
int error;
314
315
ASSERT_VOP_LOCKED(vp, "mac_vnode_setlabel_extattr");
316
317
error = VOP_OPENEXTATTR(vp, cred, curthread);
318
if (error == EOPNOTSUPP) {
319
if (ea_warn_once == 0) {
320
printf("Warning: transactions not supported "
321
"in EA write.\n");
322
ea_warn_once = 1;
323
}
324
} else if (error)
325
return (error);
326
327
MAC_POLICY_CHECK(vnode_setlabel_extattr, cred, vp, vp->v_label,
328
intlabel);
329
330
if (error) {
331
VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
332
return (error);
333
}
334
335
error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
336
if (error == EOPNOTSUPP)
337
error = 0;
338
339
return (error);
340
}
341
342
void
343
mac_vnode_execve_transition(struct ucred *old, struct ucred *new,
344
struct vnode *vp, struct label *interpvplabel, struct image_params *imgp)
345
{
346
347
ASSERT_VOP_LOCKED(vp, "mac_vnode_execve_transition");
348
349
MAC_POLICY_PERFORM(vnode_execve_transition, old, new, vp,
350
vp->v_label, interpvplabel, imgp, imgp->execlabel);
351
}
352
353
int
354
mac_vnode_execve_will_transition(struct ucred *old, struct vnode *vp,
355
struct label *interpvplabel, struct image_params *imgp)
356
{
357
int result;
358
359
ASSERT_VOP_LOCKED(vp, "mac_vnode_execve_will_transition");
360
361
result = 0;
362
/* No sleeping since the process lock will be held by the caller. */
363
MAC_POLICY_BOOLEAN_NOSLEEP(vnode_execve_will_transition, ||, old, vp,
364
vp->v_label, interpvplabel, imgp, imgp->execlabel);
365
366
return (result);
367
}
368
369
MAC_CHECK_PROBE_DEFINE3(vnode_check_access, "struct ucred *",
370
"struct vnode *", "accmode_t");
371
372
int
373
mac_vnode_check_access_impl(struct ucred *cred, struct vnode *vp, accmode_t accmode)
374
{
375
int error;
376
377
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_access");
378
379
MAC_POLICY_CHECK(vnode_check_access, cred, vp, vp->v_label, accmode);
380
MAC_CHECK_PROBE3(vnode_check_access, error, cred, vp, accmode);
381
382
return (error);
383
}
384
385
MAC_CHECK_PROBE_DEFINE2(vnode_check_chdir, "struct ucred *",
386
"struct vnode *");
387
388
int
389
mac_vnode_check_chdir(struct ucred *cred, struct vnode *dvp)
390
{
391
int error;
392
393
ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_chdir");
394
395
MAC_POLICY_CHECK(vnode_check_chdir, cred, dvp, dvp->v_label);
396
MAC_CHECK_PROBE2(vnode_check_chdir, error, cred, dvp);
397
398
return (error);
399
}
400
401
MAC_CHECK_PROBE_DEFINE2(vnode_check_chroot, "struct ucred *",
402
"struct vnode *");
403
404
int
405
mac_vnode_check_chroot(struct ucred *cred, struct vnode *dvp)
406
{
407
int error;
408
409
ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_chroot");
410
411
MAC_POLICY_CHECK(vnode_check_chroot, cred, dvp, dvp->v_label);
412
MAC_CHECK_PROBE2(vnode_check_chroot, error, cred, dvp);
413
414
return (error);
415
}
416
417
MAC_CHECK_PROBE_DEFINE4(vnode_check_create, "struct ucred *",
418
"struct vnode *", "struct componentname *", "struct vattr *");
419
420
int
421
mac_vnode_check_create(struct ucred *cred, struct vnode *dvp,
422
struct componentname *cnp, struct vattr *vap)
423
{
424
int error;
425
426
ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_create");
427
428
MAC_POLICY_CHECK(vnode_check_create, cred, dvp, dvp->v_label, cnp,
429
vap);
430
MAC_CHECK_PROBE4(vnode_check_create, error, cred, dvp, cnp, vap);
431
432
return (error);
433
}
434
435
MAC_CHECK_PROBE_DEFINE3(vnode_check_deleteacl, "struct ucred *",
436
"struct vnode *", "acl_type_t");
437
438
int
439
mac_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp,
440
acl_type_t type)
441
{
442
int error;
443
444
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_deleteacl");
445
446
MAC_POLICY_CHECK(vnode_check_deleteacl, cred, vp, vp->v_label, type);
447
MAC_CHECK_PROBE3(vnode_check_deleteacl, error, cred, vp, type);
448
449
return (error);
450
}
451
452
MAC_CHECK_PROBE_DEFINE4(vnode_check_deleteextattr, "struct ucred *",
453
"struct vnode *", "int", "const char *");
454
455
int
456
mac_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp,
457
int attrnamespace, const char *name)
458
{
459
int error;
460
461
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_deleteextattr");
462
463
MAC_POLICY_CHECK(vnode_check_deleteextattr, cred, vp, vp->v_label,
464
attrnamespace, name);
465
MAC_CHECK_PROBE4(vnode_check_deleteextattr, error, cred, vp,
466
attrnamespace, name);
467
468
return (error);
469
}
470
471
MAC_CHECK_PROBE_DEFINE3(vnode_check_exec, "struct ucred *", "struct vnode *",
472
"struct image_params *");
473
474
int
475
mac_vnode_check_exec(struct ucred *cred, struct vnode *vp,
476
struct image_params *imgp)
477
{
478
int error;
479
480
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_exec");
481
482
MAC_POLICY_CHECK(vnode_check_exec, cred, vp, vp->v_label, imgp,
483
imgp->execlabel);
484
MAC_CHECK_PROBE3(vnode_check_exec, error, cred, vp, imgp);
485
486
return (error);
487
}
488
489
MAC_CHECK_PROBE_DEFINE3(vnode_check_getacl, "struct ucred *",
490
"struct vnode *", "acl_type_t");
491
492
int
493
mac_vnode_check_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
494
{
495
int error;
496
497
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_getacl");
498
499
MAC_POLICY_CHECK(vnode_check_getacl, cred, vp, vp->v_label, type);
500
MAC_CHECK_PROBE3(vnode_check_getacl, error, cred, vp, type);
501
502
return (error);
503
}
504
505
MAC_CHECK_PROBE_DEFINE4(vnode_check_getextattr, "struct ucred *",
506
"struct vnode *", "int", "const char *");
507
508
int
509
mac_vnode_check_getextattr(struct ucred *cred, struct vnode *vp,
510
int attrnamespace, const char *name)
511
{
512
int error;
513
514
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_getextattr");
515
516
MAC_POLICY_CHECK(vnode_check_getextattr, cred, vp, vp->v_label,
517
attrnamespace, name);
518
MAC_CHECK_PROBE4(vnode_check_getextattr, error, cred, vp,
519
attrnamespace, name);
520
521
return (error);
522
}
523
524
MAC_CHECK_PROBE_DEFINE4(vnode_check_link, "struct ucred *", "struct vnode *",
525
"struct vnode *", "struct componentname *");
526
527
int
528
mac_vnode_check_link(struct ucred *cred, struct vnode *dvp,
529
struct vnode *vp, struct componentname *cnp)
530
{
531
int error;
532
533
ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_link");
534
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_link");
535
536
MAC_POLICY_CHECK(vnode_check_link, cred, dvp, dvp->v_label, vp,
537
vp->v_label, cnp);
538
MAC_CHECK_PROBE4(vnode_check_link, error, cred, dvp, vp, cnp);
539
540
return (error);
541
}
542
543
MAC_CHECK_PROBE_DEFINE3(vnode_check_listextattr, "struct ucred *",
544
"struct vnode *", "int");
545
546
int
547
mac_vnode_check_listextattr(struct ucred *cred, struct vnode *vp,
548
int attrnamespace)
549
{
550
int error;
551
552
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_listextattr");
553
554
MAC_POLICY_CHECK(vnode_check_listextattr, cred, vp, vp->v_label,
555
attrnamespace);
556
MAC_CHECK_PROBE3(vnode_check_listextattr, error, cred, vp,
557
attrnamespace);
558
559
return (error);
560
}
561
562
MAC_CHECK_PROBE_DEFINE3(vnode_check_lookup, "struct ucred *",
563
"struct vnode *", "struct componentname *");
564
565
int
566
mac_vnode_check_lookup_impl(struct ucred *cred, struct vnode *dvp,
567
struct componentname *cnp)
568
{
569
int error;
570
571
ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_lookup");
572
573
if ((cnp->cn_flags & NOMACCHECK) != 0)
574
return (0);
575
MAC_POLICY_CHECK(vnode_check_lookup, cred, dvp, dvp->v_label, cnp);
576
MAC_CHECK_PROBE3(vnode_check_lookup, error, cred, dvp, cnp);
577
578
return (error);
579
}
580
581
MAC_CHECK_PROBE_DEFINE4(vnode_check_mmap, "struct ucred *", "struct vnode *",
582
"int", "int");
583
584
int
585
mac_vnode_check_mmap_impl(struct ucred *cred, struct vnode *vp, int prot,
586
int flags)
587
{
588
int error;
589
590
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_mmap");
591
592
MAC_POLICY_CHECK(vnode_check_mmap, cred, vp, vp->v_label, prot, flags);
593
MAC_CHECK_PROBE4(vnode_check_mmap, error, cred, vp, prot, flags);
594
595
return (error);
596
}
597
598
void
599
mac_vnode_check_mmap_downgrade(struct ucred *cred, struct vnode *vp,
600
int *prot)
601
{
602
int result = *prot;
603
604
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_mmap_downgrade");
605
606
MAC_POLICY_PERFORM(vnode_check_mmap_downgrade, cred, vp, vp->v_label,
607
&result);
608
609
*prot = result;
610
}
611
612
MAC_CHECK_PROBE_DEFINE3(vnode_check_mprotect, "struct ucred *",
613
"struct vnode *", "int");
614
615
int
616
mac_vnode_check_mprotect(struct ucred *cred, struct vnode *vp, int prot)
617
{
618
int error;
619
620
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_mprotect");
621
622
MAC_POLICY_CHECK(vnode_check_mprotect, cred, vp, vp->v_label, prot);
623
MAC_CHECK_PROBE3(vnode_check_mprotect, error, cred, vp, prot);
624
625
return (error);
626
}
627
628
MAC_CHECK_PROBE_DEFINE3(vnode_check_open, "struct ucred *", "struct vnode *",
629
"accmode_t");
630
631
int
632
mac_vnode_check_open_impl(struct ucred *cred, struct vnode *vp, accmode_t accmode)
633
{
634
int error;
635
636
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_open");
637
638
MAC_POLICY_CHECK(vnode_check_open, cred, vp, vp->v_label, accmode);
639
MAC_CHECK_PROBE3(vnode_check_open, error, cred, vp, accmode);
640
641
return (error);
642
}
643
644
MAC_CHECK_PROBE_DEFINE3(vnode_check_poll, "struct ucred *", "struct ucred *",
645
"struct vnode *");
646
647
int
648
mac_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred,
649
struct vnode *vp)
650
{
651
int error;
652
653
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_poll");
654
655
MAC_POLICY_CHECK(vnode_check_poll, active_cred, file_cred, vp,
656
vp->v_label);
657
MAC_CHECK_PROBE3(vnode_check_poll, error, active_cred, file_cred,
658
vp);
659
660
return (error);
661
}
662
663
MAC_CHECK_PROBE_DEFINE3(vnode_check_read, "struct ucred *", "struct ucred *",
664
"struct vnode *");
665
666
int
667
mac_vnode_check_read_impl(struct ucred *active_cred, struct ucred *file_cred,
668
struct vnode *vp)
669
{
670
int error;
671
672
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_read");
673
674
MAC_POLICY_CHECK(vnode_check_read, active_cred, file_cred, vp,
675
vp->v_label);
676
MAC_CHECK_PROBE3(vnode_check_read, error, active_cred, file_cred,
677
vp);
678
679
return (error);
680
}
681
682
MAC_CHECK_PROBE_DEFINE2(vnode_check_readdir, "struct ucred *",
683
"struct vnode *");
684
685
int
686
mac_vnode_check_readdir(struct ucred *cred, struct vnode *dvp)
687
{
688
int error;
689
690
ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_readdir");
691
692
MAC_POLICY_CHECK(vnode_check_readdir, cred, dvp, dvp->v_label);
693
MAC_CHECK_PROBE2(vnode_check_readdir, error, cred, dvp);
694
695
return (error);
696
}
697
698
MAC_CHECK_PROBE_DEFINE2(vnode_check_readlink, "struct ucred *",
699
"struct vnode *");
700
701
int
702
mac_vnode_check_readlink_impl(struct ucred *cred, struct vnode *vp)
703
{
704
int error;
705
706
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_readlink");
707
708
MAC_POLICY_CHECK(vnode_check_readlink, cred, vp, vp->v_label);
709
MAC_CHECK_PROBE2(vnode_check_readlink, error, cred, vp);
710
711
return (error);
712
}
713
714
MAC_CHECK_PROBE_DEFINE3(vnode_check_relabel, "struct ucred *",
715
"struct vnode *", "struct label *");
716
717
static int
718
mac_vnode_check_relabel(struct ucred *cred, struct vnode *vp,
719
struct label *newlabel)
720
{
721
int error;
722
723
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_relabel");
724
725
MAC_POLICY_CHECK(vnode_check_relabel, cred, vp, vp->v_label, newlabel);
726
MAC_CHECK_PROBE3(vnode_check_relabel, error, cred, vp, newlabel);
727
728
return (error);
729
}
730
731
MAC_CHECK_PROBE_DEFINE4(vnode_check_rename_from, "struct ucred *",
732
"struct vnode *", "struct vnode *", "struct componentname *");
733
734
int
735
mac_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp,
736
struct vnode *vp, struct componentname *cnp)
737
{
738
int error;
739
740
ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_rename_from");
741
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_rename_from");
742
743
MAC_POLICY_CHECK(vnode_check_rename_from, cred, dvp, dvp->v_label, vp,
744
vp->v_label, cnp);
745
MAC_CHECK_PROBE4(vnode_check_rename_from, error, cred, dvp, vp, cnp);
746
747
return (error);
748
}
749
750
MAC_CHECK_PROBE_DEFINE4(vnode_check_rename_to, "struct ucred *",
751
"struct vnode *", "struct vnode *", "struct componentname *");
752
753
int
754
mac_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp,
755
struct vnode *vp, int samedir, struct componentname *cnp)
756
{
757
int error;
758
759
ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_rename_to");
760
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_rename_to");
761
762
MAC_POLICY_CHECK(vnode_check_rename_to, cred, dvp, dvp->v_label, vp,
763
vp != NULL ? vp->v_label : NULL, samedir, cnp);
764
MAC_CHECK_PROBE4(vnode_check_rename_to, error, cred, dvp, vp, cnp);
765
return (error);
766
}
767
768
MAC_CHECK_PROBE_DEFINE2(vnode_check_revoke, "struct ucred *",
769
"struct vnode *");
770
771
int
772
mac_vnode_check_revoke(struct ucred *cred, struct vnode *vp)
773
{
774
int error;
775
776
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_revoke");
777
778
MAC_POLICY_CHECK(vnode_check_revoke, cred, vp, vp->v_label);
779
MAC_CHECK_PROBE2(vnode_check_revoke, error, cred, vp);
780
781
return (error);
782
}
783
784
MAC_CHECK_PROBE_DEFINE4(vnode_check_setacl, "struct ucred *",
785
"struct vnode *", "acl_type_t", "struct acl *");
786
787
int
788
mac_vnode_check_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
789
struct acl *acl)
790
{
791
int error;
792
793
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setacl");
794
795
MAC_POLICY_CHECK(vnode_check_setacl, cred, vp, vp->v_label, type, acl);
796
MAC_CHECK_PROBE4(vnode_check_setacl, error, cred, vp, type, acl);
797
798
return (error);
799
}
800
801
MAC_CHECK_PROBE_DEFINE4(vnode_check_setextattr, "struct ucred *",
802
"struct vnode *", "int", "const char *");
803
804
int
805
mac_vnode_check_setextattr(struct ucred *cred, struct vnode *vp,
806
int attrnamespace, const char *name)
807
{
808
int error;
809
810
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setextattr");
811
812
MAC_POLICY_CHECK(vnode_check_setextattr, cred, vp, vp->v_label,
813
attrnamespace, name);
814
MAC_CHECK_PROBE4(vnode_check_setextattr, error, cred, vp,
815
attrnamespace, name);
816
817
return (error);
818
}
819
820
MAC_CHECK_PROBE_DEFINE3(vnode_check_setflags, "struct ucred *",
821
"struct vnode *", "u_long");
822
823
int
824
mac_vnode_check_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
825
{
826
int error;
827
828
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setflags");
829
830
MAC_POLICY_CHECK(vnode_check_setflags, cred, vp, vp->v_label, flags);
831
MAC_CHECK_PROBE3(vnode_check_setflags, error, cred, vp, flags);
832
833
return (error);
834
}
835
836
MAC_CHECK_PROBE_DEFINE3(vnode_check_setmode, "struct ucred *",
837
"struct vnode *", "mode_t");
838
839
int
840
mac_vnode_check_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
841
{
842
int error;
843
844
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setmode");
845
846
MAC_POLICY_CHECK(vnode_check_setmode, cred, vp, vp->v_label, mode);
847
MAC_CHECK_PROBE3(vnode_check_setmode, error, cred, vp, mode);
848
849
return (error);
850
}
851
852
MAC_CHECK_PROBE_DEFINE4(vnode_check_setowner, "struct ucred *",
853
"struct vnode *", "uid_t", "gid_t");
854
855
int
856
mac_vnode_check_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
857
gid_t gid)
858
{
859
int error;
860
861
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setowner");
862
863
MAC_POLICY_CHECK(vnode_check_setowner, cred, vp, vp->v_label, uid, gid);
864
MAC_CHECK_PROBE4(vnode_check_setowner, error, cred, vp, uid, gid);
865
866
return (error);
867
}
868
869
MAC_CHECK_PROBE_DEFINE4(vnode_check_setutimes, "struct ucred *",
870
"struct vnode *", "struct timespec *", "struct timespec *");
871
872
int
873
mac_vnode_check_setutimes(struct ucred *cred, struct vnode *vp,
874
struct timespec atime, struct timespec mtime)
875
{
876
int error;
877
878
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setutimes");
879
880
MAC_POLICY_CHECK(vnode_check_setutimes, cred, vp, vp->v_label, atime,
881
mtime);
882
MAC_CHECK_PROBE4(vnode_check_setutimes, error, cred, vp, &atime,
883
&mtime);
884
885
return (error);
886
}
887
888
MAC_CHECK_PROBE_DEFINE3(vnode_check_stat, "struct ucred *", "struct ucred *",
889
"struct vnode *");
890
891
int
892
mac_vnode_check_stat_impl(struct ucred *active_cred, struct ucred *file_cred,
893
struct vnode *vp)
894
{
895
int error;
896
897
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_stat");
898
899
MAC_POLICY_CHECK(vnode_check_stat, active_cred, file_cred, vp,
900
vp->v_label);
901
MAC_CHECK_PROBE3(vnode_check_stat, error, active_cred, file_cred,
902
vp);
903
904
return (error);
905
}
906
907
MAC_CHECK_PROBE_DEFINE4(vnode_check_unlink, "struct ucred *",
908
"struct vnode *", "struct vnode *", "struct componentname *");
909
910
int
911
mac_vnode_check_unlink(struct ucred *cred, struct vnode *dvp,
912
struct vnode *vp, struct componentname *cnp)
913
{
914
int error;
915
916
ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_unlink");
917
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_unlink");
918
919
MAC_POLICY_CHECK(vnode_check_unlink, cred, dvp, dvp->v_label, vp,
920
vp->v_label, cnp);
921
MAC_CHECK_PROBE4(vnode_check_unlink, error, cred, dvp, vp, cnp);
922
923
return (error);
924
}
925
926
MAC_CHECK_PROBE_DEFINE3(vnode_check_write, "struct ucred *",
927
"struct ucred *", "struct vnode *");
928
929
int
930
mac_vnode_check_write_impl(struct ucred *active_cred, struct ucred *file_cred,
931
struct vnode *vp)
932
{
933
int error;
934
935
ASSERT_VOP_LOCKED(vp, "mac_vnode_check_write");
936
937
MAC_POLICY_CHECK(vnode_check_write, active_cred, file_cred, vp,
938
vp->v_label);
939
MAC_CHECK_PROBE3(vnode_check_write, error, active_cred, file_cred,
940
vp);
941
942
return (error);
943
}
944
945
void
946
mac_vnode_relabel(struct ucred *cred, struct vnode *vp,
947
struct label *newlabel)
948
{
949
950
MAC_POLICY_PERFORM(vnode_relabel, cred, vp, vp->v_label, newlabel);
951
}
952
953
void
954
mac_mount_create(struct ucred *cred, struct mount *mp)
955
{
956
957
MAC_POLICY_PERFORM(mount_create, cred, mp, mp->mnt_label);
958
}
959
960
MAC_CHECK_PROBE_DEFINE2(mount_check_stat, "struct ucred *",
961
"struct mount *");
962
963
int
964
mac_mount_check_stat(struct ucred *cred, struct mount *mount)
965
{
966
int error;
967
968
MAC_POLICY_CHECK_NOSLEEP(mount_check_stat, cred, mount, mount->mnt_label);
969
MAC_CHECK_PROBE2(mount_check_stat, error, cred, mount);
970
971
return (error);
972
}
973
974
void
975
mac_devfs_create_device(struct ucred *cred, struct mount *mp,
976
struct cdev *dev, struct devfs_dirent *de)
977
{
978
979
MAC_POLICY_PERFORM_NOSLEEP(devfs_create_device, cred, mp, dev, de,
980
de->de_label);
981
}
982
983
void
984
mac_devfs_create_symlink(struct ucred *cred, struct mount *mp,
985
struct devfs_dirent *dd, struct devfs_dirent *de)
986
{
987
988
MAC_POLICY_PERFORM_NOSLEEP(devfs_create_symlink, cred, mp, dd,
989
dd->de_label, de, de->de_label);
990
}
991
992
void
993
mac_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen,
994
struct devfs_dirent *de)
995
{
996
997
MAC_POLICY_PERFORM_NOSLEEP(devfs_create_directory, mp, dirname,
998
dirnamelen, de, de->de_label);
999
}
1000
1001
/*
1002
* Implementation of VOP_SETLABEL() that relies on extended attributes to
1003
* store label data. Can be referenced by filesystems supporting extended
1004
* attributes.
1005
*/
1006
int
1007
vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
1008
{
1009
struct vnode *vp = ap->a_vp;
1010
struct label *intlabel = ap->a_label;
1011
int error;
1012
1013
ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
1014
1015
if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
1016
return (EOPNOTSUPP);
1017
1018
error = mac_vnode_setlabel_extattr(ap->a_cred, vp, intlabel);
1019
if (error)
1020
return (error);
1021
1022
/*
1023
* XXXRW: See the comment below in vn_setlabel() as to why this might
1024
* be the wrong place to call mac_vnode_relabel().
1025
*/
1026
mac_vnode_relabel(ap->a_cred, vp, intlabel);
1027
1028
return (0);
1029
}
1030
1031
int
1032
vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred)
1033
{
1034
int error;
1035
1036
if (vp->v_mount == NULL) {
1037
/* printf("vn_setlabel: null v_mount\n"); */
1038
if (vp->v_type != VNON)
1039
printf("vn_setlabel: null v_mount with non-VNON\n");
1040
return (EBADF);
1041
}
1042
1043
if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
1044
return (EOPNOTSUPP);
1045
1046
/*
1047
* Multi-phase commit. First check the policies to confirm the
1048
* change is OK. Then commit via the filesystem. Finally, update
1049
* the actual vnode label.
1050
*/
1051
error = mac_vnode_check_relabel(cred, vp, intlabel);
1052
if (error)
1053
return (error);
1054
1055
/*
1056
* VADMIN provides the opportunity for the filesystem to make
1057
* decisions about who is and is not able to modify labels and
1058
* protections on files. This might not be right. We can't assume
1059
* VOP_SETLABEL() will do it, because we might implement that as part
1060
* of vop_stdsetlabel_ea().
1061
*/
1062
error = VOP_ACCESS(vp, VADMIN, cred, curthread);
1063
if (error)
1064
return (error);
1065
1066
error = VOP_SETLABEL(vp, intlabel, cred, curthread);
1067
if (error)
1068
return (error);
1069
1070
/*
1071
* It would be more symmetric if mac_vnode_relabel() was called here
1072
* rather than in VOP_SETLABEL(), but we don't for historical reasons.
1073
* We should think about moving it so that the filesystem is
1074
* responsible only for persistence in VOP_SETLABEL(), not the vnode
1075
* label update itself.
1076
*/
1077
1078
return (0);
1079
}
1080
1081
#ifdef INVARIANTS
1082
void
1083
mac_vnode_assert_locked(struct vnode *vp, const char *func)
1084
{
1085
1086
ASSERT_VOP_LOCKED(vp, func);
1087
}
1088
#endif
1089
1090