summaryrefslogtreecommitdiffstats
path: root/security/selinux/selinuxfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/selinuxfs.c')
-rw-r--r--security/selinux/selinuxfs.c108
1 files changed, 96 insertions, 12 deletions
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 2fa483f2611..0341567665b 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -2,6 +2,11 @@
*
* Added conditional policy language extensions
*
+ * Updated: Hewlett-Packard <paul.moore@hp.com>
+ *
+ * Added support for the policy capability bitmap
+ *
+ * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
* Copyright (C) 2003 - 2004 Tresys Technology, LLC
* Copyright (C) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
* This program is free software; you can redistribute it and/or modify
@@ -35,6 +40,11 @@
#include "objsec.h"
#include "conditional.h"
+/* Policy capability filenames */
+static char *policycap_names[] = {
+ "network_peer_controls"
+};
+
unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
#ifdef CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT
@@ -72,6 +82,9 @@ static int *bool_pending_values = NULL;
static struct dentry *class_dir = NULL;
static unsigned long last_class_ino;
+/* global data for policy capabilities */
+static struct dentry *policycap_dir = NULL;
+
extern void selnl_notify_setenforce(int val);
/* Check whether a task is allowed to use a security operation. */
@@ -111,10 +124,11 @@ enum sel_inos {
static unsigned long sel_last_ino = SEL_INO_NEXT - 1;
-#define SEL_INITCON_INO_OFFSET 0x01000000
-#define SEL_BOOL_INO_OFFSET 0x02000000
-#define SEL_CLASS_INO_OFFSET 0x04000000
-#define SEL_INO_MASK 0x00ffffff
+#define SEL_INITCON_INO_OFFSET 0x01000000
+#define SEL_BOOL_INO_OFFSET 0x02000000
+#define SEL_CLASS_INO_OFFSET 0x04000000
+#define SEL_POLICYCAP_INO_OFFSET 0x08000000
+#define SEL_INO_MASK 0x00ffffff
#define TMPBUFLEN 12
static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
@@ -158,9 +172,10 @@ static ssize_t sel_write_enforce(struct file * file, const char __user * buf,
if (length)
goto out;
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
- "enforcing=%d old_enforcing=%d auid=%u", new_value,
- selinux_enforcing,
- audit_get_loginuid(current->audit_context));
+ "enforcing=%d old_enforcing=%d auid=%u ses=%u",
+ new_value, selinux_enforcing,
+ audit_get_loginuid(current),
+ audit_get_sessionid(current));
selinux_enforcing = new_value;
if (selinux_enforcing)
avc_ss_reset(0);
@@ -229,8 +244,9 @@ static ssize_t sel_write_disable(struct file * file, const char __user * buf,
if (length < 0)
goto out;
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
- "selinux=0 auid=%u",
- audit_get_loginuid(current->audit_context));
+ "selinux=0 auid=%u ses=%u",
+ audit_get_loginuid(current),
+ audit_get_sessionid(current));
}
length = count;
@@ -263,6 +279,7 @@ static const struct file_operations sel_policyvers_ops = {
/* declaration for sel_write_load */
static int sel_make_bools(void);
static int sel_make_classes(void);
+static int sel_make_policycap(void);
/* declaration for sel_make_class_dirs */
static int sel_make_dir(struct inode *dir, struct dentry *dentry,
@@ -323,6 +340,12 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf,
}
ret = sel_make_classes();
+ if (ret) {
+ length = ret;
+ goto out1;
+ }
+
+ ret = sel_make_policycap();
if (ret)
length = ret;
else
@@ -335,8 +358,9 @@ out1:
(security_get_allow_unknown() ? "allow" : "deny")));
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
- "policy loaded auid=%u",
- audit_get_loginuid(current->audit_context));
+ "policy loaded auid=%u ses=%u",
+ audit_get_loginuid(current),
+ audit_get_sessionid(current));
out:
mutex_unlock(&sel_mutex);
vfree(data);
@@ -1222,7 +1246,7 @@ static int sel_avc_stats_seq_show(struct seq_file *seq, void *v)
static void sel_avc_stats_seq_stop(struct seq_file *seq, void *v)
{ }
-static struct seq_operations sel_avc_cache_stats_seq_ops = {
+static const struct seq_operations sel_avc_cache_stats_seq_ops = {
.start = sel_avc_stats_seq_start,
.next = sel_avc_stats_seq_next,
.show = sel_avc_stats_seq_show,
@@ -1399,6 +1423,24 @@ static const struct file_operations sel_perm_ops = {
.read = sel_read_perm,
};
+static ssize_t sel_read_policycap(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ int value;
+ char tmpbuf[TMPBUFLEN];
+ ssize_t length;
+ unsigned long i_ino = file->f_path.dentry->d_inode->i_ino;
+
+ value = security_policycap_supported(i_ino & SEL_INO_MASK);
+ length = scnprintf(tmpbuf, TMPBUFLEN, "%d", value);
+
+ return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
+}
+
+static const struct file_operations sel_policycap_ops = {
+ .read = sel_read_policycap,
+};
+
static int sel_make_perm_files(char *objclass, int classvalue,
struct dentry *dir)
{
@@ -1545,6 +1587,36 @@ out:
return rc;
}
+static int sel_make_policycap(void)
+{
+ unsigned int iter;
+ struct dentry *dentry = NULL;
+ struct inode *inode = NULL;
+
+ sel_remove_entries(policycap_dir);
+
+ for (iter = 0; iter <= POLICYDB_CAPABILITY_MAX; iter++) {
+ if (iter < ARRAY_SIZE(policycap_names))
+ dentry = d_alloc_name(policycap_dir,
+ policycap_names[iter]);
+ else
+ dentry = d_alloc_name(policycap_dir, "unknown");
+
+ if (dentry == NULL)
+ return -ENOMEM;
+
+ inode = sel_make_inode(policycap_dir->d_sb, S_IFREG | S_IRUGO);
+ if (inode == NULL)
+ return -ENOMEM;
+
+ inode->i_fop = &sel_policycap_ops;
+ inode->i_ino = iter | SEL_POLICYCAP_INO_OFFSET;
+ d_add(dentry, inode);
+ }
+
+ return 0;
+}
+
static int sel_make_dir(struct inode *dir, struct dentry *dentry,
unsigned long *ino)
{
@@ -1673,6 +1745,18 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
class_dir = dentry;
+ dentry = d_alloc_name(sb->s_root, "policy_capabilities");
+ if (!dentry) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
+ if (ret)
+ goto err;
+
+ policycap_dir = dentry;
+
out:
return ret;
err: