From ea13ddbad0eb4be9cdc406cd7e0804fa4011f6e4 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Wed, 3 Feb 2010 06:43:06 +0900 Subject: [PATCH] TOMOYO: Extract bitfield Since list elements are rounded up to kmalloc() size rather than sizeof(int), saving one byte by using bitfields is no longer helpful. Signed-off-by: Tetsuo Handa Acked-by: Serge Hallyn Signed-off-by: James Morris --- security/tomoyo/common.c | 16 ++++-------- security/tomoyo/common.h | 53 +++++++++------------------------------- security/tomoyo/domain.c | 25 +------------------ security/tomoyo/file.c | 27 ++++++-------------- 4 files changed, 25 insertions(+), 96 deletions(-) diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index ef6622300a81..ae3ed7313ee0 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c @@ -842,9 +842,7 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain) if (!domain) return true; list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { - if (ptr->type & TOMOYO_ACL_DELETED) - continue; - switch (tomoyo_acl_type2(ptr)) { + switch (ptr->type) { struct tomoyo_single_path_acl_record *acl; u32 perm; u8 i; @@ -1384,8 +1382,7 @@ static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head) return 0; } if (!strcmp(data, TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) { - tomoyo_set_domain_flag(domain, is_delete, - TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ); + domain->ignore_global_allow_read = !is_delete; return 0; } return tomoyo_write_file_policy(data, domain, is_delete); @@ -1486,10 +1483,8 @@ static bool tomoyo_print_double_path_acl(struct tomoyo_io_buffer *head, static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, struct tomoyo_acl_info *ptr) { - const u8 acl_type = tomoyo_acl_type2(ptr); + const u8 acl_type = ptr->type; - if (acl_type & TOMOYO_ACL_DELETED) - return true; if (acl_type == TOMOYO_TYPE_SINGLE_PATH_ACL) { struct tomoyo_single_path_acl_record *acl = container_of(ptr, @@ -1540,10 +1535,9 @@ static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head) /* Print domainname and flags. */ if (domain->quota_warned) quota_exceeded = "quota_exceeded\n"; - if (domain->flags & TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED) + if (domain->transition_failed) transition_failed = "transition_failed\n"; - if (domain->flags & - TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ) + if (domain->ignore_global_allow_read) ignore_global_allow_read = TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n"; done = tomoyo_io_printf(head, "%s\n" TOMOYO_KEYWORD_USE_PROFILE diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index 8b59ec8fe11e..509ced9ce698 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h @@ -101,11 +101,9 @@ struct tomoyo_path_info_with_data { * * (1) "list" which is linked to the ->acl_info_list of * "struct tomoyo_domain_info" - * (2) "type" which tells - * (a) type & 0x7F : type of the entry (either - * "struct tomoyo_single_path_acl_record" or - * "struct tomoyo_double_path_acl_record") - * (b) type & 0x80 : whether the entry is marked as "deleted". + * (2) "type" which tells type of the entry (either + * "struct tomoyo_single_path_acl_record" or + * "struct tomoyo_double_path_acl_record"). * * Packing "struct tomoyo_acl_info" allows * "struct tomoyo_single_path_acl_record" to embed "u8" + "u16" and @@ -114,17 +112,9 @@ struct tomoyo_path_info_with_data { */ struct tomoyo_acl_info { struct list_head list; - /* - * Type of this ACL entry. - * - * MSB is is_deleted flag. - */ u8 type; } __packed; -/* This ACL entry is deleted. */ -#define TOMOYO_ACL_DELETED 0x80 - /* * tomoyo_domain_info is a structure which is used for holding permissions * (e.g. "allow_read /lib/libc-2.5.so") given to each domain. @@ -138,7 +128,13 @@ struct tomoyo_acl_info { * "deleted", false otherwise. * (6) "quota_warned" is a bool which is used for suppressing warning message * when learning mode learned too much entries. - * (7) "flags" which remembers this domain's attributes. + * (7) "ignore_global_allow_read" is a bool which is true if this domain + * should ignore "allow_read" directive in exception policy. + * (8) "transition_failed" is a bool which is set to true when this domain was + * unable to create a new domain at tomoyo_find_next_domain() because the + * name of the domain to be created was too long or it could not allocate + * memory. If set to true, more than one process continued execve() + * without domain transition. * * A domain's lifecycle is an analogy of files on / directory. * Multiple domains with the same domainname cannot be created (as with @@ -155,23 +151,13 @@ struct tomoyo_domain_info { u8 profile; /* Profile number to use. */ bool is_deleted; /* Delete flag. */ bool quota_warned; /* Quota warnning flag. */ - /* DOMAIN_FLAGS_*. Use tomoyo_set_domain_flag() to modify. */ - u8 flags; + bool ignore_global_allow_read; /* Ignore "allow_read" flag. */ + bool transition_failed; /* Domain transition failed flag. */ }; /* Profile number is an integer between 0 and 255. */ #define TOMOYO_MAX_PROFILES 256 -/* Ignore "allow_read" directive in exception policy. */ -#define TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ 1 -/* - * This domain was unable to create a new domain at tomoyo_find_next_domain() - * because the name of the domain to be created was too long or - * it could not allocate memory. - * More than one process continued execve() without domain transition. - */ -#define TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED 2 - /* * tomoyo_single_path_acl_record is a structure which is used for holding an * entry with one pathname operation (e.g. open(), mkdir()). @@ -380,9 +366,6 @@ unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain, void tomoyo_fill_path_info(struct tomoyo_path_info *ptr); /* Run policy loader when /sbin/init starts. */ void tomoyo_load_policy(const char *filename); -/* Change "struct tomoyo_domain_info"->flags. */ -void tomoyo_set_domain_flag(struct tomoyo_domain_info *domain, - const bool is_delete, const u8 flags); /* strcmp() for "struct tomoyo_path_info" structure. */ static inline bool tomoyo_pathcmp(const struct tomoyo_path_info *a, @@ -391,18 +374,6 @@ static inline bool tomoyo_pathcmp(const struct tomoyo_path_info *a, return a->hash != b->hash || strcmp(a->name, b->name); } -/* Get type of an ACL entry. */ -static inline u8 tomoyo_acl_type1(struct tomoyo_acl_info *ptr) -{ - return ptr->type & ~TOMOYO_ACL_DELETED; -} - -/* Get type of an ACL entry. */ -static inline u8 tomoyo_acl_type2(struct tomoyo_acl_info *ptr) -{ - return ptr->type; -} - /** * tomoyo_is_valid - Check whether the character is a valid char. * diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c index 34843971cc60..ec612ae87b51 100644 --- a/security/tomoyo/domain.c +++ b/security/tomoyo/domain.c @@ -129,28 +129,6 @@ struct tomoyo_alias_entry { bool is_deleted; }; -/** - * tomoyo_set_domain_flag - Set or clear domain's attribute flags. - * - * @domain: Pointer to "struct tomoyo_domain_info". - * @is_delete: True if it is a delete request. - * @flags: Flags to set or clear. - * - * Returns nothing. - */ -void tomoyo_set_domain_flag(struct tomoyo_domain_info *domain, - const bool is_delete, const u8 flags) -{ - /* We need to serialize because this is bitfield operation. */ - static DEFINE_SPINLOCK(lock); - spin_lock(&lock); - if (!is_delete) - domain->flags |= flags; - else - domain->flags &= ~flags; - spin_unlock(&lock); -} - /** * tomoyo_get_last_name - Get last component of a domainname. * @@ -896,8 +874,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm) if (is_enforce) retval = -EPERM; else - tomoyo_set_domain_flag(old_domain, false, - TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED); + old_domain->transition_failed = true; out: if (!domain) domain = old_domain; diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c index 24af081f1af9..84c821a245ca 100644 --- a/security/tomoyo/file.c +++ b/security/tomoyo/file.c @@ -688,7 +688,7 @@ static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info * list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { struct tomoyo_single_path_acl_record *acl; - if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL) + if (ptr->type != TOMOYO_TYPE_SINGLE_PATH_ACL) continue; acl = container_of(ptr, struct tomoyo_single_path_acl_record, head); @@ -770,8 +770,7 @@ static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain, if (!filename) return 0; error = tomoyo_check_file_acl(domain, filename, perm); - if (error && perm == 4 && - (domain->flags & TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ) == 0 + if (error && perm == 4 && !domain->ignore_global_allow_read && tomoyo_is_globally_readable_file(filename)) error = 0; if (perm == 6) @@ -885,15 +884,12 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename, if (is_delete) goto delete; list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { - if (tomoyo_acl_type1(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL) + if (ptr->type != TOMOYO_TYPE_SINGLE_PATH_ACL) continue; acl = container_of(ptr, struct tomoyo_single_path_acl_record, head); if (acl->filename != saved_filename) continue; - /* Special case. Clear all bits if marked as deleted. */ - if (ptr->type & TOMOYO_ACL_DELETED) - acl->perm = 0; if (perm <= 0xFFFF) acl->perm |= perm; else @@ -902,7 +898,6 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename, acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE_ACL; else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL)) acl->perm |= rw_mask; - ptr->type &= ~TOMOYO_ACL_DELETED; error = 0; goto out; } @@ -927,7 +922,7 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename, delete: error = -ENOENT; list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { - if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL) + if (ptr->type != TOMOYO_TYPE_SINGLE_PATH_ACL) continue; acl = container_of(ptr, struct tomoyo_single_path_acl_record, head); @@ -941,8 +936,6 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename, acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE_ACL); else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL))) acl->perm &= ~rw_mask; - if (!acl->perm && !acl->perm_high) - ptr->type |= TOMOYO_ACL_DELETED; error = 0; break; } @@ -989,18 +982,14 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1, if (is_delete) goto delete; list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { - if (tomoyo_acl_type1(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL) + if (ptr->type != TOMOYO_TYPE_DOUBLE_PATH_ACL) continue; acl = container_of(ptr, struct tomoyo_double_path_acl_record, head); if (acl->filename1 != saved_filename1 || acl->filename2 != saved_filename2) continue; - /* Special case. Clear all bits if marked as deleted. */ - if (ptr->type & TOMOYO_ACL_DELETED) - acl->perm = 0; acl->perm |= perm; - ptr->type &= ~TOMOYO_ACL_DELETED; error = 0; goto out; } @@ -1021,7 +1010,7 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1, delete: error = -ENOENT; list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { - if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL) + if (ptr->type != TOMOYO_TYPE_DOUBLE_PATH_ACL) continue; acl = container_of(ptr, struct tomoyo_double_path_acl_record, head); @@ -1029,8 +1018,6 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1, acl->filename2 != saved_filename2) continue; acl->perm &= ~perm; - if (!acl->perm) - ptr->type |= TOMOYO_ACL_DELETED; error = 0; break; } @@ -1086,7 +1073,7 @@ static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain, return 0; list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { struct tomoyo_double_path_acl_record *acl; - if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL) + if (ptr->type != TOMOYO_TYPE_DOUBLE_PATH_ACL) continue; acl = container_of(ptr, struct tomoyo_double_path_acl_record, head);