You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates from James Morris:
"The main change in this kernel is Casey's generalized LSM stacking
work, which removes the hard-coding of Capabilities and Yama stacking,
allowing multiple arbitrary "small" LSMs to be stacked with a default
monolithic module (e.g. SELinux, Smack, AppArmor).
See
https://lwn.net/Articles/636056/
This will allow smaller, simpler LSMs to be incorporated into the
mainline kernel and arbitrarily stacked by users. Also, this is a
useful cleanup of the LSM code in its own right"
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (38 commits)
tpm, tpm_crb: fix le64_to_cpu conversions in crb_acpi_add()
vTPM: set virtual device before passing to ibmvtpm_reset_crq
tpm_ibmvtpm: remove unneccessary message level.
ima: update builtin policies
ima: extend "mask" policy matching support
ima: add support for new "euid" policy condition
ima: fix ima_show_template_data_ascii()
Smack: freeing an error pointer in smk_write_revoke_subj()
selinux: fix setting of security labels on NFS
selinux: Remove unused permission definitions
selinux: enable genfscon labeling for sysfs and pstore files
selinux: enable per-file labeling for debugfs files.
selinux: update netlink socket classes
signals: don't abuse __flush_signals() in selinux_bprm_committed_creds()
selinux: Print 'sclass' as string when unrecognized netlink message occurs
Smack: allow multiple labels in onlycap
Smack: fix seq operations in smackfs
ima: pass iint to ima_add_violation()
ima: wrap event related data to the new ima_event_data structure
integrity: add validity checks for 'path' parameter
...
This commit is contained in:
@@ -20,17 +20,19 @@ Description:
|
|||||||
action: measure | dont_measure | appraise | dont_appraise | audit
|
action: measure | dont_measure | appraise | dont_appraise | audit
|
||||||
condition:= base | lsm [option]
|
condition:= base | lsm [option]
|
||||||
base: [[func=] [mask=] [fsmagic=] [fsuuid=] [uid=]
|
base: [[func=] [mask=] [fsmagic=] [fsuuid=] [uid=]
|
||||||
[fowner]]
|
[euid=] [fowner=]]
|
||||||
lsm: [[subj_user=] [subj_role=] [subj_type=]
|
lsm: [[subj_user=] [subj_role=] [subj_type=]
|
||||||
[obj_user=] [obj_role=] [obj_type=]]
|
[obj_user=] [obj_role=] [obj_type=]]
|
||||||
option: [[appraise_type=]] [permit_directio]
|
option: [[appraise_type=]] [permit_directio]
|
||||||
|
|
||||||
base: func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK]
|
base: func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK]
|
||||||
[FIRMWARE_CHECK]
|
[FIRMWARE_CHECK]
|
||||||
mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
|
mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND]
|
||||||
|
[[^]MAY_EXEC]
|
||||||
fsmagic:= hex value
|
fsmagic:= hex value
|
||||||
fsuuid:= file system UUID (e.g 8bcbe394-4f13-4144-be8e-5aa9ea2ce2f6)
|
fsuuid:= file system UUID (e.g 8bcbe394-4f13-4144-be8e-5aa9ea2ce2f6)
|
||||||
uid:= decimal value
|
uid:= decimal value
|
||||||
|
euid:= decimal value
|
||||||
fowner:=decimal value
|
fowner:=decimal value
|
||||||
lsm: are LSM specific
|
lsm: are LSM specific
|
||||||
option: appraise_type:= [imasig]
|
option: appraise_type:= [imasig]
|
||||||
@@ -49,11 +51,25 @@ Description:
|
|||||||
dont_measure fsmagic=0x01021994
|
dont_measure fsmagic=0x01021994
|
||||||
dont_appraise fsmagic=0x01021994
|
dont_appraise fsmagic=0x01021994
|
||||||
# RAMFS_MAGIC
|
# RAMFS_MAGIC
|
||||||
dont_measure fsmagic=0x858458f6
|
|
||||||
dont_appraise fsmagic=0x858458f6
|
dont_appraise fsmagic=0x858458f6
|
||||||
|
# DEVPTS_SUPER_MAGIC
|
||||||
|
dont_measure fsmagic=0x1cd1
|
||||||
|
dont_appraise fsmagic=0x1cd1
|
||||||
|
# BINFMTFS_MAGIC
|
||||||
|
dont_measure fsmagic=0x42494e4d
|
||||||
|
dont_appraise fsmagic=0x42494e4d
|
||||||
# SECURITYFS_MAGIC
|
# SECURITYFS_MAGIC
|
||||||
dont_measure fsmagic=0x73636673
|
dont_measure fsmagic=0x73636673
|
||||||
dont_appraise fsmagic=0x73636673
|
dont_appraise fsmagic=0x73636673
|
||||||
|
# SELINUX_MAGIC
|
||||||
|
dont_measure fsmagic=0xf97cff8c
|
||||||
|
dont_appraise fsmagic=0xf97cff8c
|
||||||
|
# CGROUP_SUPER_MAGIC
|
||||||
|
dont_measure fsmagic=0x27e0eb
|
||||||
|
dont_appraise fsmagic=0x27e0eb
|
||||||
|
# NSFS_MAGIC
|
||||||
|
dont_measure fsmagic=0x6e736673
|
||||||
|
dont_appraise fsmagic=0x6e736673
|
||||||
|
|
||||||
measure func=BPRM_CHECK
|
measure func=BPRM_CHECK
|
||||||
measure func=FILE_MMAP mask=MAY_EXEC
|
measure func=FILE_MMAP mask=MAY_EXEC
|
||||||
@@ -70,10 +86,6 @@ Description:
|
|||||||
Examples of LSM specific definitions:
|
Examples of LSM specific definitions:
|
||||||
|
|
||||||
SELinux:
|
SELinux:
|
||||||
# SELINUX_MAGIC
|
|
||||||
dont_measure fsmagic=0xf97cff8c
|
|
||||||
dont_appraise fsmagic=0xf97cff8c
|
|
||||||
|
|
||||||
dont_measure obj_type=var_log_t
|
dont_measure obj_type=var_log_t
|
||||||
dont_appraise obj_type=var_log_t
|
dont_appraise obj_type=var_log_t
|
||||||
dont_measure obj_type=auditd_log_t
|
dont_measure obj_type=auditd_log_t
|
||||||
|
|||||||
@@ -1413,7 +1413,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||||||
The list of supported hash algorithms is defined
|
The list of supported hash algorithms is defined
|
||||||
in crypto/hash_info.h.
|
in crypto/hash_info.h.
|
||||||
|
|
||||||
ima_tcb [IMA]
|
ima_policy= [IMA]
|
||||||
|
The builtin measurement policy to load during IMA
|
||||||
|
setup. Specyfing "tcb" as the value, measures all
|
||||||
|
programs exec'd, files mmap'd for exec, and all files
|
||||||
|
opened with the read mode bit set by either the
|
||||||
|
effective uid (euid=0) or uid=0.
|
||||||
|
Format: "tcb"
|
||||||
|
|
||||||
|
ima_tcb [IMA] Deprecated. Use ima_policy= instead.
|
||||||
Load a policy which meets the needs of the Trusted
|
Load a policy which meets the needs of the Trusted
|
||||||
Computing Base. This means IMA will measure all
|
Computing Base. This means IMA will measure all
|
||||||
programs exec'd, files mmap'd for exec, and all files
|
programs exec'd, files mmap'd for exec, and all files
|
||||||
@@ -1421,7 +1429,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||||||
|
|
||||||
ima_template= [IMA]
|
ima_template= [IMA]
|
||||||
Select one of defined IMA measurements template formats.
|
Select one of defined IMA measurements template formats.
|
||||||
Formats: { "ima" | "ima-ng" }
|
Formats: { "ima" | "ima-ng" | "ima-sig" }
|
||||||
Default: "ima-ng"
|
Default: "ima-ng"
|
||||||
|
|
||||||
ima_template_fmt=
|
ima_template_fmt=
|
||||||
|
|||||||
@@ -206,11 +206,11 @@ netlabel
|
|||||||
label. The format accepted on write is:
|
label. The format accepted on write is:
|
||||||
"%d.%d.%d.%d label" or "%d.%d.%d.%d/%d label".
|
"%d.%d.%d.%d label" or "%d.%d.%d.%d/%d label".
|
||||||
onlycap
|
onlycap
|
||||||
This contains the label processes must have for CAP_MAC_ADMIN
|
This contains labels processes must have for CAP_MAC_ADMIN
|
||||||
and CAP_MAC_OVERRIDE to be effective. If this file is empty
|
and CAP_MAC_OVERRIDE to be effective. If this file is empty
|
||||||
these capabilities are effective at for processes with any
|
these capabilities are effective at for processes with any
|
||||||
label. The value is set by writing the desired label to the
|
label. The values are set by writing the desired labels, separated
|
||||||
file or cleared by writing "-" to the file.
|
by spaces, to the file or cleared by writing "-" to the file.
|
||||||
ptrace
|
ptrace
|
||||||
This is used to define the current ptrace policy
|
This is used to define the current ptrace policy
|
||||||
0 - default: this is the policy that relies on Smack access rules.
|
0 - default: this is the policy that relies on Smack access rules.
|
||||||
|
|||||||
@@ -11,6 +11,9 @@
|
|||||||
|
|
||||||
extern struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id);
|
extern struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id);
|
||||||
|
|
||||||
|
extern int __asymmetric_key_hex_to_key_id(const char *id,
|
||||||
|
struct asymmetric_key_id *match_id,
|
||||||
|
size_t hexlen);
|
||||||
static inline
|
static inline
|
||||||
const struct asymmetric_key_ids *asymmetric_key_ids(const struct key *key)
|
const struct asymmetric_key_ids *asymmetric_key_ids(const struct key *key)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -104,6 +104,15 @@ static bool asymmetric_match_key_ids(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* helper function can be called directly with pre-allocated memory */
|
||||||
|
inline int __asymmetric_key_hex_to_key_id(const char *id,
|
||||||
|
struct asymmetric_key_id *match_id,
|
||||||
|
size_t hexlen)
|
||||||
|
{
|
||||||
|
match_id->len = hexlen;
|
||||||
|
return hex2bin(match_id->data, id, hexlen);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* asymmetric_key_hex_to_key_id - Convert a hex string into a key ID.
|
* asymmetric_key_hex_to_key_id - Convert a hex string into a key ID.
|
||||||
* @id: The ID as a hex string.
|
* @id: The ID as a hex string.
|
||||||
@@ -111,21 +120,20 @@ static bool asymmetric_match_key_ids(
|
|||||||
struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id)
|
struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id)
|
||||||
{
|
{
|
||||||
struct asymmetric_key_id *match_id;
|
struct asymmetric_key_id *match_id;
|
||||||
size_t hexlen;
|
size_t asciihexlen;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!*id)
|
if (!*id)
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
hexlen = strlen(id);
|
asciihexlen = strlen(id);
|
||||||
if (hexlen & 1)
|
if (asciihexlen & 1)
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
match_id = kmalloc(sizeof(struct asymmetric_key_id) + hexlen / 2,
|
match_id = kmalloc(sizeof(struct asymmetric_key_id) + asciihexlen / 2,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!match_id)
|
if (!match_id)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
match_id->len = hexlen / 2;
|
ret = __asymmetric_key_hex_to_key_id(id, match_id, asciihexlen / 2);
|
||||||
ret = hex2bin(match_id->data, id, hexlen / 2);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
kfree(match_id);
|
kfree(match_id);
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|||||||
@@ -28,17 +28,30 @@ static bool use_builtin_keys;
|
|||||||
static struct asymmetric_key_id *ca_keyid;
|
static struct asymmetric_key_id *ca_keyid;
|
||||||
|
|
||||||
#ifndef MODULE
|
#ifndef MODULE
|
||||||
|
static struct {
|
||||||
|
struct asymmetric_key_id id;
|
||||||
|
unsigned char data[10];
|
||||||
|
} cakey;
|
||||||
|
|
||||||
static int __init ca_keys_setup(char *str)
|
static int __init ca_keys_setup(char *str)
|
||||||
{
|
{
|
||||||
if (!str) /* default system keyring */
|
if (!str) /* default system keyring */
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (strncmp(str, "id:", 3) == 0) {
|
if (strncmp(str, "id:", 3) == 0) {
|
||||||
struct asymmetric_key_id *p;
|
struct asymmetric_key_id *p = &cakey.id;
|
||||||
p = asymmetric_key_hex_to_key_id(str + 3);
|
size_t hexlen = (strlen(str) - 3) / 2;
|
||||||
if (p == ERR_PTR(-EINVAL))
|
int ret;
|
||||||
pr_err("Unparsable hex string in ca_keys\n");
|
|
||||||
else if (!IS_ERR(p))
|
if (hexlen == 0 || hexlen > sizeof(cakey.data)) {
|
||||||
|
pr_err("Missing or invalid ca_keys id\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = __asymmetric_key_hex_to_key_id(str + 3, p, hexlen);
|
||||||
|
if (ret < 0)
|
||||||
|
pr_err("Unparsable ca_keys id hex string\n");
|
||||||
|
else
|
||||||
ca_keyid = p; /* owner key 'id:xxxxxx' */
|
ca_keyid = p; /* owner key 'id:xxxxxx' */
|
||||||
} else if (strcmp(str, "builtin") == 0) {
|
} else if (strcmp(str, "builtin") == 0) {
|
||||||
use_builtin_keys = true;
|
use_builtin_keys = true;
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ static int crb_acpi_add(struct acpi_device *device)
|
|||||||
|
|
||||||
memcpy_fromio(&pa, &priv->cca->cmd_pa, 8);
|
memcpy_fromio(&pa, &priv->cca->cmd_pa, 8);
|
||||||
pa = le64_to_cpu(pa);
|
pa = le64_to_cpu(pa);
|
||||||
priv->cmd = devm_ioremap_nocache(dev, le64_to_cpu(pa),
|
priv->cmd = devm_ioremap_nocache(dev, pa,
|
||||||
ioread32(&priv->cca->cmd_size));
|
ioread32(&priv->cca->cmd_size));
|
||||||
if (!priv->cmd) {
|
if (!priv->cmd) {
|
||||||
dev_err(dev, "ioremap of the command buffer failed\n");
|
dev_err(dev, "ioremap of the command buffer failed\n");
|
||||||
@@ -276,7 +276,7 @@ static int crb_acpi_add(struct acpi_device *device)
|
|||||||
|
|
||||||
memcpy_fromio(&pa, &priv->cca->rsp_pa, 8);
|
memcpy_fromio(&pa, &priv->cca->rsp_pa, 8);
|
||||||
pa = le64_to_cpu(pa);
|
pa = le64_to_cpu(pa);
|
||||||
priv->rsp = devm_ioremap_nocache(dev, le64_to_cpu(pa),
|
priv->rsp = devm_ioremap_nocache(dev, pa,
|
||||||
ioread32(&priv->cca->rsp_size));
|
ioread32(&priv->cca->rsp_size));
|
||||||
if (!priv->rsp) {
|
if (!priv->rsp) {
|
||||||
dev_err(dev, "ioremap of the response buffer failed\n");
|
dev_err(dev, "ioremap of the response buffer failed\n");
|
||||||
|
|||||||
@@ -578,6 +578,9 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ibmvtpm->dev = dev;
|
||||||
|
ibmvtpm->vdev = vio_dev;
|
||||||
|
|
||||||
crq_q = &ibmvtpm->crq_queue;
|
crq_q = &ibmvtpm->crq_queue;
|
||||||
crq_q->crq_addr = (struct ibmvtpm_crq *)get_zeroed_page(GFP_KERNEL);
|
crq_q->crq_addr = (struct ibmvtpm_crq *)get_zeroed_page(GFP_KERNEL);
|
||||||
if (!crq_q->crq_addr) {
|
if (!crq_q->crq_addr) {
|
||||||
@@ -622,8 +625,6 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
|
|||||||
|
|
||||||
crq_q->index = 0;
|
crq_q->index = 0;
|
||||||
|
|
||||||
ibmvtpm->dev = dev;
|
|
||||||
ibmvtpm->vdev = vio_dev;
|
|
||||||
TPM_VPRIV(chip) = (void *)ibmvtpm;
|
TPM_VPRIV(chip) = (void *)ibmvtpm;
|
||||||
|
|
||||||
spin_lock_init(&ibmvtpm->rtce_lock);
|
spin_lock_init(&ibmvtpm->rtce_lock);
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ int read_log(struct tpm_bios_log *log)
|
|||||||
|
|
||||||
basep = of_get_property(np, "linux,sml-base", NULL);
|
basep = of_get_property(np, "linux,sml-base", NULL);
|
||||||
if (basep == NULL) {
|
if (basep == NULL) {
|
||||||
pr_err(KERN_ERR "%s: ERROR - SML not found\n", __func__);
|
pr_err("%s: ERROR - SML not found\n", __func__);
|
||||||
goto cleanup_eio;
|
goto cleanup_eio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -298,18 +298,18 @@ vfs_removexattr(struct dentry *dentry, const char *name)
|
|||||||
|
|
||||||
mutex_lock(&inode->i_mutex);
|
mutex_lock(&inode->i_mutex);
|
||||||
error = security_inode_removexattr(dentry, name);
|
error = security_inode_removexattr(dentry, name);
|
||||||
if (error) {
|
if (error)
|
||||||
mutex_unlock(&inode->i_mutex);
|
goto out;
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = inode->i_op->removexattr(dentry, name);
|
error = inode->i_op->removexattr(dentry, name);
|
||||||
mutex_unlock(&inode->i_mutex);
|
|
||||||
|
|
||||||
if (!error) {
|
if (!error) {
|
||||||
fsnotify_xattr(dentry);
|
fsnotify_xattr(dentry);
|
||||||
evm_inode_post_removexattr(dentry, name);
|
evm_inode_post_removexattr(dentry, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
mutex_unlock(&inode->i_mutex);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(vfs_removexattr);
|
EXPORT_SYMBOL_GPL(vfs_removexattr);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2421,7 +2421,6 @@ extern void sched_dead(struct task_struct *p);
|
|||||||
|
|
||||||
extern void proc_caches_init(void);
|
extern void proc_caches_init(void);
|
||||||
extern void flush_signals(struct task_struct *);
|
extern void flush_signals(struct task_struct *);
|
||||||
extern void __flush_signals(struct task_struct *);
|
|
||||||
extern void ignore_signals(struct task_struct *);
|
extern void ignore_signals(struct task_struct *);
|
||||||
extern void flush_signal_handlers(struct task_struct *, int force_default);
|
extern void flush_signal_handlers(struct task_struct *, int force_default);
|
||||||
extern int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info);
|
extern int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info);
|
||||||
|
|||||||
+4
-1619
File diff suppressed because it is too large
Load Diff
+4
-9
@@ -414,21 +414,16 @@ void flush_sigqueue(struct sigpending *queue)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flush all pending signals for a task.
|
* Flush all pending signals for this kthread.
|
||||||
*/
|
*/
|
||||||
void __flush_signals(struct task_struct *t)
|
|
||||||
{
|
|
||||||
clear_tsk_thread_flag(t, TIF_SIGPENDING);
|
|
||||||
flush_sigqueue(&t->pending);
|
|
||||||
flush_sigqueue(&t->signal->shared_pending);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flush_signals(struct task_struct *t)
|
void flush_signals(struct task_struct *t)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&t->sighand->siglock, flags);
|
spin_lock_irqsave(&t->sighand->siglock, flags);
|
||||||
__flush_signals(t);
|
clear_tsk_thread_flag(t, TIF_SIGPENDING);
|
||||||
|
flush_sigqueue(&t->pending);
|
||||||
|
flush_sigqueue(&t->signal->shared_pending);
|
||||||
spin_unlock_irqrestore(&t->sighand->siglock, flags);
|
spin_unlock_irqrestore(&t->sighand->siglock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ obj-y += commoncap.o
|
|||||||
obj-$(CONFIG_MMU) += min_addr.o
|
obj-$(CONFIG_MMU) += min_addr.o
|
||||||
|
|
||||||
# Object file lists
|
# Object file lists
|
||||||
obj-$(CONFIG_SECURITY) += security.o capability.o
|
obj-$(CONFIG_SECURITY) += security.o
|
||||||
obj-$(CONFIG_SECURITYFS) += inode.o
|
obj-$(CONFIG_SECURITYFS) += inode.o
|
||||||
obj-$(CONFIG_SECURITY_SELINUX) += selinux/
|
obj-$(CONFIG_SECURITY_SELINUX) += selinux/
|
||||||
obj-$(CONFIG_SECURITY_SMACK) += smack/
|
obj-$(CONFIG_SECURITY_SMACK) += smack/
|
||||||
|
|||||||
@@ -347,9 +347,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
|
|||||||
file_inode(bprm->file)->i_mode
|
file_inode(bprm->file)->i_mode
|
||||||
};
|
};
|
||||||
const char *name = NULL, *target = NULL, *info = NULL;
|
const char *name = NULL, *target = NULL, *info = NULL;
|
||||||
int error = cap_bprm_set_creds(bprm);
|
int error = 0;
|
||||||
if (error)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
if (bprm->cred_prepared)
|
if (bprm->cred_prepared)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -531,15 +529,13 @@ cleanup:
|
|||||||
*/
|
*/
|
||||||
int apparmor_bprm_secureexec(struct linux_binprm *bprm)
|
int apparmor_bprm_secureexec(struct linux_binprm *bprm)
|
||||||
{
|
{
|
||||||
int ret = cap_bprm_secureexec(bprm);
|
|
||||||
|
|
||||||
/* the decision to use secure exec is computed in set_creds
|
/* the decision to use secure exec is computed in set_creds
|
||||||
* and stored in bprm->unsafe.
|
* and stored in bprm->unsafe.
|
||||||
*/
|
*/
|
||||||
if (!ret && (bprm->unsafe & AA_SECURE_X_NEEDED))
|
if (bprm->unsafe & AA_SECURE_X_NEEDED)
|
||||||
ret = 1;
|
return 1;
|
||||||
|
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+45
-68
@@ -12,7 +12,7 @@
|
|||||||
* License.
|
* License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/security.h>
|
#include <linux/lsm_hooks.h>
|
||||||
#include <linux/moduleparam.h>
|
#include <linux/moduleparam.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/mman.h>
|
#include <linux/mman.h>
|
||||||
@@ -96,19 +96,11 @@ static void apparmor_cred_transfer(struct cred *new, const struct cred *old)
|
|||||||
static int apparmor_ptrace_access_check(struct task_struct *child,
|
static int apparmor_ptrace_access_check(struct task_struct *child,
|
||||||
unsigned int mode)
|
unsigned int mode)
|
||||||
{
|
{
|
||||||
int error = cap_ptrace_access_check(child, mode);
|
|
||||||
if (error)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
return aa_ptrace(current, child, mode);
|
return aa_ptrace(current, child, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apparmor_ptrace_traceme(struct task_struct *parent)
|
static int apparmor_ptrace_traceme(struct task_struct *parent)
|
||||||
{
|
{
|
||||||
int error = cap_ptrace_traceme(parent);
|
|
||||||
if (error)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
return aa_ptrace(parent, current, PTRACE_MODE_ATTACH);
|
return aa_ptrace(parent, current, PTRACE_MODE_ATTACH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,10 +115,10 @@ static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective,
|
|||||||
cred = __task_cred(target);
|
cred = __task_cred(target);
|
||||||
profile = aa_cred_profile(cred);
|
profile = aa_cred_profile(cred);
|
||||||
|
|
||||||
*effective = cred->cap_effective;
|
/*
|
||||||
*inheritable = cred->cap_inheritable;
|
* cap_capget is stacked ahead of this and will
|
||||||
*permitted = cred->cap_permitted;
|
* initialize effective and permitted.
|
||||||
|
*/
|
||||||
if (!unconfined(profile) && !COMPLAIN_MODE(profile)) {
|
if (!unconfined(profile) && !COMPLAIN_MODE(profile)) {
|
||||||
*effective = cap_intersect(*effective, profile->caps.allow);
|
*effective = cap_intersect(*effective, profile->caps.allow);
|
||||||
*permitted = cap_intersect(*permitted, profile->caps.allow);
|
*permitted = cap_intersect(*permitted, profile->caps.allow);
|
||||||
@@ -140,13 +132,11 @@ static int apparmor_capable(const struct cred *cred, struct user_namespace *ns,
|
|||||||
int cap, int audit)
|
int cap, int audit)
|
||||||
{
|
{
|
||||||
struct aa_profile *profile;
|
struct aa_profile *profile;
|
||||||
/* cap_capable returns 0 on success, else -EPERM */
|
int error = 0;
|
||||||
int error = cap_capable(cred, ns, cap, audit);
|
|
||||||
if (!error) {
|
|
||||||
profile = aa_cred_profile(cred);
|
profile = aa_cred_profile(cred);
|
||||||
if (!unconfined(profile))
|
if (!unconfined(profile))
|
||||||
error = aa_capable(profile, cap, audit);
|
error = aa_capable(profile, cap, audit);
|
||||||
}
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -615,49 +605,46 @@ static int apparmor_task_setrlimit(struct task_struct *task,
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct security_operations apparmor_ops = {
|
static struct security_hook_list apparmor_hooks[] = {
|
||||||
.name = "apparmor",
|
LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check),
|
||||||
|
LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme),
|
||||||
|
LSM_HOOK_INIT(capget, apparmor_capget),
|
||||||
|
LSM_HOOK_INIT(capable, apparmor_capable),
|
||||||
|
|
||||||
.ptrace_access_check = apparmor_ptrace_access_check,
|
LSM_HOOK_INIT(path_link, apparmor_path_link),
|
||||||
.ptrace_traceme = apparmor_ptrace_traceme,
|
LSM_HOOK_INIT(path_unlink, apparmor_path_unlink),
|
||||||
.capget = apparmor_capget,
|
LSM_HOOK_INIT(path_symlink, apparmor_path_symlink),
|
||||||
.capable = apparmor_capable,
|
LSM_HOOK_INIT(path_mkdir, apparmor_path_mkdir),
|
||||||
|
LSM_HOOK_INIT(path_rmdir, apparmor_path_rmdir),
|
||||||
|
LSM_HOOK_INIT(path_mknod, apparmor_path_mknod),
|
||||||
|
LSM_HOOK_INIT(path_rename, apparmor_path_rename),
|
||||||
|
LSM_HOOK_INIT(path_chmod, apparmor_path_chmod),
|
||||||
|
LSM_HOOK_INIT(path_chown, apparmor_path_chown),
|
||||||
|
LSM_HOOK_INIT(path_truncate, apparmor_path_truncate),
|
||||||
|
LSM_HOOK_INIT(inode_getattr, apparmor_inode_getattr),
|
||||||
|
|
||||||
.path_link = apparmor_path_link,
|
LSM_HOOK_INIT(file_open, apparmor_file_open),
|
||||||
.path_unlink = apparmor_path_unlink,
|
LSM_HOOK_INIT(file_permission, apparmor_file_permission),
|
||||||
.path_symlink = apparmor_path_symlink,
|
LSM_HOOK_INIT(file_alloc_security, apparmor_file_alloc_security),
|
||||||
.path_mkdir = apparmor_path_mkdir,
|
LSM_HOOK_INIT(file_free_security, apparmor_file_free_security),
|
||||||
.path_rmdir = apparmor_path_rmdir,
|
LSM_HOOK_INIT(mmap_file, apparmor_mmap_file),
|
||||||
.path_mknod = apparmor_path_mknod,
|
LSM_HOOK_INIT(file_mprotect, apparmor_file_mprotect),
|
||||||
.path_rename = apparmor_path_rename,
|
LSM_HOOK_INIT(file_lock, apparmor_file_lock),
|
||||||
.path_chmod = apparmor_path_chmod,
|
|
||||||
.path_chown = apparmor_path_chown,
|
|
||||||
.path_truncate = apparmor_path_truncate,
|
|
||||||
.inode_getattr = apparmor_inode_getattr,
|
|
||||||
|
|
||||||
.file_open = apparmor_file_open,
|
LSM_HOOK_INIT(getprocattr, apparmor_getprocattr),
|
||||||
.file_permission = apparmor_file_permission,
|
LSM_HOOK_INIT(setprocattr, apparmor_setprocattr),
|
||||||
.file_alloc_security = apparmor_file_alloc_security,
|
|
||||||
.file_free_security = apparmor_file_free_security,
|
|
||||||
.mmap_file = apparmor_mmap_file,
|
|
||||||
.mmap_addr = cap_mmap_addr,
|
|
||||||
.file_mprotect = apparmor_file_mprotect,
|
|
||||||
.file_lock = apparmor_file_lock,
|
|
||||||
|
|
||||||
.getprocattr = apparmor_getprocattr,
|
LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank),
|
||||||
.setprocattr = apparmor_setprocattr,
|
LSM_HOOK_INIT(cred_free, apparmor_cred_free),
|
||||||
|
LSM_HOOK_INIT(cred_prepare, apparmor_cred_prepare),
|
||||||
|
LSM_HOOK_INIT(cred_transfer, apparmor_cred_transfer),
|
||||||
|
|
||||||
.cred_alloc_blank = apparmor_cred_alloc_blank,
|
LSM_HOOK_INIT(bprm_set_creds, apparmor_bprm_set_creds),
|
||||||
.cred_free = apparmor_cred_free,
|
LSM_HOOK_INIT(bprm_committing_creds, apparmor_bprm_committing_creds),
|
||||||
.cred_prepare = apparmor_cred_prepare,
|
LSM_HOOK_INIT(bprm_committed_creds, apparmor_bprm_committed_creds),
|
||||||
.cred_transfer = apparmor_cred_transfer,
|
LSM_HOOK_INIT(bprm_secureexec, apparmor_bprm_secureexec),
|
||||||
|
|
||||||
.bprm_set_creds = apparmor_bprm_set_creds,
|
LSM_HOOK_INIT(task_setrlimit, apparmor_task_setrlimit),
|
||||||
.bprm_committing_creds = apparmor_bprm_committing_creds,
|
|
||||||
.bprm_committed_creds = apparmor_bprm_committed_creds,
|
|
||||||
.bprm_secureexec = apparmor_bprm_secureexec,
|
|
||||||
|
|
||||||
.task_setrlimit = apparmor_task_setrlimit,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -898,7 +885,7 @@ static int __init apparmor_init(void)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (!apparmor_enabled || !security_module_enable(&apparmor_ops)) {
|
if (!apparmor_enabled || !security_module_enable("apparmor")) {
|
||||||
aa_info_message("AppArmor disabled by boot time parameter");
|
aa_info_message("AppArmor disabled by boot time parameter");
|
||||||
apparmor_enabled = 0;
|
apparmor_enabled = 0;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -913,17 +900,10 @@ static int __init apparmor_init(void)
|
|||||||
error = set_init_cxt();
|
error = set_init_cxt();
|
||||||
if (error) {
|
if (error) {
|
||||||
AA_ERROR("Failed to set context on init task\n");
|
AA_ERROR("Failed to set context on init task\n");
|
||||||
goto register_security_out;
|
aa_free_root_ns();
|
||||||
}
|
goto alloc_out;
|
||||||
|
|
||||||
error = register_security(&apparmor_ops);
|
|
||||||
if (error) {
|
|
||||||
struct cred *cred = (struct cred *)current->real_cred;
|
|
||||||
aa_free_task_context(cred_cxt(cred));
|
|
||||||
cred_cxt(cred) = NULL;
|
|
||||||
AA_ERROR("Unable to register AppArmor\n");
|
|
||||||
goto register_security_out;
|
|
||||||
}
|
}
|
||||||
|
security_add_hooks(apparmor_hooks, ARRAY_SIZE(apparmor_hooks));
|
||||||
|
|
||||||
/* Report that AppArmor successfully initialized */
|
/* Report that AppArmor successfully initialized */
|
||||||
apparmor_initialized = 1;
|
apparmor_initialized = 1;
|
||||||
@@ -936,9 +916,6 @@ static int __init apparmor_init(void)
|
|||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
register_security_out:
|
|
||||||
aa_free_root_ns();
|
|
||||||
|
|
||||||
alloc_out:
|
alloc_out:
|
||||||
aa_destroy_aafs();
|
aa_destroy_aafs();
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
+33
-8
@@ -12,7 +12,7 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/security.h>
|
#include <linux/lsm_hooks.h>
|
||||||
#include <linux/file.h>
|
#include <linux/file.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/mman.h>
|
#include <linux/mman.h>
|
||||||
@@ -53,11 +53,6 @@ static void warn_setuid_and_fcaps_mixed(const char *fname)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cap_capable - Determine whether a task has a particular effective capability
|
* cap_capable - Determine whether a task has a particular effective capability
|
||||||
* @cred: The credentials to use
|
* @cred: The credentials to use
|
||||||
@@ -941,7 +936,7 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
|
|||||||
* @pages: The size of the mapping
|
* @pages: The size of the mapping
|
||||||
*
|
*
|
||||||
* Determine whether the allocation of a new virtual mapping by the current
|
* Determine whether the allocation of a new virtual mapping by the current
|
||||||
* task is permitted, returning 0 if permission is granted, -ve if not.
|
* task is permitted, returning 1 if permission is granted, 0 if not.
|
||||||
*/
|
*/
|
||||||
int cap_vm_enough_memory(struct mm_struct *mm, long pages)
|
int cap_vm_enough_memory(struct mm_struct *mm, long pages)
|
||||||
{
|
{
|
||||||
@@ -950,7 +945,7 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages)
|
|||||||
if (cap_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN,
|
if (cap_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN,
|
||||||
SECURITY_CAP_NOAUDIT) == 0)
|
SECURITY_CAP_NOAUDIT) == 0)
|
||||||
cap_sys_admin = 1;
|
cap_sys_admin = 1;
|
||||||
return __vm_enough_memory(mm, pages, cap_sys_admin);
|
return cap_sys_admin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -981,3 +976,33 @@ int cap_mmap_file(struct file *file, unsigned long reqprot,
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SECURITY
|
||||||
|
|
||||||
|
struct security_hook_list capability_hooks[] = {
|
||||||
|
LSM_HOOK_INIT(capable, cap_capable),
|
||||||
|
LSM_HOOK_INIT(settime, cap_settime),
|
||||||
|
LSM_HOOK_INIT(ptrace_access_check, cap_ptrace_access_check),
|
||||||
|
LSM_HOOK_INIT(ptrace_traceme, cap_ptrace_traceme),
|
||||||
|
LSM_HOOK_INIT(capget, cap_capget),
|
||||||
|
LSM_HOOK_INIT(capset, cap_capset),
|
||||||
|
LSM_HOOK_INIT(bprm_set_creds, cap_bprm_set_creds),
|
||||||
|
LSM_HOOK_INIT(bprm_secureexec, cap_bprm_secureexec),
|
||||||
|
LSM_HOOK_INIT(inode_need_killpriv, cap_inode_need_killpriv),
|
||||||
|
LSM_HOOK_INIT(inode_killpriv, cap_inode_killpriv),
|
||||||
|
LSM_HOOK_INIT(mmap_addr, cap_mmap_addr),
|
||||||
|
LSM_HOOK_INIT(mmap_file, cap_mmap_file),
|
||||||
|
LSM_HOOK_INIT(task_fix_setuid, cap_task_fix_setuid),
|
||||||
|
LSM_HOOK_INIT(task_prctl, cap_task_prctl),
|
||||||
|
LSM_HOOK_INIT(task_setscheduler, cap_task_setscheduler),
|
||||||
|
LSM_HOOK_INIT(task_setioprio, cap_task_setioprio),
|
||||||
|
LSM_HOOK_INIT(task_setnice, cap_task_setnice),
|
||||||
|
LSM_HOOK_INIT(vm_enough_memory, cap_vm_enough_memory),
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init capability_add_hooks(void)
|
||||||
|
{
|
||||||
|
security_add_hooks(capability_hooks, ARRAY_SIZE(capability_hooks));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_SECURITY */
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ int __init integrity_init_keyring(const unsigned int id)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int __init integrity_load_x509(const unsigned int id, char *path)
|
int __init integrity_load_x509(const unsigned int id, const char *path)
|
||||||
{
|
{
|
||||||
key_ref_t key;
|
key_ref_t key;
|
||||||
char *data;
|
char *data;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user