TOMOYO: Allow using argv[]/envp[] of execve() as conditions.
[deliverable/linux.git] / security / tomoyo / common.c
index ec02d2ab08c3762f639960f5f73f1f881e8d3df8..4f9047e94bd172b8d2b3eee771b2735074f13069 100644 (file)
@@ -60,6 +60,8 @@ const char * const tomoyo_condition_keyword[TOMOYO_MAX_CONDITION_KEYWORD] = {
        [TOMOYO_TASK_FSGID]           = "task.fsgid",
        [TOMOYO_TASK_PID]             = "task.pid",
        [TOMOYO_TASK_PPID]            = "task.ppid",
+       [TOMOYO_EXEC_ARGC]            = "exec.argc",
+       [TOMOYO_EXEC_ENVC]            = "exec.envc",
        [TOMOYO_TYPE_IS_SOCKET]       = "socket",
        [TOMOYO_TYPE_IS_SYMLINK]      = "symlink",
        [TOMOYO_TYPE_IS_FILE]         = "file",
@@ -79,6 +81,8 @@ const char * const tomoyo_condition_keyword[TOMOYO_MAX_CONDITION_KEYWORD] = {
        [TOMOYO_MODE_OTHERS_READ]     = "others_read",
        [TOMOYO_MODE_OTHERS_WRITE]    = "others_write",
        [TOMOYO_MODE_OTHERS_EXECUTE]  = "others_execute",
+       [TOMOYO_EXEC_REALPATH]        = "exec.realpath",
+       [TOMOYO_SYMLINK_TARGET]       = "symlink.target",
        [TOMOYO_PATH1_UID]            = "path1.uid",
        [TOMOYO_PATH1_GID]            = "path1.gid",
        [TOMOYO_PATH1_INO]            = "path1.ino",
@@ -352,6 +356,27 @@ static void tomoyo_print_name_union(struct tomoyo_io_buffer *head,
        }
 }
 
+/**
+ * tomoyo_print_name_union_quoted - Print a tomoyo_name_union with a quote.
+ *
+ * @head: Pointer to "struct tomoyo_io_buffer".
+ * @ptr:  Pointer to "struct tomoyo_name_union".
+ *
+ * Returns nothing.
+ */
+static void tomoyo_print_name_union_quoted(struct tomoyo_io_buffer *head,
+                                          const struct tomoyo_name_union *ptr)
+{
+       if (ptr->group) {
+               tomoyo_set_string(head, "@");
+               tomoyo_set_string(head, ptr->group->group_name->name);
+       } else {
+               tomoyo_set_string(head, "\"");
+               tomoyo_set_string(head, ptr->filename->name);
+               tomoyo_set_string(head, "\"");
+       }
+}
+
 /**
  * tomoyo_print_number_union_nospace - Print a tomoyo_number_union without a space.
  *
@@ -1101,17 +1126,33 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head,
                                (typeof(condp)) (cond + 1);
                        const struct tomoyo_number_union *numbers_p =
                                (typeof(numbers_p)) (condp + condc);
+                       const struct tomoyo_name_union *names_p =
+                               (typeof(names_p))
+                               (numbers_p + cond->numbers_count);
+                       const struct tomoyo_argv *argv =
+                               (typeof(argv)) (names_p + cond->names_count);
+                       const struct tomoyo_envp *envp =
+                               (typeof(envp)) (argv + cond->argc);
                        u16 skip;
                        for (skip = 0; skip < head->r.cond_index; skip++) {
                                const u8 left = condp->left;
                                const u8 right = condp->right;
                                condp++;
                                switch (left) {
+                               case TOMOYO_ARGV_ENTRY:
+                                       argv++;
+                                       continue;
+                               case TOMOYO_ENVP_ENTRY:
+                                       envp++;
+                                       continue;
                                case TOMOYO_NUMBER_UNION:
                                        numbers_p++;
                                        break;
                                }
                                switch (right) {
+                               case TOMOYO_NAME_UNION:
+                                       names_p++;
+                                       break;
                                case TOMOYO_NUMBER_UNION:
                                        numbers_p++;
                                        break;
@@ -1127,6 +1168,34 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head,
                                head->r.cond_index++;
                                tomoyo_set_space(head);
                                switch (left) {
+                               case TOMOYO_ARGV_ENTRY:
+                                       tomoyo_io_printf(head,
+                                                        "exec.argv[%lu]%s=\"",
+                                                        argv->index, argv->
+                                                        is_not ? "!" : "");
+                                       tomoyo_set_string(head,
+                                                         argv->value->name);
+                                       tomoyo_set_string(head, "\"");
+                                       argv++;
+                                       continue;
+                               case TOMOYO_ENVP_ENTRY:
+                                       tomoyo_set_string(head,
+                                                         "exec.envp[\"");
+                                       tomoyo_set_string(head,
+                                                         envp->name->name);
+                                       tomoyo_io_printf(head, "\"]%s=", envp->
+                                                        is_not ? "!" : "");
+                                       if (envp->value) {
+                                               tomoyo_set_string(head, "\"");
+                                               tomoyo_set_string(head, envp->
+                                                                 value->name);
+                                               tomoyo_set_string(head, "\"");
+                                       } else {
+                                               tomoyo_set_string(head,
+                                                                 "NULL");
+                                       }
+                                       envp++;
+                                       continue;
                                case TOMOYO_NUMBER_UNION:
                                        tomoyo_print_number_union_nospace
                                                (head, numbers_p++);
@@ -1138,6 +1207,10 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head,
                                }
                                tomoyo_set_string(head, match ? "=" : "!=");
                                switch (right) {
+                               case TOMOYO_NAME_UNION:
+                                       tomoyo_print_name_union_quoted
+                                               (head, names_p++);
+                                       break;
                                case TOMOYO_NUMBER_UNION:
                                        tomoyo_print_number_union_nospace
                                                (head, numbers_p++);
@@ -1665,6 +1738,22 @@ static DEFINE_SPINLOCK(tomoyo_query_list_lock);
  */
 static atomic_t tomoyo_query_observers = ATOMIC_INIT(0);
 
+/**
+ * tomoyo_truncate - Truncate a line.
+ *
+ * @str: String to truncate.
+ *
+ * Returns length of truncated @str.
+ */
+static int tomoyo_truncate(char *str)
+{
+       char *start = str;
+       while (*(unsigned char *) str > (unsigned char) ' ')
+               str++;
+       *str = '\0';
+       return strlen(start) + 1;
+}
+
 /**
  * tomoyo_add_entry - Add an ACL to current thread's domain. Used by learning mode.
  *
@@ -1676,6 +1765,9 @@ static atomic_t tomoyo_query_observers = ATOMIC_INIT(0);
 static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
 {
        char *buffer;
+       char *realpath = NULL;
+       char *argv0 = NULL;
+       char *symlink = NULL;
        char *cp = strchr(header, '\n');
        int len;
        if (!cp)
@@ -1685,10 +1777,32 @@ static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
                return;
        *cp++ = '\0';
        len = strlen(cp) + 1;
+       /* strstr() will return NULL if ordering is wrong. */
+       if (*cp == 'f') {
+               argv0 = strstr(header, " argv[]={ \"");
+               if (argv0) {
+                       argv0 += 10;
+                       len += tomoyo_truncate(argv0) + 14;
+               }
+               realpath = strstr(header, " exec={ realpath=\"");
+               if (realpath) {
+                       realpath += 8;
+                       len += tomoyo_truncate(realpath) + 6;
+               }
+               symlink = strstr(header, " symlink.target=\"");
+               if (symlink)
+                       len += tomoyo_truncate(symlink + 1) + 1;
+       }
        buffer = kmalloc(len, GFP_NOFS);
        if (!buffer)
                return;
        snprintf(buffer, len - 1, "%s", cp);
+       if (realpath)
+               tomoyo_addprintf(buffer, len, " exec.%s", realpath);
+       if (argv0)
+               tomoyo_addprintf(buffer, len, " exec.argv[0]=%s", argv0);
+       if (symlink)
+               tomoyo_addprintf(buffer, len, "%s", symlink);
        tomoyo_normalize_line(buffer);
        if (!tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer,
                                  false))
This page took 0.027214 seconds and 5 git commands to generate.