162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * security/tomoyo/load_policy.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#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci/*
1362306a36Sopenharmony_ci * Path to the policy loader. (default = CONFIG_SECURITY_TOMOYO_POLICY_LOADER)
1462306a36Sopenharmony_ci */
1562306a36Sopenharmony_cistatic const char *tomoyo_loader;
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci/**
1862306a36Sopenharmony_ci * tomoyo_loader_setup - Set policy loader.
1962306a36Sopenharmony_ci *
2062306a36Sopenharmony_ci * @str: Program to use as a policy loader (e.g. /sbin/tomoyo-init ).
2162306a36Sopenharmony_ci *
2262306a36Sopenharmony_ci * Returns 0.
2362306a36Sopenharmony_ci */
2462306a36Sopenharmony_cistatic int __init tomoyo_loader_setup(char *str)
2562306a36Sopenharmony_ci{
2662306a36Sopenharmony_ci	tomoyo_loader = str;
2762306a36Sopenharmony_ci	return 1;
2862306a36Sopenharmony_ci}
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci__setup("TOMOYO_loader=", tomoyo_loader_setup);
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci/**
3362306a36Sopenharmony_ci * tomoyo_policy_loader_exists - Check whether /sbin/tomoyo-init exists.
3462306a36Sopenharmony_ci *
3562306a36Sopenharmony_ci * Returns true if /sbin/tomoyo-init exists, false otherwise.
3662306a36Sopenharmony_ci */
3762306a36Sopenharmony_cistatic bool tomoyo_policy_loader_exists(void)
3862306a36Sopenharmony_ci{
3962306a36Sopenharmony_ci	struct path path;
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci	if (!tomoyo_loader)
4262306a36Sopenharmony_ci		tomoyo_loader = CONFIG_SECURITY_TOMOYO_POLICY_LOADER;
4362306a36Sopenharmony_ci	if (kern_path(tomoyo_loader, LOOKUP_FOLLOW, &path)) {
4462306a36Sopenharmony_ci		pr_info("Not activating Mandatory Access Control as %s does not exist.\n",
4562306a36Sopenharmony_ci			tomoyo_loader);
4662306a36Sopenharmony_ci		return false;
4762306a36Sopenharmony_ci	}
4862306a36Sopenharmony_ci	path_put(&path);
4962306a36Sopenharmony_ci	return true;
5062306a36Sopenharmony_ci}
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci/*
5362306a36Sopenharmony_ci * Path to the trigger. (default = CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER)
5462306a36Sopenharmony_ci */
5562306a36Sopenharmony_cistatic const char *tomoyo_trigger;
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci/**
5862306a36Sopenharmony_ci * tomoyo_trigger_setup - Set trigger for activation.
5962306a36Sopenharmony_ci *
6062306a36Sopenharmony_ci * @str: Program to use as an activation trigger (e.g. /sbin/init ).
6162306a36Sopenharmony_ci *
6262306a36Sopenharmony_ci * Returns 0.
6362306a36Sopenharmony_ci */
6462306a36Sopenharmony_cistatic int __init tomoyo_trigger_setup(char *str)
6562306a36Sopenharmony_ci{
6662306a36Sopenharmony_ci	tomoyo_trigger = str;
6762306a36Sopenharmony_ci	return 1;
6862306a36Sopenharmony_ci}
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci__setup("TOMOYO_trigger=", tomoyo_trigger_setup);
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci/**
7362306a36Sopenharmony_ci * tomoyo_load_policy - Run external policy loader to load policy.
7462306a36Sopenharmony_ci *
7562306a36Sopenharmony_ci * @filename: The program about to start.
7662306a36Sopenharmony_ci *
7762306a36Sopenharmony_ci * This function checks whether @filename is /sbin/init , and if so
7862306a36Sopenharmony_ci * invoke /sbin/tomoyo-init and wait for the termination of /sbin/tomoyo-init
7962306a36Sopenharmony_ci * and then continues invocation of /sbin/init.
8062306a36Sopenharmony_ci * /sbin/tomoyo-init reads policy files in /etc/tomoyo/ directory and
8162306a36Sopenharmony_ci * writes to /sys/kernel/security/tomoyo/ interfaces.
8262306a36Sopenharmony_ci *
8362306a36Sopenharmony_ci * Returns nothing.
8462306a36Sopenharmony_ci */
8562306a36Sopenharmony_civoid tomoyo_load_policy(const char *filename)
8662306a36Sopenharmony_ci{
8762306a36Sopenharmony_ci	static bool done;
8862306a36Sopenharmony_ci	char *argv[2];
8962306a36Sopenharmony_ci	char *envp[3];
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci	if (tomoyo_policy_loaded || done)
9262306a36Sopenharmony_ci		return;
9362306a36Sopenharmony_ci	if (!tomoyo_trigger)
9462306a36Sopenharmony_ci		tomoyo_trigger = CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER;
9562306a36Sopenharmony_ci	if (strcmp(filename, tomoyo_trigger))
9662306a36Sopenharmony_ci		return;
9762306a36Sopenharmony_ci	if (!tomoyo_policy_loader_exists())
9862306a36Sopenharmony_ci		return;
9962306a36Sopenharmony_ci	done = true;
10062306a36Sopenharmony_ci	pr_info("Calling %s to load policy. Please wait.\n", tomoyo_loader);
10162306a36Sopenharmony_ci	argv[0] = (char *) tomoyo_loader;
10262306a36Sopenharmony_ci	argv[1] = NULL;
10362306a36Sopenharmony_ci	envp[0] = "HOME=/";
10462306a36Sopenharmony_ci	envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
10562306a36Sopenharmony_ci	envp[2] = NULL;
10662306a36Sopenharmony_ci	call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
10762306a36Sopenharmony_ci	tomoyo_check_profile();
10862306a36Sopenharmony_ci}
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci#endif
111