summaryrefslogtreecommitdiff
path: root/security/smack/smackfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/smack/smackfs.c')
-rw-r--r--security/smack/smackfs.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index ac4cac7c661a..90c79839271c 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -57,6 +57,9 @@ enum smk_inos {
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
SMK_UNCONFINED = 22, /* define an unconfined label */
#endif
+#ifdef CONFIG_SECURITY_SMACK_PERMISSIVE_MODE
+ SMK_PERMISSIVE = 23, /* permissive mode */
+#endif
};
/*
@@ -718,6 +721,71 @@ static const struct file_operations smk_load_ops = {
.release = seq_release,
};
+#ifdef CONFIG_SECURITY_SMACK_PERMISSIVE_MODE
+/**
+ * smk_read_permissive - read() for /smack/permissive
+ * @filp: file pointer, not actually used
+ * @buf: where to put the result
+ * @cn: maximum to send along
+ * @ppos: where to start
+ *
+ * Returns number of bytes read or error code, as appropriate
+ */
+static ssize_t smk_read_permissive(struct file *filp, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ char temp[32];
+ ssize_t rc;
+
+ if (*ppos != 0)
+ return 0;
+
+ sprintf(temp, "%d\n", permissive_mode);
+ rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
+ return rc;
+}
+
+/**
+ * smk_write_permissive - write() for /smack/permissive
+ * @file: file pointer, not actually used
+ * @buf: where to get the data from
+ * @count: bytes sent
+ * @ppos: where to start
+ *
+ * Returns number of bytes written or error code, as appropriate
+ */
+static ssize_t smk_write_permissive(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ char temp[32];
+ int i;
+
+ if (!capable(CAP_MAC_ADMIN))
+ return -EPERM;
+
+ if (count >= sizeof(temp) || count == 0)
+ return -EINVAL;
+
+ if (copy_from_user(temp, buf, count) != 0)
+ return -EFAULT;
+
+ temp[count] = '\0';
+
+ if (sscanf(temp, "%d", &i) != 1)
+ return -EINVAL;
+ if (i < 0 || i > 1)
+ return -EINVAL;
+ permissive_mode = i;
+ return count;
+}
+
+static const struct file_operations smk_permissive_ops = {
+ .read = smk_read_permissive,
+ .write = smk_write_permissive,
+ .llseek = default_llseek,
+};
+#endif /* End of CONFIG_SECURITY_SMACK_PERMISSIVE_MODE */
+
/**
* smk_cipso_doi - initialize the CIPSO domain
*/
@@ -2479,6 +2547,10 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
[SMK_UNCONFINED] = {
"unconfined", &smk_unconfined_ops, S_IRUGO|S_IWUSR},
#endif
+#ifdef CONFIG_SECURITY_SMACK_PERMISSIVE_MODE
+ [SMK_PERMISSIVE] = {
+ "permissive", &smk_permissive_ops, S_IRUGO|S_IWUSR},
+#endif
/* last one */
{""}
};