summaryrefslogtreecommitdiff
path: root/security/integrity
diff options
context:
space:
mode:
Diffstat (limited to 'security/integrity')
-rw-r--r--security/integrity/Kconfig1
-rw-r--r--security/integrity/digsig.c15
-rw-r--r--security/integrity/evm/evm_main.c6
-rw-r--r--security/integrity/ima/Kconfig36
-rw-r--r--security/integrity/ima/Makefile2
-rw-r--r--security/integrity/ima/ima.h2
-rw-r--r--security/integrity/ima/ima_api.c2
-rw-r--r--security/integrity/ima/ima_appraise.c7
-rw-r--r--security/integrity/ima/ima_main.c25
-rw-r--r--security/integrity/ima/ima_mok.c23
-rw-r--r--security/integrity/ima/ima_policy.c14
-rw-r--r--security/integrity/integrity.h1
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