mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-28 20:02:17 +00:00
![Linus Torvalds](/assets/img/avatar_default.png)
Pull integrity updates from Mimi Zohar: "Bug fixes, code clean up, and new features: - IMA policy rules can be defined in terms of LSM labels, making the IMA policy dependent on LSM policy label changes, in particular LSM label deletions. The new environment, in which IMA-appraisal is being used, frequently updates the LSM policy and permits LSM label deletions. - Prevent an mmap'ed shared file opened for write from also being mmap'ed execute. In the long term, making this and other similar changes at the VFS layer would be preferable. - The IMA per policy rule template format support is needed for a couple of new/proposed features (eg. kexec boot command line measurement, appended signatures, and VFS provided file hashes). - Other than the "boot-aggregate" record in the IMA measuremeent list, all other measurements are of file data. Measuring and storing the kexec boot command line in the IMA measurement list is the first buffer based measurement included in the measurement list" * 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity: integrity: Introduce struct evm_xattr ima: Update MAX_TEMPLATE_NAME_LEN to fit largest reasonable definition KEXEC: Call ima_kexec_cmdline to measure the boot command line args IMA: Define a new template field buf IMA: Define a new hook to measure the kexec boot command line arguments IMA: support for per policy rule template formats integrity: Fix __integrity_init_keyring() section mismatch ima: Use designated initializers for struct ima_event_data ima: use the lsm policy update notifier LSM: switch to blocking policy update notifiers x86/ima: fix the Kconfig dependency for IMA_ARCH_POLICY ima: Make arch_policy_entry static ima: prevent a file already mmap'ed write to be mmap'ed execute x86/ima: check EFI SetupMode too
135 lines
3.4 KiB
C
135 lines
3.4 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Copyright (C) 2005,2006,2007,2008 IBM Corporation
|
|
*
|
|
* Authors:
|
|
* Reiner Sailer <sailer@watson.ibm.com>
|
|
* Leendert van Doorn <leendert@watson.ibm.com>
|
|
* Mimi Zohar <zohar@us.ibm.com>
|
|
*
|
|
* File: ima_init.c
|
|
* initialization and cleanup functions
|
|
*/
|
|
|
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
|
|
|
#include <linux/init.h>
|
|
#include <linux/scatterlist.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/err.h>
|
|
|
|
#include "ima.h"
|
|
|
|
/* name for boot aggregate entry */
|
|
static const char boot_aggregate_name[] = "boot_aggregate";
|
|
struct tpm_chip *ima_tpm_chip;
|
|
|
|
/* Add the boot aggregate to the IMA measurement list and extend
|
|
* the PCR register.
|
|
*
|
|
* Calculate the boot aggregate, a SHA1 over tpm registers 0-7,
|
|
* assuming a TPM chip exists, and zeroes if the TPM chip does not
|
|
* exist. Add the boot aggregate measurement to the measurement
|
|
* list and extend the PCR register.
|
|
*
|
|
* If a tpm chip does not exist, indicate the core root of trust is
|
|
* not hardware based by invalidating the aggregate PCR value.
|
|
* (The aggregate PCR value is invalidated by adding one value to
|
|
* the measurement list and extending the aggregate PCR value with
|
|
* a different value.) Violations add a zero entry to the measurement
|
|
* list and extend the aggregate PCR value with ff...ff's.
|
|
*/
|
|
static int __init ima_add_boot_aggregate(void)
|
|
{
|
|
static const char op[] = "add_boot_aggregate";
|
|
const char *audit_cause = "ENOMEM";
|
|
struct ima_template_entry *entry;
|
|
struct integrity_iint_cache tmp_iint, *iint = &tmp_iint;
|
|
struct ima_event_data event_data = { .iint = iint,
|
|
.filename = boot_aggregate_name };
|
|
int result = -ENOMEM;
|
|
int violation = 0;
|
|
struct {
|
|
struct ima_digest_data hdr;
|
|
char digest[TPM_DIGEST_SIZE];
|
|
} hash;
|
|
|
|
memset(iint, 0, sizeof(*iint));
|
|
memset(&hash, 0, sizeof(hash));
|
|
iint->ima_hash = &hash.hdr;
|
|
iint->ima_hash->algo = HASH_ALGO_SHA1;
|
|
iint->ima_hash->length = SHA1_DIGEST_SIZE;
|
|
|
|
if (ima_tpm_chip) {
|
|
result = ima_calc_boot_aggregate(&hash.hdr);
|
|
if (result < 0) {
|
|
audit_cause = "hashing_error";
|
|
goto err_out;
|
|
}
|
|
}
|
|
|
|
result = ima_alloc_init_template(&event_data, &entry, NULL);
|
|
if (result < 0) {
|
|
audit_cause = "alloc_entry";
|
|
goto err_out;
|
|
}
|
|
|
|
result = ima_store_template(entry, violation, NULL,
|
|
boot_aggregate_name,
|
|
CONFIG_IMA_MEASURE_PCR_IDX);
|
|
if (result < 0) {
|
|
ima_free_template_entry(entry);
|
|
audit_cause = "store_entry";
|
|
goto err_out;
|
|
}
|
|
return 0;
|
|
err_out:
|
|
integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, boot_aggregate_name, op,
|
|
audit_cause, result, 0);
|
|
return result;
|
|
}
|
|
|
|
#ifdef CONFIG_IMA_LOAD_X509
|
|
void __init ima_load_x509(void)
|
|
{
|
|
int unset_flags = ima_policy_flag & IMA_APPRAISE;
|
|
|
|
ima_policy_flag &= ~unset_flags;
|
|
integrity_load_x509(INTEGRITY_KEYRING_IMA, CONFIG_IMA_X509_PATH);
|
|
ima_policy_flag |= unset_flags;
|
|
}
|
|
#endif
|
|
|
|
int __init ima_init(void)
|
|
{
|
|
int rc;
|
|
|
|
ima_tpm_chip = tpm_default_chip();
|
|
if (!ima_tpm_chip)
|
|
pr_info("No TPM chip found, activating TPM-bypass!\n");
|
|
|
|
rc = integrity_init_keyring(INTEGRITY_KEYRING_IMA);
|
|
if (rc)
|
|
return rc;
|
|
|
|
rc = ima_init_crypto();
|
|
if (rc)
|
|
return rc;
|
|
rc = ima_init_template();
|
|
if (rc != 0)
|
|
return rc;
|
|
|
|
/* It can be called before ima_init_digests(), it does not use TPM. */
|
|
ima_load_kexec_buffer();
|
|
|
|
rc = ima_init_digests();
|
|
if (rc != 0)
|
|
return rc;
|
|
rc = ima_add_boot_aggregate(); /* boot aggregate must be first entry */
|
|
if (rc != 0)
|
|
return rc;
|
|
|
|
ima_init_policy();
|
|
|
|
return ima_fs_init();
|
|
}
|