diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/commoncap.c | 8 | ||||
-rw-r--r-- | security/integrity/evm/Kconfig | 11 | ||||
-rw-r--r-- | security/integrity/evm/evm.h | 7 | ||||
-rw-r--r-- | security/integrity/evm/evm_crypto.c | 13 | ||||
-rw-r--r-- | security/integrity/evm/evm_main.c | 79 | ||||
-rw-r--r-- | security/integrity/evm/evm_secfs.c | 206 | ||||
-rw-r--r-- | security/integrity/iint.c | 18 | ||||
-rw-r--r-- | security/integrity/ima/ima.h | 1 | ||||
-rw-r--r-- | security/integrity/ima/ima_api.c | 2 | ||||
-rw-r--r-- | security/integrity/ima/ima_fs.c | 18 | ||||
-rw-r--r-- | security/integrity/ima/ima_kexec.c | 2 | ||||
-rw-r--r-- | security/integrity/ima/ima_main.c | 19 | ||||
-rw-r--r-- | security/integrity/ima/ima_policy.c | 70 | ||||
-rw-r--r-- | security/integrity/ima/ima_template_lib.c | 2 | ||||
-rw-r--r-- | security/integrity/integrity.h | 2 | ||||
-rw-r--r-- | security/integrity/integrity_audit.c | 2 | ||||
-rw-r--r-- | security/keys/proc.c | 34 | ||||
-rw-r--r-- | security/lsm_audit.c | 2 | ||||
-rw-r--r-- | security/selinux/hooks.c | 88 | ||||
-rw-r--r-- | security/selinux/include/classmap.h | 4 | ||||
-rw-r--r-- | security/selinux/selinuxfs.c | 24 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 14 |
22 files changed, 455 insertions, 171 deletions
diff --git a/security/commoncap.c b/security/commoncap.c index 1ce701fcb3f3..f4c33abd9959 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -919,6 +919,8 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) int cap_inode_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { + struct user_namespace *user_ns = dentry->d_sb->s_user_ns; + /* Ignore non-security xattrs */ if (strncmp(name, XATTR_SECURITY_PREFIX, sizeof(XATTR_SECURITY_PREFIX) - 1) != 0) @@ -931,7 +933,7 @@ int cap_inode_setxattr(struct dentry *dentry, const char *name, if (strcmp(name, XATTR_NAME_CAPS) == 0) return 0; - if (!capable(CAP_SYS_ADMIN)) + if (!ns_capable(user_ns, CAP_SYS_ADMIN)) return -EPERM; return 0; } @@ -949,6 +951,8 @@ int cap_inode_setxattr(struct dentry *dentry, const char *name, */ int cap_inode_removexattr(struct dentry *dentry, const char *name) { + struct user_namespace *user_ns = dentry->d_sb->s_user_ns; + /* Ignore non-security xattrs */ if (strncmp(name, XATTR_SECURITY_PREFIX, sizeof(XATTR_SECURITY_PREFIX) - 1) != 0) @@ -964,7 +968,7 @@ int cap_inode_removexattr(struct dentry *dentry, const char *name) return 0; } - if (!capable(CAP_SYS_ADMIN)) + if (!ns_capable(user_ns, CAP_SYS_ADMIN)) return -EPERM; return 0; } diff --git a/security/integrity/evm/Kconfig b/security/integrity/evm/Kconfig index e825e0ae78e7..d593346d0bba 100644 --- a/security/integrity/evm/Kconfig +++ b/security/integrity/evm/Kconfig @@ -42,6 +42,17 @@ config EVM_EXTRA_SMACK_XATTRS additional info to the calculation, requires existing EVM labeled file systems to be relabeled. +config EVM_ADD_XATTRS + bool "Add additional EVM extended attributes at runtime" + depends on EVM + default n + help + Allow userland to provide additional xattrs for HMAC calculation. + + When this option is enabled, root can add additional xattrs to the + list used by EVM by writing them into + /sys/kernel/security/integrity/evm/evm_xattrs. + config EVM_LOAD_X509 bool "Load an X509 certificate onto the '.evm' trusted keyring" depends on EVM && INTEGRITY_TRUSTED_KEYRING diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h index 45c4a89c02ff..1257c3c24723 100644 --- a/security/integrity/evm/evm.h +++ b/security/integrity/evm/evm.h @@ -30,6 +30,11 @@ #define EVM_INIT_MASK (EVM_INIT_HMAC | EVM_INIT_X509 | EVM_SETUP_COMPLETE | \ EVM_ALLOW_METADATA_WRITES) +struct xattr_list { + struct list_head list; + char *name; +}; + extern int evm_initialized; #define EVM_ATTR_FSUUID 0x0001 @@ -40,7 +45,7 @@ extern struct crypto_shash *hmac_tfm; extern struct crypto_shash *hash_tfm; /* List of EVM protected security xattrs */ -extern char *evm_config_xattrnames[]; +extern struct list_head evm_config_xattrnames; int evm_init_key(void); int evm_update_evmxattr(struct dentry *dentry, diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index a46fba322340..b60524310855 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c @@ -192,15 +192,16 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry, char type, char *digest) { struct inode *inode = d_backing_inode(dentry); + struct xattr_list *xattr; struct shash_desc *desc; - char **xattrname; size_t xattr_size = 0; char *xattr_value = NULL; int error; int size; bool ima_present = false; - if (!(inode->i_opflags & IOP_XATTR)) + if (!(inode->i_opflags & IOP_XATTR) || + inode->i_sb->s_user_ns != &init_user_ns) return -EOPNOTSUPP; desc = init_desc(type); @@ -208,14 +209,14 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry, return PTR_ERR(desc); error = -ENODATA; - for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) { + list_for_each_entry_rcu(xattr, &evm_config_xattrnames, list) { bool is_ima = false; - if (strcmp(*xattrname, XATTR_NAME_IMA) == 0) + if (strcmp(xattr->name, XATTR_NAME_IMA) == 0) is_ima = true; if ((req_xattr_name && req_xattr_value) - && !strcmp(*xattrname, req_xattr_name)) { + && !strcmp(xattr->name, req_xattr_name)) { error = 0; crypto_shash_update(desc, (const u8 *)req_xattr_value, req_xattr_value_len); @@ -223,7 +224,7 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry, ima_present = true; continue; } - size = vfs_getxattr_alloc(dentry, *xattrname, + size = vfs_getxattr_alloc(dentry, xattr->name, &xattr_value, xattr_size, GFP_NOFS); if (size == -ENOMEM) { error = -ENOMEM; diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index 9ea9c19a545c..f9eff5041e4c 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c @@ -35,28 +35,29 @@ static const char * const integrity_status_msg[] = { }; int evm_hmac_attrs; -char *evm_config_xattrnames[] = { +static struct xattr_list evm_config_default_xattrnames[] = { #ifdef CONFIG_SECURITY_SELINUX - XATTR_NAME_SELINUX, + {.name = XATTR_NAME_SELINUX}, #endif #ifdef CONFIG_SECURITY_SMACK - XATTR_NAME_SMACK, + {.name = XATTR_NAME_SMACK}, #ifdef CONFIG_EVM_EXTRA_SMACK_XATTRS - XATTR_NAME_SMACKEXEC, - XATTR_NAME_SMACKTRANSMUTE, - XATTR_NAME_SMACKMMAP, + {.name = XATTR_NAME_SMACKEXEC}, + {.name = XATTR_NAME_SMACKTRANSMUTE}, + {.name = XATTR_NAME_SMACKMMAP}, #endif #endif #ifdef CONFIG_SECURITY_APPARMOR - XATTR_NAME_APPARMOR, + {.name = XATTR_NAME_APPARMOR}, #endif #ifdef CONFIG_IMA_APPRAISE - XATTR_NAME_IMA, + {.name = XATTR_NAME_IMA}, #endif - XATTR_NAME_CAPS, - NULL + {.name = XATTR_NAME_CAPS}, }; +LIST_HEAD(evm_config_xattrnames); + static int evm_fixmode; static int __init evm_set_fixmode(char *str) { @@ -68,6 +69,17 @@ __setup("evm=", evm_set_fixmode); static void __init evm_init_config(void) { + int i, xattrs; + + xattrs = ARRAY_SIZE(evm_config_default_xattrnames); + + pr_info("Initialising EVM extended attributes:\n"); + for (i = 0; i < xattrs; i++) { + pr_info("%s\n", evm_config_default_xattrnames[i].name); + list_add_tail(&evm_config_default_xattrnames[i].list, + &evm_config_xattrnames); + } + #ifdef CONFIG_EVM_ATTR_FSUUID evm_hmac_attrs |= EVM_ATTR_FSUUID; #endif @@ -82,15 +94,15 @@ static bool evm_key_loaded(void) static int evm_find_protected_xattrs(struct dentry *dentry) { struct inode *inode = d_backing_inode(dentry); - char **xattr; + struct xattr_list *xattr; int error; int count = 0; if (!(inode->i_opflags & IOP_XATTR)) return -EOPNOTSUPP; - for (xattr = evm_config_xattrnames; *xattr != NULL; xattr++) { - error = __vfs_getxattr(dentry, inode, *xattr, NULL, 0); + list_for_each_entry_rcu(xattr, &evm_config_xattrnames, list) { + error = __vfs_getxattr(dentry, inode, xattr->name, NULL, 0); if (error < 0) { if (error == -ENODATA) continue; @@ -211,24 +223,25 @@ out: static int evm_protected_xattr(const char *req_xattr_name) { - char **xattrname; int namelen; int found = 0; + struct xattr_list *xattr; namelen = strlen(req_xattr_name); - for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) { - if ((strlen(*xattrname) == namelen) - && (strncmp(req_xattr_name, *xattrname, namelen) == 0)) { + list_for_each_entry_rcu(xattr, &evm_config_xattrnames, list) { + if ((strlen(xattr->name) == namelen) + && (strncmp(req_xattr_name, xattr->name, namelen) == 0)) { found = 1; break; } if (strncmp(req_xattr_name, - *xattrname + XATTR_SECURITY_PREFIX_LEN, + xattr->name + XATTR_SECURITY_PREFIX_LEN, strlen(req_xattr_name)) == 0) { found = 1; break; } } + return found; } @@ -544,35 +557,35 @@ void __init evm_load_x509(void) static int __init init_evm(void) { int error; + struct list_head *pos, *q; + struct xattr_list *xattr; evm_init_config(); error = integrity_init_keyring(INTEGRITY_KEYRING_EVM); if (error) - return error; + goto error; error = evm_init_secfs(); if (error < 0) { pr_info("Error registering secfs\n"); - return error; + goto error; } - return 0; -} - -/* - * evm_display_config - list the EVM protected security extended attributes - */ -static int __init evm_display_config(void) -{ - char **xattrname; +error: + if (error != 0) { + if (!list_empty(&evm_config_xattrnames)) { + list_for_each_safe(pos, q, &evm_config_xattrnames) { + xattr = list_entry(pos, struct xattr_list, + list); + list_del(pos); + } + } + } - for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) - pr_info("%s\n", *xattrname); - return 0; + return error; } -pure_initcall(evm_display_config); late_initcall(init_evm); MODULE_DESCRIPTION("Extended Verification Module"); diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c index feba03bbedae..637eb999e340 100644 --- a/security/integrity/evm/evm_secfs.c +++ b/security/integrity/evm/evm_secfs.c @@ -15,11 +15,21 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include <linux/audit.h> #include <linux/uaccess.h> #include <linux/module.h> +#include <linux/mutex.h> #include "evm.h" +static struct dentry *evm_dir; static struct dentry *evm_init_tpm; +static struct dentry *evm_symlink; + +#ifdef CONFIG_EVM_ADD_XATTRS +static struct dentry *evm_xattrs; +static DEFINE_MUTEX(xattr_list_mutex); +static int evm_xattrs_locked; +#endif /** * evm_read_key - read() for <securityfs>/evm @@ -107,13 +117,203 @@ static const struct file_operations evm_key_ops = { .write = evm_write_key, }; +#ifdef CONFIG_EVM_ADD_XATTRS +/** + * evm_read_xattrs - read() for <securityfs>/evm_xattrs + * + * @filp: file pointer, not actually used + * @buf: where to put the result + * @count: maximum to send along + * @ppos: where to start + * + * Returns number of bytes read or error code, as appropriate + */ +static ssize_t evm_read_xattrs(struct file *filp, char __user *buf, + size_t count, loff_t *ppos) +{ + char *temp; + int offset = 0; + ssize_t rc, size = 0; + struct xattr_list *xattr; + + if (*ppos != 0) + return 0; + + rc = mutex_lock_interruptible(&xattr_list_mutex); + if (rc) + return -ERESTARTSYS; + + list_for_each_entry(xattr, &evm_config_xattrnames, list) + size += strlen(xattr->name) + 1; + + temp = kmalloc(size + 1, GFP_KERNEL); + if (!temp) { + mutex_unlock(&xattr_list_mutex); + return -ENOMEM; + } + + list_for_each_entry(xattr, &evm_config_xattrnames, list) { + sprintf(temp + offset, "%s\n", xattr->name); + offset += strlen(xattr->name) + 1; + } + + mutex_unlock(&xattr_list_mutex); + rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp)); + + kfree(temp); + + return rc; +} + +/** + * evm_write_xattrs - write() for <securityfs>/evm_xattrs + * @file: file pointer, not actually used + * @buf: where to get the data from + * @count: bytes sent + * @ppos: where to start + * + * Returns number of bytes written or error code, as appropriate + */ +static ssize_t evm_write_xattrs(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + int len, err; + struct xattr_list *xattr, *tmp; + struct audit_buffer *ab; + struct iattr newattrs; + struct inode *inode; + + if (!capable(CAP_SYS_ADMIN) || evm_xattrs_locked) + return -EPERM; + + if (*ppos != 0) + return -EINVAL; + + if (count > XATTR_NAME_MAX) + return -E2BIG; + + ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_EVM_XATTR); + if (IS_ERR(ab)) + return PTR_ERR(ab); + + xattr = kmalloc(sizeof(struct xattr_list), GFP_KERNEL); + if (!xattr) { + err = -ENOMEM; + goto out; + } + + xattr->name = memdup_user_nul(buf, count); + if (IS_ERR(xattr->name)) { + err = PTR_ERR(xattr->name); + xattr->name = NULL; + goto out; + } + + /* Remove any trailing newline */ + len = strlen(xattr->name); + if (len && xattr->name[len-1] == '\n') + xattr->name[len-1] = '\0'; + + if (strcmp(xattr->name, ".") == 0) { + evm_xattrs_locked = 1; + newattrs.ia_mode = S_IFREG | 0440; + newattrs.ia_valid = ATTR_MODE; + inode = evm_xattrs->d_inode; + inode_lock(inode); + err = simple_setattr(evm_xattrs, &newattrs); + inode_unlock(inode); + audit_log_format(ab, "locked"); + if (!err) + err = count; + goto out; + } + + audit_log_format(ab, "xattr="); + audit_log_untrustedstring(ab, xattr->name); + + if (strncmp(xattr->name, XATTR_SECURITY_PREFIX, + XATTR_SECURITY_PREFIX_LEN) != 0) { + err = -EINVAL; + goto out; + } + + /* Guard against races in evm_read_xattrs */ + mutex_lock(&xattr_list_mutex); + list_for_each_entry(tmp, &evm_config_xattrnames, list) { + if (strcmp(xattr->name, tmp->name) == 0) { + err = -EEXIST; + mutex_unlock(&xattr_list_mutex); + goto out; + } + } + list_add_tail_rcu(&xattr->list, &evm_config_xattrnames); + mutex_unlock(&xattr_list_mutex); + + audit_log_format(ab, " res=0"); + audit_log_end(ab); + return count; +out: + audit_log_format(ab, " res=%d", err); + audit_log_end(ab); + if (xattr) { + kfree(xattr->name); + kfree(xattr); + } + return err; +} + +static const struct file_operations evm_xattr_ops = { + .read = evm_read_xattrs, + .write = evm_write_xattrs, +}; + +static int evm_init_xattrs(void) +{ + evm_xattrs = securityfs_create_file("evm_xattrs", 0660, evm_dir, NULL, + &evm_xattr_ops); + if (!evm_xattrs || IS_ERR(evm_xattrs)) + return -EFAULT; + + return 0; +} +#else +static int evm_init_xattrs(void) +{ + return 0; +} +#endif + int __init evm_init_secfs(void) { int error = 0; - evm_init_tpm = securityfs_create_file("evm", S_IRUSR | S_IRGRP, - NULL, NULL, &evm_key_ops); - if (!evm_init_tpm || IS_ERR(evm_init_tpm)) + evm_dir = securityfs_create_dir("evm", integrity_dir); + if (!evm_dir || IS_ERR(evm_dir)) + return -EFAULT; + + evm_init_tpm = securityfs_create_file("evm", 0660, + evm_dir, NULL, &evm_key_ops); + if (!evm_init_tpm || IS_ERR(evm_init_tpm)) { error = -EFAULT; + goto out; + } + + evm_symlink = securityfs_create_symlink("evm", NULL, + "integrity/evm/evm", NULL); + if (!evm_symlink || IS_ERR(evm_symlink)) { + error = -EFAULT; + goto out; + } + + if (evm_init_xattrs() != 0) { + error = -EFAULT; + goto out; + } + + return 0; +out: + securityfs_remove(evm_symlink); + securityfs_remove(evm_init_tpm); + securityfs_remove(evm_dir); return error; } diff --git a/security/integrity/iint.c b/security/integrity/iint.c index f266e4b3b7d4..149faa81f6f0 100644 --- a/security/integrity/iint.c +++ b/security/integrity/iint.c @@ -21,12 +21,15 @@ #include <linux/rbtree.h> #include <linux/file.h> #include <linux/uaccess.h> +#include <linux/security.h> #include "integrity.h" static struct rb_root integrity_iint_tree = RB_ROOT; static DEFINE_RWLOCK(integrity_iint_lock); static struct kmem_cache *iint_cache __read_mostly; +struct dentry *integrity_dir; + /* * __integrity_iint_find - return the iint associated with an inode */ @@ -211,3 +214,18 @@ void __init integrity_load_keys(void) ima_load_x509(); evm_load_x509(); } + +static int __init integrity_fs_init(void) +{ + integrity_dir = securityfs_create_dir("integrity", NULL); + if (IS_ERR(integrity_dir)) { + pr_err("Unable to create integrity sysfs dir: %ld\n", + PTR_ERR(integrity_dir)); + integrity_dir = NULL; + return PTR_ERR(integrity_dir); + } + + return 0; +} + +late_initcall(integrity_fs_init) diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 35fe91aa1fc9..354bb5716ce3 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -53,7 +53,6 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 }; extern int ima_policy_flag; /* set during initialization */ -extern int ima_initialized; extern int ima_used_chip; extern int ima_hash_algo; extern int ima_appraise; diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index bf88236b7a0b..a02c5acfd403 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -326,7 +326,7 @@ void ima_audit_measurement(struct integrity_iint_cache *iint, hex_byte_pack(hash + (i * 2), iint->ima_hash->digest[i]); hash[i * 2] = '\0'; - ab = audit_log_start(current->audit_context, GFP_KERNEL, + ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_INTEGRITY_RULE); if (!ab) goto out; diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index fa540c0469da..ae9d5c766a3c 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c @@ -15,6 +15,9 @@ * implemenents security file system for reporting * current measurement list and IMA statistics */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/fcntl.h> #include <linux/slab.h> #include <linux/module.h> @@ -336,7 +339,7 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf, if (data[0] == '/') { result = ima_read_policy(data); } else if (ima_appraise & IMA_APPRAISE_POLICY) { - pr_err("IMA: signed policy file (specified as an absolute pathname) required\n"); + pr_err("signed policy file (specified as an absolute pathname) required\n"); integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL, "policy_update", "signed policy required", 1, 0); @@ -356,6 +359,7 @@ out: } static struct dentry *ima_dir; +static struct dentry *ima_symlink; static struct dentry *binary_runtime_measurements; static struct dentry *ascii_runtime_measurements; static struct dentry *runtime_measurements_count; @@ -417,7 +421,7 @@ static int ima_release_policy(struct inode *inode, struct file *file) valid_policy = 0; } - pr_info("IMA: policy update %s\n", cause); + pr_info("policy update %s\n", cause); integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL, "policy_update", cause, !valid_policy, 0); @@ -434,6 +438,8 @@ static int ima_release_policy(struct inode *inode, struct file *file) ima_policy = NULL; #elif defined(CONFIG_IMA_WRITE_POLICY) clear_bit(IMA_FS_BUSY, &ima_fs_flags); +#elif defined(CONFIG_IMA_READ_POLICY) + inode->i_mode &= ~S_IWUSR; #endif return 0; } @@ -448,10 +454,15 @@ static const struct file_operations ima_measure_policy_ops = { int __init ima_fs_init(void) { - ima_dir = securityfs_create_dir("ima", NULL); + ima_dir = securityfs_create_dir("ima", integrity_dir); if (IS_ERR(ima_dir)) return -1; + ima_symlink = securityfs_create_symlink("ima", NULL, "integrity/ima", + NULL); + if (IS_ERR(ima_symlink)) + goto out; + binary_runtime_measurements = securityfs_create_file("binary_runtime_measurements", S_IRUSR | S_IRGRP, ima_dir, NULL, @@ -491,6 +502,7 @@ out: securityfs_remove(runtime_measurements_count); securityfs_remove(ascii_runtime_measurements); securityfs_remove(binary_runtime_measurements); + securityfs_remove(ima_symlink); securityfs_remove(ima_dir); securityfs_remove(ima_policy); return -1; diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index e473eee913cb..16bd18747cfa 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -10,6 +10,8 @@ * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/seq_file.h> #include <linux/vmalloc.h> #include <linux/kexec.h> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 74d0bd7e76d7..dca44cf7838e 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -32,8 +32,6 @@ #include "ima.h" -int ima_initialized; - #ifdef CONFIG_IMA_APPRAISE int ima_appraise = IMA_APPRAISE_ENFORCE; #else @@ -61,14 +59,11 @@ static int __init hash_setup(char *str) goto out; } - for (i = 0; i < HASH_ALGO__LAST; i++) { - if (strcmp(str, hash_algo_name[i]) == 0) { - ima_hash_algo = i; - break; - } - } - if (i == HASH_ALGO__LAST) + i = match_string(hash_algo_name, HASH_ALGO__LAST, str); + if (i < 0) return 1; + + ima_hash_algo = i; out: hash_setup_done = 1; return 1; @@ -449,6 +444,7 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id) static int read_idmap[READING_MAX_ID] = { [READING_FIRMWARE] = FIRMWARE_CHECK, + [READING_FIRMWARE_PREALLOC_BUFFER] = FIRMWARE_CHECK, [READING_MODULE] = MODULE_CHECK, [READING_KEXEC_IMAGE] = KEXEC_KERNEL_CHECK, [READING_KEXEC_INITRAMFS] = KEXEC_INITRAMFS_CHECK, @@ -517,10 +513,9 @@ static int __init init_ima(void) error = ima_init(); } - if (!error) { - ima_initialized = 1; + if (!error) ima_update_policy_flag(); - } + return error; } diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index d89bebf85421..cdcc9a7b4e24 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -33,6 +33,7 @@ #define IMA_INMASK 0x0040 #define IMA_EUID 0x0080 #define IMA_PCR 0x0100 +#define IMA_FSNAME 0x0200 #define UNKNOWN 0 #define MEASURE 0x0001 /* same as IMA_MEASURE */ @@ -74,6 +75,7 @@ struct ima_rule_entry { void *args_p; /* audit value */ int type; /* audit type */ } lsm[MAX_LSM_RULES]; + char *fsname; }; /* @@ -273,6 +275,9 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, if ((rule->flags & IMA_FSMAGIC) && rule->fsmagic != inode->i_sb->s_magic) return false; + if ((rule->flags & IMA_FSNAME) + && strcmp(rule->fsname, inode->i_sb->s_type->name)) + return false; if ((rule->flags & IMA_FSUUID) && !uuid_equal(&rule->fsuuid, &inode->i_sb->s_uuid)) return false; @@ -435,6 +440,17 @@ void ima_update_policy_flag(void) ima_policy_flag &= ~IMA_APPRAISE; } +static int ima_appraise_flag(enum ima_hooks func) +{ + if (func == MODULE_CHECK) + return IMA_APPRAISE_MODULES; + else if (func == FIRMWARE_CHECK) + return IMA_APPRAISE_FIRMWARE; + else if (func == POLICY_CHECK) + return IMA_APPRAISE_POLICY; + return 0; +} + /** * ima_init_policy - initialize the default measure rules. * @@ -473,9 +489,11 @@ void __init ima_init_policy(void) * Insert the appraise rules requiring file signatures, prior to * any other appraise rules. */ - for (i = 0; i < secure_boot_entries; i++) - list_add_tail(&secure_boot_rules[i].list, - &ima_default_rules); + for (i = 0; i < secure_boot_entries; i++) { + list_add_tail(&secure_boot_rules[i].list, &ima_default_rules); + temp_ima_appraise |= + ima_appraise_flag(secure_boot_rules[i].func); + } for (i = 0; i < appraise_entries; i++) { list_add_tail(&default_appraise_rules[i].list, @@ -509,22 +527,9 @@ int ima_check_policy(void) */ void ima_update_policy(void) { - struct list_head *first, *last, *policy; - - /* append current policy with the new rules */ - first = (&ima_temp_rules)->next; - last = (&ima_temp_rules)->prev; - policy = &ima_policy_rules; - - synchronize_rcu(); + struct list_head *policy = &ima_policy_rules; - last->next = policy; - rcu_assign_pointer(list_next_rcu(policy->prev), first); - first->prev = policy->prev; - policy->prev = last; - - /* prepare for the next policy rules addition */ - INIT_LIST_HEAD(&ima_temp_rules); + list_splice_tail_init_rcu(&ima_temp_rules, policy, synchronize_rcu); if (ima_rules != policy) { ima_policy_flag = 0; @@ -540,7 +545,7 @@ enum { Opt_audit, Opt_hash, Opt_dont_hash, Opt_obj_user, Opt_obj_role, Opt_obj_type, Opt_subj_user, Opt_subj_role, Opt_subj_type, - Opt_func, Opt_mask, Opt_fsmagic, + Opt_func, Opt_mask, Opt_fsmagic, Opt_fsname, Opt_fsuuid, Opt_uid_eq, Opt_euid_eq, Opt_fowner_eq, Opt_uid_gt, Opt_euid_gt, Opt_fowner_gt, Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt, @@ -565,6 +570,7 @@ static match_table_t policy_tokens = { {Opt_func, "func=%s"}, {Opt_mask, "mask=%s"}, {Opt_fsmagic, "fsmagic=%s"}, + {Opt_fsname, "fsname=%s"}, {Opt_fsuuid, "fsuuid=%s"}, {Opt_uid_eq, "uid=%s"}, {Opt_euid_eq, "euid=%s"}, @@ -776,6 +782,17 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) if (!result) entry->flags |= IMA_FSMAGIC; break; + case Opt_fsname: + ima_log_string(ab, "fsname", args[0].from); + + entry->fsname = kstrdup(args[0].from, GFP_KERNEL); + if (!entry->fsname) { + result = -ENOMEM; + break; + } + result = 0; + entry->flags |= IMA_FSNAME; + break; case Opt_fsuuid: ima_log_string(ab, "fsuuid", args[0].from); @@ -917,12 +934,9 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) } if (!result && (entry->action == UNKNOWN)) result = -EINVAL; - else if (entry->func == MODULE_CHECK) - temp_ima_appraise |= IMA_APPRAISE_MODULES; - else if (entry->func == FIRMWARE_CHECK) - temp_ima_appraise |= IMA_APPRAISE_FIRMWARE; - else if (entry->func == POLICY_CHECK) - temp_ima_appraise |= IMA_APPRAISE_POLICY; + else if (entry->action == APPRAISE) + temp_ima_appraise |= ima_appraise_flag(entry->func); + audit_log_format(ab, "res=%d", !result); audit_log_end(ab); return result; @@ -1104,6 +1118,12 @@ int ima_policy_show(struct seq_file *m, void *v) seq_puts(m, " "); } + if (entry->flags & IMA_FSNAME) { + snprintf(tbuf, sizeof(tbuf), "%s", entry->fsname); + seq_printf(m, pt(Opt_fsname), tbuf); + seq_puts(m, " "); + } + if (entry->flags & IMA_PCR) { snprintf(tbuf, sizeof(tbuf), "%d", entry->pcr); seq_printf(m, pt(Opt_pcr), tbuf); diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c index 5afaa53decc5..43752002c222 100644 --- a/security/integrity/ima/ima_template_lib.c +++ b/security/integrity/ima/ima_template_lib.c @@ -13,6 +13,8 @@ * Library of supported template fields. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include "ima_template_lib.h" static bool ima_template_hash_algo_allowed(u8 algo) diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 5e58e02ba8dc..0bb372eed62a 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h @@ -143,6 +143,8 @@ int integrity_kernel_read(struct file *file, loff_t offset, #define INTEGRITY_KEYRING_MODULE 2 #define INTEGRITY_KEYRING_MAX 3 +extern struct dentry *integrity_dir; + #ifdef CONFIG_INTEGRITY_SIGNATURE int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, diff --git a/security/integrity/integrity_audit.c b/security/integrity/integrity_audit.c index 90987d15b6fe..ab10a25310a1 100644 --- a/security/integrity/integrity_audit.c +++ b/security/integrity/integrity_audit.c @@ -38,7 +38,7 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode, if (!integrity_audit_info && audit_info == 1) /* Skip info messages */ return; - ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno); + ab = audit_log_start(audit_context(), GFP_KERNEL, audit_msgno); audit_log_format(ab, "pid=%d uid=%u auid=%u ses=%u", task_pid_nr(current), from_kuid(&init_user_ns, current_cred()->uid), diff --git a/security/keys/proc.c b/security/keys/proc.c index fbc4af5c6c9f..5af2934965d8 100644 --- a/security/keys/proc.c +++ b/security/keys/proc.c @@ -18,7 +18,6 @@ #include <asm/errno.h> #include "internal.h" -static int proc_keys_open(struct inode *inode, struct file *file); static void *proc_keys_start(struct seq_file *p, loff_t *_pos); static void *proc_keys_next(struct seq_file *p, void *v, loff_t *_pos); static void proc_keys_stop(struct seq_file *p, void *v); @@ -31,14 +30,6 @@ static const struct seq_operations proc_keys_ops = { .show = proc_keys_show, }; -static const struct file_operations proc_keys_fops = { - .open = proc_keys_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -static int proc_key_users_open(struct inode *inode, struct file *file); static void *proc_key_users_start(struct seq_file *p, loff_t *_pos); static void *proc_key_users_next(struct seq_file *p, void *v, loff_t *_pos); static void proc_key_users_stop(struct seq_file *p, void *v); @@ -51,13 +42,6 @@ static const struct seq_operations proc_key_users_ops = { .show = proc_key_users_show, }; -static const struct file_operations proc_key_users_fops = { - .open = proc_key_users_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - /* * Declare the /proc files. */ @@ -65,11 +49,11 @@ static int __init key_proc_init(void) { struct proc_dir_entry *p; - p = proc_create("keys", 0, NULL, &proc_keys_fops); + p = proc_create_seq("keys", 0, NULL, &proc_keys_ops); if (!p) panic("Cannot create /proc/keys\n"); - p = proc_create("key-users", 0, NULL, &proc_key_users_fops); + p = proc_create_seq("key-users", 0, NULL, &proc_key_users_ops); if (!p) panic("Cannot create /proc/key-users\n"); @@ -96,11 +80,6 @@ static struct rb_node *key_serial_next(struct seq_file *p, struct rb_node *n) return n; } -static int proc_keys_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &proc_keys_ops); -} - static struct key *find_ge_key(struct seq_file *p, key_serial_t id) { struct user_namespace *user_ns = seq_user_ns(p); @@ -293,15 +272,6 @@ static struct rb_node *key_user_first(struct user_namespace *user_ns, struct rb_ return __key_user_next(user_ns, n); } -/* - * Implement "/proc/key-users" to provides a list of the key users and their - * quotas. - */ -static int proc_key_users_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &proc_key_users_ops); -} - static void *proc_key_users_start(struct seq_file *p, loff_t *_pos) __acquires(key_user_lock) { diff --git a/security/lsm_audit.c b/security/lsm_audit.c index 67703dbe29ea..f84001019356 100644 --- a/security/lsm_audit.c +++ b/security/lsm_audit.c @@ -447,7 +447,7 @@ void common_lsm_audit(struct common_audit_data *a, if (a == NULL) return; /* we use GFP_ATOMIC so we won't sleep */ - ab = audit_log_start(current->audit_context, GFP_ATOMIC | __GFP_NOWARN, + ab = audit_log_start(audit_context(), GFP_ATOMIC | __GFP_NOWARN, AUDIT_AVC); if (ab == NULL) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 02ebd1585eaf..9a46dc24ac10 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -274,11 +274,10 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent * Try reloading inode security labels that have been marked as invalid. The * @may_sleep parameter indicates when sleeping and thus reloading labels is * allowed; when set to false, returns -ECHILD when the label is - * invalid. The @opt_dentry parameter should be set to a dentry of the inode; - * when no dentry is available, set it to NULL instead. + * invalid. The @dentry parameter should be set to a dentry of the inode. */ static int __inode_security_revalidate(struct inode *inode, - struct dentry *opt_dentry, + struct dentry *dentry, bool may_sleep) { struct inode_security_struct *isec = inode->i_security; @@ -295,7 +294,7 @@ static int __inode_security_revalidate(struct inode *inode, * @opt_dentry is NULL and no dentry for this inode can be * found; in that case, continue using the old label. */ - inode_doinit_with_dentry(inode, opt_dentry); + inode_doinit_with_dentry(inode, dentry); } return 0; } @@ -1471,7 +1470,9 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc return SECCLASS_QIPCRTR_SOCKET; case PF_SMC: return SECCLASS_SMC_SOCKET; -#if PF_MAX > 44 + case PF_XDP: + return SECCLASS_XDP_SOCKET; +#if PF_MAX > 45 #error New address family defined, please update this function. #endif } @@ -1568,8 +1569,15 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent /* Called from d_instantiate or d_splice_alias. */ dentry = dget(opt_dentry); } else { - /* Called from selinux_complete_init, try to find a dentry. */ + /* + * Called from selinux_complete_init, try to find a dentry. + * Some filesystems really want a connected one, so try + * that first. We could split SECURITY_FS_USE_XATTR in + * two, depending upon that... + */ dentry = d_find_alias(inode); + if (!dentry) + dentry = d_find_any_alias(inode); } if (!dentry) { /* @@ -1674,14 +1682,19 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent if ((sbsec->flags & SE_SBGENFS) && !S_ISLNK(inode->i_mode)) { /* We must have a dentry to determine the label on * procfs inodes */ - if (opt_dentry) + if (opt_dentry) { /* Called from d_instantiate or * d_splice_alias. */ dentry = dget(opt_dentry); - else + } else { /* Called from selinux_complete_init, try to - * find a dentry. */ + * find a dentry. Some filesystems really want + * a connected one, so try that first. + */ dentry = d_find_alias(inode); + if (!dentry) + dentry = d_find_any_alias(inode); + } /* * This can be hit on boot when a file is accessed * before the policy is loaded. When we load policy we @@ -3294,7 +3307,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, } else { audit_size = 0; } - ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR); + ab = audit_log_start(audit_context(), + GFP_ATOMIC, AUDIT_SELINUX_ERR); audit_log_format(ab, "op=setxattr invalid_context="); audit_log_n_untrustedstring(ab, value, audit_size); audit_log_end(ab); @@ -4588,6 +4602,7 @@ static int selinux_socket_socketpair(struct socket *socka, static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) { struct sock *sk = sock->sk; + struct sk_security_struct *sksec = sk->sk_security; u16 family; int err; @@ -4599,11 +4614,11 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in family = sk->sk_family; if (family == PF_INET || family == PF_INET6) { char *addrp; - struct sk_security_struct *sksec = sk->sk_security; struct common_audit_data ad; struct lsm_network_audit net = {0,}; struct sockaddr_in *addr4 = NULL; struct sockaddr_in6 *addr6 = NULL; + u16 family_sa = address->sa_family; unsigned short snum; u32 sid, node_perm; @@ -4613,11 +4628,20 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in * need to check address->sa_family as it is possible to have * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET. */ - switch (address->sa_family) { + switch (family_sa) { + case AF_UNSPEC: case AF_INET: if (addrlen < sizeof(struct sockaddr_in)) return -EINVAL; addr4 = (struct sockaddr_in *)address; + if (family_sa == AF_UNSPEC) { + /* see __inet_bind(), we only want to allow + * AF_UNSPEC if the address is INADDR_ANY + */ + if (addr4->sin_addr.s_addr != htonl(INADDR_ANY)) + goto err_af; + family_sa = AF_INET; + } snum = ntohs(addr4->sin_port); addrp = (char *)&addr4->sin_addr.s_addr; break; @@ -4629,15 +4653,14 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in addrp = (char *)&addr6->sin6_addr.s6_addr; break; default: - /* Note that SCTP services expect -EINVAL, whereas - * others expect -EAFNOSUPPORT. - */ - if (sksec->sclass == SECCLASS_SCTP_SOCKET) - return -EINVAL; - else - return -EAFNOSUPPORT; + goto err_af; } + ad.type = LSM_AUDIT_DATA_NET; + ad.u.net = &net; + ad.u.net->sport = htons(snum); + ad.u.net->family = family_sa; + if (snum) { int low, high; @@ -4649,10 +4672,6 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in snum, &sid); if (err) goto out; - ad.type = LSM_AUDIT_DATA_NET; - ad.u.net = &net; - ad.u.net->sport = htons(snum); - ad.u.net->family = family; err = avc_has_perm(&selinux_state, sksec->sid, sid, sksec->sclass, @@ -4684,16 +4703,11 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in break; } - err = sel_netnode_sid(addrp, family, &sid); + err = sel_netnode_sid(addrp, family_sa, &sid); if (err) goto out; - ad.type = LSM_AUDIT_DATA_NET; - ad.u.net = &net; - ad.u.net->sport = htons(snum); - ad.u.net->family = family; - - if (address->sa_family == AF_INET) + if (family_sa == AF_INET) ad.u.net->v4info.saddr = addr4->sin_addr.s_addr; else ad.u.net->v6info.saddr = addr6->sin6_addr; @@ -4706,6 +4720,11 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in } out: return err; +err_af: + /* Note that SCTP services expect -EINVAL, others -EAFNOSUPPORT. */ + if (sksec->sclass == SECCLASS_SCTP_SOCKET) + return -EINVAL; + return -EAFNOSUPPORT; } /* This supports connect(2) and SCTP connect services such as sctp_connectx(3) @@ -4783,7 +4802,7 @@ static int selinux_socket_connect_helper(struct socket *sock, ad.type = LSM_AUDIT_DATA_NET; ad.u.net = &net; ad.u.net->dport = htons(snum); - ad.u.net->family = sk->sk_family; + ad.u.net->family = address->sa_family; err = avc_has_perm(&selinux_state, sksec->sid, sid, sksec->sclass, perm, &ad); if (err) @@ -5284,6 +5303,7 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname, while (walk_size < addrlen) { addr = addr_buf; switch (addr->sa_family) { + case AF_UNSPEC: case AF_INET: len = sizeof(struct sockaddr_in); break; @@ -5291,7 +5311,7 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname, len = sizeof(struct sockaddr_in6); break; default: - return -EAFNOSUPPORT; + return -EINVAL; } err = -EINVAL; @@ -6443,7 +6463,9 @@ static int selinux_setprocattr(const char *name, void *value, size_t size) audit_size = size - 1; else audit_size = size; - ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR); + ab = audit_log_start(audit_context(), + GFP_ATOMIC, + AUDIT_SELINUX_ERR); audit_log_format(ab, "op=fscreate invalid_context="); audit_log_n_untrustedstring(ab, value, audit_size); audit_log_end(ab); diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index 7f0372426494..bd5fe0d3204a 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -240,9 +240,11 @@ struct security_class_mapping secclass_map[] = { { "manage_subnet", NULL } }, { "bpf", {"map_create", "map_read", "map_write", "prog_load", "prog_run"} }, + { "xdp_socket", + { COMMON_SOCK_PERMS, NULL } }, { NULL } }; -#if PF_MAX > 44 +#if PF_MAX > 45 #error New address family defined, please update secclass_map. #endif diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 245160373dab..f3d374d2ca04 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -167,11 +167,13 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf, NULL); if (length) goto out; - audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, - "enforcing=%d old_enforcing=%d auid=%u ses=%u", + audit_log(audit_context(), GFP_KERNEL, AUDIT_MAC_STATUS, + "enforcing=%d old_enforcing=%d auid=%u ses=%u" + " enabled=%d old-enabled=%d lsm=selinux res=1", new_value, old_value, from_kuid(&init_user_ns, audit_get_loginuid(current)), - audit_get_sessionid(current)); + audit_get_sessionid(current), + selinux_enabled, selinux_enabled); enforcing_set(state, new_value); if (new_value) avc_ss_reset(state->avc, 0); @@ -279,6 +281,7 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf, char *page; ssize_t length; int new_value; + int enforcing; if (count >= PAGE_SIZE) return -ENOMEM; @@ -296,13 +299,16 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf, goto out; if (new_value) { + enforcing = enforcing_enabled(fsi->state); length = selinux_disable(fsi->state); if (length) goto out; - audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, - "selinux=0 auid=%u ses=%u", + audit_log(audit_context(), GFP_KERNEL, AUDIT_MAC_STATUS, + "enforcing=%d old_enforcing=%d auid=%u ses=%u" + " enabled=%d old-enabled=%d lsm=selinux res=1", + enforcing, enforcing, from_kuid(&init_user_ns, audit_get_loginuid(current)), - audit_get_sessionid(current)); + audit_get_sessionid(current), 0, 1); } length = count; @@ -453,7 +459,7 @@ out: return ret; } -static int sel_mmap_policy_fault(struct vm_fault *vmf) +static vm_fault_t sel_mmap_policy_fault(struct vm_fault *vmf) { struct policy_load_memory *plm = vmf->vma->vm_file->private_data; unsigned long offset; @@ -575,8 +581,8 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf, length = count; out1: - audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD, - "policy loaded auid=%u ses=%u", + audit_log(audit_context(), GFP_KERNEL, AUDIT_MAC_POLICY_LOAD, + "auid=%u ses=%u lsm=selinux res=1", from_kuid(&init_user_ns, audit_get_loginuid(current)), audit_get_sessionid(current)); out: diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 8057e19dc15f..a2d44824121c 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -501,7 +501,7 @@ static void security_dump_masked_av(struct policydb *policydb, goto out; /* audit a message */ - ab = audit_log_start(current->audit_context, + ab = audit_log_start(audit_context(), GFP_ATOMIC, AUDIT_SELINUX_ERR); if (!ab) goto out; @@ -743,7 +743,7 @@ static int security_validtrans_handle_fail(struct selinux_state *state, goto out; if (context_struct_to_string(p, tcontext, &t, &tlen)) goto out; - audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, + audit_log(audit_context(), GFP_ATOMIC, AUDIT_SELINUX_ERR, "op=security_validate_transition seresult=denied" " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s", o, n, t, sym_name(p, SYM_CLASSES, tclass-1)); @@ -929,7 +929,7 @@ int security_bounded_transition(struct selinux_state *state, &old_name, &length) && !context_struct_to_string(policydb, new_context, &new_name, &length)) { - audit_log(current->audit_context, + audit_log(audit_context(), GFP_ATOMIC, AUDIT_SELINUX_ERR, "op=security_bounded_transition " "seresult=denied " @@ -1494,7 +1494,7 @@ static int security_context_to_sid_core(struct selinux_state *state, scontext_len, &context, def_sid); if (rc == -EINVAL && force) { context.str = str; - context.len = scontext_len; + context.len = strlen(str) + 1; str = NULL; } else if (rc) goto out_unlock; @@ -1586,7 +1586,7 @@ static int compute_sid_handle_invalid_context( goto out; if (context_struct_to_string(policydb, newcontext, &n, &nlen)) goto out; - audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, + audit_log(audit_context(), GFP_ATOMIC, AUDIT_SELINUX_ERR, "op=security_compute_sid invalid_context=%s" " scontext=%s" " tcontext=%s" @@ -2882,7 +2882,7 @@ int security_set_bools(struct selinux_state *state, int len, int *values) for (i = 0; i < len; i++) { if (!!values[i] != policydb->bool_val_to_struct[i]->state) { - audit_log(current->audit_context, GFP_ATOMIC, + audit_log(audit_context(), GFP_ATOMIC, AUDIT_MAC_CONFIG_CHANGE, "bool=%s val=%d old_val=%d auid=%u ses=%u", sym_name(policydb, SYM_BOOLS, i), @@ -3025,7 +3025,7 @@ int security_sid_mls_copy(struct selinux_state *state, if (rc) { if (!context_struct_to_string(policydb, &newcon, &s, &len)) { - audit_log(current->audit_context, + audit_log(audit_context(), GFP_ATOMIC, AUDIT_SELINUX_ERR, "op=security_sid_mls_copy " "invalid_context=%s", s); |