Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ea13ddba authored by Tetsuo Handa's avatar Tetsuo Handa Committed by James Morris
Browse files

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: default avatarTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Acked-by: default avatarSerge Hallyn <serue@us.ibm.com>
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
parent f40a7086
Loading
Loading
Loading
Loading
+5 −11
Original line number Original line Diff line number Diff line
@@ -842,9 +842,7 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain)
	if (!domain)
	if (!domain)
		return true;
		return true;
	list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
	list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
		if (ptr->type & TOMOYO_ACL_DELETED)
		switch (ptr->type) {
			continue;
		switch (tomoyo_acl_type2(ptr)) {
			struct tomoyo_single_path_acl_record *acl;
			struct tomoyo_single_path_acl_record *acl;
			u32 perm;
			u32 perm;
			u8 i;
			u8 i;
@@ -1384,8 +1382,7 @@ static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head)
		return 0;
		return 0;
	}
	}
	if (!strcmp(data, TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) {
	if (!strcmp(data, TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) {
		tomoyo_set_domain_flag(domain, is_delete,
		domain->ignore_global_allow_read = !is_delete;
			       TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ);
		return 0;
		return 0;
	}
	}
	return tomoyo_write_file_policy(data, domain, is_delete);
	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,
static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
			       struct tomoyo_acl_info *ptr)
			       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) {
	if (acl_type == TOMOYO_TYPE_SINGLE_PATH_ACL) {
		struct tomoyo_single_path_acl_record *acl
		struct tomoyo_single_path_acl_record *acl
			= container_of(ptr,
			= container_of(ptr,
@@ -1540,10 +1535,9 @@ static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
		/* Print domainname and flags. */
		/* Print domainname and flags. */
		if (domain->quota_warned)
		if (domain->quota_warned)
			quota_exceeded = "quota_exceeded\n";
			quota_exceeded = "quota_exceeded\n";
		if (domain->flags & TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED)
		if (domain->transition_failed)
			transition_failed = "transition_failed\n";
			transition_failed = "transition_failed\n";
		if (domain->flags &
		if (domain->ignore_global_allow_read)
		    TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ)
			ignore_global_allow_read
			ignore_global_allow_read
				= TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n";
				= TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n";
		done = tomoyo_io_printf(head, "%s\n" TOMOYO_KEYWORD_USE_PROFILE
		done = tomoyo_io_printf(head, "%s\n" TOMOYO_KEYWORD_USE_PROFILE
+12 −41
Original line number Original line Diff line number Diff line
@@ -101,11 +101,9 @@ struct tomoyo_path_info_with_data {
 *
 *
 *  (1) "list" which is linked to the ->acl_info_list of
 *  (1) "list" which is linked to the ->acl_info_list of
 *      "struct tomoyo_domain_info"
 *      "struct tomoyo_domain_info"
 *  (2) "type" which tells
 *  (2) "type" which tells type of the entry (either
 *      (a) type & 0x7F : type of the entry (either
 *      "struct tomoyo_single_path_acl_record" or
 *      "struct tomoyo_single_path_acl_record" or
 *          "struct tomoyo_double_path_acl_record")
 *      "struct tomoyo_double_path_acl_record").
 *      (b) type & 0x80 : whether the entry is marked as "deleted".
 *
 *
 * Packing "struct tomoyo_acl_info" allows
 * Packing "struct tomoyo_acl_info" allows
 * "struct tomoyo_single_path_acl_record" to embed "u8" + "u16" and
 * "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 tomoyo_acl_info {
	struct list_head list;
	struct list_head list;
	/*
	 * Type of this ACL entry.
	 *
	 * MSB is is_deleted flag.
	 */
	u8 type;
	u8 type;
} __packed;
} __packed;


/* This ACL entry is deleted.           */
#define TOMOYO_ACL_DELETED        0x80

/*
/*
 * tomoyo_domain_info is a structure which is used for holding permissions
 * 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.
 * (e.g. "allow_read /lib/libc-2.5.so") given to each domain.
@@ -138,7 +128,13 @@ struct tomoyo_acl_info {
 *      "deleted", false otherwise.
 *      "deleted", false otherwise.
 *  (6) "quota_warned" is a bool which is used for suppressing warning message
 *  (6) "quota_warned" is a bool which is used for suppressing warning message
 *      when learning mode learned too much entries.
 *      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.
 * A domain's lifecycle is an analogy of files on / directory.
 * Multiple domains with the same domainname cannot be created (as with
 * 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. */
	u8 profile;        /* Profile number to use. */
	bool is_deleted;   /* Delete flag.           */
	bool is_deleted;   /* Delete flag.           */
	bool quota_warned; /* Quota warnning flag.   */
	bool quota_warned; /* Quota warnning flag.   */
	/* DOMAIN_FLAGS_*. Use tomoyo_set_domain_flag() to modify. */
	bool ignore_global_allow_read; /* Ignore "allow_read" flag. */
	u8 flags;
	bool transition_failed; /* Domain transition failed flag. */
};
};


/* Profile number is an integer between 0 and 255. */
/* Profile number is an integer between 0 and 255. */
#define TOMOYO_MAX_PROFILES 256
#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
 * tomoyo_single_path_acl_record is a structure which is used for holding an
 * entry with one pathname operation (e.g. open(), mkdir()).
 * 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);
void tomoyo_fill_path_info(struct tomoyo_path_info *ptr);
/* Run policy loader when /sbin/init starts. */
/* Run policy loader when /sbin/init starts. */
void tomoyo_load_policy(const char *filename);
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. */
/* strcmp() for "struct tomoyo_path_info" structure. */
static inline bool tomoyo_pathcmp(const struct tomoyo_path_info *a,
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);
	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.
 * tomoyo_is_valid - Check whether the character is a valid char.
 *
 *
+1 −24
Original line number Original line Diff line number Diff line
@@ -129,28 +129,6 @@ struct tomoyo_alias_entry {
	bool is_deleted;
	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.
 * 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)
	if (is_enforce)
		retval = -EPERM;
		retval = -EPERM;
	else
	else
		tomoyo_set_domain_flag(old_domain, false,
		old_domain->transition_failed = true;
				       TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED);
 out:
 out:
	if (!domain)
	if (!domain)
		domain = old_domain;
		domain = old_domain;
+7 −20
Original line number Original line Diff line number Diff line
@@ -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) {
	list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
		struct tomoyo_single_path_acl_record *acl;
		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;
			continue;
		acl = container_of(ptr, struct tomoyo_single_path_acl_record,
		acl = container_of(ptr, struct tomoyo_single_path_acl_record,
				   head);
				   head);
@@ -770,8 +770,7 @@ static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain,
	if (!filename)
	if (!filename)
		return 0;
		return 0;
	error = tomoyo_check_file_acl(domain, filename, perm);
	error = tomoyo_check_file_acl(domain, filename, perm);
	if (error && perm == 4 &&
	if (error && perm == 4 && !domain->ignore_global_allow_read
	    (domain->flags & TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ) == 0
	    && tomoyo_is_globally_readable_file(filename))
	    && tomoyo_is_globally_readable_file(filename))
		error = 0;
		error = 0;
	if (perm == 6)
	if (perm == 6)
@@ -885,15 +884,12 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
	if (is_delete)
	if (is_delete)
		goto delete;
		goto delete;
	list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
	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;
			continue;
		acl = container_of(ptr, struct tomoyo_single_path_acl_record,
		acl = container_of(ptr, struct tomoyo_single_path_acl_record,
				   head);
				   head);
		if (acl->filename != saved_filename)
		if (acl->filename != saved_filename)
			continue;
			continue;
		/* Special case. Clear all bits if marked as deleted. */
		if (ptr->type & TOMOYO_ACL_DELETED)
			acl->perm = 0;
		if (perm <= 0xFFFF)
		if (perm <= 0xFFFF)
			acl->perm |= perm;
			acl->perm |= perm;
		else
		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;
			acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE_ACL;
		else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL))
		else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL))
			acl->perm |= rw_mask;
			acl->perm |= rw_mask;
		ptr->type &= ~TOMOYO_ACL_DELETED;
		error = 0;
		error = 0;
		goto out;
		goto out;
	}
	}
@@ -927,7 +922,7 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
 delete:
 delete:
	error = -ENOENT;
	error = -ENOENT;
	list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
	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;
			continue;
		acl = container_of(ptr, struct tomoyo_single_path_acl_record,
		acl = container_of(ptr, struct tomoyo_single_path_acl_record,
				   head);
				   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);
			acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE_ACL);
		else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL)))
		else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL)))
			acl->perm &= ~rw_mask;
			acl->perm &= ~rw_mask;
		if (!acl->perm && !acl->perm_high)
			ptr->type |= TOMOYO_ACL_DELETED;
		error = 0;
		error = 0;
		break;
		break;
	}
	}
@@ -989,18 +982,14 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
	if (is_delete)
	if (is_delete)
		goto delete;
		goto delete;
	list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
	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;
			continue;
		acl = container_of(ptr, struct tomoyo_double_path_acl_record,
		acl = container_of(ptr, struct tomoyo_double_path_acl_record,
				   head);
				   head);
		if (acl->filename1 != saved_filename1 ||
		if (acl->filename1 != saved_filename1 ||
		    acl->filename2 != saved_filename2)
		    acl->filename2 != saved_filename2)
			continue;
			continue;
		/* Special case. Clear all bits if marked as deleted. */
		if (ptr->type & TOMOYO_ACL_DELETED)
			acl->perm = 0;
		acl->perm |= perm;
		acl->perm |= perm;
		ptr->type &= ~TOMOYO_ACL_DELETED;
		error = 0;
		error = 0;
		goto out;
		goto out;
	}
	}
@@ -1021,7 +1010,7 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
 delete:
 delete:
	error = -ENOENT;
	error = -ENOENT;
	list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
	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;
			continue;
		acl = container_of(ptr, struct tomoyo_double_path_acl_record,
		acl = container_of(ptr, struct tomoyo_double_path_acl_record,
				   head);
				   head);
@@ -1029,8 +1018,6 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
		    acl->filename2 != saved_filename2)
		    acl->filename2 != saved_filename2)
			continue;
			continue;
		acl->perm &= ~perm;
		acl->perm &= ~perm;
		if (!acl->perm)
			ptr->type |= TOMOYO_ACL_DELETED;
		error = 0;
		error = 0;
		break;
		break;
	}
	}
@@ -1086,7 +1073,7 @@ static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain,
		return 0;
		return 0;
	list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
	list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
		struct tomoyo_double_path_acl_record *acl;
		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;
			continue;
		acl = container_of(ptr, struct tomoyo_double_path_acl_record,
		acl = container_of(ptr, struct tomoyo_double_path_acl_record,
				   head);
				   head);