aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-07 19:53:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-07 19:53:59 -0400
commitf8cf2f16a7c95acce497bfafa90e7c6d8397d653 (patch)
tree6451abed2025593015cde6fdc6edd54844eb15d3
parent4b3f1a151571985f7c9964260db1c31e056a67e4 (diff)
parentab60368ab6a452466885ef4edf0cefd089465132 (diff)
Merge branch 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull integrity updates from James Morris: "A mixture of bug fixes, code cleanup, and continues to close IMA-measurement, IMA-appraisal, and IMA-audit gaps. Also note the addition of a new cred_getsecid LSM hook by Matthew Garrett: For IMA purposes, we want to be able to obtain the prepared secid in the bprm structure before the credentials are committed. Add a cred_getsecid hook that makes this possible. which is used by a new CREDS_CHECK target in IMA: In ima_bprm_check(), check with both the existing process credentials and the credentials that will be committed when the new process is started. This will not change behaviour unless the system policy is extended to include CREDS_CHECK targets - BPRM_CHECK will continue to check the same credentials that it did previously" * 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: ima: Fallback to the builtin hash algorithm ima: Add smackfs to the default appraise/measure list evm: check for remount ro in progress before writing ima: Improvements in ima_appraise_measurement() ima: Simplify ima_eventsig_init() integrity: Remove unused macro IMA_ACTION_RULE_FLAGS ima: drop vla in ima_audit_measurement() ima: Fix Kconfig to select TPM 2.0 CRB interface evm: Constify *integrity_status_msg[] evm: Move evm_hmac and evm_hash from evm_main.c to evm_crypto.c fuse: define the filesystem as untrusted ima: fail signature verification based on policy ima: clear IMA_HASH ima: re-evaluate files on privileged mounted filesystems ima: fail file signature verification on non-init mounted filesystems IMA: Support using new creds in appraisal policy security: Add a cred_getsecid hook
-rw-r--r--Documentation/ABI/testing/ima_policy2
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt8
-rw-r--r--fs/fuse/inode.c3
-rw-r--r--include/linux/fs.h2
-rw-r--r--include/linux/lsm_hooks.h6
-rw-r--r--include/linux/security.h1
-rw-r--r--security/integrity/evm/evm.h2
-rw-r--r--security/integrity/evm/evm_crypto.c3
-rw-r--r--security/integrity/evm/evm_main.c12
-rw-r--r--security/integrity/iint.c2
-rw-r--r--security/integrity/ima/Kconfig1
-rw-r--r--security/integrity/ima/ima.h9
-rw-r--r--security/integrity/ima/ima_api.c25
-rw-r--r--security/integrity/ima/ima_appraise.c65
-rw-r--r--security/integrity/ima/ima_crypto.c2
-rw-r--r--security/integrity/ima/ima_main.c69
-rw-r--r--security/integrity/ima/ima_policy.c32
-rw-r--r--security/integrity/ima/ima_template_lib.c11
-rw-r--r--security/integrity/integrity.h11
-rw-r--r--security/security.c7
-rw-r--r--security/selinux/hooks.c6
-rw-r--r--security/smack/smack_lsm.c18
22 files changed, 227 insertions, 70 deletions
diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
index 2028f2d093b2..b8465e00ba5f 100644
--- a/Documentation/ABI/testing/ima_policy
+++ b/Documentation/ABI/testing/ima_policy
@@ -26,7 +26,7 @@ Description:
26 [obj_user=] [obj_role=] [obj_type=]] 26 [obj_user=] [obj_role=] [obj_type=]]
27 option: [[appraise_type=]] [permit_directio] 27 option: [[appraise_type=]] [permit_directio]
28 28
29 base: func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK] 29 base: func:= [BPRM_CHECK][MMAP_CHECK][CREDS_CHECK][FILE_CHECK][MODULE_CHECK]
30 [FIRMWARE_CHECK] 30 [FIRMWARE_CHECK]
31 [KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK] 31 [KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK]
32 mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND] 32 mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND]
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 683145d7b054..9a3edf7e901a 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1521,7 +1521,8 @@
1521 1521
1522 ima_policy= [IMA] 1522 ima_policy= [IMA]
1523 The builtin policies to load during IMA setup. 1523 The builtin policies to load during IMA setup.
1524 Format: "tcb | appraise_tcb | secure_boot" 1524 Format: "tcb | appraise_tcb | secure_boot |
1525 fail_securely"
1525 1526
1526 The "tcb" policy measures all programs exec'd, files 1527 The "tcb" policy measures all programs exec'd, files
1527 mmap'd for exec, and all files opened with the read 1528 mmap'd for exec, and all files opened with the read
@@ -1536,6 +1537,11 @@
1536 of files (eg. kexec kernel image, kernel modules, 1537 of files (eg. kexec kernel image, kernel modules,
1537 firmware, policy, etc) based on file signatures. 1538 firmware, policy, etc) based on file signatures.
1538 1539
1540 The "fail_securely" policy forces file signature
1541 verification failure also on privileged mounted
1542 filesystems with the SB_I_UNVERIFIABLE_SIGNATURE
1543 flag.
1544
1539 ima_tcb [IMA] Deprecated. Use ima_policy= instead. 1545 ima_tcb [IMA] Deprecated. Use ima_policy= instead.
1540 Load a policy which meets the needs of the Trusted 1546 Load a policy which meets the needs of the Trusted
1541 Computing Base. This means IMA will measure all 1547 Computing Base. This means IMA will measure all
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 624f18bbfd2b..ef309958e060 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -1080,6 +1080,9 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
1080 sb->s_maxbytes = MAX_LFS_FILESIZE; 1080 sb->s_maxbytes = MAX_LFS_FILESIZE;
1081 sb->s_time_gran = 1; 1081 sb->s_time_gran = 1;
1082 sb->s_export_op = &fuse_export_operations; 1082 sb->s_export_op = &fuse_export_operations;
1083 sb->s_iflags |= SB_I_IMA_UNVERIFIABLE_SIGNATURE;
1084 if (sb->s_user_ns != &init_user_ns)
1085 sb->s_iflags |= SB_I_UNTRUSTED_MOUNTER;
1083 1086
1084 file = fget(d.fd); 1087 file = fget(d.fd);
1085 err = -EINVAL; 1088 err = -EINVAL;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 0d798052bd85..1ee7f592e239 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1321,6 +1321,8 @@ extern int send_sigurg(struct fown_struct *fown);
1321 1321
1322/* sb->s_iflags to limit user namespace mounts */ 1322/* sb->s_iflags to limit user namespace mounts */
1323#define SB_I_USERNS_VISIBLE 0x00000010 /* fstype already mounted */ 1323#define SB_I_USERNS_VISIBLE 0x00000010 /* fstype already mounted */
1324#define SB_I_IMA_UNVERIFIABLE_SIGNATURE 0x00000020
1325#define SB_I_UNTRUSTED_MOUNTER 0x00000040
1324 1326
1325/* Possible states of 'frozen' field */ 1327/* Possible states of 'frozen' field */
1326enum { 1328enum {
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index c72c42dbe77b..9d0b286f3dba 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -554,6 +554,10 @@
554 * @new points to the new credentials. 554 * @new points to the new credentials.
555 * @old points to the original credentials. 555 * @old points to the original credentials.
556 * Transfer data from original creds to new creds 556 * Transfer data from original creds to new creds
557 * @cred_getsecid:
558 * Retrieve the security identifier of the cred structure @c
559 * @c contains the credentials, secid will be placed into @secid.
560 * In case of failure, @secid will be set to zero.
557 * @kernel_act_as: 561 * @kernel_act_as:
558 * Set the credentials for a kernel service to act as (subjective context). 562 * Set the credentials for a kernel service to act as (subjective context).
559 * @new points to the credentials to be modified. 563 * @new points to the credentials to be modified.
@@ -1569,6 +1573,7 @@ union security_list_options {
1569 int (*cred_prepare)(struct cred *new, const struct cred *old, 1573 int (*cred_prepare)(struct cred *new, const struct cred *old,
1570 gfp_t gfp); 1574 gfp_t gfp);
1571 void (*cred_transfer)(struct cred *new, const struct cred *old); 1575 void (*cred_transfer)(struct cred *new, const struct cred *old);
1576 void (*cred_getsecid)(const struct cred *c, u32 *secid);
1572 int (*kernel_act_as)(struct cred *new, u32 secid); 1577 int (*kernel_act_as)(struct cred *new, u32 secid);
1573 int (*kernel_create_files_as)(struct cred *new, struct inode *inode); 1578 int (*kernel_create_files_as)(struct cred *new, struct inode *inode);
1574 int (*kernel_module_request)(char *kmod_name); 1579 int (*kernel_module_request)(char *kmod_name);
@@ -1858,6 +1863,7 @@ struct security_hook_heads {
1858 struct hlist_head cred_free; 1863 struct hlist_head cred_free;
1859 struct hlist_head cred_prepare; 1864 struct hlist_head cred_prepare;
1860 struct hlist_head cred_transfer; 1865 struct hlist_head cred_transfer;
1866 struct hlist_head cred_getsecid;
1861 struct hlist_head kernel_act_as; 1867 struct hlist_head kernel_act_as;
1862 struct hlist_head kernel_create_files_as; 1868 struct hlist_head kernel_create_files_as;
1863 struct hlist_head kernel_read_file; 1869 struct hlist_head kernel_read_file;
diff --git a/include/linux/security.h b/include/linux/security.h
index 4a573c3be93d..200920f521a1 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -322,6 +322,7 @@ int security_cred_alloc_blank(struct cred *cred, gfp_t gfp);
322void security_cred_free(struct cred *cred); 322void security_cred_free(struct cred *cred);
323int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp); 323int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp);
324void security_transfer_creds(struct cred *new, const struct cred *old); 324void security_transfer_creds(struct cred *new, const struct cred *old);
325void security_cred_getsecid(const struct cred *c, u32 *secid);
325int security_kernel_act_as(struct cred *new, u32 secid); 326int security_kernel_act_as(struct cred *new, u32 secid);
326int security_kernel_create_files_as(struct cred *new, struct inode *inode); 327int security_kernel_create_files_as(struct cred *new, struct inode *inode);
327int security_kernel_module_request(char *kmod_name); 328int security_kernel_module_request(char *kmod_name);
diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h
index 04825393facb..45c4a89c02ff 100644
--- a/security/integrity/evm/evm.h
+++ b/security/integrity/evm/evm.h
@@ -31,8 +31,6 @@
31 EVM_ALLOW_METADATA_WRITES) 31 EVM_ALLOW_METADATA_WRITES)
32 32
33extern int evm_initialized; 33extern int evm_initialized;
34extern char *evm_hmac;
35extern char *evm_hash;
36 34
37#define EVM_ATTR_FSUUID 0x0001 35#define EVM_ATTR_FSUUID 0x0001
38 36
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index 691f3e09154c..a46fba322340 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -37,6 +37,9 @@ static DEFINE_MUTEX(mutex);
37 37
38static unsigned long evm_set_key_flags; 38static unsigned long evm_set_key_flags;
39 39
40static char * const evm_hmac = "hmac(sha1)";
41static char * const evm_hash = "sha1";
42
40/** 43/**
41 * evm_set_key() - set EVM HMAC key from the kernel 44 * evm_set_key() - set EVM HMAC key from the kernel
42 * @key: pointer to a buffer with the key data 45 * @key: pointer to a buffer with the key data
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index a8d502827270..9ea9c19a545c 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -30,11 +30,9 @@
30 30
31int evm_initialized; 31int evm_initialized;
32 32
33static char *integrity_status_msg[] = { 33static const char * const integrity_status_msg[] = {
34 "pass", "pass_immutable", "fail", "no_label", "no_xattrs", "unknown" 34 "pass", "pass_immutable", "fail", "no_label", "no_xattrs", "unknown"
35}; 35};
36char *evm_hmac = "hmac(sha1)";
37char *evm_hash = "sha1";
38int evm_hmac_attrs; 36int evm_hmac_attrs;
39 37
40char *evm_config_xattrnames[] = { 38char *evm_config_xattrnames[] = {
@@ -126,6 +124,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
126 struct evm_ima_xattr_data *xattr_data = NULL; 124 struct evm_ima_xattr_data *xattr_data = NULL;
127 struct evm_ima_xattr_data calc; 125 struct evm_ima_xattr_data calc;
128 enum integrity_status evm_status = INTEGRITY_PASS; 126 enum integrity_status evm_status = INTEGRITY_PASS;
127 struct inode *inode;
129 int rc, xattr_len; 128 int rc, xattr_len;
130 129
131 if (iint && (iint->evm_status == INTEGRITY_PASS || 130 if (iint && (iint->evm_status == INTEGRITY_PASS ||
@@ -180,12 +179,15 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
180 (const char *)xattr_data, xattr_len, 179 (const char *)xattr_data, xattr_len,
181 calc.digest, sizeof(calc.digest)); 180 calc.digest, sizeof(calc.digest));
182 if (!rc) { 181 if (!rc) {
182 inode = d_backing_inode(dentry);
183
183 if (xattr_data->type == EVM_XATTR_PORTABLE_DIGSIG) { 184 if (xattr_data->type == EVM_XATTR_PORTABLE_DIGSIG) {
184 if (iint) 185 if (iint)
185 iint->flags |= EVM_IMMUTABLE_DIGSIG; 186 iint->flags |= EVM_IMMUTABLE_DIGSIG;
186 evm_status = INTEGRITY_PASS_IMMUTABLE; 187 evm_status = INTEGRITY_PASS_IMMUTABLE;
187 } else if (!IS_RDONLY(d_backing_inode(dentry)) && 188 } else if (!IS_RDONLY(inode) &&
188 !IS_IMMUTABLE(d_backing_inode(dentry))) { 189 !(inode->i_sb->s_readonly_remount) &&
190 !IS_IMMUTABLE(inode)) {
189 evm_update_evmxattr(dentry, xattr_name, 191 evm_update_evmxattr(dentry, xattr_name,
190 xattr_value, 192 xattr_value,
191 xattr_value_len); 193 xattr_value_len);
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index 9700e96ab0f0..f266e4b3b7d4 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -79,6 +79,7 @@ static void iint_free(struct integrity_iint_cache *iint)
79 iint->ima_mmap_status = INTEGRITY_UNKNOWN; 79 iint->ima_mmap_status = INTEGRITY_UNKNOWN;
80 iint->ima_bprm_status = INTEGRITY_UNKNOWN; 80 iint->ima_bprm_status = INTEGRITY_UNKNOWN;
81 iint->ima_read_status = INTEGRITY_UNKNOWN; 81 iint->ima_read_status = INTEGRITY_UNKNOWN;
82 iint->ima_creds_status = INTEGRITY_UNKNOWN;
82 iint->evm_status = INTEGRITY_UNKNOWN; 83 iint->evm_status = INTEGRITY_UNKNOWN;
83 iint->measured_pcrs = 0; 84 iint->measured_pcrs = 0;
84 kmem_cache_free(iint_cache, iint); 85 kmem_cache_free(iint_cache, iint);
@@ -158,6 +159,7 @@ static void init_once(void *foo)
158 iint->ima_mmap_status = INTEGRITY_UNKNOWN; 159 iint->ima_mmap_status = INTEGRITY_UNKNOWN;
159 iint->ima_bprm_status = INTEGRITY_UNKNOWN; 160 iint->ima_bprm_status = INTEGRITY_UNKNOWN;
160 iint->ima_read_status = INTEGRITY_UNKNOWN; 161 iint->ima_read_status = INTEGRITY_UNKNOWN;
162 iint->ima_creds_status = INTEGRITY_UNKNOWN;
161 iint->evm_status = INTEGRITY_UNKNOWN; 163 iint->evm_status = INTEGRITY_UNKNOWN;
162 mutex_init(&iint->mutex); 164 mutex_init(&iint->mutex);
163} 165}
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 35ef69312811..6a8f67714c83 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -10,6 +10,7 @@ config IMA
10 select CRYPTO_HASH_INFO 10 select CRYPTO_HASH_INFO
11 select TCG_TPM if HAS_IOMEM && !UML 11 select TCG_TPM if HAS_IOMEM && !UML
12 select TCG_TIS if TCG_TPM && X86 12 select TCG_TIS if TCG_TPM && X86
13 select TCG_CRB if TCG_TPM && ACPI
13 select TCG_IBMVTPM if TCG_TPM && PPC_PSERIES 14 select TCG_IBMVTPM if TCG_TPM && PPC_PSERIES
14 help 15 help
15 The Trusted Computing Group(TCG) runtime Integrity 16 The Trusted Computing Group(TCG) runtime Integrity
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index d52b487ad259..35fe91aa1fc9 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -177,6 +177,7 @@ static inline unsigned long ima_hash_key(u8 *digest)
177 hook(FILE_CHECK) \ 177 hook(FILE_CHECK) \
178 hook(MMAP_CHECK) \ 178 hook(MMAP_CHECK) \
179 hook(BPRM_CHECK) \ 179 hook(BPRM_CHECK) \
180 hook(CREDS_CHECK) \
180 hook(POST_SETATTR) \ 181 hook(POST_SETATTR) \
181 hook(MODULE_CHECK) \ 182 hook(MODULE_CHECK) \
182 hook(FIRMWARE_CHECK) \ 183 hook(FIRMWARE_CHECK) \
@@ -191,8 +192,8 @@ enum ima_hooks {
191}; 192};
192 193
193/* LIM API function definitions */ 194/* LIM API function definitions */
194int ima_get_action(struct inode *inode, int mask, 195int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid,
195 enum ima_hooks func, int *pcr); 196 int mask, enum ima_hooks func, int *pcr);
196int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func); 197int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func);
197int ima_collect_measurement(struct integrity_iint_cache *iint, 198int ima_collect_measurement(struct integrity_iint_cache *iint,
198 struct file *file, void *buf, loff_t size, 199 struct file *file, void *buf, loff_t size,
@@ -212,8 +213,8 @@ void ima_free_template_entry(struct ima_template_entry *entry);
212const char *ima_d_path(const struct path *path, char **pathbuf, char *filename); 213const char *ima_d_path(const struct path *path, char **pathbuf, char *filename);
213 214
214/* IMA policy related functions */ 215/* IMA policy related functions */
215int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, 216int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid,
216 int flags, int *pcr); 217 enum ima_hooks func, int mask, int flags, int *pcr);
217void ima_init_policy(void); 218void ima_init_policy(void);
218void ima_update_policy(void); 219void ima_update_policy(void);
219void ima_update_policy_flag(void); 220void ima_update_policy_flag(void);
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 08fe405338e1..bf88236b7a0b 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -158,6 +158,8 @@ err_out:
158/** 158/**
159 * ima_get_action - appraise & measure decision based on policy. 159 * ima_get_action - appraise & measure decision based on policy.
160 * @inode: pointer to inode to measure 160 * @inode: pointer to inode to measure
161 * @cred: pointer to credentials structure to validate
162 * @secid: secid of the task being validated
161 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXEC, 163 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXEC,
162 * MAY_APPEND) 164 * MAY_APPEND)
163 * @func: caller identifier 165 * @func: caller identifier
@@ -166,20 +168,21 @@ err_out:
166 * The policy is defined in terms of keypairs: 168 * The policy is defined in terms of keypairs:
167 * subj=, obj=, type=, func=, mask=, fsmagic= 169 * subj=, obj=, type=, func=, mask=, fsmagic=
168 * subj,obj, and type: are LSM specific. 170 * subj,obj, and type: are LSM specific.
169 * func: FILE_CHECK | BPRM_CHECK | MMAP_CHECK | MODULE_CHECK 171 * func: FILE_CHECK | BPRM_CHECK | CREDS_CHECK | MMAP_CHECK | MODULE_CHECK
170 * mask: contains the permission mask 172 * mask: contains the permission mask
171 * fsmagic: hex value 173 * fsmagic: hex value
172 * 174 *
173 * Returns IMA_MEASURE, IMA_APPRAISE mask. 175 * Returns IMA_MEASURE, IMA_APPRAISE mask.
174 * 176 *
175 */ 177 */
176int ima_get_action(struct inode *inode, int mask, enum ima_hooks func, int *pcr) 178int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid,
179 int mask, enum ima_hooks func, int *pcr)
177{ 180{
178 int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE | IMA_HASH; 181 int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE | IMA_HASH;
179 182
180 flags &= ima_policy_flag; 183 flags &= ima_policy_flag;
181 184
182 return ima_match_policy(inode, func, mask, flags, pcr); 185 return ima_match_policy(inode, cred, secid, func, mask, flags, pcr);
183} 186}
184 187
185/* 188/*
@@ -308,14 +311,17 @@ void ima_audit_measurement(struct integrity_iint_cache *iint,
308 const unsigned char *filename) 311 const unsigned char *filename)
309{ 312{
310 struct audit_buffer *ab; 313 struct audit_buffer *ab;
311 char hash[(iint->ima_hash->length * 2) + 1]; 314 char *hash;
312 const char *algo_name = hash_algo_name[iint->ima_hash->algo]; 315 const char *algo_name = hash_algo_name[iint->ima_hash->algo];
313 char algo_hash[sizeof(hash) + strlen(algo_name) + 2];
314 int i; 316 int i;
315 317
316 if (iint->flags & IMA_AUDITED) 318 if (iint->flags & IMA_AUDITED)
317 return; 319 return;
318 320
321 hash = kzalloc((iint->ima_hash->length * 2) + 1, GFP_KERNEL);
322 if (!hash)
323 return;
324
319 for (i = 0; i < iint->ima_hash->length; i++) 325 for (i = 0; i < iint->ima_hash->length; i++)
320 hex_byte_pack(hash + (i * 2), iint->ima_hash->digest[i]); 326 hex_byte_pack(hash + (i * 2), iint->ima_hash->digest[i]);
321 hash[i * 2] = '\0'; 327 hash[i * 2] = '\0';
@@ -323,18 +329,19 @@ void ima_audit_measurement(struct integrity_iint_cache *iint,
323 ab = audit_log_start(current->audit_context, GFP_KERNEL, 329 ab = audit_log_start(current->audit_context, GFP_KERNEL,
324 AUDIT_INTEGRITY_RULE); 330 AUDIT_INTEGRITY_RULE);
325 if (!ab) 331 if (!ab)
326 return; 332 goto out;
327 333
328 audit_log_format(ab, "file="); 334 audit_log_format(ab, "file=");
329 audit_log_untrustedstring(ab, filename); 335 audit_log_untrustedstring(ab, filename);
330 audit_log_format(ab, " hash="); 336 audit_log_format(ab, " hash=\"%s:%s\"", algo_name, hash);
331 snprintf(algo_hash, sizeof(algo_hash), "%s:%s", algo_name, hash);
332 audit_log_untrustedstring(ab, algo_hash);
333 337
334 audit_log_task_info(ab, current); 338 audit_log_task_info(ab, current);
335 audit_log_end(ab); 339 audit_log_end(ab);
336 340
337 iint->flags |= IMA_AUDITED; 341 iint->flags |= IMA_AUDITED;
342out:
343 kfree(hash);
344 return;
338} 345}
339 346
340/* 347/*
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index f2803a40ff82..8bd7a0733e51 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -50,11 +50,14 @@ bool is_ima_appraise_enabled(void)
50 */ 50 */
51int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func) 51int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func)
52{ 52{
53 u32 secid;
54
53 if (!ima_appraise) 55 if (!ima_appraise)
54 return 0; 56 return 0;
55 57
56 return ima_match_policy(inode, func, mask, IMA_APPRAISE | IMA_HASH, 58 security_task_getsecid(current, &secid);
57 NULL); 59 return ima_match_policy(inode, current_cred(), secid, func, mask,
60 IMA_APPRAISE | IMA_HASH, NULL);
58} 61}
59 62
60static int ima_fix_xattr(struct dentry *dentry, 63static int ima_fix_xattr(struct dentry *dentry,
@@ -87,6 +90,8 @@ enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
87 return iint->ima_mmap_status; 90 return iint->ima_mmap_status;
88 case BPRM_CHECK: 91 case BPRM_CHECK:
89 return iint->ima_bprm_status; 92 return iint->ima_bprm_status;
93 case CREDS_CHECK:
94 return iint->ima_creds_status;
90 case FILE_CHECK: 95 case FILE_CHECK:
91 case POST_SETATTR: 96 case POST_SETATTR:
92 return iint->ima_file_status; 97 return iint->ima_file_status;
@@ -107,6 +112,8 @@ static void ima_set_cache_status(struct integrity_iint_cache *iint,
107 case BPRM_CHECK: 112 case BPRM_CHECK:
108 iint->ima_bprm_status = status; 113 iint->ima_bprm_status = status;
109 break; 114 break;
115 case CREDS_CHECK:
116 iint->ima_creds_status = status;
110 case FILE_CHECK: 117 case FILE_CHECK:
111 case POST_SETATTR: 118 case POST_SETATTR:
112 iint->ima_file_status = status; 119 iint->ima_file_status = status;
@@ -128,6 +135,9 @@ static void ima_cache_flags(struct integrity_iint_cache *iint,
128 case BPRM_CHECK: 135 case BPRM_CHECK:
129 iint->flags |= (IMA_BPRM_APPRAISED | IMA_APPRAISED); 136 iint->flags |= (IMA_BPRM_APPRAISED | IMA_APPRAISED);
130 break; 137 break;
138 case CREDS_CHECK:
139 iint->flags |= (IMA_CREDS_APPRAISED | IMA_APPRAISED);
140 break;
131 case FILE_CHECK: 141 case FILE_CHECK:
132 case POST_SETATTR: 142 case POST_SETATTR:
133 iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED); 143 iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED);
@@ -205,7 +215,7 @@ int ima_appraise_measurement(enum ima_hooks func,
205 int xattr_len, int opened) 215 int xattr_len, int opened)
206{ 216{
207 static const char op[] = "appraise_data"; 217 static const char op[] = "appraise_data";
208 char *cause = "unknown"; 218 const char *cause = "unknown";
209 struct dentry *dentry = file_dentry(file); 219 struct dentry *dentry = file_dentry(file);
210 struct inode *inode = d_backing_inode(dentry); 220 struct inode *inode = d_backing_inode(dentry);
211 enum integrity_status status = INTEGRITY_UNKNOWN; 221 enum integrity_status status = INTEGRITY_UNKNOWN;
@@ -231,16 +241,22 @@ int ima_appraise_measurement(enum ima_hooks func,
231 } 241 }
232 242
233 status = evm_verifyxattr(dentry, XATTR_NAME_IMA, xattr_value, rc, iint); 243 status = evm_verifyxattr(dentry, XATTR_NAME_IMA, xattr_value, rc, iint);
234 if ((status != INTEGRITY_PASS) && 244 switch (status) {
235 (status != INTEGRITY_PASS_IMMUTABLE) && 245 case INTEGRITY_PASS:
236 (status != INTEGRITY_UNKNOWN)) { 246 case INTEGRITY_PASS_IMMUTABLE:
237 if ((status == INTEGRITY_NOLABEL) 247 case INTEGRITY_UNKNOWN:
238 || (status == INTEGRITY_NOXATTRS)) 248 break;
239 cause = "missing-HMAC"; 249 case INTEGRITY_NOXATTRS: /* No EVM protected xattrs. */
240 else if (status == INTEGRITY_FAIL) 250 case INTEGRITY_NOLABEL: /* No security.evm xattr. */
241 cause = "invalid-HMAC"; 251 cause = "missing-HMAC";
242 goto out; 252 goto out;
253 case INTEGRITY_FAIL: /* Invalid HMAC/signature. */
254 cause = "invalid-HMAC";
255 goto out;
256 default:
257 WARN_ONCE(true, "Unexpected integrity status %d\n", status);
243 } 258 }
259
244 switch (xattr_value->type) { 260 switch (xattr_value->type) {
245 case IMA_XATTR_DIGEST_NG: 261 case IMA_XATTR_DIGEST_NG:
246 /* first byte contains algorithm id */ 262 /* first byte contains algorithm id */
@@ -292,23 +308,40 @@ int ima_appraise_measurement(enum ima_hooks func,
292 } 308 }
293 309
294out: 310out:
295 if (status != INTEGRITY_PASS) { 311 /*
312 * File signatures on some filesystems can not be properly verified.
313 * When such filesystems are mounted by an untrusted mounter or on a
314 * system not willing to accept such a risk, fail the file signature
315 * verification.
316 */
317 if ((inode->i_sb->s_iflags & SB_I_IMA_UNVERIFIABLE_SIGNATURE) &&
318 ((inode->i_sb->s_iflags & SB_I_UNTRUSTED_MOUNTER) ||
319 (iint->flags & IMA_FAIL_UNVERIFIABLE_SIGS))) {
320 status = INTEGRITY_FAIL;
321 cause = "unverifiable-signature";
322 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename,
323 op, cause, rc, 0);
324 } else if (status != INTEGRITY_PASS) {
325 /* Fix mode, but don't replace file signatures. */
296 if ((ima_appraise & IMA_APPRAISE_FIX) && 326 if ((ima_appraise & IMA_APPRAISE_FIX) &&
297 (!xattr_value || 327 (!xattr_value ||
298 xattr_value->type != EVM_IMA_XATTR_DIGSIG)) { 328 xattr_value->type != EVM_IMA_XATTR_DIGSIG)) {
299 if (!ima_fix_xattr(dentry, iint)) 329 if (!ima_fix_xattr(dentry, iint))
300 status = INTEGRITY_PASS; 330 status = INTEGRITY_PASS;
301 } else if ((inode->i_size == 0) && 331 }
302 (iint->flags & IMA_NEW_FILE) && 332
303 (xattr_value && 333 /* Permit new files with file signatures, but without data. */
304 xattr_value->type == EVM_IMA_XATTR_DIGSIG)) { 334 if (inode->i_size == 0 && iint->flags & IMA_NEW_FILE &&
335 xattr_value && xattr_value->type == EVM_IMA_XATTR_DIGSIG) {
305 status = INTEGRITY_PASS; 336 status = INTEGRITY_PASS;
306 } 337 }
338
307 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename, 339 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename,
308 op, cause, rc, 0); 340 op, cause, rc, 0);
309 } else { 341 } else {
310 ima_cache_flags(iint, func); 342 ima_cache_flags(iint, func);
311 } 343 }
344
312 ima_set_cache_status(iint, func, status); 345 ima_set_cache_status(iint, func, status);
313 return status; 346 return status;
314} 347}
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index 205bc69361ea..4e085a17124f 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -73,6 +73,8 @@ int __init ima_init_crypto(void)
73 hash_algo_name[ima_hash_algo], rc); 73 hash_algo_name[ima_hash_algo], rc);
74 return rc; 74 return rc;
75 } 75 }
76 pr_info("Allocated hash algorithm: %s\n",
77 hash_algo_name[ima_hash_algo]);
76 return 0; 78 return 0;
77} 79}
78 80
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 2cfb0c714967..74d0bd7e76d7 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -16,6 +16,9 @@
16 * implements the IMA hooks: ima_bprm_check, ima_file_mmap, 16 * implements the IMA hooks: ima_bprm_check, ima_file_mmap,
17 * and ima_file_check. 17 * and ima_file_check.
18 */ 18 */
19
20#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21
19#include <linux/module.h> 22#include <linux/module.h>
20#include <linux/file.h> 23#include <linux/file.h>
21#include <linux/binfmts.h> 24#include <linux/binfmts.h>
@@ -25,6 +28,7 @@
25#include <linux/xattr.h> 28#include <linux/xattr.h>
26#include <linux/ima.h> 29#include <linux/ima.h>
27#include <linux/iversion.h> 30#include <linux/iversion.h>
31#include <linux/fs.h>
28 32
29#include "ima.h" 33#include "ima.h"
30 34
@@ -167,8 +171,9 @@ void ima_file_free(struct file *file)
167 ima_check_last_writer(iint, inode, file); 171 ima_check_last_writer(iint, inode, file);
168} 172}
169 173
170static int process_measurement(struct file *file, char *buf, loff_t size, 174static int process_measurement(struct file *file, const struct cred *cred,
171 int mask, enum ima_hooks func, int opened) 175 u32 secid, char *buf, loff_t size, int mask,
176 enum ima_hooks func, int opened)
172{ 177{
173 struct inode *inode = file_inode(file); 178 struct inode *inode = file_inode(file);
174 struct integrity_iint_cache *iint = NULL; 179 struct integrity_iint_cache *iint = NULL;
@@ -190,7 +195,7 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
190 * bitmask based on the appraise/audit/measurement policy. 195 * bitmask based on the appraise/audit/measurement policy.
191 * Included is the appraise submask. 196 * Included is the appraise submask.
192 */ 197 */
193 action = ima_get_action(inode, mask, func, &pcr); 198 action = ima_get_action(inode, cred, secid, mask, func, &pcr);
194 violation_check = ((func == FILE_CHECK || func == MMAP_CHECK) && 199 violation_check = ((func == FILE_CHECK || func == MMAP_CHECK) &&
195 (ima_policy_flag & IMA_MEASURE)); 200 (ima_policy_flag & IMA_MEASURE));
196 if (!action && !violation_check) 201 if (!action && !violation_check)
@@ -229,9 +234,18 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
229 IMA_APPRAISE_SUBMASK | IMA_APPRAISED_SUBMASK | 234 IMA_APPRAISE_SUBMASK | IMA_APPRAISED_SUBMASK |
230 IMA_ACTION_FLAGS); 235 IMA_ACTION_FLAGS);
231 236
232 if (test_and_clear_bit(IMA_CHANGE_XATTR, &iint->atomic_flags)) 237 /*
233 /* reset all flags if ima_inode_setxattr was called */ 238 * Re-evaulate the file if either the xattr has changed or the
239 * kernel has no way of detecting file change on the filesystem.
240 * (Limited to privileged mounted filesystems.)
241 */
242 if (test_and_clear_bit(IMA_CHANGE_XATTR, &iint->atomic_flags) ||
243 ((inode->i_sb->s_iflags & SB_I_IMA_UNVERIFIABLE_SIGNATURE) &&
244 !(inode->i_sb->s_iflags & SB_I_UNTRUSTED_MOUNTER) &&
245 !(action & IMA_FAIL_UNVERIFIABLE_SIGS))) {
234 iint->flags &= ~IMA_DONE_MASK; 246 iint->flags &= ~IMA_DONE_MASK;
247 iint->measured_pcrs = 0;
248 }
235 249
236 /* Determine if already appraised/measured based on bitmask 250 /* Determine if already appraised/measured based on bitmask
237 * (IMA_MEASURE, IMA_MEASURED, IMA_XXXX_APPRAISE, IMA_XXXX_APPRAISED, 251 * (IMA_MEASURE, IMA_MEASURED, IMA_XXXX_APPRAISE, IMA_XXXX_APPRAISED,
@@ -324,9 +338,14 @@ out:
324 */ 338 */
325int ima_file_mmap(struct file *file, unsigned long prot) 339int ima_file_mmap(struct file *file, unsigned long prot)
326{ 340{
327 if (file && (prot & PROT_EXEC)) 341 u32 secid;
328 return process_measurement(file, NULL, 0, MAY_EXEC, 342
329 MMAP_CHECK, 0); 343 if (file && (prot & PROT_EXEC)) {
344 security_task_getsecid(current, &secid);
345 return process_measurement(file, current_cred(), secid, NULL,
346 0, MAY_EXEC, MMAP_CHECK, 0);
347 }
348
330 return 0; 349 return 0;
331} 350}
332 351
@@ -345,8 +364,18 @@ int ima_file_mmap(struct file *file, unsigned long prot)
345 */ 364 */
346int ima_bprm_check(struct linux_binprm *bprm) 365int ima_bprm_check(struct linux_binprm *bprm)
347{ 366{
348 return process_measurement(bprm->file, NULL, 0, MAY_EXEC, 367 int ret;
349 BPRM_CHECK, 0); 368 u32 secid;
369
370 security_task_getsecid(current, &secid);
371 ret = process_measurement(bprm->file, current_cred(), secid, NULL, 0,
372 MAY_EXEC, BPRM_CHECK, 0);
373 if (ret)
374 return ret;
375
376 security_cred_getsecid(bprm->cred, &secid);
377 return process_measurement(bprm->file, bprm->cred, secid, NULL, 0,
378 MAY_EXEC, CREDS_CHECK, 0);
350} 379}
351 380
352/** 381/**
@@ -361,7 +390,10 @@ int ima_bprm_check(struct linux_binprm *bprm)
361 */ 390 */
362int ima_file_check(struct file *file, int mask, int opened) 391int ima_file_check(struct file *file, int mask, int opened)
363{ 392{
364 return process_measurement(file, NULL, 0, 393 u32 secid;
394
395 security_task_getsecid(current, &secid);
396 return process_measurement(file, current_cred(), secid, NULL, 0,
365 mask & (MAY_READ | MAY_WRITE | MAY_EXEC | 397 mask & (MAY_READ | MAY_WRITE | MAY_EXEC |
366 MAY_APPEND), FILE_CHECK, opened); 398 MAY_APPEND), FILE_CHECK, opened);
367} 399}
@@ -440,6 +472,7 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
440 enum kernel_read_file_id read_id) 472 enum kernel_read_file_id read_id)
441{ 473{
442 enum ima_hooks func; 474 enum ima_hooks func;
475 u32 secid;
443 476
444 if (!file && read_id == READING_FIRMWARE) { 477 if (!file && read_id == READING_FIRMWARE) {
445 if ((ima_appraise & IMA_APPRAISE_FIRMWARE) && 478 if ((ima_appraise & IMA_APPRAISE_FIRMWARE) &&
@@ -462,7 +495,9 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
462 } 495 }
463 496
464 func = read_idmap[read_id] ?: FILE_CHECK; 497 func = read_idmap[read_id] ?: FILE_CHECK;
465 return process_measurement(file, buf, size, MAY_READ, func, 0); 498 security_task_getsecid(current, &secid);
499 return process_measurement(file, current_cred(), secid, buf, size,
500 MAY_READ, func, 0);
466} 501}
467 502
468static int __init init_ima(void) 503static int __init init_ima(void)
@@ -472,6 +507,16 @@ static int __init init_ima(void)
472 ima_init_template_list(); 507 ima_init_template_list();
473 hash_setup(CONFIG_IMA_DEFAULT_HASH); 508 hash_setup(CONFIG_IMA_DEFAULT_HASH);
474 error = ima_init(); 509 error = ima_init();
510
511 if (error && strcmp(hash_algo_name[ima_hash_algo],
512 CONFIG_IMA_DEFAULT_HASH) != 0) {
513 pr_info("Allocating %s failed, going to use default hash algorithm %s\n",
514 hash_algo_name[ima_hash_algo], CONFIG_IMA_DEFAULT_HASH);
515 hash_setup_done = 0;
516 hash_setup(CONFIG_IMA_DEFAULT_HASH);
517 error = ima_init();
518 }
519
475 if (!error) { 520 if (!error) {
476 ima_initialized = 1; 521 ima_initialized = 1;
477 ima_update_policy_flag(); 522 ima_update_policy_flag();
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 915f5572c6ff..d89bebf85421 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -96,6 +96,7 @@ static struct ima_rule_entry dont_measure_rules[] __ro_after_init = {
96 {.action = DONT_MEASURE, .fsmagic = BINFMTFS_MAGIC, .flags = IMA_FSMAGIC}, 96 {.action = DONT_MEASURE, .fsmagic = BINFMTFS_MAGIC, .flags = IMA_FSMAGIC},
97 {.action = DONT_MEASURE, .fsmagic = SECURITYFS_MAGIC, .flags = IMA_FSMAGIC}, 97 {.action = DONT_MEASURE, .fsmagic = SECURITYFS_MAGIC, .flags = IMA_FSMAGIC},
98 {.action = DONT_MEASURE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC}, 98 {.action = DONT_MEASURE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC},
99 {.action = DONT_MEASURE, .fsmagic = SMACK_MAGIC, .flags = IMA_FSMAGIC},
99 {.action = DONT_MEASURE, .fsmagic = CGROUP_SUPER_MAGIC, 100 {.action = DONT_MEASURE, .fsmagic = CGROUP_SUPER_MAGIC,
100 .flags = IMA_FSMAGIC}, 101 .flags = IMA_FSMAGIC},
101 {.action = DONT_MEASURE, .fsmagic = CGROUP2_SUPER_MAGIC, 102 {.action = DONT_MEASURE, .fsmagic = CGROUP2_SUPER_MAGIC,
@@ -141,6 +142,7 @@ static struct ima_rule_entry default_appraise_rules[] __ro_after_init = {
141 {.action = DONT_APPRAISE, .fsmagic = BINFMTFS_MAGIC, .flags = IMA_FSMAGIC}, 142 {.action = DONT_APPRAISE, .fsmagic = BINFMTFS_MAGIC, .flags = IMA_FSMAGIC},
142 {.action = DONT_APPRAISE, .fsmagic = SECURITYFS_MAGIC, .flags = IMA_FSMAGIC}, 143 {.action = DONT_APPRAISE, .fsmagic = SECURITYFS_MAGIC, .flags = IMA_FSMAGIC},
143 {.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC}, 144 {.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC},
145 {.action = DONT_APPRAISE, .fsmagic = SMACK_MAGIC, .flags = IMA_FSMAGIC},
144 {.action = DONT_APPRAISE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC}, 146 {.action = DONT_APPRAISE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC},
145 {.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC}, 147 {.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC},
146 {.action = DONT_APPRAISE, .fsmagic = CGROUP2_SUPER_MAGIC, .flags = IMA_FSMAGIC}, 148 {.action = DONT_APPRAISE, .fsmagic = CGROUP2_SUPER_MAGIC, .flags = IMA_FSMAGIC},
@@ -188,6 +190,7 @@ __setup("ima_tcb", default_measure_policy_setup);
188 190
189static bool ima_use_appraise_tcb __initdata; 191static bool ima_use_appraise_tcb __initdata;
190static bool ima_use_secure_boot __initdata; 192static bool ima_use_secure_boot __initdata;
193static bool ima_fail_unverifiable_sigs __ro_after_init;
191static int __init policy_setup(char *str) 194static int __init policy_setup(char *str)
192{ 195{
193 char *p; 196 char *p;
@@ -201,6 +204,8 @@ static int __init policy_setup(char *str)
201 ima_use_appraise_tcb = true; 204 ima_use_appraise_tcb = true;
202 else if (strcmp(p, "secure_boot") == 0) 205 else if (strcmp(p, "secure_boot") == 0)
203 ima_use_secure_boot = true; 206 ima_use_secure_boot = true;
207 else if (strcmp(p, "fail_securely") == 0)
208 ima_fail_unverifiable_sigs = true;
204 } 209 }
205 210
206 return 1; 211 return 1;
@@ -243,16 +248,17 @@ static void ima_lsm_update_rules(void)
243 * ima_match_rules - determine whether an inode matches the measure rule. 248 * ima_match_rules - determine whether an inode matches the measure rule.
244 * @rule: a pointer to a rule 249 * @rule: a pointer to a rule
245 * @inode: a pointer to an inode 250 * @inode: a pointer to an inode
251 * @cred: a pointer to a credentials structure for user validation
252 * @secid: the secid of the task to be validated
246 * @func: LIM hook identifier 253 * @func: LIM hook identifier
247 * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC) 254 * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
248 * 255 *
249 * Returns true on rule match, false on failure. 256 * Returns true on rule match, false on failure.
250 */ 257 */
251static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, 258static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
259 const struct cred *cred, u32 secid,
252 enum ima_hooks func, int mask) 260 enum ima_hooks func, int mask)
253{ 261{
254 struct task_struct *tsk = current;
255 const struct cred *cred = current_cred();
256 int i; 262 int i;
257 263
258 if ((rule->flags & IMA_FUNC) && 264 if ((rule->flags & IMA_FUNC) &&
@@ -287,7 +293,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
287 return false; 293 return false;
288 for (i = 0; i < MAX_LSM_RULES; i++) { 294 for (i = 0; i < MAX_LSM_RULES; i++) {
289 int rc = 0; 295 int rc = 0;
290 u32 osid, sid; 296 u32 osid;
291 int retried = 0; 297 int retried = 0;
292 298
293 if (!rule->lsm[i].rule) 299 if (!rule->lsm[i].rule)
@@ -307,8 +313,7 @@ retry:
307 case LSM_SUBJ_USER: 313 case LSM_SUBJ_USER:
308 case LSM_SUBJ_ROLE: 314 case LSM_SUBJ_ROLE:
309 case LSM_SUBJ_TYPE: 315 case LSM_SUBJ_TYPE:
310 security_task_getsecid(tsk, &sid); 316 rc = security_filter_rule_match(secid,
311 rc = security_filter_rule_match(sid,
312 rule->lsm[i].type, 317 rule->lsm[i].type,
313 Audit_equal, 318 Audit_equal,
314 rule->lsm[i].rule, 319 rule->lsm[i].rule,
@@ -341,6 +346,8 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
341 return IMA_MMAP_APPRAISE; 346 return IMA_MMAP_APPRAISE;
342 case BPRM_CHECK: 347 case BPRM_CHECK:
343 return IMA_BPRM_APPRAISE; 348 return IMA_BPRM_APPRAISE;
349 case CREDS_CHECK:
350 return IMA_CREDS_APPRAISE;
344 case FILE_CHECK: 351 case FILE_CHECK:
345 case POST_SETATTR: 352 case POST_SETATTR:
346 return IMA_FILE_APPRAISE; 353 return IMA_FILE_APPRAISE;
@@ -353,6 +360,9 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
353/** 360/**
354 * ima_match_policy - decision based on LSM and other conditions 361 * ima_match_policy - decision based on LSM and other conditions
355 * @inode: pointer to an inode for which the policy decision is being made 362 * @inode: pointer to an inode for which the policy decision is being made
363 * @cred: pointer to a credentials structure for which the policy decision is
364 * being made
365 * @secid: LSM secid of the task to be validated
356 * @func: IMA hook identifier 366 * @func: IMA hook identifier
357 * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC) 367 * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
358 * @pcr: set the pcr to extend 368 * @pcr: set the pcr to extend
@@ -364,8 +374,8 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func)
364 * list when walking it. Reads are many orders of magnitude more numerous 374 * list when walking it. Reads are many orders of magnitude more numerous
365 * than writes so ima_match_policy() is classical RCU candidate. 375 * than writes so ima_match_policy() is classical RCU candidate.
366 */ 376 */
367int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, 377int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid,
368 int flags, int *pcr) 378 enum ima_hooks func, int mask, int flags, int *pcr)
369{ 379{
370 struct ima_rule_entry *entry; 380 struct ima_rule_entry *entry;
371 int action = 0, actmask = flags | (flags << 1); 381 int action = 0, actmask = flags | (flags << 1);
@@ -376,7 +386,7 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
376 if (!(entry->action & actmask)) 386 if (!(entry->action & actmask))
377 continue; 387 continue;
378 388
379 if (!ima_match_rules(entry, inode, func, mask)) 389 if (!ima_match_rules(entry, inode, cred, secid, func, mask))
380 continue; 390 continue;
381 391
382 action |= entry->flags & IMA_ACTION_FLAGS; 392 action |= entry->flags & IMA_ACTION_FLAGS;
@@ -384,7 +394,9 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
384 action |= entry->action & IMA_DO_MASK; 394 action |= entry->action & IMA_DO_MASK;
385 if (entry->action & IMA_APPRAISE) { 395 if (entry->action & IMA_APPRAISE) {
386 action |= get_subaction(entry, func); 396 action |= get_subaction(entry, func);
387 action ^= IMA_HASH; 397 action &= ~IMA_HASH;
398 if (ima_fail_unverifiable_sigs)
399 action |= IMA_FAIL_UNVERIFIABLE_SIGS;
388 } 400 }
389 401
390 if (entry->action & IMA_DO_MASK) 402 if (entry->action & IMA_DO_MASK)
@@ -713,6 +725,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
713 entry->func = MMAP_CHECK; 725 entry->func = MMAP_CHECK;
714 else if (strcmp(args[0].from, "BPRM_CHECK") == 0) 726 else if (strcmp(args[0].from, "BPRM_CHECK") == 0)
715 entry->func = BPRM_CHECK; 727 entry->func = BPRM_CHECK;
728 else if (strcmp(args[0].from, "CREDS_CHECK") == 0)
729 entry->func = CREDS_CHECK;
716 else if (strcmp(args[0].from, "KEXEC_KERNEL_CHECK") == 730 else if (strcmp(args[0].from, "KEXEC_KERNEL_CHECK") ==
717 0) 731 0)
718 entry->func = KEXEC_KERNEL_CHECK; 732 entry->func = KEXEC_KERNEL_CHECK;
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c
index 28af43f63572..5afaa53decc5 100644
--- a/security/integrity/ima/ima_template_lib.c
+++ b/security/integrity/ima/ima_template_lib.c
@@ -378,16 +378,11 @@ int ima_eventname_ng_init(struct ima_event_data *event_data,
378int ima_eventsig_init(struct ima_event_data *event_data, 378int ima_eventsig_init(struct ima_event_data *event_data,
379 struct ima_field_data *field_data) 379 struct ima_field_data *field_data)
380{ 380{
381 enum data_formats fmt = DATA_FMT_HEX;
382 struct evm_ima_xattr_data *xattr_value = event_data->xattr_value; 381 struct evm_ima_xattr_data *xattr_value = event_data->xattr_value;
383 int xattr_len = event_data->xattr_len;
384 int rc = 0;
385 382
386 if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG)) 383 if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG))
387 goto out; 384 return 0;
388 385
389 rc = ima_write_template_field_data(xattr_value, xattr_len, fmt, 386 return ima_write_template_field_data(xattr_value, event_data->xattr_len,
390 field_data); 387 DATA_FMT_HEX, field_data);
391out:
392 return rc;
393} 388}
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 50a8e3365df7..5e58e02ba8dc 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -30,11 +30,11 @@
30 30
31/* iint cache flags */ 31/* iint cache flags */
32#define IMA_ACTION_FLAGS 0xff000000 32#define IMA_ACTION_FLAGS 0xff000000
33#define IMA_ACTION_RULE_FLAGS 0x06000000
34#define IMA_DIGSIG_REQUIRED 0x01000000 33#define IMA_DIGSIG_REQUIRED 0x01000000
35#define IMA_PERMIT_DIRECTIO 0x02000000 34#define IMA_PERMIT_DIRECTIO 0x02000000
36#define IMA_NEW_FILE 0x04000000 35#define IMA_NEW_FILE 0x04000000
37#define EVM_IMMUTABLE_DIGSIG 0x08000000 36#define EVM_IMMUTABLE_DIGSIG 0x08000000
37#define IMA_FAIL_UNVERIFIABLE_SIGS 0x10000000
38 38
39#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \ 39#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
40 IMA_HASH | IMA_APPRAISE_SUBMASK) 40 IMA_HASH | IMA_APPRAISE_SUBMASK)
@@ -51,10 +51,14 @@
51#define IMA_BPRM_APPRAISED 0x00020000 51#define IMA_BPRM_APPRAISED 0x00020000
52#define IMA_READ_APPRAISE 0x00040000 52#define IMA_READ_APPRAISE 0x00040000
53#define IMA_READ_APPRAISED 0x00080000 53#define IMA_READ_APPRAISED 0x00080000
54#define IMA_CREDS_APPRAISE 0x00100000
55#define IMA_CREDS_APPRAISED 0x00200000
54#define IMA_APPRAISE_SUBMASK (IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \ 56#define IMA_APPRAISE_SUBMASK (IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \
55 IMA_BPRM_APPRAISE | IMA_READ_APPRAISE) 57 IMA_BPRM_APPRAISE | IMA_READ_APPRAISE | \
58 IMA_CREDS_APPRAISE)
56#define IMA_APPRAISED_SUBMASK (IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \ 59#define IMA_APPRAISED_SUBMASK (IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \
57 IMA_BPRM_APPRAISED | IMA_READ_APPRAISED) 60 IMA_BPRM_APPRAISED | IMA_READ_APPRAISED | \
61 IMA_CREDS_APPRAISED)
58 62
59/* iint cache atomic_flags */ 63/* iint cache atomic_flags */
60#define IMA_CHANGE_XATTR 0 64#define IMA_CHANGE_XATTR 0
@@ -121,6 +125,7 @@ struct integrity_iint_cache {
121 enum integrity_status ima_mmap_status:4; 125 enum integrity_status ima_mmap_status:4;
122 enum integrity_status ima_bprm_status:4; 126 enum integrity_status ima_bprm_status:4;
123 enum integrity_status ima_read_status:4; 127 enum integrity_status ima_read_status:4;
128 enum integrity_status ima_creds_status:4;
124 enum integrity_status evm_status:4; 129 enum integrity_status evm_status:4;
125 struct ima_digest_data *ima_hash; 130 struct ima_digest_data *ima_hash;
126}; 131};
diff --git a/security/security.c b/security/security.c
index 7301902a8721..d2a84cda7e8d 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1005,6 +1005,13 @@ void security_transfer_creds(struct cred *new, const struct cred *old)
1005 call_void_hook(cred_transfer, new, old); 1005 call_void_hook(cred_transfer, new, old);
1006} 1006}
1007 1007
1008void security_cred_getsecid(const struct cred *c, u32 *secid)
1009{
1010 *secid = 0;
1011 call_void_hook(cred_getsecid, c, secid);
1012}
1013EXPORT_SYMBOL(security_cred_getsecid);
1014
1008int security_kernel_act_as(struct cred *new, u32 secid) 1015int security_kernel_act_as(struct cred *new, u32 secid)
1009{ 1016{
1010 return call_int_hook(kernel_act_as, 0, new, secid); 1017 return call_int_hook(kernel_act_as, 0, new, secid);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 2b8c55e181ae..1eeb70e439d7 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3947,6 +3947,11 @@ static void selinux_cred_transfer(struct cred *new, const struct cred *old)
3947 *tsec = *old_tsec; 3947 *tsec = *old_tsec;
3948} 3948}
3949 3949
3950static void selinux_cred_getsecid(const struct cred *c, u32 *secid)
3951{
3952 *secid = cred_sid(c);
3953}
3954
3950/* 3955/*
3951 * set the security data for a kernel service 3956 * set the security data for a kernel service
3952 * - all the creation contexts are set to unlabelled 3957 * - all the creation contexts are set to unlabelled
@@ -6926,6 +6931,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
6926 LSM_HOOK_INIT(cred_free, selinux_cred_free), 6931 LSM_HOOK_INIT(cred_free, selinux_cred_free),
6927 LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare), 6932 LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare),
6928 LSM_HOOK_INIT(cred_transfer, selinux_cred_transfer), 6933 LSM_HOOK_INIT(cred_transfer, selinux_cred_transfer),
6934 LSM_HOOK_INIT(cred_getsecid, selinux_cred_getsecid),
6929 LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as), 6935 LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as),
6930 LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as), 6936 LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as),
6931 LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request), 6937 LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request),
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 34e1e649f175..73549007bf9e 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -2050,6 +2050,23 @@ static void smack_cred_transfer(struct cred *new, const struct cred *old)
2050} 2050}
2051 2051
2052/** 2052/**
2053 * smack_cred_getsecid - get the secid corresponding to a creds structure
2054 * @c: the object creds
2055 * @secid: where to put the result
2056 *
2057 * Sets the secid to contain a u32 version of the smack label.
2058 */
2059static void smack_cred_getsecid(const struct cred *c, u32 *secid)
2060{
2061 struct smack_known *skp;
2062
2063 rcu_read_lock();
2064 skp = smk_of_task(c->security);
2065 *secid = skp->smk_secid;
2066 rcu_read_unlock();
2067}
2068
2069/**
2053 * smack_kernel_act_as - Set the subjective context in a set of credentials 2070 * smack_kernel_act_as - Set the subjective context in a set of credentials
2054 * @new: points to the set of credentials to be modified. 2071 * @new: points to the set of credentials to be modified.
2055 * @secid: specifies the security ID to be set 2072 * @secid: specifies the security ID to be set
@@ -4654,6 +4671,7 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
4654 LSM_HOOK_INIT(cred_free, smack_cred_free), 4671 LSM_HOOK_INIT(cred_free, smack_cred_free),
4655 LSM_HOOK_INIT(cred_prepare, smack_cred_prepare), 4672 LSM_HOOK_INIT(cred_prepare, smack_cred_prepare),
4656 LSM_HOOK_INIT(cred_transfer, smack_cred_transfer), 4673 LSM_HOOK_INIT(cred_transfer, smack_cred_transfer),
4674 LSM_HOOK_INIT(cred_getsecid, smack_cred_getsecid),
4657 LSM_HOOK_INIT(kernel_act_as, smack_kernel_act_as), 4675 LSM_HOOK_INIT(kernel_act_as, smack_kernel_act_as),
4658 LSM_HOOK_INIT(kernel_create_files_as, smack_kernel_create_files_as), 4676 LSM_HOOK_INIT(kernel_create_files_as, smack_kernel_create_files_as),
4659 LSM_HOOK_INIT(task_setpgid, smack_task_setpgid), 4677 LSM_HOOK_INIT(task_setpgid, smack_task_setpgid),