TOMOYO: Cleanup part 3.
Tetsuo Handa [Sun, 26 Jun 2011 14:16:36 +0000 (23:16 +0900)]
Use common structure for ACL with "struct list_head" + "atomic_t".
Use array/struct where possible.
Remove is_group from "struct tomoyo_name_union"/"struct tomoyo_number_union".
Pass "struct file"->private_data rather than "struct file".
Update some of comments.
Bring tomoyo_same_acl_head() from common.h to domain.c .
Bring tomoyo_invalid()/tomoyo_valid() from common.h to util.c .

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>

security/tomoyo/common.c
security/tomoyo/common.h
security/tomoyo/domain.c
security/tomoyo/file.c
security/tomoyo/gc.c
security/tomoyo/memory.c
security/tomoyo/mount.c
security/tomoyo/securityfs_if.c
security/tomoyo/util.c

index 1c34021..2e6792d 100644 (file)
@@ -192,7 +192,7 @@ static void tomoyo_print_name_union(struct tomoyo_io_buffer *head,
                                    const struct tomoyo_name_union *ptr)
 {
        tomoyo_set_space(head);
-       if (ptr->is_group) {
+       if (ptr->group) {
                tomoyo_set_string(head, "@");
                tomoyo_set_string(head, ptr->group->group_name->name);
        } else {
@@ -210,15 +210,15 @@ static void tomoyo_print_number_union(struct tomoyo_io_buffer *head,
                                      const struct tomoyo_number_union *ptr)
 {
        tomoyo_set_space(head);
-       if (ptr->is_group) {
+       if (ptr->group) {
                tomoyo_set_string(head, "@");
                tomoyo_set_string(head, ptr->group->group_name->name);
        } else {
                int i;
                unsigned long min = ptr->values[0];
                const unsigned long max = ptr->values[1];
-               u8 min_type = ptr->min_type;
-               const u8 max_type = ptr->max_type;
+               u8 min_type = ptr->value_type[0];
+               const u8 max_type = ptr->value_type[1];
                char buffer[128];
                buffer[0] = '\0';
                for (i = 0; i < 2; i++) {
@@ -769,7 +769,7 @@ static bool tomoyo_select_one(struct tomoyo_io_buffer *head, const char *data)
                        domain = tomoyo_find_domain(data + 7);
        } else
                return false;
-       head->write_var1 = domain;
+       head->w.domain = domain;
        /* Accessing read_buf is safe because head->io_sem is held. */
        if (!head->read_buf)
                return true; /* Do nothing if open(O_WRONLY). */
@@ -847,7 +847,7 @@ static int tomoyo_write_domain2(char *data, struct tomoyo_domain_info *domain,
 static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
 {
        char *data = head->write_buf;
-       struct tomoyo_domain_info *domain = head->write_var1;
+       struct tomoyo_domain_info *domain = head->w.domain;
        bool is_delete = false;
        bool is_select = false;
        unsigned int profile;
@@ -869,7 +869,7 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
                        domain = tomoyo_find_domain(data);
                else
                        domain = tomoyo_assign_domain(data, 0);
-               head->write_var1 = domain;
+               head->w.domain = domain;
                return 0;
        }
        if (!domain)
@@ -1250,7 +1250,7 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
 {
        list_for_each_cookie(head->r.group, &tomoyo_group_list[idx]) {
                struct tomoyo_group *group =
-                       list_entry(head->r.group, typeof(*group), list);
+                       list_entry(head->r.group, typeof(*group), head.list);
                list_for_each_cookie(head->r.acl, &group->member_list) {
                        struct tomoyo_acl_head *ptr =
                                list_entry(head->r.acl, typeof(*ptr), list);
@@ -1874,7 +1874,7 @@ int tomoyo_poll_control(struct file *file, poll_table *wait)
 /**
  * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface.
  *
- * @file:       Pointer to "struct file".
+ * @head:       Pointer to "struct tomoyo_io_buffer".
  * @buffer:     Poiner to buffer to write to.
  * @buffer_len: Size of @buffer.
  *
@@ -1882,11 +1882,10 @@ int tomoyo_poll_control(struct file *file, poll_table *wait)
  *
  * Caller holds tomoyo_read_lock().
  */
-int tomoyo_read_control(struct file *file, char __user *buffer,
+int tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer,
                        const int buffer_len)
 {
        int len;
-       struct tomoyo_io_buffer *head = file->private_data;
 
        if (!head->read)
                return -ENOSYS;
@@ -1906,7 +1905,7 @@ int tomoyo_read_control(struct file *file, char __user *buffer,
 /**
  * tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface.
  *
- * @file:       Pointer to "struct file".
+ * @head:       Pointer to "struct tomoyo_io_buffer".
  * @buffer:     Pointer to buffer to read from.
  * @buffer_len: Size of @buffer.
  *
@@ -1914,10 +1913,9 @@ int tomoyo_read_control(struct file *file, char __user *buffer,
  *
  * Caller holds tomoyo_read_lock().
  */
-int tomoyo_write_control(struct file *file, const char __user *buffer,
-                        const int buffer_len)
+int tomoyo_write_control(struct tomoyo_io_buffer *head,
+                        const char __user *buffer, const int buffer_len)
 {
-       struct tomoyo_io_buffer *head = file->private_data;
        int error = buffer_len;
        int avail_len = buffer_len;
        char *cp0 = head->write_buf;
@@ -1935,7 +1933,7 @@ int tomoyo_write_control(struct file *file, const char __user *buffer,
        /* Read a line and dispatch it to the policy handler. */
        while (avail_len > 0) {
                char c;
-               if (head->write_avail >= head->writebuf_size - 1) {
+               if (head->w.avail >= head->writebuf_size - 1) {
                        error = -ENOMEM;
                        break;
                } else if (get_user(c, buffer)) {
@@ -1944,11 +1942,11 @@ int tomoyo_write_control(struct file *file, const char __user *buffer,
                }
                buffer++;
                avail_len--;
-               cp0[head->write_avail++] = c;
+               cp0[head->w.avail++] = c;
                if (c != '\n')
                        continue;
-               cp0[head->write_avail - 1] = '\0';
-               head->write_avail = 0;
+               cp0[head->w.avail - 1] = '\0';
+               head->w.avail = 0;
                tomoyo_normalize_line(cp0);
                head->write(head);
        }
@@ -1959,15 +1957,14 @@ int tomoyo_write_control(struct file *file, const char __user *buffer,
 /**
  * tomoyo_close_control - close() for /sys/kernel/security/tomoyo/ interface.
  *
- * @file: Pointer to "struct file".
+ * @head: Pointer to "struct tomoyo_io_buffer".
  *
  * Releases memory and returns 0.
  *
  * Caller looses tomoyo_read_lock().
  */
-int tomoyo_close_control(struct file *file)
+int tomoyo_close_control(struct tomoyo_io_buffer *head)
 {
-       struct tomoyo_io_buffer *head = file->private_data;
        const bool is_write = !!head->write_buf;
 
        /*
@@ -1984,8 +1981,6 @@ int tomoyo_close_control(struct file *file)
        kfree(head->write_buf);
        head->write_buf = NULL;
        kfree(head);
-       head = NULL;
-       file->private_data = NULL;
        if (is_write)
                tomoyo_run_gc();
        return 0;
index d064573..7aa55ee 100644 (file)
@@ -219,6 +219,12 @@ struct tomoyo_acl_head {
        bool is_deleted;
 } __packed;
 
+/* Common header for shared entries. */
+struct tomoyo_shared_acl_head {
+       struct list_head list;
+       atomic_t users;
+} __packed;
+
 /* Structure for request info. */
 struct tomoyo_request_info {
        struct tomoyo_domain_info *domain;
@@ -281,8 +287,7 @@ struct tomoyo_path_info {
 
 /* Structure for holding string data. */
 struct tomoyo_name {
-       struct list_head list;
-       atomic_t users;
+       struct tomoyo_shared_acl_head head;
        struct tomoyo_path_info entry;
 };
 
@@ -291,8 +296,6 @@ struct tomoyo_name_union {
        /* Either @filename or @group is NULL. */
        const struct tomoyo_path_info *filename;
        struct tomoyo_group *group;
-       /* True if @group != NULL, false if @filename != NULL. */
-       u8 is_group;
 };
 
 /* Structure for holding a number. */
@@ -300,18 +303,14 @@ struct tomoyo_number_union {
        unsigned long values[2];
        struct tomoyo_group *group; /* Maybe NULL. */
        /* One of values in "enum tomoyo_value_type". */
-       u8 min_type;
-       u8 max_type;
-       /* True if @group != NULL, false otherwise. */
-       u8 is_group;
+       u8 value_type[2];
 };
 
 /* Structure for "path_group"/"number_group" directive. */
 struct tomoyo_group {
-       struct list_head list;
+       struct tomoyo_shared_acl_head head;
        const struct tomoyo_path_info *group_name;
        struct list_head member_list;
-       atomic_t users;
 };
 
 /* Structure for "path_group" directive. */
@@ -429,16 +428,18 @@ struct tomoyo_io_buffer {
                bool print_execute_only;
                const char *w[TOMOYO_MAX_IO_READ_QUEUE];
        } r;
-       /* The position currently writing to.   */
-       struct tomoyo_domain_info *write_var1;
+       struct {
+               /* The position currently writing to.   */
+               struct tomoyo_domain_info *domain;
+               /* Bytes available for writing.         */
+               int avail;
+       } w;
        /* Buffer for reading.                  */
        char *read_buf;
        /* Size of read buffer.                 */
        int readbuf_size;
        /* Buffer for writing.                  */
        char *write_buf;
-       /* Bytes available for writing.         */
-       int write_avail;
        /* Size of write buffer.                */
        int writebuf_size;
        /* Type of this interface.              */
@@ -500,12 +501,12 @@ void tomoyo_warn_log(struct tomoyo_request_info *r, const char *fmt, ...)
      __attribute__ ((format(printf, 2, 3)));
 void tomoyo_check_profile(void);
 int tomoyo_open_control(const u8 type, struct file *file);
-int tomoyo_close_control(struct file *file);
+int tomoyo_close_control(struct tomoyo_io_buffer *head);
 int tomoyo_poll_control(struct file *file, poll_table *wait);
-int tomoyo_read_control(struct file *file, char __user *buffer,
+int tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer,
                        const int buffer_len);
-int tomoyo_write_control(struct file *file, const char __user *buffer,
-                        const int buffer_len);
+int tomoyo_write_control(struct tomoyo_io_buffer *head,
+                        const char __user *buffer, const int buffer_len);
 bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r);
 void tomoyo_warn_oom(const char *function);
 const struct tomoyo_path_info *
@@ -672,30 +673,6 @@ static inline bool tomoyo_pathcmp(const struct tomoyo_path_info *a,
 }
 
 /**
- * tomoyo_valid - Check whether the character is a valid char.
- *
- * @c: The character to check.
- *
- * Returns true if @c is a valid character, false otherwise.
- */
-static inline bool tomoyo_valid(const unsigned char c)
-{
-       return c > ' ' && c < 127;
-}
-
-/**
- * tomoyo_invalid - Check whether the character is an invalid char.
- *
- * @c: The character to check.
- *
- * Returns true if @c is an invalid character, false otherwise.
- */
-static inline bool tomoyo_invalid(const unsigned char c)
-{
-       return c && (c <= ' ' || c >= 127);
-}
-
-/**
  * tomoyo_put_name - Drop reference on "struct tomoyo_name".
  *
  * @name: Pointer to "struct tomoyo_path_info". Maybe NULL.
@@ -707,7 +684,7 @@ static inline void tomoyo_put_name(const struct tomoyo_path_info *name)
        if (name) {
                struct tomoyo_name *ptr =
                        container_of(name, typeof(*ptr), entry);
-               atomic_dec(&ptr->users);
+               atomic_dec(&ptr->head.users);
        }
 }
 
@@ -721,7 +698,7 @@ static inline void tomoyo_put_name(const struct tomoyo_path_info *name)
 static inline void tomoyo_put_group(struct tomoyo_group *group)
 {
        if (group)
-               atomic_dec(&group->users);
+               atomic_dec(&group->head.users);
 }
 
 /**
@@ -747,12 +724,6 @@ static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct
        return task_cred_xxx(task, security);
 }
 
-static inline bool tomoyo_same_acl_head(const struct tomoyo_acl_info *p1,
-                                       const struct tomoyo_acl_info *p2)
-{
-       return p1->type == p2->type;
-}
-
 /**
  * tomoyo_same_name_union - Check for duplicated "struct tomoyo_name_union" entry.
  *
@@ -764,8 +735,7 @@ static inline bool tomoyo_same_acl_head(const struct tomoyo_acl_info *p1,
 static inline bool tomoyo_same_name_union
 (const struct tomoyo_name_union *a, const struct tomoyo_name_union *b)
 {
-       return a->filename == b->filename && a->group == b->group &&
-               a->is_group == b->is_group;
+       return a->filename == b->filename && a->group == b->group;
 }
 
 /**
@@ -780,8 +750,8 @@ static inline bool tomoyo_same_number_union
 (const struct tomoyo_number_union *a, const struct tomoyo_number_union *b)
 {
        return a->values[0] == b->values[0] && a->values[1] == b->values[1] &&
-               a->group == b->group && a->min_type == b->min_type &&
-               a->max_type == b->max_type && a->is_group == b->is_group;
+               a->group == b->group && a->value_type[0] == b->value_type[0] &&
+               a->value_type[1] == b->value_type[1];
 }
 
 /**
index 355b536..4397708 100644 (file)
@@ -59,6 +59,20 @@ int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
 }
 
 /**
+ * tomoyo_same_acl_head - Check for duplicated "struct tomoyo_acl_info" entry.
+ *
+ * @a: Pointer to "struct tomoyo_acl_info".
+ * @b: Pointer to "struct tomoyo_acl_info".
+ *
+ * Returns true if @a == @b, false otherwise.
+ */
+static inline bool tomoyo_same_acl_head(const struct tomoyo_acl_info *a,
+                                       const struct tomoyo_acl_info *b)
+{
+       return a->type == b->type;
+}
+
+/**
  * tomoyo_update_domain - Update an entry for domain policy.
  *
  * @new_entry:       Pointer to "struct tomoyo_acl_info".
@@ -88,7 +102,8 @@ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
        if (mutex_lock_interruptible(&tomoyo_policy_lock))
                return error;
        list_for_each_entry_rcu(entry, &domain->acl_info_list, list) {
-               if (!check_duplicate(entry, new_entry))
+               if (!tomoyo_same_acl_head(entry, new_entry) ||
+                   !check_duplicate(entry, new_entry))
                        continue;
                if (merge_duplicate)
                        entry->is_deleted = merge_duplicate(entry, new_entry,
index 3323802..4259e0a 100644 (file)
@@ -49,6 +49,9 @@ const char *tomoyo_path_number_keyword[TOMOYO_MAX_PATH_NUMBER_OPERATION] = {
        [TOMOYO_TYPE_CHGRP]      = "chgrp",
 };
 
+/*
+ * Mapping table from "enum tomoyo_path_acl_index" to "enum tomoyo_mac_index".
+ */
 static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = {
        [TOMOYO_TYPE_EXECUTE]    = TOMOYO_MAC_FILE_EXECUTE,
        [TOMOYO_TYPE_READ]       = TOMOYO_MAC_FILE_OPEN,
@@ -63,17 +66,27 @@ static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = {
        [TOMOYO_TYPE_UMOUNT]     = TOMOYO_MAC_FILE_UMOUNT,
 };
 
+/*
+ * Mapping table from "enum tomoyo_mkdev_acl_index" to "enum tomoyo_mac_index".
+ */
 static const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION] = {
        [TOMOYO_TYPE_MKBLOCK] = TOMOYO_MAC_FILE_MKBLOCK,
        [TOMOYO_TYPE_MKCHAR]  = TOMOYO_MAC_FILE_MKCHAR,
 };
 
+/*
+ * Mapping table from "enum tomoyo_path2_acl_index" to "enum tomoyo_mac_index".
+ */
 static const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION] = {
        [TOMOYO_TYPE_LINK]       = TOMOYO_MAC_FILE_LINK,
        [TOMOYO_TYPE_RENAME]     = TOMOYO_MAC_FILE_RENAME,
        [TOMOYO_TYPE_PIVOT_ROOT] = TOMOYO_MAC_FILE_PIVOT_ROOT,
 };
 
+/*
+ * Mapping table from "enum tomoyo_path_number_acl_index" to
+ * "enum tomoyo_mac_index".
+ */
 static const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = {
        [TOMOYO_TYPE_CREATE] = TOMOYO_MAC_FILE_CREATE,
        [TOMOYO_TYPE_MKDIR]  = TOMOYO_MAC_FILE_MKDIR,
@@ -85,41 +98,76 @@ static const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = {
        [TOMOYO_TYPE_CHGRP]  = TOMOYO_MAC_FILE_CHGRP,
 };
 
+/**
+ * tomoyo_put_name_union - Drop reference on "struct tomoyo_name_union".
+ *
+ * @ptr: Pointer to "struct tomoyo_name_union".
+ *
+ * Returns nothing.
+ */
 void tomoyo_put_name_union(struct tomoyo_name_union *ptr)
 {
-       if (!ptr)
-               return;
-       if (ptr->is_group)
-               tomoyo_put_group(ptr->group);
-       else
-               tomoyo_put_name(ptr->filename);
+       tomoyo_put_group(ptr->group);
+       tomoyo_put_name(ptr->filename);
 }
 
+/**
+ * tomoyo_compare_name_union - Check whether a name matches "struct tomoyo_name_union" or not.
+ *
+ * @name: Pointer to "struct tomoyo_path_info".
+ * @ptr:  Pointer to "struct tomoyo_name_union".
+ *
+ * Returns "struct tomoyo_path_info" if @name matches @ptr, NULL otherwise.
+ */
 const struct tomoyo_path_info *
 tomoyo_compare_name_union(const struct tomoyo_path_info *name,
                          const struct tomoyo_name_union *ptr)
 {
-       if (ptr->is_group)
+       if (ptr->group)
                return tomoyo_path_matches_group(name, ptr->group);
        if (tomoyo_path_matches_pattern(name, ptr->filename))
                return ptr->filename;
        return NULL;
 }
 
+/**
+ * tomoyo_put_number_union - Drop reference on "struct tomoyo_number_union".
+ *
+ * @ptr: Pointer to "struct tomoyo_number_union".
+ *
+ * Returns nothing.
+ */
 void tomoyo_put_number_union(struct tomoyo_number_union *ptr)
 {
-       if (ptr && ptr->is_group)
-               tomoyo_put_group(ptr->group);
+       tomoyo_put_group(ptr->group);
 }
 
+/**
+ * tomoyo_compare_number_union - Check whether a value matches "struct tomoyo_number_union" or not.
+ *
+ * @value: Number to check.
+ * @ptr:   Pointer to "struct tomoyo_number_union".
+ *
+ * Returns true if @value matches @ptr, false otherwise.
+ */
 bool tomoyo_compare_number_union(const unsigned long value,
                                 const struct tomoyo_number_union *ptr)
 {
-       if (ptr->is_group)
+       if (ptr->group)
                return tomoyo_number_matches_group(value, value, ptr->group);
        return value >= ptr->values[0] && value <= ptr->values[1];
 }
 
+/**
+ * tomoyo_add_slash - Add trailing '/' if needed.
+ *
+ * @buf: Pointer to "struct tomoyo_path_info".
+ *
+ * Returns nothing.
+ *
+ * @buf must be generated by tomoyo_encode() because this function does not
+ * allocate memory for adding '/'.
+ */
 static void tomoyo_add_slash(struct tomoyo_path_info *buf)
 {
        if (buf->is_dir)
@@ -247,6 +295,18 @@ static int tomoyo_audit_path_number_log(struct tomoyo_request_info *r)
                                 filename->name, buffer);
 }
 
+/**
+ * tomoyo_check_path_acl - Check permission for path operation.
+ *
+ * @r:   Pointer to "struct tomoyo_request_info".
+ * @ptr: Pointer to "struct tomoyo_acl_info".
+ *
+ * Returns true if granted, false otherwise.
+ *
+ * To be able to use wildcard for domain transition, this function sets
+ * matching entry on success. Since the caller holds tomoyo_read_lock(),
+ * it is safe to set matching entry.
+ */
 static bool tomoyo_check_path_acl(struct tomoyo_request_info *r,
                                  const struct tomoyo_acl_info *ptr)
 {
@@ -261,6 +321,14 @@ static bool tomoyo_check_path_acl(struct tomoyo_request_info *r,
        return false;
 }
 
+/**
+ * tomoyo_check_path_number_acl - Check permission for path number operation.
+ *
+ * @r:   Pointer to "struct tomoyo_request_info".
+ * @ptr: Pointer to "struct tomoyo_acl_info".
+ *
+ * Returns true if granted, false otherwise.
+ */
 static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r,
                                         const struct tomoyo_acl_info *ptr)
 {
@@ -273,6 +341,14 @@ static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r,
                                          &acl->name);
 }
 
+/**
+ * tomoyo_check_path2_acl - Check permission for path path operation.
+ *
+ * @r:   Pointer to "struct tomoyo_request_info".
+ * @ptr: Pointer to "struct tomoyo_acl_info".
+ *
+ * Returns true if granted, false otherwise.
+ */
 static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r,
                                   const struct tomoyo_acl_info *ptr)
 {
@@ -284,8 +360,16 @@ static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r,
                                             &acl->name2);
 }
 
+/**
+ * tomoyo_check_mkdev_acl - Check permission for path number number number operation.
+ *
+ * @r:   Pointer to "struct tomoyo_request_info".
+ * @ptr: Pointer to "struct tomoyo_acl_info".
+ *
+ * Returns true if granted, false otherwise.
+ */
 static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r,
-                               const struct tomoyo_acl_info *ptr)
+                                  const struct tomoyo_acl_info *ptr)
 {
        const struct tomoyo_mkdev_acl *acl =
                container_of(ptr, typeof(*acl), head);
@@ -300,13 +384,20 @@ static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r,
                                          &acl->name);
 }
 
+/**
+ * tomoyo_same_path_acl - Check for duplicated "struct tomoyo_path_acl" entry.
+ *
+ * @a: Pointer to "struct tomoyo_acl_info".
+ * @b: Pointer to "struct tomoyo_acl_info".
+ *
+ * Returns true if @a == @b except permission bits, false otherwise.
+ */
 static bool tomoyo_same_path_acl(const struct tomoyo_acl_info *a,
                                 const struct tomoyo_acl_info *b)
 {
        const struct tomoyo_path_acl *p1 = container_of(a, typeof(*p1), head);
        const struct tomoyo_path_acl *p2 = container_of(b, typeof(*p2), head);
-       return tomoyo_same_acl_head(&p1->head, &p2->head) &&
-               tomoyo_same_name_union(&p1->name, &p2->name);
+       return tomoyo_same_name_union(&p1->name, &p2->name);
 }
 
 /**
@@ -364,23 +455,37 @@ static int tomoyo_update_path_acl(const u8 type, const char *filename,
        return error;
 }
 
+/**
+ * tomoyo_same_mkdev_acl - Check for duplicated "struct tomoyo_mkdev_acl" entry.
+ *
+ * @a: Pointer to "struct tomoyo_acl_info".
+ * @b: Pointer to "struct tomoyo_acl_info".
+ *
+ * Returns true if @a == @b except permission bits, false otherwise.
+ */
 static bool tomoyo_same_mkdev_acl(const struct tomoyo_acl_info *a,
                                         const struct tomoyo_acl_info *b)
 {
-       const struct tomoyo_mkdev_acl *p1 = container_of(a, typeof(*p1),
-                                                               head);
-       const struct tomoyo_mkdev_acl *p2 = container_of(b, typeof(*p2),
-                                                               head);
-       return tomoyo_same_acl_head(&p1->head, &p2->head)
-               && tomoyo_same_name_union(&p1->name, &p2->name)
-               && tomoyo_same_number_union(&p1->mode, &p2->mode)
-               && tomoyo_same_number_union(&p1->major, &p2->major)
-               && tomoyo_same_number_union(&p1->minor, &p2->minor);
+       const struct tomoyo_mkdev_acl *p1 = container_of(a, typeof(*p1), head);
+       const struct tomoyo_mkdev_acl *p2 = container_of(b, typeof(*p2), head);
+       return tomoyo_same_name_union(&p1->name, &p2->name) &&
+               tomoyo_same_number_union(&p1->mode, &p2->mode) &&
+               tomoyo_same_number_union(&p1->major, &p2->major) &&
+               tomoyo_same_number_union(&p1->minor, &p2->minor);
 }
 
+/**
+ * tomoyo_merge_mkdev_acl - Merge duplicated "struct tomoyo_mkdev_acl" entry.
+ *
+ * @a:         Pointer to "struct tomoyo_acl_info".
+ * @b:         Pointer to "struct tomoyo_acl_info".
+ * @is_delete: True for @a &= ~@b, false for @a |= @b.
+ *
+ * Returns true if @a is empty, false otherwise.
+ */
 static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a,
-                                         struct tomoyo_acl_info *b,
-                                         const bool is_delete)
+                                  struct tomoyo_acl_info *b,
+                                  const bool is_delete)
 {
        u8 *const a_perm = &container_of(a, struct tomoyo_mkdev_acl,
                                         head)->perm;
@@ -411,9 +516,9 @@ static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a,
  * Caller holds tomoyo_read_lock().
  */
 static int tomoyo_update_mkdev_acl(const u8 type, const char *filename,
-                                         char *mode, char *major, char *minor,
-                                         struct tomoyo_domain_info * const
-                                         domain, const bool is_delete)
+                                  char *mode, char *major, char *minor,
+                                  struct tomoyo_domain_info * const domain,
+                                  const bool is_delete)
 {
        struct tomoyo_mkdev_acl e = {
                .head.type = TOMOYO_TYPE_MKDEV_ACL,
@@ -436,16 +541,32 @@ static int tomoyo_update_mkdev_acl(const u8 type, const char *filename,
        return error;
 }
 
+/**
+ * tomoyo_same_path2_acl - Check for duplicated "struct tomoyo_path2_acl" entry.
+ *
+ * @a: Pointer to "struct tomoyo_acl_info".
+ * @b: Pointer to "struct tomoyo_acl_info".
+ *
+ * Returns true if @a == @b except permission bits, false otherwise.
+ */
 static bool tomoyo_same_path2_acl(const struct tomoyo_acl_info *a,
                                  const struct tomoyo_acl_info *b)
 {
        const struct tomoyo_path2_acl *p1 = container_of(a, typeof(*p1), head);
        const struct tomoyo_path2_acl *p2 = container_of(b, typeof(*p2), head);
-       return tomoyo_same_acl_head(&p1->head, &p2->head)
-               && tomoyo_same_name_union(&p1->name1, &p2->name1)
-               && tomoyo_same_name_union(&p1->name2, &p2->name2);
+       return tomoyo_same_name_union(&p1->name1, &p2->name1) &&
+               tomoyo_same_name_union(&p1->name2, &p2->name2);
 }
 
+/**
+ * tomoyo_merge_path2_acl - Merge duplicated "struct tomoyo_path2_acl" entry.
+ *
+ * @a:         Pointer to "struct tomoyo_acl_info".
+ * @b:         Pointer to "struct tomoyo_acl_info".
+ * @is_delete: True for @a &= ~@b, false for @a |= @b.
+ *
+ * Returns true if @a is empty, false otherwise.
+ */
 static bool tomoyo_merge_path2_acl(struct tomoyo_acl_info *a,
                                   struct tomoyo_acl_info *b,
                                   const bool is_delete)
@@ -532,6 +653,14 @@ int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
        return error;
 }
 
+/**
+ * tomoyo_same_path_number_acl - Check for duplicated "struct tomoyo_path_number_acl" entry.
+ *
+ * @a: Pointer to "struct tomoyo_acl_info".
+ * @b: Pointer to "struct tomoyo_acl_info".
+ *
+ * Returns true if @a == @b except permission bits, false otherwise.
+ */
 static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a,
                                        const struct tomoyo_acl_info *b)
 {
@@ -539,11 +668,19 @@ static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a,
                                                               head);
        const struct tomoyo_path_number_acl *p2 = container_of(b, typeof(*p2),
                                                               head);
-       return tomoyo_same_acl_head(&p1->head, &p2->head)
-               && tomoyo_same_name_union(&p1->name, &p2->name)
-               && tomoyo_same_number_union(&p1->number, &p2->number);
+       return tomoyo_same_name_union(&p1->name, &p2->name) &&
+               tomoyo_same_number_union(&p1->number, &p2->number);
 }
 
+/**
+ * tomoyo_merge_path_number_acl - Merge duplicated "struct tomoyo_path_number_acl" entry.
+ *
+ * @a:         Pointer to "struct tomoyo_acl_info".
+ * @b:         Pointer to "struct tomoyo_acl_info".
+ * @is_delete: True for @a &= ~@b, false for @a |= @b.
+ *
+ * Returns true if @a is empty, false otherwise.
+ */
 static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a,
                                         struct tomoyo_acl_info *b,
                                         const bool is_delete)
@@ -575,8 +712,7 @@ static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a,
 static int tomoyo_update_path_number_acl(const u8 type, const char *filename,
                                         char *number,
                                         struct tomoyo_domain_info * const
-                                        domain,
-                                        const bool is_delete)
+                                        domain, const bool is_delete)
 {
        struct tomoyo_path_number_acl e = {
                .head.type = TOMOYO_TYPE_PATH_NUMBER_ACL,
@@ -737,7 +873,7 @@ int tomoyo_path_perm(const u8 operation, struct path *path)
  * Returns 0 on success, negative value otherwise.
  */
 int tomoyo_mkdev_perm(const u8 operation, struct path *path,
-                            const unsigned int mode, unsigned int dev)
+                     const unsigned int mode, unsigned int dev)
 {
        struct tomoyo_request_info r;
        int error = -ENOMEM;
index ba799b4..de14030 100644 (file)
 
 struct tomoyo_gc {
        struct list_head list;
-       int type;
+       enum tomoyo_policy_id type;
        struct list_head *element;
 };
 static LIST_HEAD(tomoyo_gc_queue);
 static DEFINE_MUTEX(tomoyo_gc_mutex);
 
-/* Caller holds tomoyo_policy_lock mutex. */
+/**
+ * tomoyo_add_to_gc - Add an entry to to be deleted list.
+ *
+ * @type:    One of values in "enum tomoyo_policy_id".
+ * @element: Pointer to "struct list_head".
+ *
+ * Returns true on success, false otherwise.
+ *
+ * Caller holds tomoyo_policy_lock mutex.
+ *
+ * Adding an entry needs kmalloc(). Thus, if we try to add thousands of
+ * entries at once, it will take too long time. Thus, do not add more than 128
+ * entries per a scan. But to be able to handle worst case where all entries
+ * are in-use, we accept one more entry per a scan.
+ *
+ * If we use singly linked list using "struct list_head"->prev (which is
+ * LIST_POISON2), we can avoid kmalloc().
+ */
 static bool tomoyo_add_to_gc(const int type, struct list_head *element)
 {
        struct tomoyo_gc *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
@@ -32,6 +49,13 @@ static bool tomoyo_add_to_gc(const int type, struct list_head *element)
        return true;
 }
 
+/**
+ * tomoyo_del_transition_control - Delete members in "struct tomoyo_transition_control".
+ *
+ * @element: Pointer to "struct list_head".
+ *
+ * Returns nothing.
+ */
 static void tomoyo_del_transition_control(struct list_head *element)
 {
        struct tomoyo_transition_control *ptr =
@@ -40,6 +64,13 @@ static void tomoyo_del_transition_control(struct list_head *element)
        tomoyo_put_name(ptr->program);
 }
 
+/**
+ * tomoyo_del_aggregator - Delete members in "struct tomoyo_aggregator".
+ *
+ * @element: Pointer to "struct list_head".
+ *
+ * Returns nothing.
+ */
 static void tomoyo_del_aggregator(struct list_head *element)
 {
        struct tomoyo_aggregator *ptr =
@@ -48,6 +79,13 @@ static void tomoyo_del_aggregator(struct list_head *element)
        tomoyo_put_name(ptr->aggregated_name);
 }
 
+/**
+ * tomoyo_del_manager - Delete members in "struct tomoyo_manager".
+ *
+ * @element: Pointer to "struct list_head".
+ *
+ * Returns nothing.
+ */
 static void tomoyo_del_manager(struct list_head *element)
 {
        struct tomoyo_manager *ptr =
@@ -55,6 +93,13 @@ static void tomoyo_del_manager(struct list_head *element)
        tomoyo_put_name(ptr->manager);
 }
 
+/**
+ * tomoyo_del_acl - Delete members in "struct tomoyo_acl_info".
+ *
+ * @element: Pointer to "struct list_head".
+ *
+ * Returns nothing.
+ */
 static void tomoyo_del_acl(struct list_head *element)
 {
        struct tomoyo_acl_info *acl =
@@ -145,12 +190,26 @@ static bool tomoyo_del_domain(struct list_head *element)
 }
 
 
+/**
+ * tomoyo_del_name - Delete members in "struct tomoyo_name".
+ *
+ * @element: Pointer to "struct list_head".
+ *
+ * Returns nothing.
+ */
 static void tomoyo_del_name(struct list_head *element)
 {
        const struct tomoyo_name *ptr =
-               container_of(element, typeof(*ptr), list);
+               container_of(element, typeof(*ptr), head.list);
 }
 
+/**
+ * tomoyo_del_path_group - Delete members in "struct tomoyo_path_group".
+ *
+ * @element: Pointer to "struct list_head".
+ *
+ * Returns nothing.
+ */
 static void tomoyo_del_path_group(struct list_head *element)
 {
        struct tomoyo_path_group *member =
@@ -158,20 +217,43 @@ static void tomoyo_del_path_group(struct list_head *element)
        tomoyo_put_name(member->member_name);
 }
 
+/**
+ * tomoyo_del_group - Delete "struct tomoyo_group".
+ *
+ * @element: Pointer to "struct list_head".
+ *
+ * Returns nothing.
+ */
 static void tomoyo_del_group(struct list_head *element)
 {
        struct tomoyo_group *group =
-               container_of(element, typeof(*group), list);
+               container_of(element, typeof(*group), head.list);
        tomoyo_put_name(group->group_name);
 }
 
+/**
+ * tomoyo_del_number_group - Delete members in "struct tomoyo_number_group".
+ *
+ * @element: Pointer to "struct list_head".
+ *
+ * Returns nothing.
+ */
 static void tomoyo_del_number_group(struct list_head *element)
 {
        struct tomoyo_number_group *member =
                container_of(element, typeof(*member), head.list);
 }
 
-static bool tomoyo_collect_member(struct list_head *member_list, int id)
+/**
+ * tomoyo_collect_member - Delete elements with "struct tomoyo_acl_head".
+ *
+ * @id:          One of values in "enum tomoyo_policy_id".
+ * @member_list: Pointer to "struct list_head".
+ *
+ * Returns true if some elements are deleted, false otherwise.
+ */
+static bool tomoyo_collect_member(const enum tomoyo_policy_id id,
+                                 struct list_head *member_list)
 {
        struct tomoyo_acl_head *member;
        list_for_each_entry(member, member_list, list) {
@@ -195,13 +277,18 @@ static bool tomoyo_collect_acl(struct tomoyo_domain_info *domain)
        return true;
 }
 
+/**
+ * tomoyo_collect_entry - Scan lists for deleted elements.
+ *
+ * Returns nothing.
+ */
 static void tomoyo_collect_entry(void)
 {
        int i;
        if (mutex_lock_interruptible(&tomoyo_policy_lock))
                return;
        for (i = 0; i < TOMOYO_MAX_POLICY; i++) {
-               if (!tomoyo_collect_member(&tomoyo_policy_list[i], i))
+               if (!tomoyo_collect_member(i, &tomoyo_policy_list[i]))
                        goto unlock;
        }
        {
@@ -222,10 +309,10 @@ static void tomoyo_collect_entry(void)
        }
        for (i = 0; i < TOMOYO_MAX_HASH; i++) {
                struct tomoyo_name *ptr;
-               list_for_each_entry_rcu(ptr, &tomoyo_name_list[i], list) {
-                       if (atomic_read(&ptr->users))
+               list_for_each_entry_rcu(ptr, &tomoyo_name_list[i], head.list) {
+                       if (atomic_read(&ptr->head.users))
                                continue;
-                       if (!tomoyo_add_to_gc(TOMOYO_ID_NAME, &ptr->list))
+                       if (!tomoyo_add_to_gc(TOMOYO_ID_NAME, &ptr->head.list))
                                goto unlock;
                }
        }
@@ -241,13 +328,14 @@ static void tomoyo_collect_entry(void)
                        id = TOMOYO_ID_NUMBER_GROUP;
                        break;
                }
-               list_for_each_entry(group, list, list) {
-                       if (!tomoyo_collect_member(&group->member_list, id))
+               list_for_each_entry(group, list, head.list) {
+                       if (!tomoyo_collect_member(id, &group->member_list))
                                goto unlock;
                        if (!list_empty(&group->member_list) ||
-                           atomic_read(&group->users))
+                           atomic_read(&group->head.users))
                                continue;
-                       if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP, &group->list))
+                       if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP,
+                                             &group->head.list))
                                goto unlock;
                }
        }
@@ -291,6 +379,8 @@ static void tomoyo_kfree_entry(void)
                case TOMOYO_ID_NUMBER_GROUP:
                        tomoyo_del_number_group(element);
                        break;
+               case TOMOYO_MAX_POLICY:
+                       break;
                }
                tomoyo_memory_free(element);
                list_del(&p->list);
@@ -298,6 +388,17 @@ static void tomoyo_kfree_entry(void)
        }
 }
 
+/**
+ * tomoyo_gc_thread - Garbage collector thread function.
+ *
+ * @unused: Unused.
+ *
+ * In case OOM-killer choose this thread for termination, we create this thread
+ * as a short live thread whenever /sys/kernel/security/tomoyo/ interface was
+ * close()d.
+ *
+ * Returns 0.
+ */
 static int tomoyo_gc_thread(void *unused)
 {
        daemonize("GC for TOMOYO");
index 42a7b1b..dfef0cb 100644 (file)
@@ -110,10 +110,10 @@ struct tomoyo_group *tomoyo_get_group(const char *group_name, const u8 idx)
                return NULL;
        if (mutex_lock_interruptible(&tomoyo_policy_lock))
                goto out;
-       list_for_each_entry(group, &tomoyo_group_list[idx], list) {
+       list_for_each_entry(group, &tomoyo_group_list[idx], head.list) {
                if (e.group_name != group->group_name)
                        continue;
-               atomic_inc(&group->users);
+               atomic_inc(&group->head.users);
                found = true;
                break;
        }
@@ -121,8 +121,8 @@ struct tomoyo_group *tomoyo_get_group(const char *group_name, const u8 idx)
                struct tomoyo_group *entry = tomoyo_commit_ok(&e, sizeof(e));
                if (entry) {
                        INIT_LIST_HEAD(&entry->member_list);
-                       atomic_set(&entry->users, 1);
-                       list_add_tail_rcu(&entry->list,
+                       atomic_set(&entry->head.users, 1);
+                       list_add_tail_rcu(&entry->head.list,
                                          &tomoyo_group_list[idx]);
                        group = entry;
                        found = true;
@@ -164,10 +164,10 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
        head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)];
        if (mutex_lock_interruptible(&tomoyo_policy_lock))
                return NULL;
-       list_for_each_entry(ptr, head, list) {
+       list_for_each_entry(ptr, head, head.list) {
                if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))
                        continue;
-               atomic_inc(&ptr->users);
+               atomic_inc(&ptr->head.users);
                goto out;
        }
        ptr = kzalloc(sizeof(*ptr) + len, GFP_NOFS);
@@ -183,9 +183,9 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
        atomic_add(allocated_len, &tomoyo_policy_memory_size);
        ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
        memmove((char *) ptr->entry.name, name, len);
-       atomic_set(&ptr->users, 1);
+       atomic_set(&ptr->head.users, 1);
        tomoyo_fill_path_info(&ptr->entry);
-       list_add_tail(&ptr->list, head);
+       list_add_tail(&ptr->head.list, head);
  out:
        mutex_unlock(&tomoyo_policy_lock);
        return ptr ? &ptr->entry : NULL;
index 5cfc720..7649dbc 100644 (file)
@@ -52,16 +52,28 @@ static int tomoyo_audit_mount_log(struct tomoyo_request_info *r)
                                 r->param.mount.dir->name, type, flags);
 }
 
+/**
+ * tomoyo_check_mount_acl - Check permission for path path path number operation.
+ *
+ * @r:   Pointer to "struct tomoyo_request_info".
+ * @ptr: Pointer to "struct tomoyo_acl_info".
+ *
+ * Returns true if granted, false otherwise.
+ */
 static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r,
                                   const struct tomoyo_acl_info *ptr)
 {
        const struct tomoyo_mount_acl *acl =
                container_of(ptr, typeof(*acl), head);
-       return tomoyo_compare_number_union(r->param.mount.flags, &acl->flags) &&
-               tomoyo_compare_name_union(r->param.mount.type, &acl->fs_type) &&
-               tomoyo_compare_name_union(r->param.mount.dir, &acl->dir_name) &&
+       return tomoyo_compare_number_union(r->param.mount.flags,
+                                          &acl->flags) &&
+               tomoyo_compare_name_union(r->param.mount.type,
+                                         &acl->fs_type) &&
+               tomoyo_compare_name_union(r->param.mount.dir,
+                                         &acl->dir_name) &&
                (!r->param.mount.need_dev ||
-                tomoyo_compare_name_union(r->param.mount.dev, &acl->dev_name));
+                tomoyo_compare_name_union(r->param.mount.dev,
+                                          &acl->dev_name));
 }
 
 /**
@@ -232,13 +244,20 @@ int tomoyo_mount_permission(char *dev_name, struct path *path,
        return error;
 }
 
+/**
+ * tomoyo_same_mount_acl - Check for duplicated "struct tomoyo_mount_acl" entry.
+ *
+ * @a: Pointer to "struct tomoyo_acl_info".
+ * @b: Pointer to "struct tomoyo_acl_info".
+ *
+ * Returns true if @a == @b, false otherwise.
+ */
 static bool tomoyo_same_mount_acl(const struct tomoyo_acl_info *a,
                                  const struct tomoyo_acl_info *b)
 {
        const struct tomoyo_mount_acl *p1 = container_of(a, typeof(*p1), head);
        const struct tomoyo_mount_acl *p2 = container_of(b, typeof(*p2), head);
-       return tomoyo_same_acl_head(&p1->head, &p2->head) &&
-               tomoyo_same_name_union(&p1->dev_name, &p2->dev_name) &&
+       return tomoyo_same_name_union(&p1->dev_name, &p2->dev_name) &&
                tomoyo_same_name_union(&p1->dir_name, &p2->dir_name) &&
                tomoyo_same_name_union(&p1->fs_type, &p2->fs_type) &&
                tomoyo_same_number_union(&p1->flags, &p2->flags);
index a5bd76d..6410868 100644 (file)
@@ -34,7 +34,7 @@ static int tomoyo_open(struct inode *inode, struct file *file)
  */
 static int tomoyo_release(struct inode *inode, struct file *file)
 {
-       return tomoyo_close_control(file);
+       return tomoyo_close_control(file->private_data);
 }
 
 /**
@@ -63,7 +63,7 @@ static unsigned int tomoyo_poll(struct file *file, poll_table *wait)
 static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count,
                           loff_t *ppos)
 {
-       return tomoyo_read_control(file, buf, count);
+       return tomoyo_read_control(file->private_data, buf, count);
 }
 
 /**
@@ -79,7 +79,7 @@ static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count,
 static ssize_t tomoyo_write(struct file *file, const char __user *buf,
                            size_t count, loff_t *ppos)
 {
-       return tomoyo_write_control(file, buf, count);
+       return tomoyo_write_control(file->private_data, buf, count);
 }
 
 /*
index 7fb9bbf..abb177c 100644 (file)
@@ -21,7 +21,7 @@ bool tomoyo_policy_loaded;
  * @result: Pointer to "unsigned long".
  * @str:    Pointer to string to parse.
  *
- * Returns value type on success, 0 otherwise.
+ * Returns one of values in "enum tomoyo_value_type".
  *
  * The @src is updated to point the first character after the value
  * on success.
@@ -43,7 +43,7 @@ static u8 tomoyo_parse_ulong(unsigned long *result, char **str)
        }
        *result = simple_strtoul(cp, &ep, base);
        if (cp == ep)
-               return 0;
+               return TOMOYO_VALUE_TYPE_INVALID;
        *str = ep;
        switch (base) {
        case 16:
@@ -93,11 +93,9 @@ bool tomoyo_parse_name_union(const char *filename,
                return false;
        if (filename[0] == '@') {
                ptr->group = tomoyo_get_group(filename + 1, TOMOYO_PATH_GROUP);
-               ptr->is_group = true;
                return ptr->group != NULL;
        }
        ptr->filename = tomoyo_get_name(filename);
-       ptr->is_group = false;
        return ptr->filename != NULL;
 }
 
@@ -118,17 +116,16 @@ bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num)
                if (!tomoyo_correct_word(data))
                        return false;
                num->group = tomoyo_get_group(data + 1, TOMOYO_NUMBER_GROUP);
-               num->is_group = true;
                return num->group != NULL;
        }
        type = tomoyo_parse_ulong(&v, &data);
        if (!type)
                return false;
        num->values[0] = v;
-       num->min_type = type;
+       num->value_type[0] = type;
        if (!*data) {
                num->values[1] = v;
-               num->max_type = type;
+               num->value_type[1] = type;
                return true;
        }
        if (*data++ != '-')
@@ -137,7 +134,7 @@ bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num)
        if (!type || *data)
                return false;
        num->values[1] = v;
-       num->max_type = type;
+       num->value_type[1] = type;
        return true;
 }
 
@@ -185,6 +182,30 @@ static inline u8 tomoyo_make_byte(const u8 c1, const u8 c2, const u8 c3)
 }
 
 /**
+ * tomoyo_valid - Check whether the character is a valid char.
+ *
+ * @c: The character to check.
+ *
+ * Returns true if @c is a valid character, false otherwise.
+ */
+static inline bool tomoyo_valid(const unsigned char c)
+{
+       return c > ' ' && c < 127;
+}
+
+/**
+ * tomoyo_invalid - Check whether the character is an invalid char.
+ *
+ * @c: The character to check.
+ *
+ * Returns true if @c is an invalid character, false otherwise.
+ */
+static inline bool tomoyo_invalid(const unsigned char c)
+{
+       return c && (c <= ' ' || c >= 127);
+}
+
+/**
  * tomoyo_str_starts - Check whether the given string starts with the given keyword.
  *
  * @src:  Pointer to pointer to the string.