Commit c5e3cdbf authored by Paul Moore's avatar Paul Moore

tomoyo: revert CONFIG_SECURITY_TOMOYO_LKM support

This patch reverts two TOMOYO patches that were merged into Linus' tree
during the v6.12 merge window:

8b985bbf ("tomoyo: allow building as a loadable LSM module")
268225a1 ("tomoyo: preparation step for building as a loadable LSM module")

Together these two patches introduced the CONFIG_SECURITY_TOMOYO_LKM
Kconfig build option which enabled a TOMOYO specific dynamic LSM loading
mechanism (see the original commits for more details).  Unfortunately,
this approach was widely rejected by the LSM community as well as some
members of the general kernel community.  Objections included concerns
over setting a bad precedent regarding individual LSMs managing their
LSM callback registrations as well as general kernel symbol exporting
practices.  With little to no support for the CONFIG_SECURITY_TOMOYO_LKM
approach outside of Tetsuo, and multiple objections, we need to revert
these changes.

Link: https://lore.kernel.org/all/0c4b443a-9c72-4800-97e8-a3816b6a9ae2@I-love.SAKURA.ne.jp
Link: https://lore.kernel.org/all/CAHC9VhR=QjdoHG3wJgHFJkKYBg7vkQH2MpffgVzQ0tAByo_wRg@mail.gmail.comAcked-by: default avatarJohn Johansen <john.johansen@canonical.com>
Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
parent 9852d85e
......@@ -13,21 +13,6 @@ config SECURITY_TOMOYO
found at <https://tomoyo.sourceforge.net/>.
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
int "Default maximal count for learning mode"
default 2048
......
# SPDX-License-Identifier: GPL-2.0
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
obj-y = audit.o common.o condition.o domain.o environ.o file.o gc.o group.o load_policy.o memory.o mount.o network.o realpath.o securityfs_if.o tomoyo.o util.o
targets += builtin-policy.h
......
......@@ -998,13 +998,8 @@ static bool tomoyo_select_domain(struct tomoyo_io_buffer *head,
p = find_task_by_pid_ns(pid, &init_pid_ns);
else
p = find_task_by_vpid(pid);
if (p) {
if (p)
domain = tomoyo_task(p)->domain_info;
#ifdef CONFIG_SECURITY_TOMOYO_LKM
if (!domain)
domain = &tomoyo_kernel_domain;
#endif
}
rcu_read_unlock();
} else if (!strncmp(data, "domain=", 7)) {
if (tomoyo_domain_def(data + 7))
......@@ -1715,13 +1710,8 @@ static void tomoyo_read_pid(struct tomoyo_io_buffer *head)
p = find_task_by_pid_ns(pid, &init_pid_ns);
else
p = find_task_by_vpid(pid);
if (p) {
if (p)
domain = tomoyo_task(p)->domain_info;
#ifdef CONFIG_SECURITY_TOMOYO_LKM
if (!domain)
domain = &tomoyo_kernel_domain;
#endif
}
rcu_read_unlock();
if (!domain)
return;
......
......@@ -978,7 +978,6 @@ int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile,
int tomoyo_init_request_info(struct tomoyo_request_info *r,
struct tomoyo_domain_info *domain,
const u8 index);
int __init tomoyo_interface_init(void);
int tomoyo_mkdev_perm(const u8 operation, const struct path *path,
const unsigned int mode, unsigned int dev);
int tomoyo_mount_permission(const char *dev_name, const struct path *path,
......@@ -1215,14 +1214,10 @@ static inline void tomoyo_put_group(struct tomoyo_group *group)
*
* 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)
{
return task->security + tomoyo_blob_sizes.lbs_task;
}
#endif
/**
* tomoyo_same_name_union - Check for duplicated "struct tomoyo_name_union" entry.
......@@ -1289,71 +1284,4 @@ static inline struct tomoyo_policy_namespace *tomoyo_current_namespace(void)
pos = srcu_dereference((head)->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) */
......@@ -9,9 +9,6 @@
#include <linux/kthread.h>
#include <linux/slab.h>
/* Lock for GC. */
DEFINE_SRCU(tomoyo_ss);
/**
* tomoyo_memory_free - Free memory for elements.
*
......
This diff is collapsed.
......@@ -97,14 +97,6 @@ void tomoyo_load_policy(const char *filename)
if (!tomoyo_policy_loader_exists())
return;
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);
argv[0] = (char *) tomoyo_loader;
argv[1] = NULL;
......@@ -112,11 +104,7 @@ void tomoyo_load_policy(const char *filename)
envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
envp[2] = NULL;
call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
#ifdef CONFIG_SECURITY_TOMOYO_LKM
tomoyo_ops.check_profile();
#else
tomoyo_check_profile();
#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
......@@ -229,19 +229,17 @@ static void __init tomoyo_create_entry(const char *name, const umode_t mode,
}
/**
* tomoyo_interface_init - Initialize /sys/kernel/security/tomoyo/ interface.
* tomoyo_initerface_init - Initialize /sys/kernel/security/tomoyo/ interface.
*
* Returns 0.
*/
int __init tomoyo_interface_init(void)
static int __init tomoyo_initerface_init(void)
{
struct tomoyo_domain_info *domain;
struct dentry *tomoyo_dir;
#ifndef CONFIG_SECURITY_TOMOYO_LKM
if (!tomoyo_enabled)
return 0;
#endif
domain = tomoyo_domain();
/* Don't create securityfs entries unless registered. */
if (domain != &tomoyo_kernel_domain)
......@@ -272,6 +270,4 @@ int __init tomoyo_interface_init(void)
return 0;
}
#ifndef CONFIG_SECURITY_TOMOYO_LKM
fs_initcall(tomoyo_interface_init);
#endif
fs_initcall(tomoyo_initerface_init);
// SPDX-License-Identifier: GPL-2.0
/*
* security/tomoyo/hooks.h
* security/tomoyo/tomoyo.c
*
* Copyright (C) 2005-2011 NTT DATA CORPORATION
*/
#include <linux/lsm_hooks.h>
#include <uapi/linux/lsm.h>
#include "common.h"
/**
......@@ -16,6 +18,10 @@ struct tomoyo_domain_info *tomoyo_domain(void)
{
struct tomoyo_task *s = tomoyo_task(current);
if (s->old_domain_info && !current->in_execve) {
atomic_dec(&s->old_domain_info->users);
s->old_domain_info = NULL;
}
return s->domain_info;
}
......@@ -56,6 +62,26 @@ static void tomoyo_bprm_committed_creds(const struct linux_binprm *bprm)
s->old_domain_info = NULL;
}
#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
/**
* tomoyo_bprm_creds_for_exec - Target for security_bprm_creds_for_exec().
*
* @bprm: Pointer to "struct linux_binprm".
*
* Returns 0.
*/
static int tomoyo_bprm_creds_for_exec(struct linux_binprm *bprm)
{
/*
* Load policy if /sbin/tomoyo-init exists and /sbin/init is requested
* for the first time.
*/
if (!tomoyo_policy_loaded)
tomoyo_load_policy(bprm->filename);
return 0;
}
#endif
/**
* tomoyo_bprm_check_security - Target for security_bprm_check().
*
......@@ -475,6 +501,10 @@ static int tomoyo_socket_sendmsg(struct socket *sock, struct msghdr *msg,
return tomoyo_socket_sendmsg_permission(sock, msg, size);
}
struct lsm_blob_sizes tomoyo_blob_sizes __ro_after_init = {
.lbs_task = sizeof(struct tomoyo_task),
};
/**
* tomoyo_task_alloc - Target for security_task_alloc().
*
......@@ -513,3 +543,81 @@ static void tomoyo_task_free(struct task_struct *task)
s->old_domain_info = NULL;
}
}
static const struct lsm_id tomoyo_lsmid = {
.name = "tomoyo",
.id = LSM_ID_TOMOYO,
};
/*
* tomoyo_security_ops is a "struct security_operations" which is used for
* registering TOMOYO.
*/
static struct security_hook_list tomoyo_hooks[] __ro_after_init = {
LSM_HOOK_INIT(cred_prepare, tomoyo_cred_prepare),
LSM_HOOK_INIT(bprm_committed_creds, tomoyo_bprm_committed_creds),
LSM_HOOK_INIT(task_alloc, tomoyo_task_alloc),
LSM_HOOK_INIT(task_free, tomoyo_task_free),
#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
LSM_HOOK_INIT(bprm_creds_for_exec, tomoyo_bprm_creds_for_exec),
#endif
LSM_HOOK_INIT(bprm_check_security, tomoyo_bprm_check_security),
LSM_HOOK_INIT(file_fcntl, tomoyo_file_fcntl),
LSM_HOOK_INIT(file_open, tomoyo_file_open),
LSM_HOOK_INIT(file_truncate, tomoyo_file_truncate),
LSM_HOOK_INIT(path_truncate, tomoyo_path_truncate),
LSM_HOOK_INIT(path_unlink, tomoyo_path_unlink),
LSM_HOOK_INIT(path_mkdir, tomoyo_path_mkdir),
LSM_HOOK_INIT(path_rmdir, tomoyo_path_rmdir),
LSM_HOOK_INIT(path_symlink, tomoyo_path_symlink),
LSM_HOOK_INIT(path_mknod, tomoyo_path_mknod),
LSM_HOOK_INIT(path_link, tomoyo_path_link),
LSM_HOOK_INIT(path_rename, tomoyo_path_rename),
LSM_HOOK_INIT(inode_getattr, tomoyo_inode_getattr),
LSM_HOOK_INIT(file_ioctl, tomoyo_file_ioctl),
LSM_HOOK_INIT(file_ioctl_compat, tomoyo_file_ioctl),
LSM_HOOK_INIT(path_chmod, tomoyo_path_chmod),
LSM_HOOK_INIT(path_chown, tomoyo_path_chown),
LSM_HOOK_INIT(path_chroot, tomoyo_path_chroot),
LSM_HOOK_INIT(sb_mount, tomoyo_sb_mount),
LSM_HOOK_INIT(sb_umount, tomoyo_sb_umount),
LSM_HOOK_INIT(sb_pivotroot, tomoyo_sb_pivotroot),
LSM_HOOK_INIT(socket_bind, tomoyo_socket_bind),
LSM_HOOK_INIT(socket_connect, tomoyo_socket_connect),
LSM_HOOK_INIT(socket_listen, tomoyo_socket_listen),
LSM_HOOK_INIT(socket_sendmsg, tomoyo_socket_sendmsg),
};
/* Lock for GC. */
DEFINE_SRCU(tomoyo_ss);
int tomoyo_enabled __ro_after_init = 1;
/**
* tomoyo_init - Register TOMOYO Linux as a LSM module.
*
* Returns 0.
*/
static int __init tomoyo_init(void)
{
struct tomoyo_task *s = tomoyo_task(current);
/* register ourselves with the security framework */
security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks),
&tomoyo_lsmid);
pr_info("TOMOYO Linux initialized\n");
s->domain_info = &tomoyo_kernel_domain;
atomic_inc(&tomoyo_kernel_domain.users);
s->old_domain_info = NULL;
tomoyo_mm_init();
return 0;
}
DEFINE_LSM(tomoyo) = {
.name = "tomoyo",
.enabled = &tomoyo_enabled,
.flags = LSM_FLAG_LEGACY_MAJOR,
.blobs = &tomoyo_blob_sizes,
.init = tomoyo_init,
};
......@@ -13,6 +13,9 @@
/* Lock for protecting policy. */
DEFINE_MUTEX(tomoyo_policy_lock);
/* Has /sbin/init started? */
bool tomoyo_policy_loaded;
/*
* Mapping table from "enum tomoyo_mac_index" to
* "enum tomoyo_mac_category_index".
......
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