Commit aef4892a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull integrity subsystem updates from Mimi Zohar:

 - Limit the allowed hash algorithms when writing security.ima xattrs or
   verifying them, based on the IMA policy and the configured hash
   algorithms.

 - Return the calculated "critical data" measurement hash and size to
   avoid code duplication. (Preparatory change for a proposed LSM.)

 - and a single patch to address a compiler warning.

* tag 'integrity-v5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity:
  IMA: reject unknown hash algorithms in ima_get_hash_algo
  IMA: prevent SETXATTR_CHECK policy rules with unavailable algorithms
  IMA: introduce a new policy option func=SETXATTR_CHECK
  IMA: add a policy option to restrict xattr hash algorithms on appraisal
  IMA: add support to restrict the hash algorithms used for file appraisal
  IMA: block writes of the security.ima xattr with unsupported algorithms
  IMA: remove the dependency on CRYPTO_MD5
  ima: Add digest and digest_len params to the functions to measure a buffer
  ima: Return int in the functions to measure a buffer
  ima: Introduce ima_get_current_hash_algo()
  IMA: remove -Wmissing-prototypes warning
parents b55060d7 cb181da1
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -27,12 +27,13 @@ Description:
			lsm:	[[subj_user=] [subj_role=] [subj_type=]
				 [obj_user=] [obj_role=] [obj_type=]]
			option:	[[appraise_type=]] [template=] [permit_directio]
				[appraise_flag=] [keyrings=]
				[appraise_flag=] [appraise_algos=] [keyrings=]
		  base:
			func:= [BPRM_CHECK][MMAP_CHECK][CREDS_CHECK][FILE_CHECK][MODULE_CHECK]
				[FIRMWARE_CHECK]
				[KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK]
				[KEXEC_CMDLINE] [KEY_CHECK] [CRITICAL_DATA]
				[SETXATTR_CHECK]
			mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND]
			       [[^]MAY_EXEC]
			fsmagic:= hex value
@@ -55,6 +56,10 @@ Description:
			label:= [selinux]|[kernel_info]|[data_label]
			data_label:= a unique string used for grouping and limiting critical data.
			For example, "selinux" to measure critical data for SELinux.
			appraise_algos:= comma-separated list of hash algorithms
			For example, "sha256,sha512" to only accept to appraise
			files where the security.ima xattr was hashed with one
			of these two algorithms.

		  default policy:
			# PROC_SUPER_MAGIC
@@ -134,3 +139,9 @@ Description:
		keys added to .builtin_trusted_keys or .ima keyring:

			measure func=KEY_CHECK keyrings=.builtin_trusted_keys|.ima

		Example of the special SETXATTR_CHECK appraise rule, that
		restricts the hash algorithms allowed when writing to the
		security.ima xattr of a file:

			appraise func=SETXATTR_CHECK appraise_algos=sha256,sha384,sha512
+2 −1
Original line number Diff line number Diff line
@@ -136,7 +136,8 @@ static void dm_ima_measure_data(const char *event_name, const void *buf, size_t
	if (noio)
		noio_flag = memalloc_noio_save();

	ima_measure_critical_data(DM_NAME, event_name, buf, buf_len, false);
	ima_measure_critical_data(DM_NAME, event_name, buf, buf_len,
				  false, NULL, 0);

	if (noio)
		memalloc_noio_restore(noio_flag);
+17 −6
Original line number Diff line number Diff line
@@ -11,9 +11,11 @@
#include <linux/fs.h>
#include <linux/security.h>
#include <linux/kexec.h>
#include <crypto/hash_info.h>
struct linux_binprm;

#ifdef CONFIG_IMA
extern enum hash_algo ima_get_current_hash_algo(void);
extern int ima_bprm_check(struct linux_binprm *bprm);
extern int ima_file_check(struct file *file, int mask);
extern void ima_post_create_tmpfile(struct user_namespace *mnt_userns,
@@ -33,10 +35,10 @@ extern void ima_post_path_mknod(struct user_namespace *mnt_userns,
extern int ima_file_hash(struct file *file, char *buf, size_t buf_size);
extern int ima_inode_hash(struct inode *inode, char *buf, size_t buf_size);
extern void ima_kexec_cmdline(int kernel_fd, const void *buf, int size);
extern void ima_measure_critical_data(const char *event_label,
extern int ima_measure_critical_data(const char *event_label,
				     const char *event_name,
				     const void *buf, size_t buf_len,
				      bool hash);
				     bool hash, u8 *digest, size_t digest_len);

#ifdef CONFIG_IMA_APPRAISE_BOOTPARAM
extern void ima_appraise_parse_cmdline(void);
@@ -64,6 +66,11 @@ static inline const char * const *arch_get_ima_policy(void)
#endif

#else
static inline enum hash_algo ima_get_current_hash_algo(void)
{
	return HASH_ALGO__LAST;
}

static inline int ima_bprm_check(struct linux_binprm *bprm)
{
	return 0;
@@ -137,10 +144,14 @@ static inline int ima_inode_hash(struct inode *inode, char *buf, size_t buf_size

static inline void ima_kexec_cmdline(int kernel_fd, const void *buf, int size) {}

static inline void ima_measure_critical_data(const char *event_label,
static inline int ima_measure_critical_data(const char *event_label,
					     const char *event_name,
					     const void *buf, size_t buf_len,
					     bool hash) {}
					     bool hash, u8 *digest,
					     size_t digest_len)
{
	return -ENOENT;
}

#endif /* CONFIG_IMA */

+0 −1
Original line number Diff line number Diff line
@@ -6,7 +6,6 @@ config IMA
	select SECURITYFS
	select CRYPTO
	select CRYPTO_HMAC
	select CRYPTO_MD5
	select CRYPTO_SHA1
	select CRYPTO_HASH_INFO
	select TCG_TPM if HAS_IOMEM && !UML
+14 −10
Original line number Diff line number Diff line
@@ -46,8 +46,11 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8, TPM_PCR10 = 10 };
/* current content of the policy */
extern int ima_policy_flag;

/* bitset of digests algorithms allowed in the setxattr hook */
extern atomic_t ima_setxattr_allowed_hash_algorithms;

/* set during initialization */
extern int ima_hash_algo;
extern int ima_hash_algo __ro_after_init;
extern int ima_sha1_idx __ro_after_init;
extern int ima_hash_algo_idx __ro_after_init;
extern int ima_extra_slots __ro_after_init;
@@ -198,6 +201,7 @@ static inline unsigned int ima_hash_key(u8 *digest)
	hook(KEXEC_CMDLINE, kexec_cmdline)		\
	hook(KEY_CHECK, key)				\
	hook(CRITICAL_DATA, critical_data)		\
	hook(SETXATTR_CHECK, setxattr_check)		\
	hook(MAX_CHECK, none)

#define __ima_hook_enumify(ENUM, str)	ENUM,
@@ -254,7 +258,7 @@ int ima_get_action(struct user_namespace *mnt_userns, struct inode *inode,
		   const struct cred *cred, u32 secid, int mask,
		   enum ima_hooks func, int *pcr,
		   struct ima_template_desc **template_desc,
		   const char *func_data);
		   const char *func_data, unsigned int *allowed_algos);
int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func);
int ima_collect_measurement(struct integrity_iint_cache *iint,
			    struct file *file, void *buf, loff_t size,
@@ -264,11 +268,11 @@ void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
			   struct evm_ima_xattr_data *xattr_value,
			   int xattr_len, const struct modsig *modsig, int pcr,
			   struct ima_template_desc *template_desc);
void process_buffer_measurement(struct user_namespace *mnt_userns,
int process_buffer_measurement(struct user_namespace *mnt_userns,
			       struct inode *inode, const void *buf, int size,
			       const char *eventname, enum ima_hooks func,
			       int pcr, const char *func_data,
				bool buf_hash);
			       bool buf_hash, u8 *digest, size_t digest_len);
void ima_audit_measurement(struct integrity_iint_cache *iint,
			   const unsigned char *filename);
int ima_alloc_init_template(struct ima_event_data *event_data,
@@ -285,10 +289,10 @@ int ima_match_policy(struct user_namespace *mnt_userns, struct inode *inode,
		     const struct cred *cred, u32 secid, enum ima_hooks func,
		     int mask, int flags, int *pcr,
		     struct ima_template_desc **template_desc,
		     const char *func_data);
		     const char *func_data, unsigned int *allowed_algos);
void ima_init_policy(void);
void ima_update_policy(void);
void ima_update_policy_flag(void);
void ima_update_policy_flags(void);
ssize_t ima_parse_add_rule(char *);
void ima_delete_rules(void);
int ima_check_policy(void);
@@ -319,7 +323,7 @@ int ima_must_appraise(struct user_namespace *mnt_userns, struct inode *inode,
void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
					   enum ima_hooks func);
enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
enum hash_algo ima_get_hash_algo(const struct evm_ima_xattr_data *xattr_value,
				 int xattr_len);
int ima_read_xattr(struct dentry *dentry,
		   struct evm_ima_xattr_data **xattr_value);
Loading