1 #include <linux/config.h>
2 #include <linux/kernel.h>
3 #include <linux/slab.h>
4 #include <linux/vmalloc.h>
6 #include <linux/init.h>
7 #include <linux/string.h>
8 #include <linux/security.h>
9 #include <asm/uaccess.h>
11 /* selinuxfs pseudo filesystem for exporting the security policy API.
12 Based on the proc code and the fs/nfsd/nfsctl.c code. */
20 /* Check whether a task is allowed to use a security operation. */
21 int task_has_security(struct task_struct *tsk,
24 struct task_security_struct *tsec;
28 return avc_has_perm(tsec->sid, SECINITSID_SECURITY,
29 SECCLASS_SECURITY, perms, NULL, NULL);
34 SEL_LOAD, /* load policy */
35 SEL_ENFORCE, /* get or set enforcing status */
36 SEL_CONTEXT, /* validate context */
37 SEL_ACCESS, /* compute access decision */
38 SEL_CREATE, /* compute create labeling decision */
39 SEL_RELABEL, /* compute relabeling decision */
40 SEL_USER /* compute reachable user contexts */
43 static ssize_t sel_read_enforce(struct file *filp, char *buf,
44 size_t count, loff_t *ppos)
50 if (count < 0 || count > PAGE_SIZE)
52 if (!(page = (char*)__get_free_page(GFP_KERNEL)))
54 memset(page, 0, PAGE_SIZE);
56 length = snprintf(page, PAGE_SIZE, "%d", selinux_enforcing);
58 free_page((unsigned long)page);
62 if (*ppos >= length) {
63 free_page((unsigned long)page);
66 if (count + *ppos > length)
67 count = length - *ppos;
69 if (copy_to_user(buf, (char *) page + *ppos, count)) {
75 free_page((unsigned long)page);
79 #ifdef CONFIG_SECURITY_SELINUX_DEVELOP
80 static ssize_t sel_write_enforce(struct file * file, const char * buf,
81 size_t count, loff_t *ppos)
88 if (count < 0 || count >= PAGE_SIZE)
91 /* No partial writes. */
94 page = (char*)__get_free_page(GFP_KERNEL);
97 memset(page, 0, PAGE_SIZE);
99 if (copy_from_user(page, buf, count))
103 if (sscanf(page, "%d", &new_value) != 1)
106 if (new_value != selinux_enforcing) {
107 length = task_has_security(current, SECURITY__SETENFORCE);
110 selinux_enforcing = new_value;
111 if (selinux_enforcing)
116 free_page((unsigned long) page);
120 #define sel_write_enforce NULL
123 static struct file_operations sel_enforce_ops = {
124 .read = sel_read_enforce,
125 .write = sel_write_enforce,
128 static ssize_t sel_write_load(struct file * file, const char * buf,
129 size_t count, loff_t *ppos)
135 length = task_has_security(current, SECURITY__LOAD_POLICY);
140 /* No partial writes. */
144 if ((count < 0) || (count > 64 * 1024 * 1024) || (data = vmalloc(count)) == NULL)
148 if (copy_from_user(data, buf, count) != 0)
151 length = security_load_policy(data, count);
161 static struct file_operations sel_load_ops = {
162 .write = sel_write_load,
166 static ssize_t sel_write_context(struct file * file, const char * buf,
167 size_t count, loff_t *ppos)
174 length = task_has_security(current, SECURITY__CHECK_CONTEXT);
178 if (count < 0 || count >= PAGE_SIZE)
181 /* No partial writes. */
184 page = (char*)__get_free_page(GFP_KERNEL);
187 memset(page, 0, PAGE_SIZE);
189 if (copy_from_user(page, buf, count))
192 length = security_context_to_sid(page, count, &sid);
198 free_page((unsigned long) page);
202 static struct file_operations sel_context_ops = {
203 .write = sel_write_context,
208 * Remaining nodes use transaction based IO methods like nfsd/nfsctl.c
210 static ssize_t sel_write_access(struct file * file, char *buf, size_t size);
211 static ssize_t sel_write_create(struct file * file, char *buf, size_t size);
212 static ssize_t sel_write_relabel(struct file * file, char *buf, size_t size);
213 static ssize_t sel_write_user(struct file * file, char *buf, size_t size);
215 static ssize_t (*write_op[])(struct file *, char *, size_t) = {
216 [SEL_ACCESS] = sel_write_access,
217 [SEL_CREATE] = sel_write_create,
218 [SEL_RELABEL] = sel_write_relabel,
219 [SEL_USER] = sel_write_user,
222 /* an argresp is stored in an allocated page and holds the
223 * size of the argument or response, along with its content
230 #define PAYLOAD_SIZE (PAGE_SIZE - sizeof(struct argresp))
233 * transaction based IO methods.
234 * The file expects a single write which triggers the transaction, and then
235 * possibly a read which collects the result - which is stored in a
238 static ssize_t TA_write(struct file *file, const char *buf, size_t size, loff_t *pos)
240 ino_t ino = file->f_dentry->d_inode->i_ino;
244 if (ino >= sizeof(write_op)/sizeof(write_op[0]) || !write_op[ino])
246 if (file->private_data)
247 return -EINVAL; /* only one write allowed per open */
248 if (size > PAYLOAD_SIZE - 1) /* allow one byte for null terminator */
251 ar = kmalloc(PAGE_SIZE, GFP_KERNEL);
254 memset(ar, 0, PAGE_SIZE); /* clear buffer, particularly last byte */
256 down(&file->f_dentry->d_inode->i_sem);
257 if (file->private_data)
260 file->private_data = ar;
261 up(&file->f_dentry->d_inode->i_sem);
266 if (copy_from_user(ar->data, buf, size))
269 rv = write_op[ino](file, ar->data, size);
277 static ssize_t TA_read(struct file *file, char *buf, size_t size, loff_t *pos)
282 if (file->private_data == NULL)
283 rv = TA_write(file, buf, 0, pos);
287 ar = file->private_data;
290 if (*pos >= ar->size)
292 if (*pos + size > ar->size)
293 size = ar->size - *pos;
294 if (copy_to_user(buf, ar->data + *pos, size))
300 static int TA_open(struct inode *inode, struct file *file)
302 file->private_data = NULL;
306 static int TA_release(struct inode *inode, struct file *file)
308 void *p = file->private_data;
309 file->private_data = NULL;
314 static struct file_operations transaction_ops = {
318 .release = TA_release,
322 * payload - write methods
323 * If the method has a response, the response should be put in buf,
324 * and the length returned. Otherwise return 0 or and -error.
327 static ssize_t sel_write_access(struct file * file, char *buf, size_t size)
333 struct av_decision avd;
336 length = task_has_security(current, SECURITY__COMPUTE_AV);
341 scon = kmalloc(size+1, GFP_KERNEL);
344 memset(scon, 0, size+1);
346 tcon = kmalloc(size+1, GFP_KERNEL);
349 memset(tcon, 0, size+1);
352 if (sscanf(buf, "%s %s %hu %x", scon, tcon, &tclass, &req) != 4)
355 length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
358 length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
362 length = security_compute_av(ssid, tsid, tclass, req, &avd);
366 length = snprintf(buf, PAYLOAD_SIZE, "%x %x %x %x %u",
367 avd.allowed, avd.decided,
368 avd.auditallow, avd.auditdeny,
377 static ssize_t sel_write_create(struct file * file, char *buf, size_t size)
380 u32 ssid, tsid, newsid;
386 length = task_has_security(current, SECURITY__COMPUTE_CREATE);
391 scon = kmalloc(size+1, GFP_KERNEL);
394 memset(scon, 0, size+1);
396 tcon = kmalloc(size+1, GFP_KERNEL);
399 memset(tcon, 0, size+1);
402 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
405 length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
408 length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
412 length = security_transition_sid(ssid, tsid, tclass, &newsid);
416 length = security_sid_to_context(newsid, &newcon, &len);
420 if (len > PAYLOAD_SIZE) {
421 printk(KERN_ERR "%s: context size (%u) exceeds payload "
422 "max\n", __FUNCTION__, len);
427 memcpy(buf, newcon, len);
438 static ssize_t sel_write_relabel(struct file * file, char *buf, size_t size)
441 u32 ssid, tsid, newsid;
447 length = task_has_security(current, SECURITY__COMPUTE_RELABEL);
452 scon = kmalloc(size+1, GFP_KERNEL);
455 memset(scon, 0, size+1);
457 tcon = kmalloc(size+1, GFP_KERNEL);
460 memset(tcon, 0, size+1);
463 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
466 length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
469 length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
473 length = security_change_sid(ssid, tsid, tclass, &newsid);
477 length = security_sid_to_context(newsid, &newcon, &len);
481 if (len > PAYLOAD_SIZE) {
486 memcpy(buf, newcon, len);
497 static ssize_t sel_write_user(struct file * file, char *buf, size_t size)
499 char *con, *user, *ptr;
506 length = task_has_security(current, SECURITY__COMPUTE_USER);
511 con = kmalloc(size+1, GFP_KERNEL);
514 memset(con, 0, size+1);
516 user = kmalloc(size+1, GFP_KERNEL);
519 memset(user, 0, size+1);
522 if (sscanf(buf, "%s %s", con, user) != 2)
525 length = security_context_to_sid(con, strlen(con)+1, &sid);
529 length = security_get_user_sids(sid, user, &sids, &nsids);
533 length = sprintf(buf, "%u", nsids) + 1;
535 for (i = 0; i < nsids; i++) {
536 rc = security_sid_to_context(sids[i], &newcon, &len);
541 if ((length + len) >= PAYLOAD_SIZE) {
546 memcpy(ptr, newcon, len);
561 static int sel_fill_super(struct super_block * sb, void * data, int silent)
563 static struct tree_descr selinux_files[] = {
564 [SEL_LOAD] = {"load", &sel_load_ops, S_IRUSR|S_IWUSR},
565 [SEL_ENFORCE] = {"enforce", &sel_enforce_ops, S_IRUSR|S_IWUSR},
566 [SEL_CONTEXT] = {"context", &sel_context_ops, S_IRUGO|S_IWUGO},
567 [SEL_ACCESS] = {"access", &transaction_ops, S_IRUGO|S_IWUGO},
568 [SEL_CREATE] = {"create", &transaction_ops, S_IRUGO|S_IWUGO},
569 [SEL_RELABEL] = {"relabel", &transaction_ops, S_IRUGO|S_IWUGO},
570 [SEL_USER] = {"user", &transaction_ops, S_IRUGO|S_IWUGO},
573 return simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
576 static struct super_block *sel_get_sb(struct file_system_type *fs_type,
577 int flags, const char *dev_name, void *data)
579 return get_sb_single(fs_type, flags, data, sel_fill_super);
582 static struct file_system_type sel_fs_type = {
584 .get_sb = sel_get_sb,
585 .kill_sb = kill_litter_super,
588 static int __init init_sel_fs(void)
590 return register_filesystem(&sel_fs_type);
593 __initcall(init_sel_fs);