diff options
Diffstat (limited to 'security/integrity')
-rw-r--r-- | security/integrity/Kconfig | 1 | ||||
-rw-r--r-- | security/integrity/digsig.c | 15 | ||||
-rw-r--r-- | security/integrity/evm/evm_main.c | 6 | ||||
-rw-r--r-- | security/integrity/ima/Kconfig | 36 | ||||
-rw-r--r-- | security/integrity/ima/Makefile | 2 | ||||
-rw-r--r-- | security/integrity/ima/ima.h | 2 | ||||
-rw-r--r-- | security/integrity/ima/ima_api.c | 2 | ||||
-rw-r--r-- | security/integrity/ima/ima_appraise.c | 7 | ||||
-rw-r--r-- | security/integrity/ima/ima_main.c | 25 | ||||
-rw-r--r-- | security/integrity/ima/ima_mok.c | 23 | ||||
-rw-r--r-- | security/integrity/ima/ima_policy.c | 14 | ||||
-rw-r--r-- | security/integrity/integrity.h | 1 |
12 files changed, 80 insertions, 54 deletions
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig index 979be65d2..da9565891 100644 --- a/security/integrity/Kconfig +++ b/security/integrity/Kconfig @@ -35,7 +35,6 @@ config INTEGRITY_ASYMMETRIC_KEYS default n select ASYMMETRIC_KEY_TYPE select ASYMMETRIC_PUBLIC_KEY_SUBTYPE - select PUBLIC_KEY_ALGO_RSA select CRYPTO_RSA select X509_CERTIFICATE_PARSER help diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 8ef15118c..4304372b3 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -18,6 +18,8 @@ #include <linux/cred.h> #include <linux/key-type.h> #include <linux/digsig.h> +#include <crypto/public_key.h> +#include <keys/system_keyring.h> #include "integrity.h" @@ -40,6 +42,12 @@ static bool init_keyring __initdata = true; static bool init_keyring __initdata; #endif +#ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY +#define restrict_link_to_ima restrict_link_by_builtin_and_secondary_trusted +#else +#define restrict_link_to_ima restrict_link_by_builtin_trusted +#endif + int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, const char *digest, int digestlen) { @@ -83,10 +91,9 @@ int __init integrity_init_keyring(const unsigned int id) ((KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_WRITE | KEY_USR_SEARCH), - KEY_ALLOC_NOT_IN_QUOTA, NULL); - if (!IS_ERR(keyring[id])) - set_bit(KEY_FLAG_TRUSTED_ONLY, &keyring[id]->flags); - else { + KEY_ALLOC_NOT_IN_QUOTA, + restrict_link_to_ima, NULL); + if (IS_ERR(keyring[id])) { err = PTR_ERR(keyring[id]); pr_info("Can't allocate %s keyring (%d)\n", keyring_name[id], err); diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index e6ea9d4b1..b9e26288d 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c @@ -82,7 +82,7 @@ static int evm_find_protected_xattrs(struct dentry *dentry) return -EOPNOTSUPP; for (xattr = evm_config_xattrnames; *xattr != NULL; xattr++) { - error = inode->i_op->getxattr(dentry, *xattr, NULL, 0); + error = inode->i_op->getxattr(dentry, inode, *xattr, NULL, 0); if (error < 0) { if (error == -ENODATA) continue; @@ -299,8 +299,8 @@ static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name, return 0; /* exception for pseudo filesystems */ - if (dentry->d_inode->i_sb->s_magic == TMPFS_MAGIC - || dentry->d_inode->i_sb->s_magic == SYSFS_MAGIC) + if (dentry->d_sb->s_magic == TMPFS_MAGIC + || dentry->d_sb->s_magic == SYSFS_MAGIC) return 0; integrity_audit_msg(AUDIT_INTEGRITY_METADATA, diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index e54a8a8da..5487827fa 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig @@ -155,23 +155,33 @@ config IMA_TRUSTED_KEYRING This option is deprecated in favor of INTEGRITY_TRUSTED_KEYRING -config IMA_MOK_KEYRING - bool "Create IMA machine owner keys (MOK) and blacklist keyrings" +config IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY + bool "Permit keys validly signed by a built-in or secondary CA cert (EXPERIMENTAL)" + depends on SYSTEM_TRUSTED_KEYRING + depends on SECONDARY_TRUSTED_KEYRING + depends on INTEGRITY_ASYMMETRIC_KEYS + select INTEGRITY_TRUSTED_KEYRING + default n + help + Keys may be added to the IMA or IMA blacklist keyrings, if the + key is validly signed by a CA cert in the system built-in or + secondary trusted keyrings. + + Intermediate keys between those the kernel has compiled in and the + IMA keys to be added may be added to the system secondary keyring, + provided they are validly signed by a key already resident in the + built-in or secondary trusted keyrings. + +config IMA_BLACKLIST_KEYRING + bool "Create IMA machine owner blacklist keyrings (EXPERIMENTAL)" depends on SYSTEM_TRUSTED_KEYRING depends on IMA_TRUSTED_KEYRING default n help - This option creates IMA MOK and blacklist keyrings. IMA MOK is an - intermediate keyring that sits between .system and .ima keyrings, - effectively forming a simple CA hierarchy. To successfully import a - key into .ima_mok it must be signed by a key which CA is in .system - keyring. On turn any key that needs to go in .ima keyring must be - signed by CA in either .system or .ima_mok keyrings. IMA MOK is empty - at kernel boot. - - IMA blacklist keyring contains all revoked IMA keys. It is consulted - before any other keyring. If the search is successful the requested - operation is rejected and error is returned to the caller. + This option creates an IMA blacklist keyring, which contains all + revoked IMA keys. It is consulted before any other keyring. If + the search is successful the requested operation is rejected and + an error is returned to the caller. config IMA_LOAD_X509 bool "Load X509 certificate onto the '.ima' trusted keyring" diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile index a8539f9e0..9aeaedad1 100644 --- a/security/integrity/ima/Makefile +++ b/security/integrity/ima/Makefile @@ -8,4 +8,4 @@ obj-$(CONFIG_IMA) += ima.o ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ ima_policy.o ima_template.o ima_template_lib.o ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o -obj-$(CONFIG_IMA_MOK_KEYRING) += ima_mok.o +obj-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 5d0f61163..d3a939bf2 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -170,7 +170,7 @@ int ima_alloc_init_template(struct ima_event_data *event_data, int ima_store_template(struct ima_template_entry *entry, int violation, struct inode *inode, const unsigned char *filename); void ima_free_template_entry(struct ima_template_entry *entry); -const char *ima_d_path(struct path *path, char **pathbuf); +const char *ima_d_path(const struct path *path, char **pathbuf); /* IMA policy related functions */ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index 370e42dfc..5a2218fe8 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -313,7 +313,7 @@ void ima_audit_measurement(struct integrity_iint_cache *iint, iint->flags |= IMA_AUDITED; } -const char *ima_d_path(struct path *path, char **pathbuf) +const char *ima_d_path(const struct path *path, char **pathbuf) { char *pathname = NULL; diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 6b4694aed..1bcbc12e0 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -275,6 +275,11 @@ out: xattr_value->type != EVM_IMA_XATTR_DIGSIG)) { if (!ima_fix_xattr(dentry, iint)) status = INTEGRITY_PASS; + } else if ((inode->i_size == 0) && + (iint->flags & IMA_NEW_FILE) && + (xattr_value && + xattr_value->type == EVM_IMA_XATTR_DIGSIG)) { + status = INTEGRITY_PASS; } integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename, op, cause, rc, 0); @@ -328,7 +333,7 @@ void ima_inode_post_setattr(struct dentry *dentry) if (iint) { iint->flags &= ~(IMA_APPRAISE | IMA_APPRAISED | IMA_APPRAISE_SUBMASK | IMA_APPRAISED_SUBMASK | - IMA_ACTION_FLAGS); + IMA_ACTION_RULE_FLAGS); if (must_appraise) iint->flags |= IMA_APPRAISE; } diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 391f41751..68b26c340 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -246,7 +246,8 @@ static int process_measurement(struct file *file, char *buf, loff_t size, ima_audit_measurement(iint, pathname); out_digsig: - if ((mask & MAY_WRITE) && (iint->flags & IMA_DIGSIG)) + if ((mask & MAY_WRITE) && (iint->flags & IMA_DIGSIG) && + !(iint->flags & IMA_NEW_FILE)) rc = -EACCES; kfree(xattr_value); out_free: @@ -316,6 +317,28 @@ int ima_file_check(struct file *file, int mask, int opened) EXPORT_SYMBOL_GPL(ima_file_check); /** + * ima_post_path_mknod - mark as a new inode + * @dentry: newly created dentry + * + * Mark files created via the mknodat syscall as new, so that the + * file data can be written later. + */ +void ima_post_path_mknod(struct dentry *dentry) +{ + struct integrity_iint_cache *iint; + struct inode *inode = dentry->d_inode; + int must_appraise; + + must_appraise = ima_must_appraise(inode, MAY_ACCESS, FILE_CHECK); + if (!must_appraise) + return; + + iint = integrity_inode_get(inode); + if (iint) + iint->flags |= IMA_NEW_FILE; +} + +/** * ima_read_file - pre-measure/appraise hook decision based on policy * @file: pointer to the file to be measured/appraised/audit * @read_id: caller identifier diff --git a/security/integrity/ima/ima_mok.c b/security/integrity/ima/ima_mok.c index 676885e43..74a279957 100644 --- a/security/integrity/ima/ima_mok.c +++ b/security/integrity/ima/ima_mok.c @@ -17,38 +17,29 @@ #include <linux/cred.h> #include <linux/err.h> #include <linux/init.h> -#include <keys/asymmetric-type.h> +#include <keys/system_keyring.h> -struct key *ima_mok_keyring; struct key *ima_blacklist_keyring; /* - * Allocate the IMA MOK and blacklist keyrings + * Allocate the IMA blacklist keyring */ __init int ima_mok_init(void) { - pr_notice("Allocating IMA MOK and blacklist keyrings.\n"); - - ima_mok_keyring = keyring_alloc(".ima_mok", - KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), - (KEY_POS_ALL & ~KEY_POS_SETATTR) | - KEY_USR_VIEW | KEY_USR_READ | - KEY_USR_WRITE | KEY_USR_SEARCH, - KEY_ALLOC_NOT_IN_QUOTA, NULL); + pr_notice("Allocating IMA blacklist keyring.\n"); ima_blacklist_keyring = keyring_alloc(".ima_blacklist", KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_WRITE | KEY_USR_SEARCH, - KEY_ALLOC_NOT_IN_QUOTA, NULL); + KEY_ALLOC_NOT_IN_QUOTA, + restrict_link_by_builtin_trusted, NULL); - if (IS_ERR(ima_mok_keyring) || IS_ERR(ima_blacklist_keyring)) - panic("Can't allocate IMA MOK or blacklist keyrings."); - set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_mok_keyring->flags); + if (IS_ERR(ima_blacklist_keyring)) + panic("Can't allocate IMA blacklist keyring."); - set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_blacklist_keyring->flags); set_bit(KEY_FLAG_KEEP, &ima_blacklist_keyring->flags); return 0; } diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 3cd0a5867..0f887a564 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -972,7 +972,7 @@ static void policy_func_show(struct seq_file *m, enum ima_hooks func) int ima_policy_show(struct seq_file *m, void *v) { struct ima_rule_entry *entry = v; - int i = 0; + int i; char tbuf[64] = {0,}; rcu_read_lock(); @@ -1012,17 +1012,7 @@ int ima_policy_show(struct seq_file *m, void *v) } if (entry->flags & IMA_FSUUID) { - seq_puts(m, "fsuuid="); - for (i = 0; i < ARRAY_SIZE(entry->fsuuid); ++i) { - switch (i) { - case 4: - case 6: - case 8: - case 10: - seq_puts(m, "-"); - } - seq_printf(m, "%x", entry->fsuuid[i]); - } + seq_printf(m, "fsuuid=%pU", entry->fsuuid); seq_puts(m, " "); } diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index e08935cf3..90bc57d79 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h @@ -28,6 +28,7 @@ /* iint cache flags */ #define IMA_ACTION_FLAGS 0xff000000 +#define IMA_ACTION_RULE_FLAGS 0x06000000 #define IMA_DIGSIG 0x01000000 #define IMA_DIGSIG_REQUIRED 0x02000000 #define IMA_PERMIT_DIRECTIO 0x04000000 |