mirror of
https://git.proxmox.com/git/mirror_ubuntu-kernels.git
synced 2025-11-11 20:40:36 +00:00
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
136 lines
3.4 KiB
C
136 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();
|
|
}
|