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

Commit aa569fa0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull more security layer updates from Serge Hallyn:
 "A few more commits had previously failed to make it through
  security-next into linux-next but this week made it into linux-next.
  At least commit "ima: introduce ima_kernel_read()" was deemed critical
  by Mimi to make this merge window.

  This is a temporary tree just for this request.  Mimi has pointed me
  to some previous threads about keeping maintainer trees at the
  previous release, which I'll certainly do for anything long-term,
  after talking with James"

* 'serge-next-2' of git://git.kernel.org/pub/scm/linux/kernel/git/sergeh/linux-security:
  ima: introduce ima_kernel_read()
  evm: prohibit userspace writing 'security.evm' HMAC value
  ima: check inode integrity cache in violation check
  ima: prevent unnecessary policy checking
  evm: provide option to protect additional SMACK xattrs
  evm: replace HMAC version with attribute mask
  ima: prevent new digsig xattr from being replaced
parents 6d87c225 0430e49b
Loading
Loading
Loading
Loading
+34 −8
Original line number Diff line number Diff line
@@ -12,15 +12,41 @@ config EVM

	  If you are unsure how to answer this question, answer N.

config EVM_HMAC_VERSION
	int "EVM HMAC version"
if EVM

menu "EVM options"

config EVM_ATTR_FSUUID
	bool "FSUUID (version 2)"
	default y
	depends on EVM
	default 2
	help
	  This options adds EVM HMAC version support.
	  1 - original version
	  2 - add per filesystem unique identifier (UUID) (default)
	  Include filesystem UUID for HMAC calculation.

	  Default value is 'selected', which is former version 2.
	  if 'not selected', it is former version 1

	  WARNING: changing the HMAC calculation method or adding
	  additional info to the calculation, requires existing EVM
	  labeled file systems to be relabeled.

config EVM_EXTRA_SMACK_XATTRS
	bool "Additional SMACK xattrs"
	depends on EVM && SECURITY_SMACK
	default n
	help
	  Include additional SMACK xattrs for HMAC calculation.

	  In addition to the original security xattrs (eg. security.selinux,
	  security.SMACK64, security.capability, and security.ima) included
	  in the HMAC calculation, enabling this option includes newly defined
	  Smack xattrs: security.SMACK64EXEC, security.SMACK64TRANSMUTE and
	  security.SMACK64MMAP.

	  WARNING: changing the HMAC calculation method or adding
	  additional info to the calculation, requires existing EVM
	  labeled file systems to be relabeled.

endmenu

endif
+4 −1
Original line number Diff line number Diff line
@@ -24,7 +24,10 @@
extern int evm_initialized;
extern char *evm_hmac;
extern char *evm_hash;
extern int evm_hmac_version;

#define EVM_ATTR_FSUUID		0x0001

extern int evm_hmac_attrs;

extern struct crypto_shash *hmac_tfm;
extern struct crypto_shash *hash_tfm;
+1 −1
Original line number Diff line number Diff line
@@ -112,7 +112,7 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
	hmac_misc.gid = from_kgid(&init_user_ns, inode->i_gid);
	hmac_misc.mode = inode->i_mode;
	crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof(hmac_misc));
	if (evm_hmac_version > 1)
	if (evm_hmac_attrs & EVM_ATTR_FSUUID)
		crypto_shash_update(desc, inode->i_sb->s_uuid,
				    sizeof(inode->i_sb->s_uuid));
	crypto_shash_final(desc, digest);
+26 −3
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ static char *integrity_status_msg[] = {
};
char *evm_hmac = "hmac(sha1)";
char *evm_hash = "sha1";
int evm_hmac_version = CONFIG_EVM_HMAC_VERSION;
int evm_hmac_attrs;

char *evm_config_xattrnames[] = {
#ifdef CONFIG_SECURITY_SELINUX
@@ -40,6 +40,11 @@ char *evm_config_xattrnames[] = {
#endif
#ifdef CONFIG_SECURITY_SMACK
	XATTR_NAME_SMACK,
#ifdef CONFIG_EVM_EXTRA_SMACK_XATTRS
	XATTR_NAME_SMACKEXEC,
	XATTR_NAME_SMACKTRANSMUTE,
	XATTR_NAME_SMACKMMAP,
#endif
#endif
#ifdef CONFIG_IMA_APPRAISE
	XATTR_NAME_IMA,
@@ -57,6 +62,14 @@ static int __init evm_set_fixmode(char *str)
}
__setup("evm=", evm_set_fixmode);

static void __init evm_init_config(void)
{
#ifdef CONFIG_EVM_ATTR_FSUUID
	evm_hmac_attrs |= EVM_ATTR_FSUUID;
#endif
	pr_info("HMAC attrs: 0x%x\n", evm_hmac_attrs);
}

static int evm_find_protected_xattrs(struct dentry *dentry)
{
	struct inode *inode = dentry->d_inode;
@@ -287,12 +300,20 @@ static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name,
 * @xattr_value: pointer to the new extended attribute value
 * @xattr_value_len: pointer to the new extended attribute value length
 *
 * Updating 'security.evm' requires CAP_SYS_ADMIN privileges and that
 * the current value is valid.
 * Before allowing the 'security.evm' protected xattr to be updated,
 * verify the existing value is valid.  As only the kernel should have
 * access to the EVM encrypted key needed to calculate the HMAC, prevent
 * userspace from writing HMAC value.  Writing 'security.evm' requires
 * requires CAP_SYS_ADMIN privileges.
 */
int evm_inode_setxattr(struct dentry *dentry, const char *xattr_name,
		       const void *xattr_value, size_t xattr_value_len)
{
	const struct evm_ima_xattr_data *xattr_data = xattr_value;

	if ((strcmp(xattr_name, XATTR_NAME_EVM) == 0)
	    && (xattr_data->type == EVM_XATTR_HMAC))
		return -EPERM;
	return evm_protect_xattr(dentry, xattr_name, xattr_value,
				 xattr_value_len);
}
@@ -432,6 +453,8 @@ static int __init init_evm(void)
{
	int error;

	evm_init_config();

	error = evm_init_secfs();
	if (error < 0) {
		pr_info("Error registering secfs\n");
+7 −3
Original line number Diff line number Diff line
@@ -341,7 +341,7 @@ static int ima_protect_xattr(struct dentry *dentry, const char *xattr_name,
	return 0;
}

static void ima_reset_appraise_flags(struct inode *inode)
static void ima_reset_appraise_flags(struct inode *inode, int digsig)
{
	struct integrity_iint_cache *iint;

@@ -353,18 +353,22 @@ static void ima_reset_appraise_flags(struct inode *inode)
		return;

	iint->flags &= ~IMA_DONE_MASK;
	if (digsig)
		iint->flags |= IMA_DIGSIG;
	return;
}

int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
		       const void *xattr_value, size_t xattr_value_len)
{
	const struct evm_ima_xattr_data *xvalue = xattr_value;
	int result;

	result = ima_protect_xattr(dentry, xattr_name, xattr_value,
				   xattr_value_len);
	if (result == 1) {
		ima_reset_appraise_flags(dentry->d_inode);
		ima_reset_appraise_flags(dentry->d_inode,
			 (xvalue->type == EVM_IMA_XATTR_DIGSIG) ? 1 : 0);
		result = 0;
	}
	return result;
@@ -376,7 +380,7 @@ int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name)

	result = ima_protect_xattr(dentry, xattr_name, NULL, 0);
	if (result == 1) {
		ima_reset_appraise_flags(dentry->d_inode);
		ima_reset_appraise_flags(dentry->d_inode, 0);
		result = 0;
	}
	return result;
Loading