Commit f1f2f614 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'next-integrity' of...

Merge branch 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity

Pull integrity updates from Mimi Zohar:
 "The major feature in this time is IMA support for measuring and
  appraising appended file signatures. In addition are a couple of bug
  fixes and code cleanup to use struct_size().

  In addition to the PE/COFF and IMA xattr signatures, the kexec kernel
  image may be signed with an appended signature, using the same
  scripts/sign-file tool that is used to sign kernel modules.

  Similarly, the initramfs may contain an appended signature.

  This contained a lot of refactoring of the existing appended signature
  verification code, so that IMA could retain the existing framework of
  calculating the file hash once, storing it in the IMA measurement list
  and extending the TPM, verifying the file's integrity based on a file
  hash or signature (eg. xattrs), and adding an audit record containing
  the file hash, all based on policy. (The IMA support for appended
  signatures patch set was posted and reviewed 11 times.)

  The support for appended signature paves the way for adding other
  signature verification methods, such as fs-verity, based on a single
  system-wide policy. The file hash used for verifying the signature and
  the signature, itself, can be included in the IMA measurement list"

* 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity:
  ima: ima_api: Use struct_size() in kzalloc()
  ima: use struct_size() in kzalloc()
  sefltest/ima: support appended signatures (modsig)
  ima: Fix use after free in ima_read_modsig()
  MODSIGN: make new include file self contained
  ima: fix freeing ongoing ahash_request
  ima: always return negative code for error
  ima: Store the measurement again when appraising a modsig
  ima: Define ima-modsig template
  ima: Collect modsig
  ima: Implement support for module-style appended signatures
  ima: Factor xattr_verify() out of ima_appraise_measurement()
  ima: Add modsig appraise_type option for module-style appended signatures
  integrity: Select CONFIG_KEYS instead of depending on it
  PKCS#7: Introduce pkcs7_get_digest()
  PKCS#7: Refactor verify_pkcs7_signature()
  MODSIGN: Export module signature definitions
  ima: initialize the "template" field with the default template
parents 298fb76a 2a7f0e53
Loading
Loading
Loading
Loading
+5 −1
Original line number Original line Diff line number Diff line
@@ -37,7 +37,7 @@ Description:
			euid:= decimal value
			euid:= decimal value
			fowner:= decimal value
			fowner:= decimal value
		lsm:  	are LSM specific
		lsm:  	are LSM specific
		option:	appraise_type:= [imasig]
		option:	appraise_type:= [imasig] [imasig|modsig]
			template:= name of a defined IMA template type
			template:= name of a defined IMA template type
			(eg, ima-ng). Only valid when action is "measure".
			(eg, ima-ng). Only valid when action is "measure".
			pcr:= decimal value
			pcr:= decimal value
@@ -105,3 +105,7 @@ Description:


			measure func=KEXEC_KERNEL_CHECK pcr=4
			measure func=KEXEC_KERNEL_CHECK pcr=4
			measure func=KEXEC_INITRAMFS_CHECK pcr=5
			measure func=KEXEC_INITRAMFS_CHECK pcr=5

		Example of appraise rule allowing modsig appended signatures:

			appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig|modsig
+3 −0
Original line number Original line Diff line number Diff line
@@ -68,8 +68,10 @@ descriptors by adding their identifier to the format string
 - 'd-ng': the digest of the event, calculated with an arbitrary hash
 - 'd-ng': the digest of the event, calculated with an arbitrary hash
   algorithm (field format: [<hash algo>:]digest, where the digest
   algorithm (field format: [<hash algo>:]digest, where the digest
   prefix is shown only if the hash algorithm is not SHA1 or MD5);
   prefix is shown only if the hash algorithm is not SHA1 or MD5);
 - 'd-modsig': the digest of the event without the appended modsig;
 - 'n-ng': the name of the event, without size limitations;
 - 'n-ng': the name of the event, without size limitations;
 - 'sig': the file signature;
 - 'sig': the file signature;
 - 'modsig' the appended file signature;
 - 'buf': the buffer data that was used to generate the hash without size limitations;
 - 'buf': the buffer data that was used to generate the hash without size limitations;




@@ -79,6 +81,7 @@ Below, there is the list of defined template descriptors:
 - "ima-ng" (default): its format is ``d-ng|n-ng``;
 - "ima-ng" (default): its format is ``d-ng|n-ng``;
 - "ima-sig": its format is ``d-ng|n-ng|sig``;
 - "ima-sig": its format is ``d-ng|n-ng|sig``;
 - "ima-buf": its format is ``d-ng|n-ng|buf``;
 - "ima-buf": its format is ``d-ng|n-ng|buf``;
 - "ima-modsig": its format is ``d-ng|n-ng|sig|d-modsig|modsig``;




Use
Use
+1 −1
Original line number Original line Diff line number Diff line
@@ -556,7 +556,7 @@ config ARCH_HAS_KEXEC_PURGATORY


config KEXEC_VERIFY_SIG
config KEXEC_VERIFY_SIG
	bool "Verify kernel signature during kexec_file_load() syscall"
	bool "Verify kernel signature during kexec_file_load() syscall"
	depends on KEXEC_FILE && SYSTEM_DATA_VERIFICATION
	depends on KEXEC_FILE && MODULE_SIG_FORMAT
	help
	help
	  This option makes kernel signature verification mandatory for
	  This option makes kernel signature verification mandatory for
	  the kexec_file_load() syscall.
	  the kexec_file_load() syscall.
+1 −23
Original line number Original line Diff line number Diff line
@@ -10,7 +10,7 @@
#include <linux/elf.h>
#include <linux/elf.h>
#include <linux/errno.h>
#include <linux/errno.h>
#include <linux/kexec.h>
#include <linux/kexec.h>
#include <linux/module.h>
#include <linux/module_signature.h>
#include <linux/verification.h>
#include <linux/verification.h>
#include <asm/boot_data.h>
#include <asm/boot_data.h>
#include <asm/ipl.h>
#include <asm/ipl.h>
@@ -23,28 +23,6 @@ const struct kexec_file_ops * const kexec_file_loaders[] = {
};
};


#ifdef CONFIG_KEXEC_VERIFY_SIG
#ifdef CONFIG_KEXEC_VERIFY_SIG
/*
 * Module signature information block.
 *
 * The constituents of the signature section are, in order:
 *
 *	- Signer's name
 *	- Key identifier
 *	- Signature data
 *	- Information block
 */
struct module_signature {
	u8	algo;		/* Public-key crypto algorithm [0] */
	u8	hash;		/* Digest algorithm [0] */
	u8	id_type;	/* Key identifier type [PKEY_ID_PKCS7] */
	u8	signer_len;	/* Length of signer's name [0] */
	u8	key_id_len;	/* Length of key identifier [0] */
	u8	__pad[3];
	__be32	sig_len;	/* Length of signature data */
};

#define PKEY_ID_PKCS7 2

int s390_verify_sig(const char *kernel, unsigned long kernel_len)
int s390_verify_sig(const char *kernel, unsigned long kernel_len)
{
{
	const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1;
	const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1;
+45 −16
Original line number Original line Diff line number Diff line
@@ -190,19 +190,18 @@ late_initcall(load_system_certificate_list);
#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
#ifdef CONFIG_SYSTEM_DATA_VERIFICATION


/**
/**
 * verify_pkcs7_signature - Verify a PKCS#7-based signature on system data.
 * verify_pkcs7_message_sig - Verify a PKCS#7-based signature on system data.
 * @data: The data to be verified (NULL if expecting internal data).
 * @data: The data to be verified (NULL if expecting internal data).
 * @len: Size of @data.
 * @len: Size of @data.
 * @raw_pkcs7: The PKCS#7 message that is the signature.
 * @pkcs7: The PKCS#7 message that is the signature.
 * @pkcs7_len: The size of @raw_pkcs7.
 * @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only,
 * @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only,
 *					(void *)1UL for all trusted keys).
 *					(void *)1UL for all trusted keys).
 * @usage: The use to which the key is being put.
 * @usage: The use to which the key is being put.
 * @view_content: Callback to gain access to content.
 * @view_content: Callback to gain access to content.
 * @ctx: Context for callback.
 * @ctx: Context for callback.
 */
 */
int verify_pkcs7_signature(const void *data, size_t len,
int verify_pkcs7_message_sig(const void *data, size_t len,
			   const void *raw_pkcs7, size_t pkcs7_len,
			     struct pkcs7_message *pkcs7,
			     struct key *trusted_keys,
			     struct key *trusted_keys,
			     enum key_being_used_for usage,
			     enum key_being_used_for usage,
			     int (*view_content)(void *ctx,
			     int (*view_content)(void *ctx,
@@ -210,13 +209,8 @@ int verify_pkcs7_signature(const void *data, size_t len,
						 size_t asn1hdrlen),
						 size_t asn1hdrlen),
			     void *ctx)
			     void *ctx)
{
{
	struct pkcs7_message *pkcs7;
	int ret;
	int ret;


	pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len);
	if (IS_ERR(pkcs7))
		return PTR_ERR(pkcs7);

	/* The data should be detached - so we need to supply it. */
	/* The data should be detached - so we need to supply it. */
	if (data && pkcs7_supply_detached_data(pkcs7, data, len) < 0) {
	if (data && pkcs7_supply_detached_data(pkcs7, data, len) < 0) {
		pr_err("PKCS#7 signature with non-detached data\n");
		pr_err("PKCS#7 signature with non-detached data\n");
@@ -269,6 +263,41 @@ int verify_pkcs7_signature(const void *data, size_t len,
	}
	}


error:
error:
	pr_devel("<==%s() = %d\n", __func__, ret);
	return ret;
}

/**
 * verify_pkcs7_signature - Verify a PKCS#7-based signature on system data.
 * @data: The data to be verified (NULL if expecting internal data).
 * @len: Size of @data.
 * @raw_pkcs7: The PKCS#7 message that is the signature.
 * @pkcs7_len: The size of @raw_pkcs7.
 * @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only,
 *					(void *)1UL for all trusted keys).
 * @usage: The use to which the key is being put.
 * @view_content: Callback to gain access to content.
 * @ctx: Context for callback.
 */
int verify_pkcs7_signature(const void *data, size_t len,
			   const void *raw_pkcs7, size_t pkcs7_len,
			   struct key *trusted_keys,
			   enum key_being_used_for usage,
			   int (*view_content)(void *ctx,
					       const void *data, size_t len,
					       size_t asn1hdrlen),
			   void *ctx)
{
	struct pkcs7_message *pkcs7;
	int ret;

	pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len);
	if (IS_ERR(pkcs7))
		return PTR_ERR(pkcs7);

	ret = verify_pkcs7_message_sig(data, len, pkcs7, trusted_keys, usage,
				       view_content, ctx);

	pkcs7_free_message(pkcs7);
	pkcs7_free_message(pkcs7);
	pr_devel("<==%s() = %d\n", __func__, ret);
	pr_devel("<==%s() = %d\n", __func__, ret);
	return ret;
	return ret;
Loading