apparmor: add lib fn to find the "split" for fqnames
authorJohn Johansen <john.johansen@canonical.com>
Mon, 16 Jan 2017 08:42:23 +0000 (00:42 -0800)
committerJohn Johansen <john.johansen@canonical.com>
Mon, 16 Jan 2017 09:18:21 +0000 (01:18 -0800)
Signed-off-by: John Johansen <john.johansen@canonical.com>
security/apparmor/include/lib.h
security/apparmor/lib.c

index 74cc68e..4699c2b 100644 (file)
@@ -38,6 +38,8 @@ extern int apparmor_initialized __initdata;
 
 /* fn's in lib */
 char *aa_split_fqname(char *args, char **ns_name);
+const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name,
+                            size_t *ns_len);
 void aa_info_message(const char *str);
 void *__aa_kvmalloc(size_t size, gfp_t flags);
 
index e29ccdb..fec78ee 100644 (file)
@@ -12,6 +12,7 @@
  * License.
  */
 
+#include <linux/ctype.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/string.h>
@@ -61,6 +62,58 @@ char *aa_split_fqname(char *fqname, char **ns_name)
 }
 
 /**
+ * skipn_spaces - Removes leading whitespace from @str.
+ * @str: The string to be stripped.
+ *
+ * Returns a pointer to the first non-whitespace character in @str.
+ * if all whitespace will return NULL
+ */
+
+static const char *skipn_spaces(const char *str, size_t n)
+{
+       for (; n && isspace(*str); --n)
+               ++str;
+       if (n)
+               return (char *)str;
+       return NULL;
+}
+
+const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name,
+                            size_t *ns_len)
+{
+       const char *end = fqname + n;
+       const char *name = skipn_spaces(fqname, n);
+
+       if (!name)
+               return NULL;
+       *ns_name = NULL;
+       *ns_len = 0;
+       if (name[0] == ':') {
+               char *split = strnchr(&name[1], end - &name[1], ':');
+               *ns_name = skipn_spaces(&name[1], end - &name[1]);
+               if (!*ns_name)
+                       return NULL;
+               if (split) {
+                       *ns_len = split - *ns_name;
+                       if (*ns_len == 0)
+                               *ns_name = NULL;
+                       split++;
+                       if (end - split > 1 && strncmp(split, "//", 2) == 0)
+                               split += 2;
+                       name = skipn_spaces(split, end - split);
+               } else {
+                       /* a ns name without a following profile is allowed */
+                       name = NULL;
+                       *ns_len = end - *ns_name;
+               }
+       }
+       if (name && *name == 0)
+               name = NULL;
+
+       return name;
+}
+
+/**
  * aa_info_message - log a none profile related status message
  * @str: message to log
  */