aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Garrett <mjg59@google.com>2018-05-11 19:12:35 -0400
committerMimi Zohar <zohar@linux.vnet.ibm.com>2018-05-18 15:34:36 -0400
commit21af76631476030709f85f48e20bb9429a912b6f (patch)
tree787cb3a9d80665d4d55afe7b727dff40d334b15c
parent0c343af8065be5ceb0c03a876af7c513e960e2ff (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.h7
-rw-r--r--security/integrity/evm/evm_crypto.c10
-rw-r--r--security/integrity/evm/evm_main.c79
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
33struct xattr_list {
34 struct list_head list;
35 char *name;
36};
37
33extern int evm_initialized; 38extern 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;
40extern struct crypto_shash *hash_tfm; 45extern struct crypto_shash *hash_tfm;
41 46
42/* List of EVM protected security xattrs */ 47/* List of EVM protected security xattrs */
43extern char *evm_config_xattrnames[]; 48extern struct list_head evm_config_xattrnames;
44 49
45int evm_init_key(void); 50int evm_init_key(void);
46int evm_update_evmxattr(struct dentry *dentry, 51int 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};
36int evm_hmac_attrs; 36int evm_hmac_attrs;
37 37
38char *evm_config_xattrnames[] = { 38static 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
59LIST_HEAD(evm_config_xattrnames);
60
60static int evm_fixmode; 61static int evm_fixmode;
61static int __init evm_set_fixmode(char *str) 62static int __init evm_set_fixmode(char *str)
62{ 63{
@@ -68,6 +69,17 @@ __setup("evm=", evm_set_fixmode);
68 69
69static void __init evm_init_config(void) 70static 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)
82static int evm_find_protected_xattrs(struct dentry *dentry) 94static 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
212static int evm_protected_xattr(const char *req_xattr_name) 224static 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)
544static int __init init_evm(void) 557static 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; 575error:
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);
566static 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
575pure_initcall(evm_display_config);
576late_initcall(init_evm); 589late_initcall(init_evm);
577 590
578MODULE_DESCRIPTION("Extended Verification Module"); 591MODULE_DESCRIPTION("Extended Verification Module");