security/tomoyo/domain.c

Source file repositories/reference/linux-study-clean/security/tomoyo/domain.c

File Facts

System
Linux kernel
Corpus path
security/tomoyo/domain.c
Extension
.c
Size
26190 bytes
Lines
951
Domain
Core OS
Bucket
Security And Isolation
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

srcu_read_lock_held(&tomoyo_ss)) {
		if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS)
			continue;
		if (!check_duplicate(entry, new_entry))
			continue;
		entry->is_deleted = param->is_delete;
		error = 0;
		break;
	}
	if (error && !param->is_delete) {
		entry = tomoyo_commit_ok(new_entry, size);
		if (entry) {
			list_add_tail_rcu(&entry->list, list);
			error = 0;
		}
	}
	mutex_unlock(&tomoyo_policy_lock);
	return error;
}

/**
 * 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 && a->cond == b->cond;
}

/**
 * tomoyo_update_domain - Update an entry for domain policy.
 *
 * @new_entry:       Pointer to "struct tomoyo_acl_info".
 * @size:            Size of @new_entry in bytes.
 * @param:           Pointer to "struct tomoyo_acl_param".
 * @check_duplicate: Callback function to find duplicated entry.
 * @merge_duplicate: Callback function to merge duplicated entry.
 *
 * Returns 0 on success, negative value otherwise.
 *
 * Caller holds tomoyo_read_lock().
 */
int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
			 struct tomoyo_acl_param *param,
			 bool (*check_duplicate)(const struct tomoyo_acl_info
						 *,
						 const struct tomoyo_acl_info
						 *),
			 bool (*merge_duplicate)(struct tomoyo_acl_info *,
						 struct tomoyo_acl_info *,
						 const bool))
{
	const bool is_delete = param->is_delete;
	int error = is_delete ? -ENOENT : -ENOMEM;
	struct tomoyo_acl_info *entry;
	struct list_head * const list = param->list;

	if (param->data[0]) {
		new_entry->cond = tomoyo_get_condition(param);
		if (!new_entry->cond)
			return -EINVAL;
		/*
		 * Domain transition preference is allowed for only
		 * "file execute" entries.
		 */
		if (new_entry->cond->transit &&
		    !(new_entry->type == TOMOYO_TYPE_PATH_ACL &&
		      container_of(new_entry, struct tomoyo_path_acl, head)
		      ->perm == 1 << TOMOYO_TYPE_EXECUTE))
			goto out;
	}
	if (mutex_lock_interruptible(&tomoyo_policy_lock))
		goto out;
	list_for_each_entry_rcu(entry, list, list,
				srcu_read_lock_held(&tomoyo_ss)) {
		if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS)
			continue;
		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,
							    is_delete);
		else
			entry->is_deleted = is_delete;

Annotation

Implementation Notes