162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * security/tomoyo/environ.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2005-2011  NTT DATA CORPORATION
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include "common.h"
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci/**
1162306a36Sopenharmony_ci * tomoyo_check_env_acl - Check permission for environment variable's name.
1262306a36Sopenharmony_ci *
1362306a36Sopenharmony_ci * @r:   Pointer to "struct tomoyo_request_info".
1462306a36Sopenharmony_ci * @ptr: Pointer to "struct tomoyo_acl_info".
1562306a36Sopenharmony_ci *
1662306a36Sopenharmony_ci * Returns true if granted, false otherwise.
1762306a36Sopenharmony_ci */
1862306a36Sopenharmony_cistatic bool tomoyo_check_env_acl(struct tomoyo_request_info *r,
1962306a36Sopenharmony_ci				 const struct tomoyo_acl_info *ptr)
2062306a36Sopenharmony_ci{
2162306a36Sopenharmony_ci	const struct tomoyo_env_acl *acl =
2262306a36Sopenharmony_ci		container_of(ptr, typeof(*acl), head);
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	return tomoyo_path_matches_pattern(r->param.environ.name, acl->env);
2562306a36Sopenharmony_ci}
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci/**
2862306a36Sopenharmony_ci * tomoyo_audit_env_log - Audit environment variable name log.
2962306a36Sopenharmony_ci *
3062306a36Sopenharmony_ci * @r: Pointer to "struct tomoyo_request_info".
3162306a36Sopenharmony_ci *
3262306a36Sopenharmony_ci * Returns 0 on success, negative value otherwise.
3362306a36Sopenharmony_ci */
3462306a36Sopenharmony_cistatic int tomoyo_audit_env_log(struct tomoyo_request_info *r)
3562306a36Sopenharmony_ci{
3662306a36Sopenharmony_ci	return tomoyo_supervisor(r, "misc env %s\n",
3762306a36Sopenharmony_ci				 r->param.environ.name->name);
3862306a36Sopenharmony_ci}
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci/**
4162306a36Sopenharmony_ci * tomoyo_env_perm - Check permission for environment variable's name.
4262306a36Sopenharmony_ci *
4362306a36Sopenharmony_ci * @r:   Pointer to "struct tomoyo_request_info".
4462306a36Sopenharmony_ci * @env: The name of environment variable.
4562306a36Sopenharmony_ci *
4662306a36Sopenharmony_ci * Returns 0 on success, negative value otherwise.
4762306a36Sopenharmony_ci *
4862306a36Sopenharmony_ci * Caller holds tomoyo_read_lock().
4962306a36Sopenharmony_ci */
5062306a36Sopenharmony_ciint tomoyo_env_perm(struct tomoyo_request_info *r, const char *env)
5162306a36Sopenharmony_ci{
5262306a36Sopenharmony_ci	struct tomoyo_path_info environ;
5362306a36Sopenharmony_ci	int error;
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	if (!env || !*env)
5662306a36Sopenharmony_ci		return 0;
5762306a36Sopenharmony_ci	environ.name = env;
5862306a36Sopenharmony_ci	tomoyo_fill_path_info(&environ);
5962306a36Sopenharmony_ci	r->param_type = TOMOYO_TYPE_ENV_ACL;
6062306a36Sopenharmony_ci	r->param.environ.name = &environ;
6162306a36Sopenharmony_ci	do {
6262306a36Sopenharmony_ci		tomoyo_check_acl(r, tomoyo_check_env_acl);
6362306a36Sopenharmony_ci		error = tomoyo_audit_env_log(r);
6462306a36Sopenharmony_ci	} while (error == TOMOYO_RETRY_REQUEST);
6562306a36Sopenharmony_ci	return error;
6662306a36Sopenharmony_ci}
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci/**
6962306a36Sopenharmony_ci * tomoyo_same_env_acl - Check for duplicated "struct tomoyo_env_acl" entry.
7062306a36Sopenharmony_ci *
7162306a36Sopenharmony_ci * @a: Pointer to "struct tomoyo_acl_info".
7262306a36Sopenharmony_ci * @b: Pointer to "struct tomoyo_acl_info".
7362306a36Sopenharmony_ci *
7462306a36Sopenharmony_ci * Returns true if @a == @b, false otherwise.
7562306a36Sopenharmony_ci */
7662306a36Sopenharmony_cistatic bool tomoyo_same_env_acl(const struct tomoyo_acl_info *a,
7762306a36Sopenharmony_ci				const struct tomoyo_acl_info *b)
7862306a36Sopenharmony_ci{
7962306a36Sopenharmony_ci	const struct tomoyo_env_acl *p1 = container_of(a, typeof(*p1), head);
8062306a36Sopenharmony_ci	const struct tomoyo_env_acl *p2 = container_of(b, typeof(*p2), head);
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci	return p1->env == p2->env;
8362306a36Sopenharmony_ci}
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci/**
8662306a36Sopenharmony_ci * tomoyo_write_env - Write "struct tomoyo_env_acl" list.
8762306a36Sopenharmony_ci *
8862306a36Sopenharmony_ci * @param: Pointer to "struct tomoyo_acl_param".
8962306a36Sopenharmony_ci *
9062306a36Sopenharmony_ci * Returns 0 on success, negative value otherwise.
9162306a36Sopenharmony_ci *
9262306a36Sopenharmony_ci * Caller holds tomoyo_read_lock().
9362306a36Sopenharmony_ci */
9462306a36Sopenharmony_cistatic int tomoyo_write_env(struct tomoyo_acl_param *param)
9562306a36Sopenharmony_ci{
9662306a36Sopenharmony_ci	struct tomoyo_env_acl e = { .head.type = TOMOYO_TYPE_ENV_ACL };
9762306a36Sopenharmony_ci	int error = -ENOMEM;
9862306a36Sopenharmony_ci	const char *data = tomoyo_read_token(param);
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	if (!tomoyo_correct_word(data) || strchr(data, '='))
10162306a36Sopenharmony_ci		return -EINVAL;
10262306a36Sopenharmony_ci	e.env = tomoyo_get_name(data);
10362306a36Sopenharmony_ci	if (!e.env)
10462306a36Sopenharmony_ci		return error;
10562306a36Sopenharmony_ci	error = tomoyo_update_domain(&e.head, sizeof(e), param,
10662306a36Sopenharmony_ci				  tomoyo_same_env_acl, NULL);
10762306a36Sopenharmony_ci	tomoyo_put_name(e.env);
10862306a36Sopenharmony_ci	return error;
10962306a36Sopenharmony_ci}
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci/**
11262306a36Sopenharmony_ci * tomoyo_write_misc - Update environment variable list.
11362306a36Sopenharmony_ci *
11462306a36Sopenharmony_ci * @param: Pointer to "struct tomoyo_acl_param".
11562306a36Sopenharmony_ci *
11662306a36Sopenharmony_ci * Returns 0 on success, negative value otherwise.
11762306a36Sopenharmony_ci */
11862306a36Sopenharmony_ciint tomoyo_write_misc(struct tomoyo_acl_param *param)
11962306a36Sopenharmony_ci{
12062306a36Sopenharmony_ci	if (tomoyo_str_starts(&param->data, "env "))
12162306a36Sopenharmony_ci		return tomoyo_write_env(param);
12262306a36Sopenharmony_ci	return -EINVAL;
12362306a36Sopenharmony_ci}
124