forked from Minki/linux
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>
This commit is contained in:
parent
0c343af806
commit
21af766314
@ -30,6 +30,11 @@
|
||||
#define EVM_INIT_MASK (EVM_INIT_HMAC | EVM_INIT_X509 | EVM_SETUP_COMPLETE | \
|
||||
EVM_ALLOW_METADATA_WRITES)
|
||||
|
||||
struct xattr_list {
|
||||
struct list_head list;
|
||||
char *name;
|
||||
};
|
||||
|
||||
extern int evm_initialized;
|
||||
|
||||
#define EVM_ATTR_FSUUID 0x0001
|
||||
@ -40,7 +45,7 @@ extern struct crypto_shash *hmac_tfm;
|
||||
extern struct crypto_shash *hash_tfm;
|
||||
|
||||
/* List of EVM protected security xattrs */
|
||||
extern char *evm_config_xattrnames[];
|
||||
extern struct list_head evm_config_xattrnames;
|
||||
|
||||
int evm_init_key(void);
|
||||
int evm_update_evmxattr(struct dentry *dentry,
|
||||
|
@ -192,8 +192,8 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
|
||||
char type, char *digest)
|
||||
{
|
||||
struct inode *inode = d_backing_inode(dentry);
|
||||
struct xattr_list *xattr;
|
||||
struct shash_desc *desc;
|
||||
char **xattrname;
|
||||
size_t xattr_size = 0;
|
||||
char *xattr_value = NULL;
|
||||
int error;
|
||||
@ -208,14 +208,14 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
|
||||
return PTR_ERR(desc);
|
||||
|
||||
error = -ENODATA;
|
||||
for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
|
||||
list_for_each_entry(xattr, &evm_config_xattrnames, list) {
|
||||
bool is_ima = false;
|
||||
|
||||
if (strcmp(*xattrname, XATTR_NAME_IMA) == 0)
|
||||
if (strcmp(xattr->name, XATTR_NAME_IMA) == 0)
|
||||
is_ima = true;
|
||||
|
||||
if ((req_xattr_name && req_xattr_value)
|
||||
&& !strcmp(*xattrname, req_xattr_name)) {
|
||||
&& !strcmp(xattr->name, req_xattr_name)) {
|
||||
error = 0;
|
||||
crypto_shash_update(desc, (const u8 *)req_xattr_value,
|
||||
req_xattr_value_len);
|
||||
@ -223,7 +223,7 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
|
||||
ima_present = true;
|
||||
continue;
|
||||
}
|
||||
size = vfs_getxattr_alloc(dentry, *xattrname,
|
||||
size = vfs_getxattr_alloc(dentry, xattr->name,
|
||||
&xattr_value, xattr_size, GFP_NOFS);
|
||||
if (size == -ENOMEM) {
|
||||
error = -ENOMEM;
|
||||
|
@ -35,28 +35,29 @@ static const char * const integrity_status_msg[] = {
|
||||
};
|
||||
int evm_hmac_attrs;
|
||||
|
||||
char *evm_config_xattrnames[] = {
|
||||
static struct xattr_list evm_config_default_xattrnames[] __ro_after_init = {
|
||||
#ifdef CONFIG_SECURITY_SELINUX
|
||||
XATTR_NAME_SELINUX,
|
||||
{.name = XATTR_NAME_SELINUX},
|
||||
#endif
|
||||
#ifdef CONFIG_SECURITY_SMACK
|
||||
XATTR_NAME_SMACK,
|
||||
{.name = XATTR_NAME_SMACK},
|
||||
#ifdef CONFIG_EVM_EXTRA_SMACK_XATTRS
|
||||
XATTR_NAME_SMACKEXEC,
|
||||
XATTR_NAME_SMACKTRANSMUTE,
|
||||
XATTR_NAME_SMACKMMAP,
|
||||
{.name = XATTR_NAME_SMACKEXEC},
|
||||
{.name = XATTR_NAME_SMACKTRANSMUTE},
|
||||
{.name = XATTR_NAME_SMACKMMAP},
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_SECURITY_APPARMOR
|
||||
XATTR_NAME_APPARMOR,
|
||||
{.name = XATTR_NAME_APPARMOR},
|
||||
#endif
|
||||
#ifdef CONFIG_IMA_APPRAISE
|
||||
XATTR_NAME_IMA,
|
||||
{.name = XATTR_NAME_IMA},
|
||||
#endif
|
||||
XATTR_NAME_CAPS,
|
||||
NULL
|
||||
{.name = XATTR_NAME_CAPS},
|
||||
};
|
||||
|
||||
LIST_HEAD(evm_config_xattrnames);
|
||||
|
||||
static int evm_fixmode;
|
||||
static int __init evm_set_fixmode(char *str)
|
||||
{
|
||||
@ -68,6 +69,17 @@ __setup("evm=", evm_set_fixmode);
|
||||
|
||||
static void __init evm_init_config(void)
|
||||
{
|
||||
int i, xattrs;
|
||||
|
||||
xattrs = ARRAY_SIZE(evm_config_default_xattrnames);
|
||||
|
||||
pr_info("Initialising EVM extended attributes:\n");
|
||||
for (i = 0; i < xattrs; i++) {
|
||||
pr_info("%s\n", evm_config_default_xattrnames[i].name);
|
||||
list_add_tail(&evm_config_default_xattrnames[i].list,
|
||||
&evm_config_xattrnames);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EVM_ATTR_FSUUID
|
||||
evm_hmac_attrs |= EVM_ATTR_FSUUID;
|
||||
#endif
|
||||
@ -82,15 +94,15 @@ static bool evm_key_loaded(void)
|
||||
static int evm_find_protected_xattrs(struct dentry *dentry)
|
||||
{
|
||||
struct inode *inode = d_backing_inode(dentry);
|
||||
char **xattr;
|
||||
struct xattr_list *xattr;
|
||||
int error;
|
||||
int count = 0;
|
||||
|
||||
if (!(inode->i_opflags & IOP_XATTR))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
for (xattr = evm_config_xattrnames; *xattr != NULL; xattr++) {
|
||||
error = __vfs_getxattr(dentry, inode, *xattr, NULL, 0);
|
||||
list_for_each_entry(xattr, &evm_config_xattrnames, list) {
|
||||
error = __vfs_getxattr(dentry, inode, xattr->name, NULL, 0);
|
||||
if (error < 0) {
|
||||
if (error == -ENODATA)
|
||||
continue;
|
||||
@ -211,24 +223,25 @@ out:
|
||||
|
||||
static int evm_protected_xattr(const char *req_xattr_name)
|
||||
{
|
||||
char **xattrname;
|
||||
int namelen;
|
||||
int found = 0;
|
||||
struct xattr_list *xattr;
|
||||
|
||||
namelen = strlen(req_xattr_name);
|
||||
for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
|
||||
if ((strlen(*xattrname) == namelen)
|
||||
&& (strncmp(req_xattr_name, *xattrname, namelen) == 0)) {
|
||||
list_for_each_entry(xattr, &evm_config_xattrnames, list) {
|
||||
if ((strlen(xattr->name) == namelen)
|
||||
&& (strncmp(req_xattr_name, xattr->name, namelen) == 0)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
if (strncmp(req_xattr_name,
|
||||
*xattrname + XATTR_SECURITY_PREFIX_LEN,
|
||||
xattr->name + XATTR_SECURITY_PREFIX_LEN,
|
||||
strlen(req_xattr_name)) == 0) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
@ -544,35 +557,35 @@ void __init evm_load_x509(void)
|
||||
static int __init init_evm(void)
|
||||
{
|
||||
int error;
|
||||
struct list_head *pos, *q;
|
||||
struct xattr_list *xattr;
|
||||
|
||||
evm_init_config();
|
||||
|
||||
error = integrity_init_keyring(INTEGRITY_KEYRING_EVM);
|
||||
if (error)
|
||||
return error;
|
||||
goto error;
|
||||
|
||||
error = evm_init_secfs();
|
||||
if (error < 0) {
|
||||
pr_info("Error registering secfs\n");
|
||||
return error;
|
||||
goto error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
error:
|
||||
if (error != 0) {
|
||||
if (!list_empty(&evm_config_xattrnames)) {
|
||||
list_for_each_safe(pos, q, &evm_config_xattrnames) {
|
||||
xattr = list_entry(pos, struct xattr_list,
|
||||
list);
|
||||
list_del(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* evm_display_config - list the EVM protected security extended attributes
|
||||
*/
|
||||
static int __init evm_display_config(void)
|
||||
{
|
||||
char **xattrname;
|
||||
|
||||
for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++)
|
||||
pr_info("%s\n", *xattrname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pure_initcall(evm_display_config);
|
||||
late_initcall(init_evm);
|
||||
|
||||
MODULE_DESCRIPTION("Extended Verification Module");
|
||||
|
Loading…
Reference in New Issue
Block a user