Commit 8b985bbf authored by Tetsuo Handa's avatar Tetsuo Handa

tomoyo: allow building as a loadable LSM module

One of concerns for enabling TOMOYO in prebuilt kernels is that distributor
wants to avoid bloating kernel packages. Although boot-time kernel command
line options allows selecting built-in LSMs to enable, file size increase
of vmlinux and memory footprint increase of vmlinux caused by builtin-but-
not-enabled LSMs remains. If it becomes possible to make LSMs dynamically
appendable after boot using loadable kernel modules, these problems will
go away.

Another of concerns for enabling TOMOYO in prebuilt kernels is that who can
provide support when distributor cannot provide support. Due to "those who
compiled kernel code is expected to provide support for that kernel code"
spell, TOMOYO is failing to get enabled in Fedora distribution [1]. The
point of loadable kernel module is to share the workload. If it becomes
possible to make LSMs dynamically appendable after boot using loadable
kernel modules, as with people can use device drivers not supported by
distributors but provided by third party device vendors, we can break
this spell and can lower the barrier for using TOMOYO.

This patch is intended for demonstrating that there is nothing difficult
for supporting TOMOYO-like loadable LSM modules. For now we need to live
with a mixture of built-in part and loadable part because fully loadable
LSM modules are not supported since Linux 2.6.24 [2] and number of LSMs
which can reserve static call slots is determined at compile time in
Linux 6.12.

Major changes in this patch are described below.
There are no behavior changes as long as TOMOYO is built into vmlinux.

Add CONFIG_SECURITY_TOMOYO_LKM as "bool" instead of changing
CONFIG_SECURITY_TOMOYO from "bool" to "tristate", for something went
wrong with how Makefile is evaluated if I choose "tristate".

Add proxy.c for serving as a bridge between vmlinux and tomoyo.ko .
Move callback functions from init.c to proxy.c when building as a loadable
LSM module. init.c is built-in part and remains for reserving static call
slots. proxy.c contains module's init function and tells init.c location of
callback functions, making it possible to use static call for tomoyo.ko .

By deferring initialization of "struct tomoyo_task" until tomoyo.ko is
loaded, threads created between init.c reserved LSM hooks and proxy.c
updates LSM hooks will have NULL "struct tomoyo_task" instances. Assuming
that tomoyo.ko is loaded by the moment when the global init process starts,
initialize "struct tomoyo_task" instance for current thread as a kernel
thread when tomoyo_task(current) is called for the first time.

There is a hack for exporting currently not-exported functions.
This hack will be removed after all relevant functions are exported.

Link: https://bugzilla.redhat.com/show_bug.cgi?id=542986 [1]
Link: https://lkml.kernel.org/r/caafb609-8bef-4840-a080-81537356fc60@I-love.SAKURA.ne.jp [2]
Signed-off-by: default avatarTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
parent 268225a1
...@@ -13,6 +13,21 @@ config SECURITY_TOMOYO ...@@ -13,6 +13,21 @@ config SECURITY_TOMOYO
found at <https://tomoyo.sourceforge.net/>. found at <https://tomoyo.sourceforge.net/>.
If you are unsure how to answer this question, answer N. If you are unsure how to answer this question, answer N.
config SECURITY_TOMOYO_LKM
bool "Cut out most of TOMOYO's code to a loadable kernel module"
default n
depends on SECURITY_TOMOYO
depends on MODULES
help
Say Y here if you want to include TOMOYO without bloating
vmlinux file. If you say Y, most of TOMOYO code is cut out to
a loadable kernel module named tomoyo.ko . This option will be
useful for kernels built by Linux distributors where TOMOYO is
included but TOMOYO is not enabled by default. Please be sure
to explicitly load tomoyo.ko if you want to activate TOMOYO
without calling userspace policy loader, for tomoyo.ko is
loaded immediately before calling userspace policy loader.
config SECURITY_TOMOYO_MAX_ACCEPT_ENTRY config SECURITY_TOMOYO_MAX_ACCEPT_ENTRY
int "Default maximal count for learning mode" int "Default maximal count for learning mode"
default 2048 default 2048
......
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
obj-y = audit.o common.o condition.o domain.o environ.o file.o gc.o group.o init.o load_policy.o memory.o mount.o network.o realpath.o securityfs_if.o util.o tomoyo-objs := audit.o common.o condition.o domain.o environ.o file.o gc.o group.o memory.o mount.o network.o proxy.o realpath.o securityfs_if.o util.o
obj-y += init.o load_policy.o
ifdef CONFIG_SECURITY_TOMOYO_LKM
obj-m += tomoyo.o
else
obj-y += tomoyo.o
endif
targets += builtin-policy.h targets += builtin-policy.h
......
...@@ -998,8 +998,13 @@ static bool tomoyo_select_domain(struct tomoyo_io_buffer *head, ...@@ -998,8 +998,13 @@ static bool tomoyo_select_domain(struct tomoyo_io_buffer *head,
p = find_task_by_pid_ns(pid, &init_pid_ns); p = find_task_by_pid_ns(pid, &init_pid_ns);
else else
p = find_task_by_vpid(pid); p = find_task_by_vpid(pid);
if (p) if (p) {
domain = tomoyo_task(p)->domain_info; domain = tomoyo_task(p)->domain_info;
#ifdef CONFIG_SECURITY_TOMOYO_LKM
if (!domain)
domain = &tomoyo_kernel_domain;
#endif
}
rcu_read_unlock(); rcu_read_unlock();
} else if (!strncmp(data, "domain=", 7)) { } else if (!strncmp(data, "domain=", 7)) {
if (tomoyo_domain_def(data + 7)) if (tomoyo_domain_def(data + 7))
...@@ -1710,8 +1715,13 @@ static void tomoyo_read_pid(struct tomoyo_io_buffer *head) ...@@ -1710,8 +1715,13 @@ static void tomoyo_read_pid(struct tomoyo_io_buffer *head)
p = find_task_by_pid_ns(pid, &init_pid_ns); p = find_task_by_pid_ns(pid, &init_pid_ns);
else else
p = find_task_by_vpid(pid); p = find_task_by_vpid(pid);
if (p) if (p) {
domain = tomoyo_task(p)->domain_info; domain = tomoyo_task(p)->domain_info;
#ifdef CONFIG_SECURITY_TOMOYO_LKM
if (!domain)
domain = &tomoyo_kernel_domain;
#endif
}
rcu_read_unlock(); rcu_read_unlock();
if (!domain) if (!domain)
return; return;
......
...@@ -978,6 +978,7 @@ int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile, ...@@ -978,6 +978,7 @@ int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile,
int tomoyo_init_request_info(struct tomoyo_request_info *r, int tomoyo_init_request_info(struct tomoyo_request_info *r,
struct tomoyo_domain_info *domain, struct tomoyo_domain_info *domain,
const u8 index); const u8 index);
int __init tomoyo_interface_init(void);
int tomoyo_mkdev_perm(const u8 operation, const struct path *path, int tomoyo_mkdev_perm(const u8 operation, const struct path *path,
const unsigned int mode, unsigned int dev); const unsigned int mode, unsigned int dev);
int tomoyo_mount_permission(const char *dev_name, const struct path *path, int tomoyo_mount_permission(const char *dev_name, const struct path *path,
...@@ -1214,10 +1215,14 @@ static inline void tomoyo_put_group(struct tomoyo_group *group) ...@@ -1214,10 +1215,14 @@ static inline void tomoyo_put_group(struct tomoyo_group *group)
* *
* Returns pointer to "struct tomoyo_task" for specified thread. * Returns pointer to "struct tomoyo_task" for specified thread.
*/ */
#ifdef CONFIG_SECURITY_TOMOYO_LKM
extern struct tomoyo_task *tomoyo_task(struct task_struct *task);
#else
static inline struct tomoyo_task *tomoyo_task(struct task_struct *task) static inline struct tomoyo_task *tomoyo_task(struct task_struct *task)
{ {
return task->security + tomoyo_blob_sizes.lbs_task; return task->security + tomoyo_blob_sizes.lbs_task;
} }
#endif
/** /**
* tomoyo_same_name_union - Check for duplicated "struct tomoyo_name_union" entry. * tomoyo_same_name_union - Check for duplicated "struct tomoyo_name_union" entry.
...@@ -1284,4 +1289,71 @@ static inline struct tomoyo_policy_namespace *tomoyo_current_namespace(void) ...@@ -1284,4 +1289,71 @@ static inline struct tomoyo_policy_namespace *tomoyo_current_namespace(void)
pos = srcu_dereference((head)->next, &tomoyo_ss); \ pos = srcu_dereference((head)->next, &tomoyo_ss); \
for ( ; pos != (head); pos = srcu_dereference(pos->next, &tomoyo_ss)) for ( ; pos != (head); pos = srcu_dereference(pos->next, &tomoyo_ss))
#ifdef CONFIG_SECURITY_TOMOYO_LKM
#define LSM_HOOK(RET, DEFAULT, NAME, ...) typedef RET (NAME##_t)(__VA_ARGS__);
#include <linux/lsm_hook_defs.h>
#undef LSM_HOOK
struct tomoyo_hooks {
cred_prepare_t *cred_prepare;
bprm_committed_creds_t *bprm_committed_creds;
task_alloc_t *task_alloc;
task_free_t *task_free;
bprm_check_security_t *bprm_check_security;
file_fcntl_t *file_fcntl;
file_open_t *file_open;
file_truncate_t *file_truncate;
path_truncate_t *path_truncate;
path_unlink_t *path_unlink;
path_mkdir_t *path_mkdir;
path_rmdir_t *path_rmdir;
path_symlink_t *path_symlink;
path_mknod_t *path_mknod;
path_link_t *path_link;
path_rename_t *path_rename;
inode_getattr_t *inode_getattr;
file_ioctl_t *file_ioctl;
file_ioctl_compat_t *file_ioctl_compat;
path_chmod_t *path_chmod;
path_chown_t *path_chown;
path_chroot_t *path_chroot;
sb_mount_t *sb_mount;
sb_umount_t *sb_umount;
sb_pivotroot_t *sb_pivotroot;
socket_bind_t *socket_bind;
socket_connect_t *socket_connect;
socket_listen_t *socket_listen;
socket_sendmsg_t *socket_sendmsg;
};
extern void tomoyo_register_hooks(const struct tomoyo_hooks *tomoyo_hooks);
struct tomoyo_operations {
void (*check_profile)(void);
int enabled;
};
extern struct tomoyo_operations tomoyo_ops;
/*
* Temporary hack: functions needed by tomoyo.ko . This will be removed
* after all functions are marked as EXPORT_STMBOL_GPL().
*/
struct tomoyo_tmp_exports {
struct task_struct * (*find_task_by_vpid)(pid_t nr);
struct task_struct * (*find_task_by_pid_ns)(pid_t nr, struct pid_namespace *ns);
void (*put_filesystem)(struct file_system_type *fs);
struct file * (*get_mm_exe_file)(struct mm_struct *mm);
char * (*d_absolute_path)(const struct path *path, char *buf, int buflen);
};
extern const struct tomoyo_tmp_exports tomoyo_tmp_exports;
#define find_task_by_vpid tomoyo_tmp_exports.find_task_by_vpid
#define find_task_by_pid_ns tomoyo_tmp_exports.find_task_by_pid_ns
#define put_filesystem tomoyo_tmp_exports.put_filesystem
#define get_mm_exe_file tomoyo_tmp_exports.get_mm_exe_file
#define d_absolute_path tomoyo_tmp_exports.d_absolute_path
#endif /* defined(CONFIG_SECURITY_TOMOYO_LKM) */
#endif /* !defined(_SECURITY_TOMOYO_COMMON_H) */ #endif /* !defined(_SECURITY_TOMOYO_COMMON_H) */
...@@ -9,8 +9,248 @@ ...@@ -9,8 +9,248 @@
#include <uapi/linux/lsm.h> #include <uapi/linux/lsm.h>
#include "common.h" #include "common.h"
#ifndef CONFIG_SECURITY_TOMOYO_LKM
#include "hooks.h" #include "hooks.h"
#else
#define DEFINE_STATIC_CALL_PROXY(NAME) \
static NAME##_t tomoyo_##NAME; \
DEFINE_STATIC_CALL_RET0(tomoyo_##NAME, tomoyo_##NAME);
DEFINE_STATIC_CALL_PROXY(cred_prepare)
DEFINE_STATIC_CALL_PROXY(bprm_committed_creds)
DEFINE_STATIC_CALL_PROXY(bprm_check_security)
DEFINE_STATIC_CALL_PROXY(inode_getattr)
DEFINE_STATIC_CALL_PROXY(path_truncate)
DEFINE_STATIC_CALL_PROXY(file_truncate)
DEFINE_STATIC_CALL_PROXY(path_unlink)
DEFINE_STATIC_CALL_PROXY(path_mkdir)
DEFINE_STATIC_CALL_PROXY(path_rmdir)
DEFINE_STATIC_CALL_PROXY(path_symlink)
DEFINE_STATIC_CALL_PROXY(path_mknod)
DEFINE_STATIC_CALL_PROXY(path_link)
DEFINE_STATIC_CALL_PROXY(path_rename)
DEFINE_STATIC_CALL_PROXY(file_fcntl)
DEFINE_STATIC_CALL_PROXY(file_open)
DEFINE_STATIC_CALL_PROXY(file_ioctl)
DEFINE_STATIC_CALL_PROXY(path_chmod)
DEFINE_STATIC_CALL_PROXY(path_chown)
DEFINE_STATIC_CALL_PROXY(path_chroot)
DEFINE_STATIC_CALL_PROXY(sb_mount)
DEFINE_STATIC_CALL_PROXY(sb_umount)
DEFINE_STATIC_CALL_PROXY(sb_pivotroot)
DEFINE_STATIC_CALL_PROXY(socket_listen)
DEFINE_STATIC_CALL_PROXY(socket_connect)
DEFINE_STATIC_CALL_PROXY(socket_bind)
DEFINE_STATIC_CALL_PROXY(socket_sendmsg)
DEFINE_STATIC_CALL_PROXY(task_alloc)
DEFINE_STATIC_CALL_PROXY(task_free)
#undef DEFINE_STATIC_CALL_PROXY
static int tomoyo_cred_prepare(struct cred *new, const struct cred *old, gfp_t gfp)
{
return static_call(tomoyo_cred_prepare)(new, old, gfp);
}
static void tomoyo_bprm_committed_creds(const struct linux_binprm *bprm)
{
static_call(tomoyo_bprm_committed_creds)(bprm);
}
static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
{
return static_call(tomoyo_bprm_check_security)(bprm);
}
static int tomoyo_inode_getattr(const struct path *path)
{
return static_call(tomoyo_inode_getattr)(path);
}
static int tomoyo_path_truncate(const struct path *path)
{
return static_call(tomoyo_path_truncate)(path);
}
static int tomoyo_file_truncate(struct file *file)
{
return static_call(tomoyo_file_truncate)(file);
}
static int tomoyo_path_unlink(const struct path *parent, struct dentry *dentry)
{
return static_call(tomoyo_path_unlink)(parent, dentry);
}
static int tomoyo_path_mkdir(const struct path *parent, struct dentry *dentry, umode_t mode)
{
return static_call(tomoyo_path_mkdir)(parent, dentry, mode);
}
static int tomoyo_path_rmdir(const struct path *parent, struct dentry *dentry)
{
return static_call(tomoyo_path_rmdir)(parent, dentry);
}
static int tomoyo_path_symlink(const struct path *parent, struct dentry *dentry,
const char *old_name)
{
return static_call(tomoyo_path_symlink)(parent, dentry, old_name);
}
static int tomoyo_path_mknod(const struct path *parent, struct dentry *dentry,
umode_t mode, unsigned int dev)
{
return static_call(tomoyo_path_mknod)(parent, dentry, mode, dev);
}
static int tomoyo_path_link(struct dentry *old_dentry, const struct path *new_dir,
struct dentry *new_dentry)
{
return static_call(tomoyo_path_link)(old_dentry, new_dir, new_dentry);
}
static int tomoyo_path_rename(const struct path *old_parent, struct dentry *old_dentry,
const struct path *new_parent, struct dentry *new_dentry,
const unsigned int flags)
{
return static_call(tomoyo_path_rename)(old_parent, old_dentry, new_parent, new_dentry, flags);
}
static int tomoyo_file_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
{
return static_call(tomoyo_file_fcntl)(file, cmd, arg);
}
static int tomoyo_file_open(struct file *f)
{
return static_call(tomoyo_file_open)(f);
}
static int tomoyo_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
return static_call(tomoyo_file_ioctl)(file, cmd, arg);
}
static int tomoyo_path_chmod(const struct path *path, umode_t mode)
{
return static_call(tomoyo_path_chmod)(path, mode);
}
static int tomoyo_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
{
return static_call(tomoyo_path_chown)(path, uid, gid);
}
static int tomoyo_path_chroot(const struct path *path)
{
return static_call(tomoyo_path_chroot)(path);
}
static int tomoyo_sb_mount(const char *dev_name, const struct path *path,
const char *type, unsigned long flags, void *data)
{
return static_call(tomoyo_sb_mount)(dev_name, path, type, flags, data);
}
static int tomoyo_sb_umount(struct vfsmount *mnt, int flags)
{
return static_call(tomoyo_sb_umount)(mnt, flags);
}
static int tomoyo_sb_pivotroot(const struct path *old_path, const struct path *new_path)
{
return static_call(tomoyo_sb_pivotroot)(old_path, new_path);
}
static int tomoyo_socket_listen(struct socket *sock, int backlog)
{
return static_call(tomoyo_socket_listen)(sock, backlog);
}
static int tomoyo_socket_connect(struct socket *sock, struct sockaddr *addr, int addr_len)
{
return static_call(tomoyo_socket_connect)(sock, addr, addr_len);
}
static int tomoyo_socket_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
{
return static_call(tomoyo_socket_bind)(sock, addr, addr_len);
}
static int tomoyo_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size)
{
return static_call(tomoyo_socket_sendmsg)(sock, msg, size);
}
static int tomoyo_task_alloc(struct task_struct *task, unsigned long clone_flags)
{
return static_call(tomoyo_task_alloc)(task, clone_flags);
}
static void tomoyo_task_free(struct task_struct *task)
{
static_call(tomoyo_task_free)(task);
}
void tomoyo_register_hooks(const struct tomoyo_hooks *tomoyo_hooks)
{
static void *registered;
if (cmpxchg(&registered, NULL, &registered))
panic("%s was called twice!\n", __func__);
static_call_update(tomoyo_task_free, tomoyo_hooks->task_free);
static_call_update(tomoyo_task_alloc, tomoyo_hooks->task_alloc);
static_call_update(tomoyo_cred_prepare, tomoyo_hooks->cred_prepare);
static_call_update(tomoyo_bprm_committed_creds, tomoyo_hooks->bprm_committed_creds);
static_call_update(tomoyo_bprm_check_security, tomoyo_hooks->bprm_check_security);
static_call_update(tomoyo_inode_getattr, tomoyo_hooks->inode_getattr);
static_call_update(tomoyo_path_truncate, tomoyo_hooks->path_truncate);
static_call_update(tomoyo_file_truncate, tomoyo_hooks->file_truncate);
static_call_update(tomoyo_path_unlink, tomoyo_hooks->path_unlink);
static_call_update(tomoyo_path_mkdir, tomoyo_hooks->path_mkdir);
static_call_update(tomoyo_path_rmdir, tomoyo_hooks->path_rmdir);
static_call_update(tomoyo_path_symlink, tomoyo_hooks->path_symlink);
static_call_update(tomoyo_path_mknod, tomoyo_hooks->path_mknod);
static_call_update(tomoyo_path_link, tomoyo_hooks->path_link);
static_call_update(tomoyo_path_rename, tomoyo_hooks->path_rename);
static_call_update(tomoyo_file_fcntl, tomoyo_hooks->file_fcntl);
static_call_update(tomoyo_file_open, tomoyo_hooks->file_open);
static_call_update(tomoyo_file_ioctl, tomoyo_hooks->file_ioctl);
static_call_update(tomoyo_path_chmod, tomoyo_hooks->path_chmod);
static_call_update(tomoyo_path_chown, tomoyo_hooks->path_chown);
static_call_update(tomoyo_path_chroot, tomoyo_hooks->path_chroot);
static_call_update(tomoyo_sb_mount, tomoyo_hooks->sb_mount);
static_call_update(tomoyo_sb_umount, tomoyo_hooks->sb_umount);
static_call_update(tomoyo_sb_pivotroot, tomoyo_hooks->sb_pivotroot);
static_call_update(tomoyo_socket_listen, tomoyo_hooks->socket_listen);
static_call_update(tomoyo_socket_connect, tomoyo_hooks->socket_connect);
static_call_update(tomoyo_socket_bind, tomoyo_hooks->socket_bind);
static_call_update(tomoyo_socket_sendmsg, tomoyo_hooks->socket_sendmsg);
}
EXPORT_SYMBOL_GPL(tomoyo_register_hooks);
/*
* Temporary hack: functions needed by tomoyo.ko . This hack will be removed
* after all functions are marked as EXPORT_STMBOL_GPL().
*/
#undef find_task_by_vpid
#undef find_task_by_pid_ns
#undef put_filesystem
#undef get_mm_exe_file
#undef d_absolute_path
const struct tomoyo_tmp_exports tomoyo_tmp_exports = {
.find_task_by_vpid = find_task_by_vpid,
.find_task_by_pid_ns = find_task_by_pid_ns,
.put_filesystem = put_filesystem,
.get_mm_exe_file = get_mm_exe_file,
.d_absolute_path = d_absolute_path,
};
EXPORT_SYMBOL_GPL(tomoyo_tmp_exports);
#endif
#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER #ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
static int tomoyo_bprm_creds_for_exec(struct linux_binprm *bprm) static int tomoyo_bprm_creds_for_exec(struct linux_binprm *bprm)
{ {
...@@ -74,6 +314,27 @@ int tomoyo_enabled __ro_after_init = 1; ...@@ -74,6 +314,27 @@ int tomoyo_enabled __ro_after_init = 1;
/* Has /sbin/init started? */ /* Has /sbin/init started? */
bool tomoyo_policy_loaded; bool tomoyo_policy_loaded;
#ifdef CONFIG_SECURITY_TOMOYO_LKM
EXPORT_SYMBOL_GPL(tomoyo_blob_sizes);
EXPORT_SYMBOL_GPL(tomoyo_policy_loaded);
struct tomoyo_operations tomoyo_ops;
EXPORT_SYMBOL_GPL(tomoyo_ops);
/**
* tomoyo_init - Reserve hooks for TOMOYO Linux.
*
* Returns 0.
*/
static int __init tomoyo_init(void)
{
/* register ourselves with the security framework */
security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), &tomoyo_lsmid);
tomoyo_ops.enabled = tomoyo_enabled;
pr_info("Hooks for initializing TOMOYO Linux are ready\n");
return 0;
}
#else
/** /**
* tomoyo_init - Register TOMOYO Linux as a LSM module. * tomoyo_init - Register TOMOYO Linux as a LSM module.
* *
...@@ -94,6 +355,7 @@ static int __init tomoyo_init(void) ...@@ -94,6 +355,7 @@ static int __init tomoyo_init(void)
return 0; return 0;
} }
#endif
DEFINE_LSM(tomoyo) = { DEFINE_LSM(tomoyo) = {
.name = "tomoyo", .name = "tomoyo",
......
...@@ -97,6 +97,14 @@ void tomoyo_load_policy(const char *filename) ...@@ -97,6 +97,14 @@ void tomoyo_load_policy(const char *filename)
if (!tomoyo_policy_loader_exists()) if (!tomoyo_policy_loader_exists())
return; return;
done = true; done = true;
#ifdef CONFIG_SECURITY_TOMOYO_LKM
/* Load tomoyo.ko if not yet loaded. */
if (!tomoyo_ops.check_profile)
request_module("tomoyo");
/* Check if tomoyo.ko was successfully loaded. */
if (!tomoyo_ops.check_profile)
panic("Failed to load tomoyo module.");
#endif
pr_info("Calling %s to load policy. Please wait.\n", tomoyo_loader); pr_info("Calling %s to load policy. Please wait.\n", tomoyo_loader);
argv[0] = (char *) tomoyo_loader; argv[0] = (char *) tomoyo_loader;
argv[1] = NULL; argv[1] = NULL;
...@@ -104,7 +112,11 @@ void tomoyo_load_policy(const char *filename) ...@@ -104,7 +112,11 @@ void tomoyo_load_policy(const char *filename)
envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
envp[2] = NULL; envp[2] = NULL;
call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC); call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
#ifdef CONFIG_SECURITY_TOMOYO_LKM
tomoyo_ops.check_profile();
#else
tomoyo_check_profile(); tomoyo_check_profile();
#endif
} }
#endif #endif
// SPDX-License-Identifier: GPL-2.0
/*
* security/tomoyo/proxy.c
*
* Copyright (C) 2005-2011 NTT DATA CORPORATION
*/
#include <linux/security.h>
#include "common.h"
#ifdef CONFIG_SECURITY_TOMOYO_LKM
struct tomoyo_task *tomoyo_task(struct task_struct *task)
{
struct tomoyo_task *s = task->security + tomoyo_blob_sizes.lbs_task;
if (unlikely(!s->domain_info)) {
if (likely(task == current)) {
s->domain_info = &tomoyo_kernel_domain;
atomic_inc(&tomoyo_kernel_domain.users);
} else {
/* Caller handles s->domain_info == NULL case. */
}
}
return s;
}
#include "hooks.h"
/**
* tomoyo_runtime_init - Register TOMOYO Linux as a loadable LSM module.
*
* Returns 0 if TOMOYO is enabled, -EINVAL otherwise.
*/
static int __init tomoyo_runtime_init(void)
{
const struct tomoyo_hooks tomoyo_hooks = {
.cred_prepare = tomoyo_cred_prepare,
.bprm_committed_creds = tomoyo_bprm_committed_creds,
.task_alloc = tomoyo_task_alloc,
.task_free = tomoyo_task_free,
.bprm_check_security = tomoyo_bprm_check_security,
.file_fcntl = tomoyo_file_fcntl,
.file_open = tomoyo_file_open,
.file_truncate = tomoyo_file_truncate,
.path_truncate = tomoyo_path_truncate,
.path_unlink = tomoyo_path_unlink,
.path_mkdir = tomoyo_path_mkdir,
.path_rmdir = tomoyo_path_rmdir,
.path_symlink = tomoyo_path_symlink,
.path_mknod = tomoyo_path_mknod,
.path_link = tomoyo_path_link,
.path_rename = tomoyo_path_rename,
.inode_getattr = tomoyo_inode_getattr,
.file_ioctl = tomoyo_file_ioctl,
.file_ioctl_compat = tomoyo_file_ioctl,
.path_chmod = tomoyo_path_chmod,
.path_chown = tomoyo_path_chown,
.path_chroot = tomoyo_path_chroot,
.sb_mount = tomoyo_sb_mount,
.sb_umount = tomoyo_sb_umount,
.sb_pivotroot = tomoyo_sb_pivotroot,
.socket_bind = tomoyo_socket_bind,
.socket_connect = tomoyo_socket_connect,
.socket_listen = tomoyo_socket_listen,
.socket_sendmsg = tomoyo_socket_sendmsg,
};
if (!tomoyo_ops.enabled)
return -EINVAL;
tomoyo_ops.check_profile = tomoyo_check_profile;
pr_info("TOMOYO Linux initialized\n");
tomoyo_task(current);
tomoyo_mm_init();
tomoyo_interface_init();
tomoyo_register_hooks(&tomoyo_hooks);
return 0;
}
module_init(tomoyo_runtime_init);
MODULE_LICENSE("GPL");
#endif
...@@ -233,13 +233,15 @@ static void __init tomoyo_create_entry(const char *name, const umode_t mode, ...@@ -233,13 +233,15 @@ static void __init tomoyo_create_entry(const char *name, const umode_t mode,
* *
* Returns 0. * Returns 0.
*/ */
static int __init tomoyo_interface_init(void) int __init tomoyo_interface_init(void)
{ {
struct tomoyo_domain_info *domain; struct tomoyo_domain_info *domain;
struct dentry *tomoyo_dir; struct dentry *tomoyo_dir;
#ifndef CONFIG_SECURITY_TOMOYO_LKM
if (!tomoyo_enabled) if (!tomoyo_enabled)
return 0; return 0;
#endif
domain = tomoyo_domain(); domain = tomoyo_domain();
/* Don't create securityfs entries unless registered. */ /* Don't create securityfs entries unless registered. */
if (domain != &tomoyo_kernel_domain) if (domain != &tomoyo_kernel_domain)
...@@ -270,4 +272,6 @@ static int __init tomoyo_interface_init(void) ...@@ -270,4 +272,6 @@ static int __init tomoyo_interface_init(void)
return 0; return 0;
} }
#ifndef CONFIG_SECURITY_TOMOYO_LKM
fs_initcall(tomoyo_interface_init); fs_initcall(tomoyo_interface_init);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment