diff options
| author | Matthew Garrett <mjg59@google.com> | 2018-05-11 19:12:35 -0400 |
|---|---|---|
| committer | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2018-05-18 15:34:36 -0400 |
| commit | 21af76631476030709f85f48e20bb9429a912b6f (patch) | |
| tree | 787cb3a9d80665d4d55afe7b727dff40d334b15c | |
| parent | 0c343af8065be5ceb0c03a876af7c513e960e2ff (diff) | |
EVM: turn evm_config_xattrnames into a list
Use a list of xattrs rather than an array - this makes it easier to
extend the list at runtime.
Signed-off-by: Matthew Garrett <mjg59@google.com>
Reviewed-by: James Morris <james.morris@microsoft.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
| -rw-r--r-- | security/integrity/evm/evm.h | 7 | ||||
| -rw-r--r-- | security/integrity/evm/evm_crypto.c | 10 | ||||
| -rw-r--r-- | security/integrity/evm/evm_main.c | 79 |
3 files changed, 57 insertions, 39 deletions
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 @@ | |||
| 30 | #define EVM_INIT_MASK (EVM_INIT_HMAC | EVM_INIT_X509 | EVM_SETUP_COMPLETE | \ | 30 | #define EVM_INIT_MASK (EVM_INIT_HMAC | EVM_INIT_X509 | EVM_SETUP_COMPLETE | \ |
| 31 | EVM_ALLOW_METADATA_WRITES) | 31 | EVM_ALLOW_METADATA_WRITES) |
| 32 | 32 | ||
| 33 | struct xattr_list { | ||
| 34 | struct list_head list; | ||
| 35 | char *name; | ||
| 36 | }; | ||
| 37 | |||
| 33 | extern int evm_initialized; | 38 | extern int evm_initialized; |
| 34 | 39 | ||
| 35 | #define EVM_ATTR_FSUUID 0x0001 | 40 | #define EVM_ATTR_FSUUID 0x0001 |
| @@ -40,7 +45,7 @@ extern struct crypto_shash *hmac_tfm; | |||
| 40 | extern struct crypto_shash *hash_tfm; | 45 | extern struct crypto_shash *hash_tfm; |
| 41 | 46 | ||
| 42 | /* List of EVM protected security xattrs */ | 47 | /* List of EVM protected security xattrs */ |
| 43 | extern char *evm_config_xattrnames[]; | 48 | extern struct list_head evm_config_xattrnames; |
| 44 | 49 | ||
| 45 | int evm_init_key(void); | 50 | int evm_init_key(void); |
| 46 | int evm_update_evmxattr(struct dentry *dentry, | 51 | 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..caeea20670cc 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c | |||
| @@ -192,8 +192,8 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry, | |||
| 192 | char type, char *digest) | 192 | char type, char *digest) |
| 193 | { | 193 | { |
| 194 | struct inode *inode = d_backing_inode(dentry); | 194 | struct inode *inode = d_backing_inode(dentry); |
| 195 | struct xattr_list *xattr; | ||
| 195 | struct shash_desc *desc; | 196 | struct shash_desc *desc; |
| 196 | char **xattrname; | ||
| 197 | size_t xattr_size = 0; | 197 | size_t xattr_size = 0; |
| 198 | char *xattr_value = NULL; | 198 | char *xattr_value = NULL; |
| 199 | int error; | 199 | int error; |
| @@ -208,14 +208,14 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry, | |||
| 208 | return PTR_ERR(desc); | 208 | return PTR_ERR(desc); |
| 209 | 209 | ||
| 210 | error = -ENODATA; | 210 | error = -ENODATA; |
| 211 | for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) { | 211 | list_for_each_entry(xattr, &evm_config_xattrnames, list) { |
| 212 | bool is_ima = false; | 212 | bool is_ima = false; |
| 213 | 213 | ||
| 214 | if (strcmp(*xattrname, XATTR_NAME_IMA) == 0) | 214 | if (strcmp(xattr->name, XATTR_NAME_IMA) == 0) |
| 215 | is_ima = true; | 215 | is_ima = true; |
| 216 | 216 | ||
| 217 | if ((req_xattr_name && req_xattr_value) | 217 | if ((req_xattr_name && req_xattr_value) |
| 218 | && !strcmp(*xattrname, req_xattr_name)) { | 218 | && !strcmp(xattr->name, req_xattr_name)) { |
| 219 | error = 0; | 219 | error = 0; |
| 220 | crypto_shash_update(desc, (const u8 *)req_xattr_value, | 220 | crypto_shash_update(desc, (const u8 *)req_xattr_value, |
| 221 | req_xattr_value_len); | 221 | req_xattr_value_len); |
| @@ -223,7 +223,7 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry, | |||
| 223 | ima_present = true; | 223 | ima_present = true; |
| 224 | continue; | 224 | continue; |
| 225 | } | 225 | } |
| 226 | size = vfs_getxattr_alloc(dentry, *xattrname, | 226 | size = vfs_getxattr_alloc(dentry, xattr->name, |
| 227 | &xattr_value, xattr_size, GFP_NOFS); | 227 | &xattr_value, xattr_size, GFP_NOFS); |
| 228 | if (size == -ENOMEM) { | 228 | if (size == -ENOMEM) { |
| 229 | error = -ENOMEM; | 229 | error = -ENOMEM; |
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index 9ea9c19a545c..09582d4fc4a8 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[] = { | |||
| 35 | }; | 35 | }; |
| 36 | int evm_hmac_attrs; | 36 | int evm_hmac_attrs; |
| 37 | 37 | ||
| 38 | char *evm_config_xattrnames[] = { | 38 | static struct xattr_list evm_config_default_xattrnames[] __ro_after_init = { |
| 39 | #ifdef CONFIG_SECURITY_SELINUX | 39 | #ifdef CONFIG_SECURITY_SELINUX |
| 40 | XATTR_NAME_SELINUX, | 40 | {.name = XATTR_NAME_SELINUX}, |
| 41 | #endif | 41 | #endif |
| 42 | #ifdef CONFIG_SECURITY_SMACK | 42 | #ifdef CONFIG_SECURITY_SMACK |
| 43 | XATTR_NAME_SMACK, | 43 | {.name = XATTR_NAME_SMACK}, |
| 44 | #ifdef CONFIG_EVM_EXTRA_SMACK_XATTRS | 44 | #ifdef CONFIG_EVM_EXTRA_SMACK_XATTRS |
| 45 | XATTR_NAME_SMACKEXEC, | 45 | {.name = XATTR_NAME_SMACKEXEC}, |
| 46 | XATTR_NAME_SMACKTRANSMUTE, | 46 | {.name = XATTR_NAME_SMACKTRANSMUTE}, |
| 47 | XATTR_NAME_SMACKMMAP, | 47 | {.name = XATTR_NAME_SMACKMMAP}, |
| 48 | #endif | 48 | #endif |
| 49 | #endif | 49 | #endif |
| 50 | #ifdef CONFIG_SECURITY_APPARMOR | 50 | #ifdef CONFIG_SECURITY_APPARMOR |
| 51 | XATTR_NAME_APPARMOR, | 51 | {.name = XATTR_NAME_APPARMOR}, |
| 52 | #endif | 52 | #endif |
| 53 | #ifdef CONFIG_IMA_APPRAISE | 53 | #ifdef CONFIG_IMA_APPRAISE |
| 54 | XATTR_NAME_IMA, | 54 | {.name = XATTR_NAME_IMA}, |
| 55 | #endif | 55 | #endif |
| 56 | XATTR_NAME_CAPS, | 56 | {.name = XATTR_NAME_CAPS}, |
| 57 | NULL | ||
| 58 | }; | 57 | }; |
| 59 | 58 | ||
| 59 | LIST_HEAD(evm_config_xattrnames); | ||
| 60 | |||
| 60 | static int evm_fixmode; | 61 | static int evm_fixmode; |
| 61 | static int __init evm_set_fixmode(char *str) | 62 | static int __init evm_set_fixmode(char *str) |
| 62 | { | 63 | { |
| @@ -68,6 +69,17 @@ __setup("evm=", evm_set_fixmode); | |||
| 68 | 69 | ||
| 69 | static void __init evm_init_config(void) | 70 | static void __init evm_init_config(void) |
| 70 | { | 71 | { |
| 72 | int i, xattrs; | ||
| 73 | |||
| 74 | xattrs = ARRAY_SIZE(evm_config_default_xattrnames); | ||
| 75 | |||
| 76 | pr_info("Initialising EVM extended attributes:\n"); | ||
| 77 | for (i = 0; i < xattrs; i++) { | ||
| 78 | pr_info("%s\n", evm_config_default_xattrnames[i].name); | ||
| 79 | list_add_tail(&evm_config_default_xattrnames[i].list, | ||
| 80 | &evm_config_xattrnames); | ||
| 81 | } | ||
| 82 | |||
| 71 | #ifdef CONFIG_EVM_ATTR_FSUUID | 83 | #ifdef CONFIG_EVM_ATTR_FSUUID |
| 72 | evm_hmac_attrs |= EVM_ATTR_FSUUID; | 84 | evm_hmac_attrs |= EVM_ATTR_FSUUID; |
| 73 | #endif | 85 | #endif |
| @@ -82,15 +94,15 @@ static bool evm_key_loaded(void) | |||
| 82 | static int evm_find_protected_xattrs(struct dentry *dentry) | 94 | static int evm_find_protected_xattrs(struct dentry *dentry) |
| 83 | { | 95 | { |
| 84 | struct inode *inode = d_backing_inode(dentry); | 96 | struct inode *inode = d_backing_inode(dentry); |
| 85 | char **xattr; | 97 | struct xattr_list *xattr; |
| 86 | int error; | 98 | int error; |
| 87 | int count = 0; | 99 | int count = 0; |
| 88 | 100 | ||
| 89 | if (!(inode->i_opflags & IOP_XATTR)) | 101 | if (!(inode->i_opflags & IOP_XATTR)) |
| 90 | return -EOPNOTSUPP; | 102 | return -EOPNOTSUPP; |
| 91 | 103 | ||
| 92 | for (xattr = evm_config_xattrnames; *xattr != NULL; xattr++) { | 104 | list_for_each_entry(xattr, &evm_config_xattrnames, list) { |
| 93 | error = __vfs_getxattr(dentry, inode, *xattr, NULL, 0); | 105 | error = __vfs_getxattr(dentry, inode, xattr->name, NULL, 0); |
| 94 | if (error < 0) { | 106 | if (error < 0) { |
| 95 | if (error == -ENODATA) | 107 | if (error == -ENODATA) |
| 96 | continue; | 108 | continue; |
| @@ -211,24 +223,25 @@ out: | |||
| 211 | 223 | ||
| 212 | static int evm_protected_xattr(const char *req_xattr_name) | 224 | static int evm_protected_xattr(const char *req_xattr_name) |
| 213 | { | 225 | { |
| 214 | char **xattrname; | ||
| 215 | int namelen; | 226 | int namelen; |
| 216 | int found = 0; | 227 | int found = 0; |
| 228 | struct xattr_list *xattr; | ||
| 217 | 229 | ||
| 218 | namelen = strlen(req_xattr_name); | 230 | namelen = strlen(req_xattr_name); |
| 219 | for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) { | 231 | list_for_each_entry(xattr, &evm_config_xattrnames, list) { |
| 220 | if ((strlen(*xattrname) == namelen) | 232 | if ((strlen(xattr->name) == namelen) |
| 221 | && (strncmp(req_xattr_name, *xattrname, namelen) == 0)) { | 233 | && (strncmp(req_xattr_name, xattr->name, namelen) == 0)) { |
| 222 | found = 1; | 234 | found = 1; |
| 223 | break; | 235 | break; |
| 224 | } | 236 | } |
| 225 | if (strncmp(req_xattr_name, | 237 | if (strncmp(req_xattr_name, |
| 226 | *xattrname + XATTR_SECURITY_PREFIX_LEN, | 238 | xattr->name + XATTR_SECURITY_PREFIX_LEN, |
| 227 | strlen(req_xattr_name)) == 0) { | 239 | strlen(req_xattr_name)) == 0) { |
| 228 | found = 1; | 240 | found = 1; |
| 229 | break; | 241 | break; |
| 230 | } | 242 | } |
| 231 | } | 243 | } |
| 244 | |||
| 232 | return found; | 245 | return found; |
| 233 | } | 246 | } |
| 234 | 247 | ||
| @@ -544,35 +557,35 @@ void __init evm_load_x509(void) | |||
| 544 | static int __init init_evm(void) | 557 | static int __init init_evm(void) |
| 545 | { | 558 | { |
| 546 | int error; | 559 | int error; |
| 560 | struct list_head *pos, *q; | ||
| 561 | struct xattr_list *xattr; | ||
| 547 | 562 | ||
| 548 | evm_init_config(); | 563 | evm_init_config(); |
| 549 | 564 | ||
| 550 | error = integrity_init_keyring(INTEGRITY_KEYRING_EVM); | 565 | error = integrity_init_keyring(INTEGRITY_KEYRING_EVM); |
| 551 | if (error) | 566 | if (error) |
| 552 | return error; | 567 | goto error; |
| 553 | 568 | ||
| 554 | error = evm_init_secfs(); | 569 | error = evm_init_secfs(); |
| 555 | if (error < 0) { | 570 | if (error < 0) { |
| 556 | pr_info("Error registering secfs\n"); | 571 | pr_info("Error registering secfs\n"); |
| 557 | return error; | 572 | goto error; |
| 558 | } | 573 | } |
| 559 | 574 | ||
| 560 | return 0; | 575 | error: |
| 561 | } | 576 | if (error != 0) { |
| 562 | 577 | if (!list_empty(&evm_config_xattrnames)) { | |
| 563 | /* | 578 | list_for_each_safe(pos, q, &evm_config_xattrnames) { |
| 564 | * evm_display_config - list the EVM protected security extended attributes | 579 | xattr = list_entry(pos, struct xattr_list, |
| 565 | */ | 580 | list); |
| 566 | static int __init evm_display_config(void) | 581 | list_del(pos); |
| 567 | { | 582 | } |
| 568 | char **xattrname; | 583 | } |
| 584 | } | ||
| 569 | 585 | ||
| 570 | for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) | 586 | return error; |
| 571 | pr_info("%s\n", *xattrname); | ||
| 572 | return 0; | ||
| 573 | } | 587 | } |
| 574 | 588 | ||
| 575 | pure_initcall(evm_display_config); | ||
| 576 | late_initcall(init_evm); | 589 | late_initcall(init_evm); |
| 577 | 590 | ||
| 578 | MODULE_DESCRIPTION("Extended Verification Module"); | 591 | MODULE_DESCRIPTION("Extended Verification Module"); |
