Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/security/selinux/selinuxfs.c
26378 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/* Updated: Karl MacMillan <[email protected]>
3
*
4
* Added conditional policy language extensions
5
*
6
* Updated: Hewlett-Packard <[email protected]>
7
*
8
* Added support for the policy capability bitmap
9
*
10
* Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
11
* Copyright (C) 2003 - 2004 Tresys Technology, LLC
12
* Copyright (C) 2004 Red Hat, Inc., James Morris <[email protected]>
13
*/
14
15
#include <linux/kernel.h>
16
#include <linux/pagemap.h>
17
#include <linux/slab.h>
18
#include <linux/vmalloc.h>
19
#include <linux/fs.h>
20
#include <linux/fs_context.h>
21
#include <linux/mount.h>
22
#include <linux/mutex.h>
23
#include <linux/namei.h>
24
#include <linux/init.h>
25
#include <linux/string.h>
26
#include <linux/security.h>
27
#include <linux/major.h>
28
#include <linux/seq_file.h>
29
#include <linux/percpu.h>
30
#include <linux/audit.h>
31
#include <linux/uaccess.h>
32
#include <linux/kobject.h>
33
#include <linux/ctype.h>
34
35
/* selinuxfs pseudo filesystem for exporting the security policy API.
36
Based on the proc code and the fs/nfsd/nfsctl.c code. */
37
38
#include "flask.h"
39
#include "avc.h"
40
#include "avc_ss.h"
41
#include "security.h"
42
#include "objsec.h"
43
#include "conditional.h"
44
#include "ima.h"
45
46
enum sel_inos {
47
SEL_ROOT_INO = 2,
48
SEL_LOAD, /* load policy */
49
SEL_ENFORCE, /* get or set enforcing status */
50
SEL_CONTEXT, /* validate context */
51
SEL_ACCESS, /* compute access decision */
52
SEL_CREATE, /* compute create labeling decision */
53
SEL_RELABEL, /* compute relabeling decision */
54
SEL_USER, /* compute reachable user contexts */
55
SEL_POLICYVERS, /* return policy version for this kernel */
56
SEL_COMMIT_BOOLS, /* commit new boolean values */
57
SEL_MLS, /* return if MLS policy is enabled */
58
SEL_DISABLE, /* disable SELinux until next reboot */
59
SEL_MEMBER, /* compute polyinstantiation membership decision */
60
SEL_CHECKREQPROT, /* check requested protection, not kernel-applied one */
61
SEL_COMPAT_NET, /* whether to use old compat network packet controls */
62
SEL_REJECT_UNKNOWN, /* export unknown reject handling to userspace */
63
SEL_DENY_UNKNOWN, /* export unknown deny handling to userspace */
64
SEL_STATUS, /* export current status using mmap() */
65
SEL_POLICY, /* allow userspace to read the in kernel policy */
66
SEL_VALIDATE_TRANS, /* compute validatetrans decision */
67
SEL_INO_NEXT, /* The next inode number to use */
68
};
69
70
struct selinux_fs_info {
71
struct dentry *bool_dir;
72
unsigned int bool_num;
73
char **bool_pending_names;
74
int *bool_pending_values;
75
struct dentry *class_dir;
76
unsigned long last_class_ino;
77
bool policy_opened;
78
struct dentry *policycap_dir;
79
unsigned long last_ino;
80
struct super_block *sb;
81
};
82
83
static int selinux_fs_info_create(struct super_block *sb)
84
{
85
struct selinux_fs_info *fsi;
86
87
fsi = kzalloc(sizeof(*fsi), GFP_KERNEL);
88
if (!fsi)
89
return -ENOMEM;
90
91
fsi->last_ino = SEL_INO_NEXT - 1;
92
fsi->sb = sb;
93
sb->s_fs_info = fsi;
94
return 0;
95
}
96
97
static void selinux_fs_info_free(struct super_block *sb)
98
{
99
struct selinux_fs_info *fsi = sb->s_fs_info;
100
unsigned int i;
101
102
if (fsi) {
103
for (i = 0; i < fsi->bool_num; i++)
104
kfree(fsi->bool_pending_names[i]);
105
kfree(fsi->bool_pending_names);
106
kfree(fsi->bool_pending_values);
107
}
108
kfree(sb->s_fs_info);
109
sb->s_fs_info = NULL;
110
}
111
112
#define SEL_INITCON_INO_OFFSET 0x01000000
113
#define SEL_BOOL_INO_OFFSET 0x02000000
114
#define SEL_CLASS_INO_OFFSET 0x04000000
115
#define SEL_POLICYCAP_INO_OFFSET 0x08000000
116
#define SEL_INO_MASK 0x00ffffff
117
118
#define BOOL_DIR_NAME "booleans"
119
#define CLASS_DIR_NAME "class"
120
#define POLICYCAP_DIR_NAME "policy_capabilities"
121
122
#define TMPBUFLEN 12
123
static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
124
size_t count, loff_t *ppos)
125
{
126
char tmpbuf[TMPBUFLEN];
127
ssize_t length;
128
129
length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
130
enforcing_enabled());
131
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
132
}
133
134
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
135
static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
136
size_t count, loff_t *ppos)
137
138
{
139
char *page = NULL;
140
ssize_t length;
141
int scan_value;
142
bool old_value, new_value;
143
144
if (count >= PAGE_SIZE)
145
return -ENOMEM;
146
147
/* No partial writes. */
148
if (*ppos != 0)
149
return -EINVAL;
150
151
page = memdup_user_nul(buf, count);
152
if (IS_ERR(page))
153
return PTR_ERR(page);
154
155
length = -EINVAL;
156
if (sscanf(page, "%d", &scan_value) != 1)
157
goto out;
158
159
new_value = !!scan_value;
160
161
old_value = enforcing_enabled();
162
if (new_value != old_value) {
163
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
164
SECCLASS_SECURITY, SECURITY__SETENFORCE,
165
NULL);
166
if (length)
167
goto out;
168
audit_log(audit_context(), GFP_KERNEL, AUDIT_MAC_STATUS,
169
"enforcing=%d old_enforcing=%d auid=%u ses=%u"
170
" enabled=1 old-enabled=1 lsm=selinux res=1",
171
new_value, old_value,
172
from_kuid(&init_user_ns, audit_get_loginuid(current)),
173
audit_get_sessionid(current));
174
enforcing_set(new_value);
175
if (new_value)
176
avc_ss_reset(0);
177
selnl_notify_setenforce(new_value);
178
selinux_status_update_setenforce(new_value);
179
if (!new_value)
180
call_blocking_lsm_notifier(LSM_POLICY_CHANGE, NULL);
181
182
selinux_ima_measure_state();
183
}
184
length = count;
185
out:
186
kfree(page);
187
return length;
188
}
189
#else
190
#define sel_write_enforce NULL
191
#endif
192
193
static const struct file_operations sel_enforce_ops = {
194
.read = sel_read_enforce,
195
.write = sel_write_enforce,
196
.llseek = generic_file_llseek,
197
};
198
199
static ssize_t sel_read_handle_unknown(struct file *filp, char __user *buf,
200
size_t count, loff_t *ppos)
201
{
202
char tmpbuf[TMPBUFLEN];
203
ssize_t length;
204
ino_t ino = file_inode(filp)->i_ino;
205
int handle_unknown = (ino == SEL_REJECT_UNKNOWN) ?
206
security_get_reject_unknown() :
207
!security_get_allow_unknown();
208
209
length = scnprintf(tmpbuf, TMPBUFLEN, "%d", handle_unknown);
210
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
211
}
212
213
static const struct file_operations sel_handle_unknown_ops = {
214
.read = sel_read_handle_unknown,
215
.llseek = generic_file_llseek,
216
};
217
218
static int sel_open_handle_status(struct inode *inode, struct file *filp)
219
{
220
struct page *status = selinux_kernel_status_page();
221
222
if (!status)
223
return -ENOMEM;
224
225
filp->private_data = status;
226
227
return 0;
228
}
229
230
static ssize_t sel_read_handle_status(struct file *filp, char __user *buf,
231
size_t count, loff_t *ppos)
232
{
233
struct page *status = filp->private_data;
234
235
BUG_ON(!status);
236
237
return simple_read_from_buffer(buf, count, ppos,
238
page_address(status),
239
sizeof(struct selinux_kernel_status));
240
}
241
242
static int sel_mmap_handle_status(struct file *filp,
243
struct vm_area_struct *vma)
244
{
245
struct page *status = filp->private_data;
246
unsigned long size = vma->vm_end - vma->vm_start;
247
248
BUG_ON(!status);
249
250
/* only allows one page from the head */
251
if (vma->vm_pgoff > 0 || size != PAGE_SIZE)
252
return -EIO;
253
/* disallow writable mapping */
254
if (vma->vm_flags & VM_WRITE)
255
return -EPERM;
256
/* disallow mprotect() turns it into writable */
257
vm_flags_clear(vma, VM_MAYWRITE);
258
259
return remap_pfn_range(vma, vma->vm_start,
260
page_to_pfn(status),
261
size, vma->vm_page_prot);
262
}
263
264
static const struct file_operations sel_handle_status_ops = {
265
.open = sel_open_handle_status,
266
.read = sel_read_handle_status,
267
.mmap = sel_mmap_handle_status,
268
.llseek = generic_file_llseek,
269
};
270
271
static ssize_t sel_write_disable(struct file *file, const char __user *buf,
272
size_t count, loff_t *ppos)
273
274
{
275
char *page;
276
ssize_t length;
277
int new_value;
278
279
if (count >= PAGE_SIZE)
280
return -ENOMEM;
281
282
/* No partial writes. */
283
if (*ppos != 0)
284
return -EINVAL;
285
286
page = memdup_user_nul(buf, count);
287
if (IS_ERR(page))
288
return PTR_ERR(page);
289
290
if (sscanf(page, "%d", &new_value) != 1) {
291
length = -EINVAL;
292
goto out;
293
}
294
length = count;
295
296
if (new_value) {
297
pr_err("SELinux: https://github.com/SELinuxProject/selinux-kernel/wiki/DEPRECATE-runtime-disable\n");
298
pr_err("SELinux: Runtime disable is not supported, use selinux=0 on the kernel cmdline.\n");
299
}
300
301
out:
302
kfree(page);
303
return length;
304
}
305
306
static const struct file_operations sel_disable_ops = {
307
.write = sel_write_disable,
308
.llseek = generic_file_llseek,
309
};
310
311
static ssize_t sel_read_policyvers(struct file *filp, char __user *buf,
312
size_t count, loff_t *ppos)
313
{
314
char tmpbuf[TMPBUFLEN];
315
ssize_t length;
316
317
length = scnprintf(tmpbuf, TMPBUFLEN, "%u", POLICYDB_VERSION_MAX);
318
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
319
}
320
321
static const struct file_operations sel_policyvers_ops = {
322
.read = sel_read_policyvers,
323
.llseek = generic_file_llseek,
324
};
325
326
/* declaration for sel_write_load */
327
static int sel_make_bools(struct selinux_policy *newpolicy, struct dentry *bool_dir,
328
unsigned int *bool_num, char ***bool_pending_names,
329
int **bool_pending_values);
330
static int sel_make_classes(struct selinux_policy *newpolicy,
331
struct dentry *class_dir,
332
unsigned long *last_class_ino);
333
334
/* declaration for sel_make_class_dirs */
335
static struct dentry *sel_make_dir(struct dentry *dir, const char *name,
336
unsigned long *ino);
337
338
/* declaration for sel_make_policy_nodes */
339
static struct dentry *sel_make_swapover_dir(struct super_block *sb,
340
unsigned long *ino);
341
342
static ssize_t sel_read_mls(struct file *filp, char __user *buf,
343
size_t count, loff_t *ppos)
344
{
345
char tmpbuf[TMPBUFLEN];
346
ssize_t length;
347
348
length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
349
security_mls_enabled());
350
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
351
}
352
353
static const struct file_operations sel_mls_ops = {
354
.read = sel_read_mls,
355
.llseek = generic_file_llseek,
356
};
357
358
struct policy_load_memory {
359
size_t len;
360
void *data;
361
};
362
363
static int sel_open_policy(struct inode *inode, struct file *filp)
364
{
365
struct selinux_fs_info *fsi = inode->i_sb->s_fs_info;
366
struct policy_load_memory *plm = NULL;
367
int rc;
368
369
BUG_ON(filp->private_data);
370
371
mutex_lock(&selinux_state.policy_mutex);
372
373
rc = avc_has_perm(current_sid(), SECINITSID_SECURITY,
374
SECCLASS_SECURITY, SECURITY__READ_POLICY, NULL);
375
if (rc)
376
goto err;
377
378
rc = -EBUSY;
379
if (fsi->policy_opened)
380
goto err;
381
382
rc = -ENOMEM;
383
plm = kzalloc(sizeof(*plm), GFP_KERNEL);
384
if (!plm)
385
goto err;
386
387
rc = security_read_policy(&plm->data, &plm->len);
388
if (rc)
389
goto err;
390
391
if ((size_t)i_size_read(inode) != plm->len) {
392
inode_lock(inode);
393
i_size_write(inode, plm->len);
394
inode_unlock(inode);
395
}
396
397
fsi->policy_opened = 1;
398
399
filp->private_data = plm;
400
401
mutex_unlock(&selinux_state.policy_mutex);
402
403
return 0;
404
err:
405
mutex_unlock(&selinux_state.policy_mutex);
406
407
if (plm)
408
vfree(plm->data);
409
kfree(plm);
410
return rc;
411
}
412
413
static int sel_release_policy(struct inode *inode, struct file *filp)
414
{
415
struct selinux_fs_info *fsi = inode->i_sb->s_fs_info;
416
struct policy_load_memory *plm = filp->private_data;
417
418
BUG_ON(!plm);
419
420
fsi->policy_opened = 0;
421
422
vfree(plm->data);
423
kfree(plm);
424
425
return 0;
426
}
427
428
static ssize_t sel_read_policy(struct file *filp, char __user *buf,
429
size_t count, loff_t *ppos)
430
{
431
struct policy_load_memory *plm = filp->private_data;
432
int ret;
433
434
ret = avc_has_perm(current_sid(), SECINITSID_SECURITY,
435
SECCLASS_SECURITY, SECURITY__READ_POLICY, NULL);
436
if (ret)
437
return ret;
438
439
return simple_read_from_buffer(buf, count, ppos, plm->data, plm->len);
440
}
441
442
static vm_fault_t sel_mmap_policy_fault(struct vm_fault *vmf)
443
{
444
struct policy_load_memory *plm = vmf->vma->vm_file->private_data;
445
unsigned long offset;
446
struct page *page;
447
448
if (vmf->flags & (FAULT_FLAG_MKWRITE | FAULT_FLAG_WRITE))
449
return VM_FAULT_SIGBUS;
450
451
offset = vmf->pgoff << PAGE_SHIFT;
452
if (offset >= roundup(plm->len, PAGE_SIZE))
453
return VM_FAULT_SIGBUS;
454
455
page = vmalloc_to_page(plm->data + offset);
456
get_page(page);
457
458
vmf->page = page;
459
460
return 0;
461
}
462
463
static const struct vm_operations_struct sel_mmap_policy_ops = {
464
.fault = sel_mmap_policy_fault,
465
.page_mkwrite = sel_mmap_policy_fault,
466
};
467
468
static int sel_mmap_policy(struct file *filp, struct vm_area_struct *vma)
469
{
470
if (vma->vm_flags & VM_SHARED) {
471
/* do not allow mprotect to make mapping writable */
472
vm_flags_clear(vma, VM_MAYWRITE);
473
474
if (vma->vm_flags & VM_WRITE)
475
return -EACCES;
476
}
477
478
vm_flags_set(vma, VM_DONTEXPAND | VM_DONTDUMP);
479
vma->vm_ops = &sel_mmap_policy_ops;
480
481
return 0;
482
}
483
484
static const struct file_operations sel_policy_ops = {
485
.open = sel_open_policy,
486
.read = sel_read_policy,
487
.mmap = sel_mmap_policy,
488
.release = sel_release_policy,
489
.llseek = generic_file_llseek,
490
};
491
492
static void sel_remove_old_bool_data(unsigned int bool_num, char **bool_names,
493
int *bool_values)
494
{
495
u32 i;
496
497
/* bool_dir cleanup */
498
for (i = 0; i < bool_num; i++)
499
kfree(bool_names[i]);
500
kfree(bool_names);
501
kfree(bool_values);
502
}
503
504
static int sel_make_policy_nodes(struct selinux_fs_info *fsi,
505
struct selinux_policy *newpolicy)
506
{
507
int ret = 0;
508
struct dentry *tmp_parent, *tmp_bool_dir, *tmp_class_dir;
509
unsigned int bool_num = 0;
510
char **bool_names = NULL;
511
int *bool_values = NULL;
512
unsigned long tmp_ino = fsi->last_ino; /* Don't increment last_ino in this function */
513
514
tmp_parent = sel_make_swapover_dir(fsi->sb, &tmp_ino);
515
if (IS_ERR(tmp_parent))
516
return PTR_ERR(tmp_parent);
517
518
tmp_ino = fsi->bool_dir->d_inode->i_ino - 1; /* sel_make_dir will increment and set */
519
tmp_bool_dir = sel_make_dir(tmp_parent, BOOL_DIR_NAME, &tmp_ino);
520
if (IS_ERR(tmp_bool_dir)) {
521
ret = PTR_ERR(tmp_bool_dir);
522
goto out;
523
}
524
525
tmp_ino = fsi->class_dir->d_inode->i_ino - 1; /* sel_make_dir will increment and set */
526
tmp_class_dir = sel_make_dir(tmp_parent, CLASS_DIR_NAME, &tmp_ino);
527
if (IS_ERR(tmp_class_dir)) {
528
ret = PTR_ERR(tmp_class_dir);
529
goto out;
530
}
531
532
ret = sel_make_bools(newpolicy, tmp_bool_dir, &bool_num,
533
&bool_names, &bool_values);
534
if (ret)
535
goto out;
536
537
ret = sel_make_classes(newpolicy, tmp_class_dir,
538
&fsi->last_class_ino);
539
if (ret)
540
goto out;
541
542
lock_rename(tmp_parent, fsi->sb->s_root);
543
544
/* booleans */
545
d_exchange(tmp_bool_dir, fsi->bool_dir);
546
547
swap(fsi->bool_num, bool_num);
548
swap(fsi->bool_pending_names, bool_names);
549
swap(fsi->bool_pending_values, bool_values);
550
551
fsi->bool_dir = tmp_bool_dir;
552
553
/* classes */
554
d_exchange(tmp_class_dir, fsi->class_dir);
555
fsi->class_dir = tmp_class_dir;
556
557
unlock_rename(tmp_parent, fsi->sb->s_root);
558
559
out:
560
sel_remove_old_bool_data(bool_num, bool_names, bool_values);
561
/* Since the other temporary dirs are children of tmp_parent
562
* this will handle all the cleanup in the case of a failure before
563
* the swapover
564
*/
565
simple_recursive_removal(tmp_parent, NULL);
566
567
return ret;
568
}
569
570
static ssize_t sel_write_load(struct file *file, const char __user *buf,
571
size_t count, loff_t *ppos)
572
573
{
574
struct selinux_fs_info *fsi;
575
struct selinux_load_state load_state;
576
ssize_t length;
577
void *data = NULL;
578
579
/* no partial writes */
580
if (*ppos)
581
return -EINVAL;
582
/* no empty policies */
583
if (!count)
584
return -EINVAL;
585
586
mutex_lock(&selinux_state.policy_mutex);
587
588
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
589
SECCLASS_SECURITY, SECURITY__LOAD_POLICY, NULL);
590
if (length)
591
goto out;
592
593
data = vmalloc(count);
594
if (!data) {
595
length = -ENOMEM;
596
goto out;
597
}
598
if (copy_from_user(data, buf, count) != 0) {
599
length = -EFAULT;
600
goto out;
601
}
602
603
length = security_load_policy(data, count, &load_state);
604
if (length) {
605
pr_warn_ratelimited("SELinux: failed to load policy\n");
606
goto out;
607
}
608
fsi = file_inode(file)->i_sb->s_fs_info;
609
length = sel_make_policy_nodes(fsi, load_state.policy);
610
if (length) {
611
pr_warn_ratelimited("SELinux: failed to initialize selinuxfs\n");
612
selinux_policy_cancel(&load_state);
613
goto out;
614
}
615
616
selinux_policy_commit(&load_state);
617
length = count;
618
audit_log(audit_context(), GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
619
"auid=%u ses=%u lsm=selinux res=1",
620
from_kuid(&init_user_ns, audit_get_loginuid(current)),
621
audit_get_sessionid(current));
622
623
out:
624
mutex_unlock(&selinux_state.policy_mutex);
625
vfree(data);
626
return length;
627
}
628
629
static const struct file_operations sel_load_ops = {
630
.write = sel_write_load,
631
.llseek = generic_file_llseek,
632
};
633
634
static ssize_t sel_write_context(struct file *file, char *buf, size_t size)
635
{
636
char *canon = NULL;
637
u32 sid, len;
638
ssize_t length;
639
640
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
641
SECCLASS_SECURITY, SECURITY__CHECK_CONTEXT, NULL);
642
if (length)
643
goto out;
644
645
length = security_context_to_sid(buf, size, &sid, GFP_KERNEL);
646
if (length)
647
goto out;
648
649
length = security_sid_to_context(sid, &canon, &len);
650
if (length)
651
goto out;
652
653
length = -ERANGE;
654
if (len > SIMPLE_TRANSACTION_LIMIT) {
655
pr_err("SELinux: %s: context size (%u) exceeds "
656
"payload max\n", __func__, len);
657
goto out;
658
}
659
660
memcpy(buf, canon, len);
661
length = len;
662
out:
663
kfree(canon);
664
return length;
665
}
666
667
static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
668
size_t count, loff_t *ppos)
669
{
670
char tmpbuf[TMPBUFLEN];
671
ssize_t length;
672
673
length = scnprintf(tmpbuf, TMPBUFLEN, "%u",
674
checkreqprot_get());
675
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
676
}
677
678
static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
679
size_t count, loff_t *ppos)
680
{
681
char *page;
682
ssize_t length;
683
unsigned int new_value;
684
685
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
686
SECCLASS_SECURITY, SECURITY__SETCHECKREQPROT,
687
NULL);
688
if (length)
689
return length;
690
691
if (count >= PAGE_SIZE)
692
return -ENOMEM;
693
694
/* No partial writes. */
695
if (*ppos != 0)
696
return -EINVAL;
697
698
page = memdup_user_nul(buf, count);
699
if (IS_ERR(page))
700
return PTR_ERR(page);
701
702
if (sscanf(page, "%u", &new_value) != 1) {
703
length = -EINVAL;
704
goto out;
705
}
706
length = count;
707
708
if (new_value) {
709
char comm[sizeof(current->comm)];
710
711
strscpy(comm, current->comm);
712
pr_err("SELinux: %s (%d) set checkreqprot to 1. This is no longer supported.\n",
713
comm, current->pid);
714
}
715
716
selinux_ima_measure_state();
717
718
out:
719
kfree(page);
720
return length;
721
}
722
static const struct file_operations sel_checkreqprot_ops = {
723
.read = sel_read_checkreqprot,
724
.write = sel_write_checkreqprot,
725
.llseek = generic_file_llseek,
726
};
727
728
static ssize_t sel_write_validatetrans(struct file *file,
729
const char __user *buf,
730
size_t count, loff_t *ppos)
731
{
732
char *oldcon = NULL, *newcon = NULL, *taskcon = NULL;
733
char *req = NULL;
734
u32 osid, nsid, tsid;
735
u16 tclass;
736
int rc;
737
738
rc = avc_has_perm(current_sid(), SECINITSID_SECURITY,
739
SECCLASS_SECURITY, SECURITY__VALIDATE_TRANS, NULL);
740
if (rc)
741
goto out;
742
743
rc = -ENOMEM;
744
if (count >= PAGE_SIZE)
745
goto out;
746
747
/* No partial writes. */
748
rc = -EINVAL;
749
if (*ppos != 0)
750
goto out;
751
752
req = memdup_user_nul(buf, count);
753
if (IS_ERR(req)) {
754
rc = PTR_ERR(req);
755
req = NULL;
756
goto out;
757
}
758
759
rc = -ENOMEM;
760
oldcon = kzalloc(count + 1, GFP_KERNEL);
761
if (!oldcon)
762
goto out;
763
764
newcon = kzalloc(count + 1, GFP_KERNEL);
765
if (!newcon)
766
goto out;
767
768
taskcon = kzalloc(count + 1, GFP_KERNEL);
769
if (!taskcon)
770
goto out;
771
772
rc = -EINVAL;
773
if (sscanf(req, "%s %s %hu %s", oldcon, newcon, &tclass, taskcon) != 4)
774
goto out;
775
776
rc = security_context_str_to_sid(oldcon, &osid, GFP_KERNEL);
777
if (rc)
778
goto out;
779
780
rc = security_context_str_to_sid(newcon, &nsid, GFP_KERNEL);
781
if (rc)
782
goto out;
783
784
rc = security_context_str_to_sid(taskcon, &tsid, GFP_KERNEL);
785
if (rc)
786
goto out;
787
788
rc = security_validate_transition_user(osid, nsid, tsid, tclass);
789
if (!rc)
790
rc = count;
791
out:
792
kfree(req);
793
kfree(oldcon);
794
kfree(newcon);
795
kfree(taskcon);
796
return rc;
797
}
798
799
static const struct file_operations sel_transition_ops = {
800
.write = sel_write_validatetrans,
801
.llseek = generic_file_llseek,
802
};
803
804
/*
805
* Remaining nodes use transaction based IO methods like nfsd/nfsctl.c
806
*/
807
static ssize_t sel_write_access(struct file *file, char *buf, size_t size);
808
static ssize_t sel_write_create(struct file *file, char *buf, size_t size);
809
static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size);
810
static ssize_t sel_write_user(struct file *file, char *buf, size_t size);
811
static ssize_t sel_write_member(struct file *file, char *buf, size_t size);
812
813
static ssize_t (*const write_op[])(struct file *, char *, size_t) = {
814
[SEL_ACCESS] = sel_write_access,
815
[SEL_CREATE] = sel_write_create,
816
[SEL_RELABEL] = sel_write_relabel,
817
[SEL_USER] = sel_write_user,
818
[SEL_MEMBER] = sel_write_member,
819
[SEL_CONTEXT] = sel_write_context,
820
};
821
822
static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
823
{
824
ino_t ino = file_inode(file)->i_ino;
825
char *data;
826
ssize_t rv;
827
828
if (ino >= ARRAY_SIZE(write_op) || !write_op[ino])
829
return -EINVAL;
830
831
data = simple_transaction_get(file, buf, size);
832
if (IS_ERR(data))
833
return PTR_ERR(data);
834
835
rv = write_op[ino](file, data, size);
836
if (rv > 0) {
837
simple_transaction_set(file, rv);
838
rv = size;
839
}
840
return rv;
841
}
842
843
static const struct file_operations transaction_ops = {
844
.write = selinux_transaction_write,
845
.read = simple_transaction_read,
846
.release = simple_transaction_release,
847
.llseek = generic_file_llseek,
848
};
849
850
/*
851
* payload - write methods
852
* If the method has a response, the response should be put in buf,
853
* and the length returned. Otherwise return 0 or and -error.
854
*/
855
856
static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
857
{
858
char *scon = NULL, *tcon = NULL;
859
u32 ssid, tsid;
860
u16 tclass;
861
struct av_decision avd;
862
ssize_t length;
863
864
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
865
SECCLASS_SECURITY, SECURITY__COMPUTE_AV, NULL);
866
if (length)
867
goto out;
868
869
length = -ENOMEM;
870
scon = kzalloc(size + 1, GFP_KERNEL);
871
if (!scon)
872
goto out;
873
874
length = -ENOMEM;
875
tcon = kzalloc(size + 1, GFP_KERNEL);
876
if (!tcon)
877
goto out;
878
879
length = -EINVAL;
880
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
881
goto out;
882
883
length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL);
884
if (length)
885
goto out;
886
887
length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL);
888
if (length)
889
goto out;
890
891
security_compute_av_user(ssid, tsid, tclass, &avd);
892
893
length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT,
894
"%x %x %x %x %u %x",
895
avd.allowed, 0xffffffff,
896
avd.auditallow, avd.auditdeny,
897
avd.seqno, avd.flags);
898
out:
899
kfree(tcon);
900
kfree(scon);
901
return length;
902
}
903
904
static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
905
{
906
char *scon = NULL, *tcon = NULL;
907
char *namebuf = NULL, *objname = NULL;
908
u32 ssid, tsid, newsid;
909
u16 tclass;
910
ssize_t length;
911
char *newcon = NULL;
912
u32 len;
913
int nargs;
914
915
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
916
SECCLASS_SECURITY, SECURITY__COMPUTE_CREATE,
917
NULL);
918
if (length)
919
goto out;
920
921
length = -ENOMEM;
922
scon = kzalloc(size + 1, GFP_KERNEL);
923
if (!scon)
924
goto out;
925
926
length = -ENOMEM;
927
tcon = kzalloc(size + 1, GFP_KERNEL);
928
if (!tcon)
929
goto out;
930
931
length = -ENOMEM;
932
namebuf = kzalloc(size + 1, GFP_KERNEL);
933
if (!namebuf)
934
goto out;
935
936
length = -EINVAL;
937
nargs = sscanf(buf, "%s %s %hu %s", scon, tcon, &tclass, namebuf);
938
if (nargs < 3 || nargs > 4)
939
goto out;
940
if (nargs == 4) {
941
/*
942
* If and when the name of new object to be queried contains
943
* either whitespace or multibyte characters, they shall be
944
* encoded based on the percentage-encoding rule.
945
* If not encoded, the sscanf logic picks up only left-half
946
* of the supplied name; split by a whitespace unexpectedly.
947
*/
948
char *r, *w;
949
int c1, c2;
950
951
r = w = namebuf;
952
do {
953
c1 = *r++;
954
if (c1 == '+')
955
c1 = ' ';
956
else if (c1 == '%') {
957
c1 = hex_to_bin(*r++);
958
if (c1 < 0)
959
goto out;
960
c2 = hex_to_bin(*r++);
961
if (c2 < 0)
962
goto out;
963
c1 = (c1 << 4) | c2;
964
}
965
*w++ = c1;
966
} while (c1 != '\0');
967
968
objname = namebuf;
969
}
970
971
length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL);
972
if (length)
973
goto out;
974
975
length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL);
976
if (length)
977
goto out;
978
979
length = security_transition_sid_user(ssid, tsid, tclass,
980
objname, &newsid);
981
if (length)
982
goto out;
983
984
length = security_sid_to_context(newsid, &newcon, &len);
985
if (length)
986
goto out;
987
988
length = -ERANGE;
989
if (len > SIMPLE_TRANSACTION_LIMIT) {
990
pr_err("SELinux: %s: context size (%u) exceeds "
991
"payload max\n", __func__, len);
992
goto out;
993
}
994
995
memcpy(buf, newcon, len);
996
length = len;
997
out:
998
kfree(newcon);
999
kfree(namebuf);
1000
kfree(tcon);
1001
kfree(scon);
1002
return length;
1003
}
1004
1005
static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
1006
{
1007
char *scon = NULL, *tcon = NULL;
1008
u32 ssid, tsid, newsid;
1009
u16 tclass;
1010
ssize_t length;
1011
char *newcon = NULL;
1012
u32 len;
1013
1014
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
1015
SECCLASS_SECURITY, SECURITY__COMPUTE_RELABEL,
1016
NULL);
1017
if (length)
1018
goto out;
1019
1020
length = -ENOMEM;
1021
scon = kzalloc(size + 1, GFP_KERNEL);
1022
if (!scon)
1023
goto out;
1024
1025
length = -ENOMEM;
1026
tcon = kzalloc(size + 1, GFP_KERNEL);
1027
if (!tcon)
1028
goto out;
1029
1030
length = -EINVAL;
1031
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
1032
goto out;
1033
1034
length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL);
1035
if (length)
1036
goto out;
1037
1038
length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL);
1039
if (length)
1040
goto out;
1041
1042
length = security_change_sid(ssid, tsid, tclass, &newsid);
1043
if (length)
1044
goto out;
1045
1046
length = security_sid_to_context(newsid, &newcon, &len);
1047
if (length)
1048
goto out;
1049
1050
length = -ERANGE;
1051
if (len > SIMPLE_TRANSACTION_LIMIT)
1052
goto out;
1053
1054
memcpy(buf, newcon, len);
1055
length = len;
1056
out:
1057
kfree(newcon);
1058
kfree(tcon);
1059
kfree(scon);
1060
return length;
1061
}
1062
1063
static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
1064
{
1065
char *con = NULL, *user = NULL, *ptr;
1066
u32 sid, *sids = NULL;
1067
ssize_t length;
1068
char *newcon;
1069
int rc;
1070
u32 i, len, nsids;
1071
1072
pr_warn_ratelimited("SELinux: %s (%d) wrote to /sys/fs/selinux/user!"
1073
" This will not be supported in the future; please update your"
1074
" userspace.\n", current->comm, current->pid);
1075
ssleep(5);
1076
1077
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
1078
SECCLASS_SECURITY, SECURITY__COMPUTE_USER,
1079
NULL);
1080
if (length)
1081
goto out;
1082
1083
length = -ENOMEM;
1084
con = kzalloc(size + 1, GFP_KERNEL);
1085
if (!con)
1086
goto out;
1087
1088
length = -ENOMEM;
1089
user = kzalloc(size + 1, GFP_KERNEL);
1090
if (!user)
1091
goto out;
1092
1093
length = -EINVAL;
1094
if (sscanf(buf, "%s %s", con, user) != 2)
1095
goto out;
1096
1097
length = security_context_str_to_sid(con, &sid, GFP_KERNEL);
1098
if (length)
1099
goto out;
1100
1101
length = security_get_user_sids(sid, user, &sids, &nsids);
1102
if (length)
1103
goto out;
1104
1105
length = sprintf(buf, "%u", nsids) + 1;
1106
ptr = buf + length;
1107
for (i = 0; i < nsids; i++) {
1108
rc = security_sid_to_context(sids[i], &newcon, &len);
1109
if (rc) {
1110
length = rc;
1111
goto out;
1112
}
1113
if ((length + len) >= SIMPLE_TRANSACTION_LIMIT) {
1114
kfree(newcon);
1115
length = -ERANGE;
1116
goto out;
1117
}
1118
memcpy(ptr, newcon, len);
1119
kfree(newcon);
1120
ptr += len;
1121
length += len;
1122
}
1123
out:
1124
kfree(sids);
1125
kfree(user);
1126
kfree(con);
1127
return length;
1128
}
1129
1130
static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
1131
{
1132
char *scon = NULL, *tcon = NULL;
1133
u32 ssid, tsid, newsid;
1134
u16 tclass;
1135
ssize_t length;
1136
char *newcon = NULL;
1137
u32 len;
1138
1139
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
1140
SECCLASS_SECURITY, SECURITY__COMPUTE_MEMBER,
1141
NULL);
1142
if (length)
1143
goto out;
1144
1145
length = -ENOMEM;
1146
scon = kzalloc(size + 1, GFP_KERNEL);
1147
if (!scon)
1148
goto out;
1149
1150
length = -ENOMEM;
1151
tcon = kzalloc(size + 1, GFP_KERNEL);
1152
if (!tcon)
1153
goto out;
1154
1155
length = -EINVAL;
1156
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
1157
goto out;
1158
1159
length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL);
1160
if (length)
1161
goto out;
1162
1163
length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL);
1164
if (length)
1165
goto out;
1166
1167
length = security_member_sid(ssid, tsid, tclass, &newsid);
1168
if (length)
1169
goto out;
1170
1171
length = security_sid_to_context(newsid, &newcon, &len);
1172
if (length)
1173
goto out;
1174
1175
length = -ERANGE;
1176
if (len > SIMPLE_TRANSACTION_LIMIT) {
1177
pr_err("SELinux: %s: context size (%u) exceeds "
1178
"payload max\n", __func__, len);
1179
goto out;
1180
}
1181
1182
memcpy(buf, newcon, len);
1183
length = len;
1184
out:
1185
kfree(newcon);
1186
kfree(tcon);
1187
kfree(scon);
1188
return length;
1189
}
1190
1191
static struct inode *sel_make_inode(struct super_block *sb, umode_t mode)
1192
{
1193
struct inode *ret = new_inode(sb);
1194
1195
if (ret) {
1196
ret->i_mode = mode;
1197
simple_inode_init_ts(ret);
1198
}
1199
return ret;
1200
}
1201
1202
static ssize_t sel_read_bool(struct file *filep, char __user *buf,
1203
size_t count, loff_t *ppos)
1204
{
1205
struct selinux_fs_info *fsi = file_inode(filep)->i_sb->s_fs_info;
1206
char *page = NULL;
1207
ssize_t length;
1208
ssize_t ret;
1209
int cur_enforcing;
1210
unsigned index = file_inode(filep)->i_ino & SEL_INO_MASK;
1211
const char *name = filep->f_path.dentry->d_name.name;
1212
1213
mutex_lock(&selinux_state.policy_mutex);
1214
1215
ret = -EINVAL;
1216
if (index >= fsi->bool_num || strcmp(name,
1217
fsi->bool_pending_names[index]))
1218
goto out_unlock;
1219
1220
ret = -ENOMEM;
1221
page = (char *)get_zeroed_page(GFP_KERNEL);
1222
if (!page)
1223
goto out_unlock;
1224
1225
cur_enforcing = security_get_bool_value(index);
1226
if (cur_enforcing < 0) {
1227
ret = cur_enforcing;
1228
goto out_unlock;
1229
}
1230
length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing,
1231
fsi->bool_pending_values[index]);
1232
mutex_unlock(&selinux_state.policy_mutex);
1233
ret = simple_read_from_buffer(buf, count, ppos, page, length);
1234
out_free:
1235
free_page((unsigned long)page);
1236
return ret;
1237
1238
out_unlock:
1239
mutex_unlock(&selinux_state.policy_mutex);
1240
goto out_free;
1241
}
1242
1243
static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
1244
size_t count, loff_t *ppos)
1245
{
1246
struct selinux_fs_info *fsi = file_inode(filep)->i_sb->s_fs_info;
1247
char *page = NULL;
1248
ssize_t length;
1249
int new_value;
1250
unsigned index = file_inode(filep)->i_ino & SEL_INO_MASK;
1251
const char *name = filep->f_path.dentry->d_name.name;
1252
1253
if (count >= PAGE_SIZE)
1254
return -ENOMEM;
1255
1256
/* No partial writes. */
1257
if (*ppos != 0)
1258
return -EINVAL;
1259
1260
page = memdup_user_nul(buf, count);
1261
if (IS_ERR(page))
1262
return PTR_ERR(page);
1263
1264
mutex_lock(&selinux_state.policy_mutex);
1265
1266
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
1267
SECCLASS_SECURITY, SECURITY__SETBOOL,
1268
NULL);
1269
if (length)
1270
goto out;
1271
1272
length = -EINVAL;
1273
if (index >= fsi->bool_num || strcmp(name,
1274
fsi->bool_pending_names[index]))
1275
goto out;
1276
1277
length = -EINVAL;
1278
if (sscanf(page, "%d", &new_value) != 1)
1279
goto out;
1280
1281
if (new_value)
1282
new_value = 1;
1283
1284
fsi->bool_pending_values[index] = new_value;
1285
length = count;
1286
1287
out:
1288
mutex_unlock(&selinux_state.policy_mutex);
1289
kfree(page);
1290
return length;
1291
}
1292
1293
static const struct file_operations sel_bool_ops = {
1294
.read = sel_read_bool,
1295
.write = sel_write_bool,
1296
.llseek = generic_file_llseek,
1297
};
1298
1299
static ssize_t sel_commit_bools_write(struct file *filep,
1300
const char __user *buf,
1301
size_t count, loff_t *ppos)
1302
{
1303
struct selinux_fs_info *fsi = file_inode(filep)->i_sb->s_fs_info;
1304
char *page = NULL;
1305
ssize_t length;
1306
int new_value;
1307
1308
if (count >= PAGE_SIZE)
1309
return -ENOMEM;
1310
1311
/* No partial writes. */
1312
if (*ppos != 0)
1313
return -EINVAL;
1314
1315
page = memdup_user_nul(buf, count);
1316
if (IS_ERR(page))
1317
return PTR_ERR(page);
1318
1319
mutex_lock(&selinux_state.policy_mutex);
1320
1321
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
1322
SECCLASS_SECURITY, SECURITY__SETBOOL,
1323
NULL);
1324
if (length)
1325
goto out;
1326
1327
length = -EINVAL;
1328
if (sscanf(page, "%d", &new_value) != 1)
1329
goto out;
1330
1331
length = 0;
1332
if (new_value && fsi->bool_pending_values)
1333
length = security_set_bools(fsi->bool_num,
1334
fsi->bool_pending_values);
1335
1336
if (!length)
1337
length = count;
1338
1339
out:
1340
mutex_unlock(&selinux_state.policy_mutex);
1341
kfree(page);
1342
return length;
1343
}
1344
1345
static const struct file_operations sel_commit_bools_ops = {
1346
.write = sel_commit_bools_write,
1347
.llseek = generic_file_llseek,
1348
};
1349
1350
static int sel_make_bools(struct selinux_policy *newpolicy, struct dentry *bool_dir,
1351
unsigned int *bool_num, char ***bool_pending_names,
1352
int **bool_pending_values)
1353
{
1354
int ret;
1355
char **names, *page;
1356
u32 i, num;
1357
1358
page = (char *)get_zeroed_page(GFP_KERNEL);
1359
if (!page)
1360
return -ENOMEM;
1361
1362
ret = security_get_bools(newpolicy, &num, &names, bool_pending_values);
1363
if (ret)
1364
goto out;
1365
1366
*bool_num = num;
1367
*bool_pending_names = names;
1368
1369
for (i = 0; i < num; i++) {
1370
struct dentry *dentry;
1371
struct inode *inode;
1372
struct inode_security_struct *isec;
1373
ssize_t len;
1374
u32 sid;
1375
1376
len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]);
1377
if (len >= PAGE_SIZE) {
1378
ret = -ENAMETOOLONG;
1379
break;
1380
}
1381
dentry = d_alloc_name(bool_dir, names[i]);
1382
if (!dentry) {
1383
ret = -ENOMEM;
1384
break;
1385
}
1386
1387
inode = sel_make_inode(bool_dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR);
1388
if (!inode) {
1389
dput(dentry);
1390
ret = -ENOMEM;
1391
break;
1392
}
1393
1394
isec = selinux_inode(inode);
1395
ret = selinux_policy_genfs_sid(newpolicy, "selinuxfs", page,
1396
SECCLASS_FILE, &sid);
1397
if (ret) {
1398
pr_warn_ratelimited("SELinux: no sid found, defaulting to security isid for %s\n",
1399
page);
1400
sid = SECINITSID_SECURITY;
1401
}
1402
1403
isec->sid = sid;
1404
isec->initialized = LABEL_INITIALIZED;
1405
inode->i_fop = &sel_bool_ops;
1406
inode->i_ino = i|SEL_BOOL_INO_OFFSET;
1407
d_add(dentry, inode);
1408
}
1409
out:
1410
free_page((unsigned long)page);
1411
return ret;
1412
}
1413
1414
static ssize_t sel_read_avc_cache_threshold(struct file *filp, char __user *buf,
1415
size_t count, loff_t *ppos)
1416
{
1417
char tmpbuf[TMPBUFLEN];
1418
ssize_t length;
1419
1420
length = scnprintf(tmpbuf, TMPBUFLEN, "%u",
1421
avc_get_cache_threshold());
1422
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
1423
}
1424
1425
static ssize_t sel_write_avc_cache_threshold(struct file *file,
1426
const char __user *buf,
1427
size_t count, loff_t *ppos)
1428
1429
{
1430
char *page;
1431
ssize_t ret;
1432
unsigned int new_value;
1433
1434
ret = avc_has_perm(current_sid(), SECINITSID_SECURITY,
1435
SECCLASS_SECURITY, SECURITY__SETSECPARAM,
1436
NULL);
1437
if (ret)
1438
return ret;
1439
1440
if (count >= PAGE_SIZE)
1441
return -ENOMEM;
1442
1443
/* No partial writes. */
1444
if (*ppos != 0)
1445
return -EINVAL;
1446
1447
page = memdup_user_nul(buf, count);
1448
if (IS_ERR(page))
1449
return PTR_ERR(page);
1450
1451
ret = -EINVAL;
1452
if (sscanf(page, "%u", &new_value) != 1)
1453
goto out;
1454
1455
avc_set_cache_threshold(new_value);
1456
1457
ret = count;
1458
out:
1459
kfree(page);
1460
return ret;
1461
}
1462
1463
static ssize_t sel_read_avc_hash_stats(struct file *filp, char __user *buf,
1464
size_t count, loff_t *ppos)
1465
{
1466
char *page;
1467
ssize_t length;
1468
1469
page = (char *)__get_free_page(GFP_KERNEL);
1470
if (!page)
1471
return -ENOMEM;
1472
1473
length = avc_get_hash_stats(page);
1474
if (length >= 0)
1475
length = simple_read_from_buffer(buf, count, ppos, page, length);
1476
free_page((unsigned long)page);
1477
1478
return length;
1479
}
1480
1481
static ssize_t sel_read_sidtab_hash_stats(struct file *filp, char __user *buf,
1482
size_t count, loff_t *ppos)
1483
{
1484
char *page;
1485
ssize_t length;
1486
1487
page = (char *)__get_free_page(GFP_KERNEL);
1488
if (!page)
1489
return -ENOMEM;
1490
1491
length = security_sidtab_hash_stats(page);
1492
if (length >= 0)
1493
length = simple_read_from_buffer(buf, count, ppos, page,
1494
length);
1495
free_page((unsigned long)page);
1496
1497
return length;
1498
}
1499
1500
static const struct file_operations sel_sidtab_hash_stats_ops = {
1501
.read = sel_read_sidtab_hash_stats,
1502
.llseek = generic_file_llseek,
1503
};
1504
1505
static const struct file_operations sel_avc_cache_threshold_ops = {
1506
.read = sel_read_avc_cache_threshold,
1507
.write = sel_write_avc_cache_threshold,
1508
.llseek = generic_file_llseek,
1509
};
1510
1511
static const struct file_operations sel_avc_hash_stats_ops = {
1512
.read = sel_read_avc_hash_stats,
1513
.llseek = generic_file_llseek,
1514
};
1515
1516
#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
1517
static struct avc_cache_stats *sel_avc_get_stat_idx(loff_t *idx)
1518
{
1519
loff_t cpu;
1520
1521
for (cpu = *idx; cpu < nr_cpu_ids; ++cpu) {
1522
if (!cpu_possible(cpu))
1523
continue;
1524
*idx = cpu + 1;
1525
return &per_cpu(avc_cache_stats, cpu);
1526
}
1527
(*idx)++;
1528
return NULL;
1529
}
1530
1531
static void *sel_avc_stats_seq_start(struct seq_file *seq, loff_t *pos)
1532
{
1533
loff_t n = *pos - 1;
1534
1535
if (*pos == 0)
1536
return SEQ_START_TOKEN;
1537
1538
return sel_avc_get_stat_idx(&n);
1539
}
1540
1541
static void *sel_avc_stats_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1542
{
1543
return sel_avc_get_stat_idx(pos);
1544
}
1545
1546
static int sel_avc_stats_seq_show(struct seq_file *seq, void *v)
1547
{
1548
struct avc_cache_stats *st = v;
1549
1550
if (v == SEQ_START_TOKEN) {
1551
seq_puts(seq,
1552
"lookups hits misses allocations reclaims frees\n");
1553
} else {
1554
unsigned int lookups = st->lookups;
1555
unsigned int misses = st->misses;
1556
unsigned int hits = lookups - misses;
1557
seq_printf(seq, "%u %u %u %u %u %u\n", lookups,
1558
hits, misses, st->allocations,
1559
st->reclaims, st->frees);
1560
}
1561
return 0;
1562
}
1563
1564
static void sel_avc_stats_seq_stop(struct seq_file *seq, void *v)
1565
{ }
1566
1567
static const struct seq_operations sel_avc_cache_stats_seq_ops = {
1568
.start = sel_avc_stats_seq_start,
1569
.next = sel_avc_stats_seq_next,
1570
.show = sel_avc_stats_seq_show,
1571
.stop = sel_avc_stats_seq_stop,
1572
};
1573
1574
static int sel_open_avc_cache_stats(struct inode *inode, struct file *file)
1575
{
1576
return seq_open(file, &sel_avc_cache_stats_seq_ops);
1577
}
1578
1579
static const struct file_operations sel_avc_cache_stats_ops = {
1580
.open = sel_open_avc_cache_stats,
1581
.read = seq_read,
1582
.llseek = seq_lseek,
1583
.release = seq_release,
1584
};
1585
#endif
1586
1587
static int sel_make_avc_files(struct dentry *dir)
1588
{
1589
struct super_block *sb = dir->d_sb;
1590
struct selinux_fs_info *fsi = sb->s_fs_info;
1591
unsigned int i;
1592
static const struct tree_descr files[] = {
1593
{ "cache_threshold",
1594
&sel_avc_cache_threshold_ops, S_IRUGO|S_IWUSR },
1595
{ "hash_stats", &sel_avc_hash_stats_ops, S_IRUGO },
1596
#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
1597
{ "cache_stats", &sel_avc_cache_stats_ops, S_IRUGO },
1598
#endif
1599
};
1600
1601
for (i = 0; i < ARRAY_SIZE(files); i++) {
1602
struct inode *inode;
1603
struct dentry *dentry;
1604
1605
dentry = d_alloc_name(dir, files[i].name);
1606
if (!dentry)
1607
return -ENOMEM;
1608
1609
inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode);
1610
if (!inode) {
1611
dput(dentry);
1612
return -ENOMEM;
1613
}
1614
1615
inode->i_fop = files[i].ops;
1616
inode->i_ino = ++fsi->last_ino;
1617
d_add(dentry, inode);
1618
}
1619
1620
return 0;
1621
}
1622
1623
static int sel_make_ss_files(struct dentry *dir)
1624
{
1625
struct super_block *sb = dir->d_sb;
1626
struct selinux_fs_info *fsi = sb->s_fs_info;
1627
unsigned int i;
1628
static const struct tree_descr files[] = {
1629
{ "sidtab_hash_stats", &sel_sidtab_hash_stats_ops, S_IRUGO },
1630
};
1631
1632
for (i = 0; i < ARRAY_SIZE(files); i++) {
1633
struct inode *inode;
1634
struct dentry *dentry;
1635
1636
dentry = d_alloc_name(dir, files[i].name);
1637
if (!dentry)
1638
return -ENOMEM;
1639
1640
inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode);
1641
if (!inode) {
1642
dput(dentry);
1643
return -ENOMEM;
1644
}
1645
1646
inode->i_fop = files[i].ops;
1647
inode->i_ino = ++fsi->last_ino;
1648
d_add(dentry, inode);
1649
}
1650
1651
return 0;
1652
}
1653
1654
static ssize_t sel_read_initcon(struct file *file, char __user *buf,
1655
size_t count, loff_t *ppos)
1656
{
1657
char *con;
1658
u32 sid, len;
1659
ssize_t ret;
1660
1661
sid = file_inode(file)->i_ino&SEL_INO_MASK;
1662
ret = security_sid_to_context(sid, &con, &len);
1663
if (ret)
1664
return ret;
1665
1666
ret = simple_read_from_buffer(buf, count, ppos, con, len);
1667
kfree(con);
1668
return ret;
1669
}
1670
1671
static const struct file_operations sel_initcon_ops = {
1672
.read = sel_read_initcon,
1673
.llseek = generic_file_llseek,
1674
};
1675
1676
static int sel_make_initcon_files(struct dentry *dir)
1677
{
1678
unsigned int i;
1679
1680
for (i = 1; i <= SECINITSID_NUM; i++) {
1681
struct inode *inode;
1682
struct dentry *dentry;
1683
const char *s = security_get_initial_sid_context(i);
1684
1685
if (!s)
1686
continue;
1687
dentry = d_alloc_name(dir, s);
1688
if (!dentry)
1689
return -ENOMEM;
1690
1691
inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1692
if (!inode) {
1693
dput(dentry);
1694
return -ENOMEM;
1695
}
1696
1697
inode->i_fop = &sel_initcon_ops;
1698
inode->i_ino = i|SEL_INITCON_INO_OFFSET;
1699
d_add(dentry, inode);
1700
}
1701
1702
return 0;
1703
}
1704
1705
static inline unsigned long sel_class_to_ino(u16 class)
1706
{
1707
return (class * (SEL_VEC_MAX + 1)) | SEL_CLASS_INO_OFFSET;
1708
}
1709
1710
static inline u16 sel_ino_to_class(unsigned long ino)
1711
{
1712
return (ino & SEL_INO_MASK) / (SEL_VEC_MAX + 1);
1713
}
1714
1715
static inline unsigned long sel_perm_to_ino(u16 class, u32 perm)
1716
{
1717
return (class * (SEL_VEC_MAX + 1) + perm) | SEL_CLASS_INO_OFFSET;
1718
}
1719
1720
static inline u32 sel_ino_to_perm(unsigned long ino)
1721
{
1722
return (ino & SEL_INO_MASK) % (SEL_VEC_MAX + 1);
1723
}
1724
1725
static ssize_t sel_read_class(struct file *file, char __user *buf,
1726
size_t count, loff_t *ppos)
1727
{
1728
unsigned long ino = file_inode(file)->i_ino;
1729
char res[TMPBUFLEN];
1730
ssize_t len = scnprintf(res, sizeof(res), "%d", sel_ino_to_class(ino));
1731
return simple_read_from_buffer(buf, count, ppos, res, len);
1732
}
1733
1734
static const struct file_operations sel_class_ops = {
1735
.read = sel_read_class,
1736
.llseek = generic_file_llseek,
1737
};
1738
1739
static ssize_t sel_read_perm(struct file *file, char __user *buf,
1740
size_t count, loff_t *ppos)
1741
{
1742
unsigned long ino = file_inode(file)->i_ino;
1743
char res[TMPBUFLEN];
1744
ssize_t len = scnprintf(res, sizeof(res), "%d", sel_ino_to_perm(ino));
1745
return simple_read_from_buffer(buf, count, ppos, res, len);
1746
}
1747
1748
static const struct file_operations sel_perm_ops = {
1749
.read = sel_read_perm,
1750
.llseek = generic_file_llseek,
1751
};
1752
1753
static ssize_t sel_read_policycap(struct file *file, char __user *buf,
1754
size_t count, loff_t *ppos)
1755
{
1756
int value;
1757
char tmpbuf[TMPBUFLEN];
1758
ssize_t length;
1759
unsigned long i_ino = file_inode(file)->i_ino;
1760
1761
value = security_policycap_supported(i_ino & SEL_INO_MASK);
1762
length = scnprintf(tmpbuf, TMPBUFLEN, "%d", value);
1763
1764
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
1765
}
1766
1767
static const struct file_operations sel_policycap_ops = {
1768
.read = sel_read_policycap,
1769
.llseek = generic_file_llseek,
1770
};
1771
1772
static int sel_make_perm_files(struct selinux_policy *newpolicy,
1773
char *objclass, int classvalue,
1774
struct dentry *dir)
1775
{
1776
u32 i, nperms;
1777
int rc;
1778
char **perms;
1779
1780
rc = security_get_permissions(newpolicy, objclass, &perms, &nperms);
1781
if (rc)
1782
return rc;
1783
1784
for (i = 0; i < nperms; i++) {
1785
struct inode *inode;
1786
struct dentry *dentry;
1787
1788
rc = -ENOMEM;
1789
dentry = d_alloc_name(dir, perms[i]);
1790
if (!dentry)
1791
goto out;
1792
1793
rc = -ENOMEM;
1794
inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1795
if (!inode) {
1796
dput(dentry);
1797
goto out;
1798
}
1799
1800
inode->i_fop = &sel_perm_ops;
1801
/* i+1 since perm values are 1-indexed */
1802
inode->i_ino = sel_perm_to_ino(classvalue, i + 1);
1803
d_add(dentry, inode);
1804
}
1805
rc = 0;
1806
out:
1807
for (i = 0; i < nperms; i++)
1808
kfree(perms[i]);
1809
kfree(perms);
1810
return rc;
1811
}
1812
1813
static int sel_make_class_dir_entries(struct selinux_policy *newpolicy,
1814
char *classname, int index,
1815
struct dentry *dir)
1816
{
1817
struct super_block *sb = dir->d_sb;
1818
struct selinux_fs_info *fsi = sb->s_fs_info;
1819
struct dentry *dentry = NULL;
1820
struct inode *inode = NULL;
1821
1822
dentry = d_alloc_name(dir, "index");
1823
if (!dentry)
1824
return -ENOMEM;
1825
1826
inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1827
if (!inode) {
1828
dput(dentry);
1829
return -ENOMEM;
1830
}
1831
1832
inode->i_fop = &sel_class_ops;
1833
inode->i_ino = sel_class_to_ino(index);
1834
d_add(dentry, inode);
1835
1836
dentry = sel_make_dir(dir, "perms", &fsi->last_class_ino);
1837
if (IS_ERR(dentry))
1838
return PTR_ERR(dentry);
1839
1840
return sel_make_perm_files(newpolicy, classname, index, dentry);
1841
}
1842
1843
static int sel_make_classes(struct selinux_policy *newpolicy,
1844
struct dentry *class_dir,
1845
unsigned long *last_class_ino)
1846
{
1847
u32 i, nclasses;
1848
int rc;
1849
char **classes;
1850
1851
rc = security_get_classes(newpolicy, &classes, &nclasses);
1852
if (rc)
1853
return rc;
1854
1855
/* +2 since classes are 1-indexed */
1856
*last_class_ino = sel_class_to_ino(nclasses + 2);
1857
1858
for (i = 0; i < nclasses; i++) {
1859
struct dentry *class_name_dir;
1860
1861
class_name_dir = sel_make_dir(class_dir, classes[i],
1862
last_class_ino);
1863
if (IS_ERR(class_name_dir)) {
1864
rc = PTR_ERR(class_name_dir);
1865
goto out;
1866
}
1867
1868
/* i+1 since class values are 1-indexed */
1869
rc = sel_make_class_dir_entries(newpolicy, classes[i], i + 1,
1870
class_name_dir);
1871
if (rc)
1872
goto out;
1873
}
1874
rc = 0;
1875
out:
1876
for (i = 0; i < nclasses; i++)
1877
kfree(classes[i]);
1878
kfree(classes);
1879
return rc;
1880
}
1881
1882
static int sel_make_policycap(struct selinux_fs_info *fsi)
1883
{
1884
unsigned int iter;
1885
struct dentry *dentry = NULL;
1886
struct inode *inode = NULL;
1887
1888
for (iter = 0; iter <= POLICYDB_CAP_MAX; iter++) {
1889
if (iter < ARRAY_SIZE(selinux_policycap_names))
1890
dentry = d_alloc_name(fsi->policycap_dir,
1891
selinux_policycap_names[iter]);
1892
else
1893
dentry = d_alloc_name(fsi->policycap_dir, "unknown");
1894
1895
if (dentry == NULL)
1896
return -ENOMEM;
1897
1898
inode = sel_make_inode(fsi->sb, S_IFREG | 0444);
1899
if (inode == NULL) {
1900
dput(dentry);
1901
return -ENOMEM;
1902
}
1903
1904
inode->i_fop = &sel_policycap_ops;
1905
inode->i_ino = iter | SEL_POLICYCAP_INO_OFFSET;
1906
d_add(dentry, inode);
1907
}
1908
1909
return 0;
1910
}
1911
1912
static struct dentry *sel_make_dir(struct dentry *dir, const char *name,
1913
unsigned long *ino)
1914
{
1915
struct dentry *dentry = d_alloc_name(dir, name);
1916
struct inode *inode;
1917
1918
if (!dentry)
1919
return ERR_PTR(-ENOMEM);
1920
1921
inode = sel_make_inode(dir->d_sb, S_IFDIR | S_IRUGO | S_IXUGO);
1922
if (!inode) {
1923
dput(dentry);
1924
return ERR_PTR(-ENOMEM);
1925
}
1926
1927
inode->i_op = &simple_dir_inode_operations;
1928
inode->i_fop = &simple_dir_operations;
1929
inode->i_ino = ++(*ino);
1930
/* directory inodes start off with i_nlink == 2 (for "." entry) */
1931
inc_nlink(inode);
1932
d_add(dentry, inode);
1933
/* bump link count on parent directory, too */
1934
inc_nlink(d_inode(dir));
1935
1936
return dentry;
1937
}
1938
1939
static int reject_all(struct mnt_idmap *idmap, struct inode *inode, int mask)
1940
{
1941
return -EPERM; // no access for anyone, root or no root.
1942
}
1943
1944
static const struct inode_operations swapover_dir_inode_operations = {
1945
.lookup = simple_lookup,
1946
.permission = reject_all,
1947
};
1948
1949
static struct dentry *sel_make_swapover_dir(struct super_block *sb,
1950
unsigned long *ino)
1951
{
1952
struct dentry *dentry = d_alloc_name(sb->s_root, ".swapover");
1953
struct inode *inode;
1954
1955
if (!dentry)
1956
return ERR_PTR(-ENOMEM);
1957
1958
inode = sel_make_inode(sb, S_IFDIR);
1959
if (!inode) {
1960
dput(dentry);
1961
return ERR_PTR(-ENOMEM);
1962
}
1963
1964
inode->i_op = &swapover_dir_inode_operations;
1965
inode->i_ino = ++(*ino);
1966
/* directory inodes start off with i_nlink == 2 (for "." entry) */
1967
inc_nlink(inode);
1968
inode_lock(sb->s_root->d_inode);
1969
d_add(dentry, inode);
1970
inc_nlink(sb->s_root->d_inode);
1971
inode_unlock(sb->s_root->d_inode);
1972
return dentry;
1973
}
1974
1975
#define NULL_FILE_NAME "null"
1976
1977
static int sel_fill_super(struct super_block *sb, struct fs_context *fc)
1978
{
1979
struct selinux_fs_info *fsi;
1980
int ret;
1981
struct dentry *dentry;
1982
struct inode *inode;
1983
struct inode_security_struct *isec;
1984
1985
static const struct tree_descr selinux_files[] = {
1986
[SEL_LOAD] = {"load", &sel_load_ops, S_IRUSR|S_IWUSR},
1987
[SEL_ENFORCE] = {"enforce", &sel_enforce_ops, S_IRUGO|S_IWUSR},
1988
[SEL_CONTEXT] = {"context", &transaction_ops, S_IRUGO|S_IWUGO},
1989
[SEL_ACCESS] = {"access", &transaction_ops, S_IRUGO|S_IWUGO},
1990
[SEL_CREATE] = {"create", &transaction_ops, S_IRUGO|S_IWUGO},
1991
[SEL_RELABEL] = {"relabel", &transaction_ops, S_IRUGO|S_IWUGO},
1992
[SEL_USER] = {"user", &transaction_ops, S_IRUGO|S_IWUGO},
1993
[SEL_POLICYVERS] = {"policyvers", &sel_policyvers_ops, S_IRUGO},
1994
[SEL_COMMIT_BOOLS] = {"commit_pending_bools", &sel_commit_bools_ops, S_IWUSR},
1995
[SEL_MLS] = {"mls", &sel_mls_ops, S_IRUGO},
1996
[SEL_DISABLE] = {"disable", &sel_disable_ops, S_IWUSR},
1997
[SEL_MEMBER] = {"member", &transaction_ops, S_IRUGO|S_IWUGO},
1998
[SEL_CHECKREQPROT] = {"checkreqprot", &sel_checkreqprot_ops, S_IRUGO|S_IWUSR},
1999
[SEL_REJECT_UNKNOWN] = {"reject_unknown", &sel_handle_unknown_ops, S_IRUGO},
2000
[SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO},
2001
[SEL_STATUS] = {"status", &sel_handle_status_ops, S_IRUGO},
2002
[SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUGO},
2003
[SEL_VALIDATE_TRANS] = {"validatetrans", &sel_transition_ops,
2004
S_IWUGO},
2005
/* last one */ {"", NULL, 0}
2006
};
2007
2008
ret = selinux_fs_info_create(sb);
2009
if (ret)
2010
goto err;
2011
2012
ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
2013
if (ret)
2014
goto err;
2015
2016
fsi = sb->s_fs_info;
2017
fsi->bool_dir = sel_make_dir(sb->s_root, BOOL_DIR_NAME, &fsi->last_ino);
2018
if (IS_ERR(fsi->bool_dir)) {
2019
ret = PTR_ERR(fsi->bool_dir);
2020
fsi->bool_dir = NULL;
2021
goto err;
2022
}
2023
2024
ret = -ENOMEM;
2025
dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME);
2026
if (!dentry)
2027
goto err;
2028
2029
ret = -ENOMEM;
2030
inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO);
2031
if (!inode) {
2032
dput(dentry);
2033
goto err;
2034
}
2035
2036
inode->i_ino = ++fsi->last_ino;
2037
isec = selinux_inode(inode);
2038
isec->sid = SECINITSID_DEVNULL;
2039
isec->sclass = SECCLASS_CHR_FILE;
2040
isec->initialized = LABEL_INITIALIZED;
2041
2042
init_special_inode(inode, S_IFCHR | S_IRUGO | S_IWUGO, MKDEV(MEM_MAJOR, 3));
2043
d_add(dentry, inode);
2044
2045
dentry = sel_make_dir(sb->s_root, "avc", &fsi->last_ino);
2046
if (IS_ERR(dentry)) {
2047
ret = PTR_ERR(dentry);
2048
goto err;
2049
}
2050
2051
ret = sel_make_avc_files(dentry);
2052
if (ret)
2053
goto err;
2054
2055
dentry = sel_make_dir(sb->s_root, "ss", &fsi->last_ino);
2056
if (IS_ERR(dentry)) {
2057
ret = PTR_ERR(dentry);
2058
goto err;
2059
}
2060
2061
ret = sel_make_ss_files(dentry);
2062
if (ret)
2063
goto err;
2064
2065
dentry = sel_make_dir(sb->s_root, "initial_contexts", &fsi->last_ino);
2066
if (IS_ERR(dentry)) {
2067
ret = PTR_ERR(dentry);
2068
goto err;
2069
}
2070
2071
ret = sel_make_initcon_files(dentry);
2072
if (ret)
2073
goto err;
2074
2075
fsi->class_dir = sel_make_dir(sb->s_root, CLASS_DIR_NAME, &fsi->last_ino);
2076
if (IS_ERR(fsi->class_dir)) {
2077
ret = PTR_ERR(fsi->class_dir);
2078
fsi->class_dir = NULL;
2079
goto err;
2080
}
2081
2082
fsi->policycap_dir = sel_make_dir(sb->s_root, POLICYCAP_DIR_NAME,
2083
&fsi->last_ino);
2084
if (IS_ERR(fsi->policycap_dir)) {
2085
ret = PTR_ERR(fsi->policycap_dir);
2086
fsi->policycap_dir = NULL;
2087
goto err;
2088
}
2089
2090
ret = sel_make_policycap(fsi);
2091
if (ret) {
2092
pr_err("SELinux: failed to load policy capabilities\n");
2093
goto err;
2094
}
2095
2096
return 0;
2097
err:
2098
pr_err("SELinux: %s: failed while creating inodes\n",
2099
__func__);
2100
2101
return ret;
2102
}
2103
2104
static int sel_get_tree(struct fs_context *fc)
2105
{
2106
return get_tree_single(fc, sel_fill_super);
2107
}
2108
2109
static const struct fs_context_operations sel_context_ops = {
2110
.get_tree = sel_get_tree,
2111
};
2112
2113
static int sel_init_fs_context(struct fs_context *fc)
2114
{
2115
fc->ops = &sel_context_ops;
2116
return 0;
2117
}
2118
2119
static void sel_kill_sb(struct super_block *sb)
2120
{
2121
selinux_fs_info_free(sb);
2122
kill_litter_super(sb);
2123
}
2124
2125
static struct file_system_type sel_fs_type = {
2126
.name = "selinuxfs",
2127
.init_fs_context = sel_init_fs_context,
2128
.kill_sb = sel_kill_sb,
2129
};
2130
2131
struct path selinux_null __ro_after_init;
2132
2133
static int __init init_sel_fs(void)
2134
{
2135
struct qstr null_name = QSTR_INIT(NULL_FILE_NAME,
2136
sizeof(NULL_FILE_NAME)-1);
2137
int err;
2138
2139
if (!selinux_enabled_boot)
2140
return 0;
2141
2142
err = sysfs_create_mount_point(fs_kobj, "selinux");
2143
if (err)
2144
return err;
2145
2146
err = register_filesystem(&sel_fs_type);
2147
if (err) {
2148
sysfs_remove_mount_point(fs_kobj, "selinux");
2149
return err;
2150
}
2151
2152
selinux_null.mnt = kern_mount(&sel_fs_type);
2153
if (IS_ERR(selinux_null.mnt)) {
2154
pr_err("selinuxfs: could not mount!\n");
2155
err = PTR_ERR(selinux_null.mnt);
2156
selinux_null.mnt = NULL;
2157
return err;
2158
}
2159
2160
selinux_null.dentry = try_lookup_noperm(&null_name,
2161
selinux_null.mnt->mnt_root);
2162
if (IS_ERR(selinux_null.dentry)) {
2163
pr_err("selinuxfs: could not lookup null!\n");
2164
err = PTR_ERR(selinux_null.dentry);
2165
selinux_null.dentry = NULL;
2166
return err;
2167
}
2168
2169
/*
2170
* Try to pre-allocate the status page, so the sequence number of the
2171
* initial policy load can be stored.
2172
*/
2173
(void) selinux_kernel_status_page();
2174
2175
return err;
2176
}
2177
2178
__initcall(init_sel_fs);
2179
2180