diff options
| author | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2013-08-13 08:47:43 -0400 |
|---|---|---|
| committer | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2013-10-31 20:20:48 -0400 |
| commit | 217091dd7a7a1bdac027ddb7c5a25f6ac0b8e241 (patch) | |
| tree | 3a8a39da527431153698fc73640db47e8a1bd43a /security | |
| parent | bcbc9b0cf6d8f340a1d166e414f4612b353f7a9b (diff) | |
ima: define '_ima' as a builtin 'trusted' keyring
Require all keys added to the IMA keyring be signed by an
existing trusted key on the system trusted keyring.
Changelog:
- define stub integrity_init_keyring() function (reported-by Fengguang Wu)
- differentiate between regular and trusted keyring names.
- replace printk with pr_info (D. Kasatkin)
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Diffstat (limited to 'security')
| -rw-r--r-- | security/integrity/digsig.c | 30 | ||||
| -rw-r--r-- | security/integrity/ima/Kconfig | 8 | ||||
| -rw-r--r-- | security/integrity/ima/ima_appraise.c | 11 | ||||
| -rw-r--r-- | security/integrity/integrity.h | 7 |
4 files changed, 55 insertions, 1 deletions
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index b4af4ebc5be2..77ca965ab684 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c | |||
| @@ -13,7 +13,9 @@ | |||
| 13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 14 | 14 | ||
| 15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
| 16 | #include <linux/sched.h> | ||
| 16 | #include <linux/rbtree.h> | 17 | #include <linux/rbtree.h> |
| 18 | #include <linux/cred.h> | ||
| 17 | #include <linux/key-type.h> | 19 | #include <linux/key-type.h> |
| 18 | #include <linux/digsig.h> | 20 | #include <linux/digsig.h> |
| 19 | 21 | ||
| @@ -21,11 +23,19 @@ | |||
| 21 | 23 | ||
| 22 | static struct key *keyring[INTEGRITY_KEYRING_MAX]; | 24 | static struct key *keyring[INTEGRITY_KEYRING_MAX]; |
| 23 | 25 | ||
| 26 | #ifdef CONFIG_IMA_TRUSTED_KEYRING | ||
| 27 | static const char *keyring_name[INTEGRITY_KEYRING_MAX] = { | ||
| 28 | ".evm", | ||
| 29 | ".module", | ||
| 30 | ".ima", | ||
| 31 | }; | ||
| 32 | #else | ||
| 24 | static const char *keyring_name[INTEGRITY_KEYRING_MAX] = { | 33 | static const char *keyring_name[INTEGRITY_KEYRING_MAX] = { |
| 25 | "_evm", | 34 | "_evm", |
| 26 | "_module", | 35 | "_module", |
| 27 | "_ima", | 36 | "_ima", |
| 28 | }; | 37 | }; |
| 38 | #endif | ||
| 29 | 39 | ||
| 30 | int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, | 40 | int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, |
| 31 | const char *digest, int digestlen) | 41 | const char *digest, int digestlen) |
| @@ -35,7 +45,7 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, | |||
| 35 | 45 | ||
| 36 | if (!keyring[id]) { | 46 | if (!keyring[id]) { |
| 37 | keyring[id] = | 47 | keyring[id] = |
| 38 | request_key(&key_type_keyring, keyring_name[id], NULL); | 48 | request_key(&key_type_keyring, keyring_name[id], NULL); |
| 39 | if (IS_ERR(keyring[id])) { | 49 | if (IS_ERR(keyring[id])) { |
| 40 | int err = PTR_ERR(keyring[id]); | 50 | int err = PTR_ERR(keyring[id]); |
| 41 | pr_err("no %s keyring: %d\n", keyring_name[id], err); | 51 | pr_err("no %s keyring: %d\n", keyring_name[id], err); |
| @@ -56,3 +66,21 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, | |||
| 56 | 66 | ||
| 57 | return -EOPNOTSUPP; | 67 | return -EOPNOTSUPP; |
| 58 | } | 68 | } |
| 69 | |||
| 70 | int integrity_init_keyring(const unsigned int id) | ||
| 71 | { | ||
| 72 | const struct cred *cred = current_cred(); | ||
| 73 | const struct user_struct *user = cred->user; | ||
| 74 | |||
| 75 | keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), | ||
| 76 | KGIDT_INIT(0), cred, | ||
| 77 | ((KEY_POS_ALL & ~KEY_POS_SETATTR) | | ||
| 78 | KEY_USR_VIEW | KEY_USR_READ), | ||
| 79 | KEY_ALLOC_NOT_IN_QUOTA, user->uid_keyring); | ||
| 80 | if (!IS_ERR(keyring[id])) | ||
| 81 | set_bit(KEY_FLAG_TRUSTED_ONLY, &keyring[id]->flags); | ||
| 82 | else | ||
| 83 | pr_info("Can't allocate %s keyring (%ld)\n", | ||
| 84 | keyring_name[id], PTR_ERR(keyring[id])); | ||
| 85 | return 0; | ||
| 86 | } | ||
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index 81a27971d884..dad8d4ca2437 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig | |||
| @@ -123,3 +123,11 @@ config IMA_APPRAISE | |||
| 123 | For more information on integrity appraisal refer to: | 123 | For more information on integrity appraisal refer to: |
| 124 | <http://linux-ima.sourceforge.net> | 124 | <http://linux-ima.sourceforge.net> |
| 125 | If unsure, say N. | 125 | If unsure, say N. |
| 126 | |||
| 127 | config IMA_TRUSTED_KEYRING | ||
| 128 | bool "Require all keys on the _ima keyring be signed" | ||
| 129 | depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING | ||
| 130 | default y | ||
| 131 | help | ||
| 132 | This option requires that all keys added to the _ima | ||
| 133 | keyring be signed by a key on the system trusted keyring. | ||
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 734e9468aca0..46353ee517f6 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c | |||
| @@ -381,3 +381,14 @@ int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name) | |||
| 381 | } | 381 | } |
| 382 | return result; | 382 | return result; |
| 383 | } | 383 | } |
| 384 | |||
| 385 | #ifdef CONFIG_IMA_TRUSTED_KEYRING | ||
| 386 | static int __init init_ima_keyring(void) | ||
| 387 | { | ||
| 388 | int ret; | ||
| 389 | |||
| 390 | ret = integrity_init_keyring(INTEGRITY_KEYRING_IMA); | ||
| 391 | return 0; | ||
| 392 | } | ||
| 393 | late_initcall(init_ima_keyring); | ||
| 394 | #endif | ||
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 2fb5e53e927f..b9e7c133734a 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h | |||
| @@ -137,12 +137,19 @@ static inline int integrity_digsig_verify(const unsigned int id, | |||
| 137 | #ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS | 137 | #ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS |
| 138 | int asymmetric_verify(struct key *keyring, const char *sig, | 138 | int asymmetric_verify(struct key *keyring, const char *sig, |
| 139 | int siglen, const char *data, int datalen); | 139 | int siglen, const char *data, int datalen); |
| 140 | |||
| 141 | int integrity_init_keyring(const unsigned int id); | ||
| 140 | #else | 142 | #else |
| 141 | static inline int asymmetric_verify(struct key *keyring, const char *sig, | 143 | static inline int asymmetric_verify(struct key *keyring, const char *sig, |
| 142 | int siglen, const char *data, int datalen) | 144 | int siglen, const char *data, int datalen) |
| 143 | { | 145 | { |
| 144 | return -EOPNOTSUPP; | 146 | return -EOPNOTSUPP; |
| 145 | } | 147 | } |
| 148 | |||
| 149 | static int integrity_init_keyring(const unsigned int id) | ||
| 150 | { | ||
| 151 | return 0; | ||
| 152 | } | ||
| 146 | #endif | 153 | #endif |
| 147 | 154 | ||
| 148 | #ifdef CONFIG_INTEGRITY_AUDIT | 155 | #ifdef CONFIG_INTEGRITY_AUDIT |
