Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fa516b66 authored by Matthew Garrett's avatar Matthew Garrett Committed by Mimi Zohar
Browse files

EVM: Allow runtime modification of the set of verified xattrs



Sites may wish to provide additional metadata alongside files in order
to make more fine-grained security decisions[1]. The security of this is
enhanced if this metadata is protected, something that EVM makes
possible. However, the kernel cannot know about the set of extended
attributes that local admins may wish to protect, and hardcoding this
policy in the kernel makes it difficult to change over time and less
convenient for distributions to enable.

This patch adds a new /sys/kernel/security/integrity/evm/evm_xattrs node,
which can be read to obtain the current set of EVM-protected extended
attributes or written to in order to add new entries. Extending this list
will not change the validity of any existing signatures provided that the
file in question does not have any of the additional extended attributes -
missing xattrs are skipped when calculating the EVM hash.

[1] For instance, a package manager could install information about the
package uploader in an additional extended attribute. Local LSM policy
could then be associated with that extended attribute in order to
restrict the privileges available to packages from less trusted
uploaders.

Signed-off-by: default avatarMatthew Garrett <mjg59@google.com>
Reviewed-by: default avatarJames Morris <james.morris@microsoft.com>
Signed-off-by: default avatarMimi Zohar <zohar@linux.vnet.ibm.com>
parent 21af7663
Loading
Loading
Loading
Loading
+13 −0
Original line number Original line Diff line number Diff line
@@ -57,3 +57,16 @@ Description:
		dracut (via 97masterkey and 98integrity) and systemd (via
		dracut (via 97masterkey and 98integrity) and systemd (via
		core/ima-setup) have support for loading keys at boot
		core/ima-setup) have support for loading keys at boot
		time.
		time.

What:		security/integrity/evm/evm_xattrs
Date:		April 2018
Contact:	Matthew Garrett <mjg59@google.com>
Description:
		Shows the set of extended attributes used to calculate or
		validate the EVM signature, and allows additional attributes
		to be added at runtime. Any signatures generated after
		additional attributes are added (and on files posessing those
		additional attributes) will only be valid if the same
		additional attributes are configured on system boot. Writing
		a single period (.) will lock the xattr list from any further
		modification.
+1 −0
Original line number Original line Diff line number Diff line
@@ -147,6 +147,7 @@
#define AUDIT_INTEGRITY_HASH	    1803 /* Integrity HASH type */
#define AUDIT_INTEGRITY_HASH	    1803 /* Integrity HASH type */
#define AUDIT_INTEGRITY_PCR	    1804 /* PCR invalidation msgs */
#define AUDIT_INTEGRITY_PCR	    1804 /* PCR invalidation msgs */
#define AUDIT_INTEGRITY_RULE	    1805 /* policy rule */
#define AUDIT_INTEGRITY_RULE	    1805 /* policy rule */
#define AUDIT_INTEGRITY_EVM_XATTR   1806 /* New EVM-covered xattr */


#define AUDIT_KERNEL		2000	/* Asynchronous audit record. NOT A REQUEST. */
#define AUDIT_KERNEL		2000	/* Asynchronous audit record. NOT A REQUEST. */


+11 −0
Original line number Original line Diff line number Diff line
@@ -42,6 +42,17 @@ config EVM_EXTRA_SMACK_XATTRS
	  additional info to the calculation, requires existing EVM
	  additional info to the calculation, requires existing EVM
	  labeled file systems to be relabeled.
	  labeled file systems to be relabeled.


config EVM_ADD_XATTRS
	bool "Add additional EVM extended attributes at runtime"
	depends on EVM
	default n
	help
	  Allow userland to provide additional xattrs for HMAC calculation.

	  When this option is enabled, root can add additional xattrs to the
	  list used by EVM by writing them into
	  /sys/kernel/security/integrity/evm/evm_xattrs.

config EVM_LOAD_X509
config EVM_LOAD_X509
	bool "Load an X509 certificate onto the '.evm' trusted keyring"
	bool "Load an X509 certificate onto the '.evm' trusted keyring"
	depends on EVM && INTEGRITY_TRUSTED_KEYRING
	depends on EVM && INTEGRITY_TRUSTED_KEYRING
+1 −1
Original line number Original line Diff line number Diff line
@@ -208,7 +208,7 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
		return PTR_ERR(desc);
		return PTR_ERR(desc);


	error = -ENODATA;
	error = -ENODATA;
	list_for_each_entry(xattr, &evm_config_xattrnames, list) {
	list_for_each_entry_rcu(xattr, &evm_config_xattrnames, list) {
		bool is_ima = false;
		bool is_ima = false;


		if (strcmp(xattr->name, XATTR_NAME_IMA) == 0)
		if (strcmp(xattr->name, XATTR_NAME_IMA) == 0)
+3 −3
Original line number Original line Diff line number Diff line
@@ -35,7 +35,7 @@ static const char * const integrity_status_msg[] = {
};
};
int evm_hmac_attrs;
int evm_hmac_attrs;


static struct xattr_list evm_config_default_xattrnames[] __ro_after_init = {
static struct xattr_list evm_config_default_xattrnames[] = {
#ifdef CONFIG_SECURITY_SELINUX
#ifdef CONFIG_SECURITY_SELINUX
	{.name = XATTR_NAME_SELINUX},
	{.name = XATTR_NAME_SELINUX},
#endif
#endif
@@ -101,7 +101,7 @@ static int evm_find_protected_xattrs(struct dentry *dentry)
	if (!(inode->i_opflags & IOP_XATTR))
	if (!(inode->i_opflags & IOP_XATTR))
		return -EOPNOTSUPP;
		return -EOPNOTSUPP;


	list_for_each_entry(xattr, &evm_config_xattrnames, list) {
	list_for_each_entry_rcu(xattr, &evm_config_xattrnames, list) {
		error = __vfs_getxattr(dentry, inode, xattr->name, NULL, 0);
		error = __vfs_getxattr(dentry, inode, xattr->name, NULL, 0);
		if (error < 0) {
		if (error < 0) {
			if (error == -ENODATA)
			if (error == -ENODATA)
@@ -228,7 +228,7 @@ static int evm_protected_xattr(const char *req_xattr_name)
	struct xattr_list *xattr;
	struct xattr_list *xattr;


	namelen = strlen(req_xattr_name);
	namelen = strlen(req_xattr_name);
	list_for_each_entry(xattr, &evm_config_xattrnames, list) {
	list_for_each_entry_rcu(xattr, &evm_config_xattrnames, list) {
		if ((strlen(xattr->name) == namelen)
		if ((strlen(xattr->name) == namelen)
		    && (strncmp(req_xattr_name, xattr->name, namelen) == 0)) {
		    && (strncmp(req_xattr_name, xattr->name, namelen) == 0)) {
			found = 1;
			found = 1;
Loading