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

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

TOMOYO: Use struct for passing ACL line.



Use structure for passing ACL line, in preparation for supporting policy
namespace and conditional parameters.

Signed-off-by: default avatarTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
parent 0df7e8b8
Loading
Loading
Loading
Loading
+45 −32
Original line number Original line Diff line number Diff line
@@ -611,8 +611,11 @@ static int tomoyo_update_manager_entry(const char *manager,
				       const bool is_delete)
				       const bool is_delete)
{
{
	struct tomoyo_manager e = { };
	struct tomoyo_manager e = { };
	int error;
	struct tomoyo_acl_param param = {

		.is_delete = is_delete,
		.list = &tomoyo_policy_list[TOMOYO_ID_MANAGER],
	};
	int error = is_delete ? -ENOENT : -ENOMEM;
	if (tomoyo_domain_def(manager)) {
	if (tomoyo_domain_def(manager)) {
		if (!tomoyo_correct_domain(manager))
		if (!tomoyo_correct_domain(manager))
			return -EINVAL;
			return -EINVAL;
@@ -622,12 +625,11 @@ static int tomoyo_update_manager_entry(const char *manager,
			return -EINVAL;
			return -EINVAL;
	}
	}
	e.manager = tomoyo_get_name(manager);
	e.manager = tomoyo_get_name(manager);
	if (!e.manager)
	if (e.manager) {
		return -ENOMEM;
		error = tomoyo_update_policy(&e.head, sizeof(e), &param,
	error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
				     &tomoyo_policy_list[TOMOYO_ID_MANAGER],
					     tomoyo_same_manager);
					     tomoyo_same_manager);
		tomoyo_put_name(e.manager);
		tomoyo_put_name(e.manager);
	}
	return error;
	return error;
}
}


@@ -821,18 +823,36 @@ static int tomoyo_delete_domain(char *domainname)
/**
/**
 * tomoyo_write_domain2 - Write domain policy.
 * tomoyo_write_domain2 - Write domain policy.
 *
 *
 * @head: Pointer to "struct tomoyo_io_buffer".
 * @list:      Pointer to "struct list_head".
 * @data:      Policy to be interpreted.
 * @is_delete: True if it is a delete request.
 *
 *
 * Returns 0 on success, negative value otherwise.
 * Returns 0 on success, negative value otherwise.
 *
 *
 * Caller holds tomoyo_read_lock().
 * Caller holds tomoyo_read_lock().
 */
 */
static int tomoyo_write_domain2(char *data, struct tomoyo_domain_info *domain,
static int tomoyo_write_domain2(struct list_head *list, char *data,
				const bool is_delete)
				const bool is_delete)
{
{
	if (tomoyo_str_starts(&data, "allow_mount "))
	struct tomoyo_acl_param param = {
		return tomoyo_write_mount(data, domain, is_delete);
		.list = list,
	return tomoyo_write_file(data, domain, is_delete);
		.data = data,
		.is_delete = is_delete,
	};
	static const struct {
		const char *keyword;
		int (*write) (struct tomoyo_acl_param *);
	} tomoyo_callback[1] = {
		{ "file ", tomoyo_write_file },
	};
	u8 i;
	for (i = 0; i < 1; i++) {
		if (!tomoyo_str_starts(&param.data,
				       tomoyo_callback[i].keyword))
			continue;
		return tomoyo_callback[i].write(&param);
	}
	return -EINVAL;
}
}


/**
/**
@@ -889,7 +909,7 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
		domain->transition_failed = !is_delete;
		domain->transition_failed = !is_delete;
		return 0;
		return 0;
	}
	}
	return tomoyo_write_domain2(data, domain, is_delete);
	return tomoyo_write_domain2(&domain->acl_info_list, data, is_delete);
}
}


/**
/**
@@ -1213,26 +1233,19 @@ static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = {
 */
 */
static int tomoyo_write_exception(struct tomoyo_io_buffer *head)
static int tomoyo_write_exception(struct tomoyo_io_buffer *head)
{
{
	char *data = head->write_buf;
	struct tomoyo_acl_param param = {
	bool is_delete = tomoyo_str_starts(&data, "delete ");
		.data = head->write_buf,
	u8 i;
	static const struct {
		const char *keyword;
		int (*write) (char *, const bool);
	} tomoyo_callback[1] = {
		{ "aggregator ", tomoyo_write_aggregator },
	};
	};

	u8 i;
	param.is_delete = tomoyo_str_starts(&param.data, "delete ");
	if (tomoyo_str_starts(&param.data, "aggregator "))
		return tomoyo_write_aggregator(&param);
	for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++)
	for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++)
		if (tomoyo_str_starts(&data, tomoyo_transition_type[i]))
		if (tomoyo_str_starts(&param.data, tomoyo_transition_type[i]))
			return tomoyo_write_transition_control(data, is_delete,
			return tomoyo_write_transition_control(&param, i);
							       i);
	for (i = 0; i < 1; i++)
		if (tomoyo_str_starts(&data, tomoyo_callback[i].keyword))
			return tomoyo_callback[i].write(data, is_delete);
	for (i = 0; i < TOMOYO_MAX_GROUP; i++)
	for (i = 0; i < TOMOYO_MAX_GROUP; i++)
		if (tomoyo_str_starts(&data, tomoyo_group_name[i]))
		if (tomoyo_str_starts(&param.data, tomoyo_group_name[i]))
			return tomoyo_write_group(data, is_delete, i);
			return tomoyo_write_group(&param, i);
	return -EINVAL;
	return -EINVAL;
}
}


@@ -1490,7 +1503,7 @@ int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
		vsnprintf(buffer, len - 1, fmt, args);
		vsnprintf(buffer, len - 1, fmt, args);
		va_end(args);
		va_end(args);
		tomoyo_normalize_line(buffer);
		tomoyo_normalize_line(buffer);
		tomoyo_write_domain2(buffer, r->domain, false);
		tomoyo_write_domain2(&r->domain->acl_info_list, buffer, false);
		kfree(buffer);
		kfree(buffer);
		/* fall through */
		/* fall through */
	case TOMOYO_CONFIG_PERMISSIVE:
	case TOMOYO_CONFIG_PERMISSIVE:
+20 −12
Original line number Original line Diff line number Diff line
@@ -397,6 +397,13 @@ struct tomoyo_mount_acl {
	struct tomoyo_number_union flags;
	struct tomoyo_number_union flags;
};
};


/* Structure for holding a line from /sys/kernel/security/tomoyo/ interface. */
struct tomoyo_acl_param {
	char *data;
	struct list_head *list;
	bool is_delete;
};

#define TOMOYO_MAX_IO_READ_QUEUE 32
#define TOMOYO_MAX_IO_READ_QUEUE 32


/*
/*
@@ -521,7 +528,7 @@ bool tomoyo_correct_domain(const unsigned char *domainname);
bool tomoyo_correct_path(const char *filename);
bool tomoyo_correct_path(const char *filename);
bool tomoyo_correct_word(const char *string);
bool tomoyo_correct_word(const char *string);
bool tomoyo_domain_def(const unsigned char *buffer);
bool tomoyo_domain_def(const unsigned char *buffer);
bool tomoyo_parse_name_union(const char *filename,
bool tomoyo_parse_name_union(struct tomoyo_acl_param *param,
			     struct tomoyo_name_union *ptr);
			     struct tomoyo_name_union *ptr);
const struct tomoyo_path_info *
const struct tomoyo_path_info *
tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
@@ -531,7 +538,8 @@ bool tomoyo_number_matches_group(const unsigned long min,
				 const struct tomoyo_group *group);
				 const struct tomoyo_group *group);
bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
				 const struct tomoyo_path_info *pattern);
				 const struct tomoyo_path_info *pattern);
bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num);
bool tomoyo_parse_number_union(struct tomoyo_acl_param *param,
			       struct tomoyo_number_union *ptr);
bool tomoyo_tokenize(char *buffer, char *w[], size_t size);
bool tomoyo_tokenize(char *buffer, char *w[], size_t size);
bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain);
bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain);
int tomoyo_init_request_info(struct tomoyo_request_info *r,
int tomoyo_init_request_info(struct tomoyo_request_info *r,
@@ -540,21 +548,19 @@ int tomoyo_init_request_info(struct tomoyo_request_info *r,
int tomoyo_mount_permission(char *dev_name, struct path *path,
int tomoyo_mount_permission(char *dev_name, struct path *path,
			    const char *type, unsigned long flags,
			    const char *type, unsigned long flags,
			    void *data_page);
			    void *data_page);
int tomoyo_write_aggregator(char *data, const bool is_delete);
int tomoyo_write_aggregator(struct tomoyo_acl_param *param);
int tomoyo_write_transition_control(char *data, const bool is_delete,
int tomoyo_write_transition_control(struct tomoyo_acl_param *param,
				    const u8 type);
				    const u8 type);
int tomoyo_write_file(char *data, struct tomoyo_domain_info *domain,
int tomoyo_write_file(struct tomoyo_acl_param *param);
		      const bool is_delete);
int tomoyo_write_group(struct tomoyo_acl_param *param, const u8 type);
int tomoyo_write_mount(char *data, struct tomoyo_domain_info *domain,
		       const bool is_delete);
int tomoyo_write_group(char *data, const bool is_delete, const u8 type);
int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
     __attribute__ ((format(printf, 2, 3)));
     __attribute__ ((format(printf, 2, 3)));
struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname);
struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname);
struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
						const u8 profile);
						const u8 profile);
struct tomoyo_profile *tomoyo_profile(const u8 profile);
struct tomoyo_profile *tomoyo_profile(const u8 profile);
struct tomoyo_group *tomoyo_get_group(const char *group_name, const u8 type);
struct tomoyo_group *tomoyo_get_group(struct tomoyo_acl_param *param,
				      const u8 idx);
unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
				const u8 index);
				const u8 index);
void tomoyo_fill_path_info(struct tomoyo_path_info *ptr);
void tomoyo_fill_path_info(struct tomoyo_path_info *ptr);
@@ -587,7 +593,7 @@ void tomoyo_put_name_union(struct tomoyo_name_union *ptr);
void tomoyo_run_gc(void);
void tomoyo_run_gc(void);
void tomoyo_memory_free(void *ptr);
void tomoyo_memory_free(void *ptr);
int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
			 bool is_delete, struct tomoyo_domain_info *domain,
			 struct tomoyo_acl_param *param,
			 bool (*check_duplicate) (const struct tomoyo_acl_info
			 bool (*check_duplicate) (const struct tomoyo_acl_info
						  *,
						  *,
						  const struct tomoyo_acl_info
						  const struct tomoyo_acl_info
@@ -596,7 +602,7 @@ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
						  struct tomoyo_acl_info *,
						  struct tomoyo_acl_info *,
						  const bool));
						  const bool));
int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
			 bool is_delete, struct list_head *list,
			 struct tomoyo_acl_param *param,
			 bool (*check_duplicate) (const struct tomoyo_acl_head
			 bool (*check_duplicate) (const struct tomoyo_acl_head
						  *,
						  *,
						  const struct tomoyo_acl_head
						  const struct tomoyo_acl_head
@@ -604,6 +610,8 @@ int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
void tomoyo_check_acl(struct tomoyo_request_info *r,
void tomoyo_check_acl(struct tomoyo_request_info *r,
		      bool (*check_entry) (struct tomoyo_request_info *,
		      bool (*check_entry) (struct tomoyo_request_info *,
					   const struct tomoyo_acl_info *));
					   const struct tomoyo_acl_info *));
char *tomoyo_read_token(struct tomoyo_acl_param *param);
bool tomoyo_permstr(const char *string, const char *keyword);


/********** External variable definitions. **********/
/********** External variable definitions. **********/


+61 −85
Original line number Original line Diff line number Diff line
@@ -20,8 +20,7 @@ struct tomoyo_domain_info tomoyo_kernel_domain;
 *
 *
 * @new_entry:       Pointer to "struct tomoyo_acl_info".
 * @new_entry:       Pointer to "struct tomoyo_acl_info".
 * @size:            Size of @new_entry in bytes.
 * @size:            Size of @new_entry in bytes.
 * @is_delete:       True if it is a delete request.
 * @param:           Pointer to "struct tomoyo_acl_param".
 * @list:            Pointer to "struct list_head".
 * @check_duplicate: Callback function to find duplicated entry.
 * @check_duplicate: Callback function to find duplicated entry.
 *
 *
 * Returns 0 on success, negative value otherwise.
 * Returns 0 on success, negative value otherwise.
@@ -29,25 +28,26 @@ struct tomoyo_domain_info tomoyo_kernel_domain;
 * Caller holds tomoyo_read_lock().
 * Caller holds tomoyo_read_lock().
 */
 */
int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
			 bool is_delete, struct list_head *list,
			 struct tomoyo_acl_param *param,
			 bool (*check_duplicate) (const struct tomoyo_acl_head
			 bool (*check_duplicate) (const struct tomoyo_acl_head
						  *,
						  *,
						  const struct tomoyo_acl_head
						  const struct tomoyo_acl_head
						  *))
						  *))
{
{
	int error = is_delete ? -ENOENT : -ENOMEM;
	int error = param->is_delete ? -ENOENT : -ENOMEM;
	struct tomoyo_acl_head *entry;
	struct tomoyo_acl_head *entry;
	struct list_head *list = param->list;


	if (mutex_lock_interruptible(&tomoyo_policy_lock))
	if (mutex_lock_interruptible(&tomoyo_policy_lock))
		return -ENOMEM;
		return -ENOMEM;
	list_for_each_entry_rcu(entry, list, list) {
	list_for_each_entry_rcu(entry, list, list) {
		if (!check_duplicate(entry, new_entry))
		if (!check_duplicate(entry, new_entry))
			continue;
			continue;
		entry->is_deleted = is_delete;
		entry->is_deleted = param->is_delete;
		error = 0;
		error = 0;
		break;
		break;
	}
	}
	if (error && !is_delete) {
	if (error && !param->is_delete) {
		entry = tomoyo_commit_ok(new_entry, size);
		entry = tomoyo_commit_ok(new_entry, size);
		if (entry) {
		if (entry) {
			list_add_tail_rcu(&entry->list, list);
			list_add_tail_rcu(&entry->list, list);
@@ -77,8 +77,7 @@ static inline bool tomoyo_same_acl_head(const struct tomoyo_acl_info *a,
 *
 *
 * @new_entry:       Pointer to "struct tomoyo_acl_info".
 * @new_entry:       Pointer to "struct tomoyo_acl_info".
 * @size:            Size of @new_entry in bytes.
 * @size:            Size of @new_entry in bytes.
 * @is_delete:       True if it is a delete request.
 * @param:           Pointer to "struct tomoyo_acl_param".
 * @domain:          Pointer to "struct tomoyo_domain_info".
 * @check_duplicate: Callback function to find duplicated entry.
 * @check_duplicate: Callback function to find duplicated entry.
 * @merge_duplicate: Callback function to merge duplicated entry.
 * @merge_duplicate: Callback function to merge duplicated entry.
 *
 *
@@ -87,7 +86,7 @@ static inline bool tomoyo_same_acl_head(const struct tomoyo_acl_info *a,
 * Caller holds tomoyo_read_lock().
 * Caller holds tomoyo_read_lock().
 */
 */
int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
			 bool is_delete, struct tomoyo_domain_info *domain,
			 struct tomoyo_acl_param *param,
			 bool (*check_duplicate) (const struct tomoyo_acl_info
			 bool (*check_duplicate) (const struct tomoyo_acl_info
						  *,
						  *,
						  const struct tomoyo_acl_info
						  const struct tomoyo_acl_info
@@ -96,12 +95,14 @@ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
						  struct tomoyo_acl_info *,
						  struct tomoyo_acl_info *,
						  const bool))
						  const bool))
{
{
	const bool is_delete = param->is_delete;
	int error = is_delete ? -ENOENT : -ENOMEM;
	int error = is_delete ? -ENOENT : -ENOMEM;
	struct tomoyo_acl_info *entry;
	struct tomoyo_acl_info *entry;
	struct list_head * const list = param->list;


	if (mutex_lock_interruptible(&tomoyo_policy_lock))
	if (mutex_lock_interruptible(&tomoyo_policy_lock))
		return error;
		return error;
	list_for_each_entry_rcu(entry, &domain->acl_info_list, list) {
	list_for_each_entry_rcu(entry, list, list) {
		if (!tomoyo_same_acl_head(entry, new_entry) ||
		if (!tomoyo_same_acl_head(entry, new_entry) ||
		    !check_duplicate(entry, new_entry))
		    !check_duplicate(entry, new_entry))
			continue;
			continue;
@@ -116,7 +117,7 @@ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
	if (error && !is_delete) {
	if (error && !is_delete) {
		entry = tomoyo_commit_ok(new_entry, size);
		entry = tomoyo_commit_ok(new_entry, size);
		if (entry) {
		if (entry) {
			list_add_tail_rcu(&entry->list, &domain->acl_info_list);
			list_add_tail_rcu(&entry->list, list);
			error = 0;
			error = 0;
		}
		}
	}
	}
@@ -163,6 +164,14 @@ static const char *tomoyo_last_word(const char *name)
        return name;
        return name;
}
}


/**
 * tomoyo_same_transition_control - Check for duplicated "struct tomoyo_transition_control" entry.
 *
 * @a: Pointer to "struct tomoyo_acl_head".
 * @b: Pointer to "struct tomoyo_acl_head".
 *
 * Returns true if @a == @b, false otherwise.
 */
static bool tomoyo_same_transition_control(const struct tomoyo_acl_head *a,
static bool tomoyo_same_transition_control(const struct tomoyo_acl_head *a,
					   const struct tomoyo_acl_head *b)
					   const struct tomoyo_acl_head *b)
{
{
@@ -178,22 +187,28 @@ static bool tomoyo_same_transition_control(const struct tomoyo_acl_head *a,
}
}


/**
/**
 * tomoyo_update_transition_control_entry - Update "struct tomoyo_transition_control" list.
 * tomoyo_write_transition_control - Write "struct tomoyo_transition_control" list.
 *
 *
 * @domainname: The name of domain. Maybe NULL.
 * @param: Pointer to "struct tomoyo_acl_param".
 * @program:    The name of program. Maybe NULL.
 * @type:  Type of this entry.
 * @type:       Type of transition.
 * @is_delete:  True if it is a delete request.
 *
 *
 * Returns 0 on success, negative value otherwise.
 * Returns 0 on success, negative value otherwise.
 */
 */
static int tomoyo_update_transition_control_entry(const char *domainname,
int tomoyo_write_transition_control(struct tomoyo_acl_param *param,
						  const char *program,
				    const u8 type)
						  const u8 type,
						  const bool is_delete)
{
{
	struct tomoyo_transition_control e = { .type = type };
	struct tomoyo_transition_control e = { .type = type };
	int error = is_delete ? -ENOENT : -ENOMEM;
	int error = param->is_delete ? -ENOENT : -ENOMEM;
	char *program = param->data;
	char *domainname = strstr(program, " from ");
	if (domainname) {
		*domainname = '\0';
		domainname += 6;
	} else if (type == TOMOYO_TRANSITION_CONTROL_NO_KEEP ||
		   type == TOMOYO_TRANSITION_CONTROL_KEEP) {
		domainname = program;
		program = NULL;
	}
	if (program) {
	if (program) {
		if (!tomoyo_correct_path(program))
		if (!tomoyo_correct_path(program))
			return -EINVAL;
			return -EINVAL;
@@ -211,9 +226,8 @@ static int tomoyo_update_transition_control_entry(const char *domainname,
		if (!e.domainname)
		if (!e.domainname)
			goto out;
			goto out;
	}
	}
	error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
	param->list = &tomoyo_policy_list[TOMOYO_ID_TRANSITION_CONTROL];
				     &tomoyo_policy_list
	error = tomoyo_update_policy(&e.head, sizeof(e), param,
				     [TOMOYO_ID_TRANSITION_CONTROL],
				     tomoyo_same_transition_control);
				     tomoyo_same_transition_control);
out:
out:
	tomoyo_put_name(e.domainname);
	tomoyo_put_name(e.domainname);
@@ -221,31 +235,6 @@ static int tomoyo_update_transition_control_entry(const char *domainname,
	return error;
	return error;
}
}


/**
 * tomoyo_write_transition_control - Write "struct tomoyo_transition_control" list.
 *
 * @data:      String to parse.
 * @is_delete: True if it is a delete request.
 * @type:      Type of this entry.
 *
 * Returns 0 on success, negative value otherwise.
 */
int tomoyo_write_transition_control(char *data, const bool is_delete,
				    const u8 type)
{
	char *domainname = strstr(data, " from ");
	if (domainname) {
		*domainname = '\0';
		domainname += 6;
	} else if (type == TOMOYO_TRANSITION_CONTROL_NO_KEEP ||
		   type == TOMOYO_TRANSITION_CONTROL_KEEP) {
		domainname = data;
		data = NULL;
	}
	return tomoyo_update_transition_control_entry(domainname, data, type,
						      is_delete);
}

/**
/**
 * tomoyo_transition_type - Get domain transition type.
 * tomoyo_transition_type - Get domain transition type.
 *
 *
@@ -303,34 +292,41 @@ static u8 tomoyo_transition_type(const struct tomoyo_path_info *domainname,
	return type;
	return type;
}
}


/**
 * tomoyo_same_aggregator - Check for duplicated "struct tomoyo_aggregator" entry.
 *
 * @a: Pointer to "struct tomoyo_acl_head".
 * @b: Pointer to "struct tomoyo_acl_head".
 *
 * Returns true if @a == @b, false otherwise.
 */
static bool tomoyo_same_aggregator(const struct tomoyo_acl_head *a,
static bool tomoyo_same_aggregator(const struct tomoyo_acl_head *a,
				   const struct tomoyo_acl_head *b)
				   const struct tomoyo_acl_head *b)
{
{
	const struct tomoyo_aggregator *p1 = container_of(a, typeof(*p1), head);
	const struct tomoyo_aggregator *p1 = container_of(a, typeof(*p1),
	const struct tomoyo_aggregator *p2 = container_of(b, typeof(*p2), head);
							  head);
	const struct tomoyo_aggregator *p2 = container_of(b, typeof(*p2),
							  head);
	return p1->original_name == p2->original_name &&
	return p1->original_name == p2->original_name &&
		p1->aggregated_name == p2->aggregated_name;
		p1->aggregated_name == p2->aggregated_name;
}
}


/**
/**
 * tomoyo_update_aggregator_entry - Update "struct tomoyo_aggregator" list.
 * tomoyo_write_aggregator - Write "struct tomoyo_aggregator" list.
 *
 *
 * @original_name:   The original program's name.
 * @param: Pointer to "struct tomoyo_acl_param".
 * @aggregated_name: The program name to use.
 * @is_delete:       True if it is a delete request.
 *
 *
 * Returns 0 on success, negative value otherwise.
 * Returns 0 on success, negative value otherwise.
 *
 *
 * Caller holds tomoyo_read_lock().
 * Caller holds tomoyo_read_lock().
 */
 */
static int tomoyo_update_aggregator_entry(const char *original_name,
int tomoyo_write_aggregator(struct tomoyo_acl_param *param)
					  const char *aggregated_name,
					  const bool is_delete)
{
{
	struct tomoyo_aggregator e = { };
	struct tomoyo_aggregator e = { };
	int error = is_delete ? -ENOENT : -ENOMEM;
	int error = param->is_delete ? -ENOENT : -ENOMEM;

	const char *original_name = tomoyo_read_token(param);
	if (!tomoyo_correct_path(original_name) ||
	const char *aggregated_name = tomoyo_read_token(param);
	if (!tomoyo_correct_word(original_name) ||
	    !tomoyo_correct_path(aggregated_name))
	    !tomoyo_correct_path(aggregated_name))
		return -EINVAL;
		return -EINVAL;
	e.original_name = tomoyo_get_name(original_name);
	e.original_name = tomoyo_get_name(original_name);
@@ -338,8 +334,8 @@ static int tomoyo_update_aggregator_entry(const char *original_name,
	if (!e.original_name || !e.aggregated_name ||
	if (!e.original_name || !e.aggregated_name ||
	    e.aggregated_name->is_patterned) /* No patterns allowed. */
	    e.aggregated_name->is_patterned) /* No patterns allowed. */
		goto out;
		goto out;
	error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
	param->list = &tomoyo_policy_list[TOMOYO_ID_AGGREGATOR];
				     &tomoyo_policy_list[TOMOYO_ID_AGGREGATOR],
	error = tomoyo_update_policy(&e.head, sizeof(e), param,
				     tomoyo_same_aggregator);
				     tomoyo_same_aggregator);
out:
out:
	tomoyo_put_name(e.original_name);
	tomoyo_put_name(e.original_name);
@@ -347,26 +343,6 @@ static int tomoyo_update_aggregator_entry(const char *original_name,
	return error;
	return error;
}
}


/**
 * tomoyo_write_aggregator - Write "struct tomoyo_aggregator" list.
 *
 * @data:      String to parse.
 * @is_delete: True if it is a delete request.
 *
 * Returns 0 on success, negative value otherwise.
 *
 * Caller holds tomoyo_read_lock().
 */
int tomoyo_write_aggregator(char *data, const bool is_delete)
{
	char *cp = strchr(data, ' ');

	if (!cp)
		return -EINVAL;
	*cp++ = '\0';
	return tomoyo_update_aggregator_entry(data, cp, is_delete);
}

/**
/**
 * tomoyo_assign_domain - Create a domain.
 * tomoyo_assign_domain - Create a domain.
 *
 *
+126 −111

File changed.

Preview size limit exceeded, changes collapsed.

+13 −20
Original line number Original line Diff line number Diff line
@@ -28,45 +28,38 @@ static bool tomoyo_same_number_group(const struct tomoyo_acl_head *a,
/**
/**
 * tomoyo_write_group - Write "struct tomoyo_path_group"/"struct tomoyo_number_group" list.
 * tomoyo_write_group - Write "struct tomoyo_path_group"/"struct tomoyo_number_group" list.
 *
 *
 * @data:      String to parse.
 * @param: Pointer to "struct tomoyo_acl_param".
 * @is_delete: True if it is a delete request.
 * @type:      Type of this group.
 * @type:      Type of this group.
 *
 *
 * Returns 0 on success, negative value otherwise.
 * Returns 0 on success, negative value otherwise.
 */
 */
int tomoyo_write_group(char *data, const bool is_delete, const u8 type)
int tomoyo_write_group(struct tomoyo_acl_param *param, const u8 type)
{
{
	struct tomoyo_group *group;
	struct tomoyo_group *group = tomoyo_get_group(param, type);
	struct list_head *member;
	char *w[2];
	int error = -EINVAL;
	int error = -EINVAL;
	if (!tomoyo_tokenize(data, w, sizeof(w)) || !w[1][0])
		return -EINVAL;
	group = tomoyo_get_group(w[0], type);
	if (!group)
	if (!group)
		return -ENOMEM;
		return -ENOMEM;
	member = &group->member_list;
	param->list = &group->member_list;
	if (type == TOMOYO_PATH_GROUP) {
	if (type == TOMOYO_PATH_GROUP) {
		struct tomoyo_path_group e = { };
		struct tomoyo_path_group e = { };
		e.member_name = tomoyo_get_name(w[1]);
		e.member_name = tomoyo_get_name(tomoyo_read_token(param));
		if (!e.member_name) {
		if (!e.member_name) {
			error = -ENOMEM;
			error = -ENOMEM;
			goto out;
			goto out;
		}
		}
		error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
		error = tomoyo_update_policy(&e.head, sizeof(e), param,
					     member, tomoyo_same_path_group);
					  tomoyo_same_path_group);
		tomoyo_put_name(e.member_name);
		tomoyo_put_name(e.member_name);
	} else if (type == TOMOYO_NUMBER_GROUP) {
	} else if (type == TOMOYO_NUMBER_GROUP) {
		struct tomoyo_number_group e = { };
		struct tomoyo_number_group e = { };
		if (w[1][0] == '@'
		if (param->data[0] == '@' ||
		    || !tomoyo_parse_number_union(w[1], &e.number)
		    !tomoyo_parse_number_union(param, &e.number))
		    || e.number.values[0] > e.number.values[1])
			goto out;
			goto out;
		error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
		error = tomoyo_update_policy(&e.head, sizeof(e), param,
					     member, tomoyo_same_number_group);
					  tomoyo_same_number_group);
		/*
		/*
		 * tomoyo_put_number_union() is not needed because
		 * tomoyo_put_number_union() is not needed because
		 * w[1][0] != '@'.
		 * param->data[0] != '@'.
		 */
		 */
	}
	}
out:
out:
Loading