mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-05 01:54:09 +08:00
8b68150883
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
333 lines
9.8 KiB
C
333 lines
9.8 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Copyright (C) 2005,2006,2007,2008 IBM Corporation
|
|
*
|
|
* Authors:
|
|
* Reiner Sailer <sailer@watson.ibm.com>
|
|
* Mimi Zohar <zohar@us.ibm.com>
|
|
*
|
|
* File: ima.h
|
|
* internal Integrity Measurement Architecture (IMA) definitions
|
|
*/
|
|
|
|
#ifndef __LINUX_IMA_H
|
|
#define __LINUX_IMA_H
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/crypto.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/security.h>
|
|
#include <linux/hash.h>
|
|
#include <linux/tpm.h>
|
|
#include <linux/audit.h>
|
|
#include <crypto/hash_info.h>
|
|
|
|
#include "../integrity.h"
|
|
|
|
#ifdef CONFIG_HAVE_IMA_KEXEC
|
|
#include <asm/ima.h>
|
|
#endif
|
|
|
|
enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_BINARY_NO_FIELD_LEN,
|
|
IMA_SHOW_BINARY_OLD_STRING_FMT, IMA_SHOW_ASCII };
|
|
enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
|
|
|
|
/* digest size for IMA, fits SHA1 or MD5 */
|
|
#define IMA_DIGEST_SIZE SHA1_DIGEST_SIZE
|
|
#define IMA_EVENT_NAME_LEN_MAX 255
|
|
|
|
#define IMA_HASH_BITS 9
|
|
#define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS)
|
|
|
|
#define IMA_TEMPLATE_FIELD_ID_MAX_LEN 16
|
|
#define IMA_TEMPLATE_NUM_FIELDS_MAX 15
|
|
|
|
#define IMA_TEMPLATE_IMA_NAME "ima"
|
|
#define IMA_TEMPLATE_IMA_FMT "d|n"
|
|
|
|
/* current content of the policy */
|
|
extern int ima_policy_flag;
|
|
|
|
/* set during initialization */
|
|
extern int ima_hash_algo;
|
|
extern int ima_appraise;
|
|
extern struct tpm_chip *ima_tpm_chip;
|
|
|
|
/* IMA event related data */
|
|
struct ima_event_data {
|
|
struct integrity_iint_cache *iint;
|
|
struct file *file;
|
|
const unsigned char *filename;
|
|
struct evm_ima_xattr_data *xattr_value;
|
|
int xattr_len;
|
|
const char *violation;
|
|
const void *buf;
|
|
int buf_len;
|
|
};
|
|
|
|
/* IMA template field data definition */
|
|
struct ima_field_data {
|
|
u8 *data;
|
|
u32 len;
|
|
};
|
|
|
|
/* IMA template field definition */
|
|
struct ima_template_field {
|
|
const char field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN];
|
|
int (*field_init)(struct ima_event_data *event_data,
|
|
struct ima_field_data *field_data);
|
|
void (*field_show)(struct seq_file *m, enum ima_show_type show,
|
|
struct ima_field_data *field_data);
|
|
};
|
|
|
|
/* IMA template descriptor definition */
|
|
struct ima_template_desc {
|
|
struct list_head list;
|
|
char *name;
|
|
char *fmt;
|
|
int num_fields;
|
|
const struct ima_template_field **fields;
|
|
};
|
|
|
|
struct ima_template_entry {
|
|
int pcr;
|
|
u8 digest[TPM_DIGEST_SIZE]; /* sha1 or md5 measurement hash */
|
|
struct ima_template_desc *template_desc; /* template descriptor */
|
|
u32 template_data_len;
|
|
struct ima_field_data template_data[0]; /* template related data */
|
|
};
|
|
|
|
struct ima_queue_entry {
|
|
struct hlist_node hnext; /* place in hash collision list */
|
|
struct list_head later; /* place in ima_measurements list */
|
|
struct ima_template_entry *entry;
|
|
};
|
|
extern struct list_head ima_measurements; /* list of all measurements */
|
|
|
|
/* Some details preceding the binary serialized measurement list */
|
|
struct ima_kexec_hdr {
|
|
u16 version;
|
|
u16 _reserved0;
|
|
u32 _reserved1;
|
|
u64 buffer_size;
|
|
u64 count;
|
|
};
|
|
|
|
#ifdef CONFIG_HAVE_IMA_KEXEC
|
|
void ima_load_kexec_buffer(void);
|
|
#else
|
|
static inline void ima_load_kexec_buffer(void) {}
|
|
#endif /* CONFIG_HAVE_IMA_KEXEC */
|
|
|
|
/*
|
|
* The default binary_runtime_measurements list format is defined as the
|
|
* platform native format. The canonical format is defined as little-endian.
|
|
*/
|
|
extern bool ima_canonical_fmt;
|
|
|
|
/* Internal IMA function definitions */
|
|
int ima_init(void);
|
|
int ima_fs_init(void);
|
|
int ima_add_template_entry(struct ima_template_entry *entry, int violation,
|
|
const char *op, struct inode *inode,
|
|
const unsigned char *filename);
|
|
int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash);
|
|
int ima_calc_buffer_hash(const void *buf, loff_t len,
|
|
struct ima_digest_data *hash);
|
|
int ima_calc_field_array_hash(struct ima_field_data *field_data,
|
|
struct ima_template_desc *desc, int num_fields,
|
|
struct ima_digest_data *hash);
|
|
int __init ima_calc_boot_aggregate(struct ima_digest_data *hash);
|
|
void ima_add_violation(struct file *file, const unsigned char *filename,
|
|
struct integrity_iint_cache *iint,
|
|
const char *op, const char *cause);
|
|
int ima_init_crypto(void);
|
|
void ima_putc(struct seq_file *m, void *data, int datalen);
|
|
void ima_print_digest(struct seq_file *m, u8 *digest, u32 size);
|
|
int template_desc_init_fields(const char *template_fmt,
|
|
const struct ima_template_field ***fields,
|
|
int *num_fields);
|
|
struct ima_template_desc *ima_template_desc_current(void);
|
|
struct ima_template_desc *lookup_template_desc(const char *name);
|
|
int ima_restore_measurement_entry(struct ima_template_entry *entry);
|
|
int ima_restore_measurement_list(loff_t bufsize, void *buf);
|
|
int ima_measurements_show(struct seq_file *m, void *v);
|
|
unsigned long ima_get_binary_runtime_size(void);
|
|
int ima_init_template(void);
|
|
void ima_init_template_list(void);
|
|
int __init ima_init_digests(void);
|
|
int ima_lsm_policy_change(struct notifier_block *nb, unsigned long event,
|
|
void *lsm_data);
|
|
|
|
/*
|
|
* used to protect h_table and sha_table
|
|
*/
|
|
extern spinlock_t ima_queue_lock;
|
|
|
|
struct ima_h_table {
|
|
atomic_long_t len; /* number of stored measurements in the list */
|
|
atomic_long_t violations;
|
|
struct hlist_head queue[IMA_MEASURE_HTABLE_SIZE];
|
|
};
|
|
extern struct ima_h_table ima_htable;
|
|
|
|
static inline unsigned long ima_hash_key(u8 *digest)
|
|
{
|
|
return hash_long(*digest, IMA_HASH_BITS);
|
|
}
|
|
|
|
#define __ima_hooks(hook) \
|
|
hook(NONE) \
|
|
hook(FILE_CHECK) \
|
|
hook(MMAP_CHECK) \
|
|
hook(BPRM_CHECK) \
|
|
hook(CREDS_CHECK) \
|
|
hook(POST_SETATTR) \
|
|
hook(MODULE_CHECK) \
|
|
hook(FIRMWARE_CHECK) \
|
|
hook(KEXEC_KERNEL_CHECK) \
|
|
hook(KEXEC_INITRAMFS_CHECK) \
|
|
hook(POLICY_CHECK) \
|
|
hook(KEXEC_CMDLINE) \
|
|
hook(MAX_CHECK)
|
|
#define __ima_hook_enumify(ENUM) ENUM,
|
|
|
|
enum ima_hooks {
|
|
__ima_hooks(__ima_hook_enumify)
|
|
};
|
|
|
|
/* LIM API function definitions */
|
|
int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid,
|
|
int mask, enum ima_hooks func, int *pcr,
|
|
struct ima_template_desc **template_desc);
|
|
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,
|
|
enum hash_algo algo);
|
|
void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
|
|
const unsigned char *filename,
|
|
struct evm_ima_xattr_data *xattr_value,
|
|
int xattr_len, int pcr,
|
|
struct ima_template_desc *template_desc);
|
|
void ima_audit_measurement(struct integrity_iint_cache *iint,
|
|
const unsigned char *filename);
|
|
int ima_alloc_init_template(struct ima_event_data *event_data,
|
|
struct ima_template_entry **entry,
|
|
struct ima_template_desc *template_desc);
|
|
int ima_store_template(struct ima_template_entry *entry, int violation,
|
|
struct inode *inode,
|
|
const unsigned char *filename, int pcr);
|
|
void ima_free_template_entry(struct ima_template_entry *entry);
|
|
const char *ima_d_path(const struct path *path, char **pathbuf, char *filename);
|
|
|
|
/* IMA policy related functions */
|
|
int ima_match_policy(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);
|
|
void ima_init_policy(void);
|
|
void ima_update_policy(void);
|
|
void ima_update_policy_flag(void);
|
|
ssize_t ima_parse_add_rule(char *);
|
|
void ima_delete_rules(void);
|
|
int ima_check_policy(void);
|
|
void *ima_policy_start(struct seq_file *m, loff_t *pos);
|
|
void *ima_policy_next(struct seq_file *m, void *v, loff_t *pos);
|
|
void ima_policy_stop(struct seq_file *m, void *v);
|
|
int ima_policy_show(struct seq_file *m, void *v);
|
|
|
|
/* Appraise integrity measurements */
|
|
#define IMA_APPRAISE_ENFORCE 0x01
|
|
#define IMA_APPRAISE_FIX 0x02
|
|
#define IMA_APPRAISE_LOG 0x04
|
|
#define IMA_APPRAISE_MODULES 0x08
|
|
#define IMA_APPRAISE_FIRMWARE 0x10
|
|
#define IMA_APPRAISE_POLICY 0x20
|
|
#define IMA_APPRAISE_KEXEC 0x40
|
|
|
|
#ifdef CONFIG_IMA_APPRAISE
|
|
int ima_appraise_measurement(enum ima_hooks func,
|
|
struct integrity_iint_cache *iint,
|
|
struct file *file, const unsigned char *filename,
|
|
struct evm_ima_xattr_data *xattr_value,
|
|
int xattr_len);
|
|
int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func);
|
|
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,
|
|
int xattr_len);
|
|
int ima_read_xattr(struct dentry *dentry,
|
|
struct evm_ima_xattr_data **xattr_value);
|
|
|
|
#else
|
|
static inline int ima_appraise_measurement(enum ima_hooks func,
|
|
struct integrity_iint_cache *iint,
|
|
struct file *file,
|
|
const unsigned char *filename,
|
|
struct evm_ima_xattr_data *xattr_value,
|
|
int xattr_len)
|
|
{
|
|
return INTEGRITY_UNKNOWN;
|
|
}
|
|
|
|
static inline int ima_must_appraise(struct inode *inode, int mask,
|
|
enum ima_hooks func)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline void ima_update_xattr(struct integrity_iint_cache *iint,
|
|
struct file *file)
|
|
{
|
|
}
|
|
|
|
static inline enum integrity_status ima_get_cache_status(struct integrity_iint_cache
|
|
*iint,
|
|
enum ima_hooks func)
|
|
{
|
|
return INTEGRITY_UNKNOWN;
|
|
}
|
|
|
|
static inline enum hash_algo
|
|
ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len)
|
|
{
|
|
return ima_hash_algo;
|
|
}
|
|
|
|
static inline int ima_read_xattr(struct dentry *dentry,
|
|
struct evm_ima_xattr_data **xattr_value)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
#endif /* CONFIG_IMA_APPRAISE */
|
|
|
|
/* LSM based policy rules require audit */
|
|
#ifdef CONFIG_IMA_LSM_RULES
|
|
|
|
#define security_filter_rule_init security_audit_rule_init
|
|
#define security_filter_rule_match security_audit_rule_match
|
|
|
|
#else
|
|
|
|
static inline int security_filter_rule_init(u32 field, u32 op, char *rulestr,
|
|
void **lsmrule)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
static inline int security_filter_rule_match(u32 secid, u32 field, u32 op,
|
|
void *lsmrule)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
#endif /* CONFIG_IMA_LSM_RULES */
|
|
|
|
#ifdef CONFIG_IMA_READ_POLICY
|
|
#define POLICY_FILE_FLAGS (S_IWUSR | S_IRUSR)
|
|
#else
|
|
#define POLICY_FILE_FLAGS S_IWUSR
|
|
#endif /* CONFIG_IMA_READ_POLICY */
|
|
|
|
#endif /* __LINUX_IMA_H */
|