Merge branch 'next-general' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates from James Morris: - Extend LSM stacking to allow sharing of cred, file, ipc, inode, and task blobs. This paves the way for more full-featured LSMs to be merged, and is specifically aimed at LandLock and SARA LSMs. This work is from Casey and Kees. - There's a new LSM from Micah Morton: "SafeSetID gates the setid family of syscalls to restrict UID/GID transitions from a given UID/GID to only those approved by a system-wide whitelist." This feature is currently shipping in ChromeOS. * 'next-general' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (62 commits) keys: fix missing __user in KEYCTL_PKEY_QUERY LSM: Update list of SECURITYFS users in Kconfig LSM: Ignore "security=" when "lsm=" is specified LSM: Update function documentation for cap_capable security: mark expected switch fall-throughs and add a missing break tomoyo: Bump version. LSM: fix return value check in safesetid_init_securityfs() LSM: SafeSetID: add selftest LSM: SafeSetID: remove unused include LSM: SafeSetID: 'depend' on CONFIG_SECURITY LSM: Add 'name' field for SafeSetID in DEFINE_LSM LSM: add SafeSetID module that gates setid calls LSM: add SafeSetID module that gates setid calls tomoyo: Allow multiple use_group lines. tomoyo: Coding style fix. tomoyo: Swicth from cred->security to task_struct->security. security: keys: annotate implicit fall throughs security: keys: annotate implicit fall throughs security: keys: annotate implicit fall through capabilities:: annotate implicit fall through ...
This commit is contained in:
@@ -60,7 +60,7 @@ DEFINE_PER_CPU(struct aa_buffers, aa_buffers);
|
||||
static void apparmor_cred_free(struct cred *cred)
|
||||
{
|
||||
aa_put_label(cred_label(cred));
|
||||
cred_label(cred) = NULL;
|
||||
set_cred_label(cred, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -68,7 +68,7 @@ static void apparmor_cred_free(struct cred *cred)
|
||||
*/
|
||||
static int apparmor_cred_alloc_blank(struct cred *cred, gfp_t gfp)
|
||||
{
|
||||
cred_label(cred) = NULL;
|
||||
set_cred_label(cred, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ static int apparmor_cred_alloc_blank(struct cred *cred, gfp_t gfp)
|
||||
static int apparmor_cred_prepare(struct cred *new, const struct cred *old,
|
||||
gfp_t gfp)
|
||||
{
|
||||
cred_label(new) = aa_get_newest_label(cred_label(old));
|
||||
set_cred_label(new, aa_get_newest_label(cred_label(old)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -87,26 +87,21 @@ static int apparmor_cred_prepare(struct cred *new, const struct cred *old,
|
||||
*/
|
||||
static void apparmor_cred_transfer(struct cred *new, const struct cred *old)
|
||||
{
|
||||
cred_label(new) = aa_get_newest_label(cred_label(old));
|
||||
set_cred_label(new, aa_get_newest_label(cred_label(old)));
|
||||
}
|
||||
|
||||
static void apparmor_task_free(struct task_struct *task)
|
||||
{
|
||||
|
||||
aa_free_task_ctx(task_ctx(task));
|
||||
task_ctx(task) = NULL;
|
||||
}
|
||||
|
||||
static int apparmor_task_alloc(struct task_struct *task,
|
||||
unsigned long clone_flags)
|
||||
{
|
||||
struct aa_task_ctx *new = aa_alloc_task_ctx(GFP_KERNEL);
|
||||
|
||||
if (!new)
|
||||
return -ENOMEM;
|
||||
struct aa_task_ctx *new = task_ctx(task);
|
||||
|
||||
aa_dup_task_ctx(new, task_ctx(current));
|
||||
task_ctx(task) = new;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -177,14 +172,14 @@ static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective,
|
||||
}
|
||||
|
||||
static int apparmor_capable(const struct cred *cred, struct user_namespace *ns,
|
||||
int cap, int audit)
|
||||
int cap, unsigned int opts)
|
||||
{
|
||||
struct aa_label *label;
|
||||
int error = 0;
|
||||
|
||||
label = aa_get_newest_cred_label(cred);
|
||||
if (!unconfined(label))
|
||||
error = aa_capable(label, cap, audit);
|
||||
error = aa_capable(label, cap, opts);
|
||||
aa_put_label(label);
|
||||
|
||||
return error;
|
||||
@@ -434,21 +429,21 @@ static int apparmor_file_open(struct file *file)
|
||||
|
||||
static int apparmor_file_alloc_security(struct file *file)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
/* freed by apparmor_file_free_security */
|
||||
struct aa_file_ctx *ctx = file_ctx(file);
|
||||
struct aa_label *label = begin_current_label_crit_section();
|
||||
file->f_security = aa_alloc_file_ctx(label, GFP_KERNEL);
|
||||
if (!file_ctx(file))
|
||||
error = -ENOMEM;
|
||||
end_current_label_crit_section(label);
|
||||
|
||||
return error;
|
||||
spin_lock_init(&ctx->lock);
|
||||
rcu_assign_pointer(ctx->label, aa_get_label(label));
|
||||
end_current_label_crit_section(label);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void apparmor_file_free_security(struct file *file)
|
||||
{
|
||||
aa_free_file_ctx(file_ctx(file));
|
||||
struct aa_file_ctx *ctx = file_ctx(file);
|
||||
|
||||
if (ctx)
|
||||
aa_put_label(rcu_access_pointer(ctx->label));
|
||||
}
|
||||
|
||||
static int common_file_perm(const char *op, struct file *file, u32 mask)
|
||||
@@ -1151,6 +1146,15 @@ static int apparmor_inet_conn_request(struct sock *sk, struct sk_buff *skb,
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The cred blob is a pointer to, not an instance of, an aa_task_ctx.
|
||||
*/
|
||||
struct lsm_blob_sizes apparmor_blob_sizes __lsm_ro_after_init = {
|
||||
.lbs_cred = sizeof(struct aa_task_ctx *),
|
||||
.lbs_file = sizeof(struct aa_file_ctx),
|
||||
.lbs_task = sizeof(struct aa_task_ctx),
|
||||
};
|
||||
|
||||
static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
|
||||
LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check),
|
||||
LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme),
|
||||
@@ -1333,8 +1337,8 @@ bool aa_g_paranoid_load = true;
|
||||
module_param_named(paranoid_load, aa_g_paranoid_load, aabool, S_IRUGO);
|
||||
|
||||
/* Boot time disable flag */
|
||||
static bool apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
|
||||
module_param_named(enabled, apparmor_enabled, bool, S_IRUGO);
|
||||
static int apparmor_enabled __lsm_ro_after_init = 1;
|
||||
module_param_named(enabled, apparmor_enabled, int, 0444);
|
||||
|
||||
static int __init apparmor_enabled_setup(char *str)
|
||||
{
|
||||
@@ -1479,14 +1483,8 @@ static int param_set_mode(const char *val, const struct kernel_param *kp)
|
||||
static int __init set_init_ctx(void)
|
||||
{
|
||||
struct cred *cred = (struct cred *)current->real_cred;
|
||||
struct aa_task_ctx *ctx;
|
||||
|
||||
ctx = aa_alloc_task_ctx(GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
cred_label(cred) = aa_get_label(ns_unconfined(root_ns));
|
||||
task_ctx(current) = ctx;
|
||||
set_cred_label(cred, aa_get_label(ns_unconfined(root_ns)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1665,12 +1663,6 @@ static int __init apparmor_init(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (!apparmor_enabled || !security_module_enable("apparmor")) {
|
||||
aa_info_message("AppArmor disabled by boot time parameter");
|
||||
apparmor_enabled = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
aa_secids_init();
|
||||
|
||||
error = aa_setup_dfa_engine();
|
||||
@@ -1731,5 +1723,8 @@ alloc_out:
|
||||
|
||||
DEFINE_LSM(apparmor) = {
|
||||
.name = "apparmor",
|
||||
.flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
|
||||
.enabled = &apparmor_enabled,
|
||||
.blobs = &apparmor_blob_sizes,
|
||||
.init = apparmor_init,
|
||||
};
|
||||
|
Reference in New Issue
Block a user