smack: add permissive mode for debugging purpose
authorChanho Park <chanho61.park@samsung.com>
Tue, 3 Jun 2014 10:54:53 +0000 (19:54 +0900)
committerChanho Park <chanho61.park@samsung.com>
Thu, 6 Nov 2014 11:04:18 +0000 (20:04 +0900)
Change-Id: I4389736181c63ae5af670695784cedd21631ba89
Signed-off-by: Chanho Park <chanho61.park@samsung.com>
security/smack/Kconfig
security/smack/smack.h
security/smack/smack_access.c
security/smack/smack_lsm.c
security/smack/smackfs.c

index e69de9c..9da1158 100644 (file)
@@ -12,3 +12,10 @@ config SECURITY_SMACK
          of other mandatory security schemes.
          If you are unsure how to answer this question, answer N.
 
+config SECURITY_SMACK_PERMISSIVE_MODE
+       bool "Enable Permissive mode for debugging purpose"
+       depends on SECURITY_SMACK
+       help
+         This selects the permissive mode of smack for debug purpose. This
+         do not block any access of the smack policy and just warn the block
+         by log message.
index d072fd3..3ade3e2 100644 (file)
@@ -318,6 +318,15 @@ static inline int smack_privileged(int cap)
        return 0;
 }
 
+#ifdef CONFIG_SECURITY_SMACK_PERMISSIVE_MODE
+/*
+ * permissive mode
+ */
+#define SMACK_PERMISSIVE_DENIED 0x0
+#define SMACK_PERMISSIVE_ALLOWED 0x1
+extern int permissive_mode;
+#endif
+
 /*
  * logging functions
  */
index 14293cd..e0aa8bd 100644 (file)
@@ -55,6 +55,14 @@ LIST_HEAD(smack_known_list);
 static u32 smack_next_secid = 10;
 
 /*
+ * are we running in permissive mode?
+ * can be overwritten at run-time by /smack/permissive
+ */
+#ifdef CONFIG_SECURITY_SMACK_PERMISSIVE_MODE
+int permissive_mode = SMACK_PERMISSIVE_ALLOWED;
+#endif
+
+/*
  * what events do we log
  * can be overwritten at run-time by /smack/logging
  */
@@ -188,6 +196,10 @@ out_audit:
                smack_log(subject_known->smk_known, object_label, request,
                                rc, a);
 #endif
+#ifdef CONFIG_SECURITY_SMACK_PERMISSIVE_MODE
+       if (permissive_mode == SMACK_PERMISSIVE_ALLOWED)
+               return 0;
+#endif
        return rc;
 }
 
index 14f52be..cb484a7 100644 (file)
@@ -3936,6 +3936,17 @@ static __init int smack_init(void)
        return 0;
 }
 
+#ifdef CONFIG_SECURITY_SMACK_PERMISSIVE_MODE
+static int __init mode_setup(char *str)
+{
+       unsigned long mode;
+       if (!kstrtoul(str, 10, &mode))
+               permissive_mode = mode ? 1 : 0;
+       return 1;
+}
+__setup("permissive=", mode_setup);
+#endif
+
 /*
  * Smack requires early initialization in order to label
  * all processes and objects when they are created.
index 3198cfe..16efd03 100644 (file)
@@ -53,6 +53,9 @@ enum smk_inos {
        SMK_REVOKE_SUBJ = 18,   /* set rules with subject label to '-' */
        SMK_CHANGE_RULE = 19,   /* change or add rules (long labels) */
        SMK_SYSLOG      = 20,   /* change syslog label) */
+#ifdef CONFIG_SECURITY_SMACK_PERMISSIVE_MODE
+       SMK_PERMISSIVE  = 21,   /* permissive mode */
+#endif
 };
 
 /*
@@ -685,6 +688,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
  */
@@ -2296,6 +2364,10 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
                        "change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR},
                [SMK_SYSLOG] = {
                        "syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR},
+#ifdef CONFIG_SECURITY_SMACK_PERMISSIVE_MODE
+               [SMK_PERMISSIVE] = {
+                       "permissive", &smk_permissive_ops, S_IRUGO|S_IWUSR},
+#endif
                /* last one */
                        {""}
        };