mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-28 16:53:49 +00:00
integrity-v6.7
-----BEGIN PGP SIGNATURE----- iIoEABYIADIWIQQdXVVFGN5XqKr1Hj7LwZzRsCrn5QUCZUDyWhQcem9oYXJAbGlu dXguaWJtLmNvbQAKCRDLwZzRsCrn5QtIAPwLSdHw2qix1A6lMhbRiXqFOWINHcTF DMtZkiPmpeuTKAEA0KaXfddKq5OC5S/ixPEEZCVqOq2ixxfMDhudyoh/qQs= =lh3g -----END PGP SIGNATURE----- Merge tag 'integrity-v6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity Pull integrity updates from Mimi Zohar: "Four integrity changes: two IMA-overlay updates, an integrity Kconfig cleanup, and a secondary keyring update" * tag 'integrity-v6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity: ima: detect changes to the backing overlay file certs: Only allow certs signed by keys on the builtin keyring integrity: fix indentation of config attributes ima: annotate iint mutex to avoid lockdep false positive warnings
This commit is contained in:
commit
ca219be012
@ -88,7 +88,21 @@ config SECONDARY_TRUSTED_KEYRING
|
||||
help
|
||||
If set, provide a keyring to which extra keys may be added, provided
|
||||
those keys are not blacklisted and are vouched for by a key built
|
||||
into the kernel or already in the secondary trusted keyring.
|
||||
into the kernel, machine keyring (if configured), or already in the
|
||||
secondary trusted keyring.
|
||||
|
||||
config SECONDARY_TRUSTED_KEYRING_SIGNED_BY_BUILTIN
|
||||
bool "Only allow additional certs signed by keys on the builtin trusted keyring"
|
||||
depends on SECONDARY_TRUSTED_KEYRING
|
||||
help
|
||||
If set, only certificates signed by keys on the builtin trusted
|
||||
keyring may be loaded onto the secondary trusted keyring.
|
||||
|
||||
Note: The machine keyring, if configured, will be linked to the
|
||||
secondary keyring. When enabling this option, it is recommended
|
||||
to also configure INTEGRITY_CA_MACHINE_KEYRING_MAX to prevent
|
||||
linking code signing keys with imputed trust to the secondary
|
||||
trusted keyring.
|
||||
|
||||
config SYSTEM_BLACKLIST_KEYRING
|
||||
bool "Provide system-wide ring of blacklisted keys"
|
||||
|
@ -102,6 +102,10 @@ int restrict_link_by_signature(struct key *dest_keyring,
|
||||
|
||||
if (use_builtin_keys && !test_bit(KEY_FLAG_BUILTIN, &key->flags))
|
||||
ret = -ENOKEY;
|
||||
else if (IS_BUILTIN(CONFIG_SECONDARY_TRUSTED_KEYRING_SIGNED_BY_BUILTIN) &&
|
||||
!strcmp(dest_keyring->description, ".secondary_trusted_keys") &&
|
||||
!test_bit(KEY_FLAG_BUILTIN, &key->flags))
|
||||
ret = -ENOKEY;
|
||||
else
|
||||
ret = verify_signature(key, sig);
|
||||
key_put(key);
|
||||
|
@ -1499,7 +1499,7 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
|
||||
#ifdef CONFIG_FS_POSIX_ACL
|
||||
sb->s_flags |= SB_POSIXACL;
|
||||
#endif
|
||||
sb->s_iflags |= SB_I_SKIP_SYNC | SB_I_IMA_UNVERIFIABLE_SIGNATURE;
|
||||
sb->s_iflags |= SB_I_SKIP_SYNC;
|
||||
/*
|
||||
* Ensure that umask handling is done by the filesystems used
|
||||
* for the the upper layer instead of overlayfs as that would
|
||||
|
@ -34,10 +34,10 @@ config INTEGRITY_ASYMMETRIC_KEYS
|
||||
bool "Enable asymmetric keys support"
|
||||
depends on INTEGRITY_SIGNATURE
|
||||
default n
|
||||
select ASYMMETRIC_KEY_TYPE
|
||||
select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
|
||||
select CRYPTO_RSA
|
||||
select X509_CERTIFICATE_PARSER
|
||||
select ASYMMETRIC_KEY_TYPE
|
||||
select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
|
||||
select CRYPTO_RSA
|
||||
select X509_CERTIFICATE_PARSER
|
||||
help
|
||||
This option enables digital signature verification using
|
||||
asymmetric keys.
|
||||
@ -53,14 +53,14 @@ config INTEGRITY_TRUSTED_KEYRING
|
||||
keyring.
|
||||
|
||||
config INTEGRITY_PLATFORM_KEYRING
|
||||
bool "Provide keyring for platform/firmware trusted keys"
|
||||
depends on INTEGRITY_ASYMMETRIC_KEYS
|
||||
depends on SYSTEM_BLACKLIST_KEYRING
|
||||
help
|
||||
Provide a separate, distinct keyring for platform trusted keys, which
|
||||
the kernel automatically populates during initialization from values
|
||||
provided by the platform for verifying the kexec'ed kerned image
|
||||
and, possibly, the initramfs signature.
|
||||
bool "Provide keyring for platform/firmware trusted keys"
|
||||
depends on INTEGRITY_ASYMMETRIC_KEYS
|
||||
depends on SYSTEM_BLACKLIST_KEYRING
|
||||
help
|
||||
Provide a separate, distinct keyring for platform trusted keys, which
|
||||
the kernel automatically populates during initialization from values
|
||||
provided by the platform for verifying the kexec'ed kerned image
|
||||
and, possibly, the initramfs signature.
|
||||
|
||||
config INTEGRITY_MACHINE_KEYRING
|
||||
bool "Provide a keyring to which Machine Owner Keys may be added"
|
||||
@ -69,10 +69,10 @@ config INTEGRITY_MACHINE_KEYRING
|
||||
depends on SYSTEM_BLACKLIST_KEYRING
|
||||
depends on LOAD_UEFI_KEYS || LOAD_PPC_KEYS
|
||||
help
|
||||
If set, provide a keyring to which Machine Owner Keys (MOK) may
|
||||
be added. This keyring shall contain just MOK keys. Unlike keys
|
||||
in the platform keyring, keys contained in the .machine keyring will
|
||||
be trusted within the kernel.
|
||||
If set, provide a keyring to which Machine Owner Keys (MOK) may
|
||||
be added. This keyring shall contain just MOK keys. Unlike keys
|
||||
in the platform keyring, keys contained in the .machine keyring will
|
||||
be trusted within the kernel.
|
||||
|
||||
config INTEGRITY_CA_MACHINE_KEYRING
|
||||
bool "Enforce Machine Keyring CA Restrictions"
|
||||
@ -97,14 +97,14 @@ config INTEGRITY_CA_MACHINE_KEYRING_MAX
|
||||
.platform keyring.
|
||||
|
||||
config LOAD_UEFI_KEYS
|
||||
depends on INTEGRITY_PLATFORM_KEYRING
|
||||
depends on EFI
|
||||
def_bool y
|
||||
depends on INTEGRITY_PLATFORM_KEYRING
|
||||
depends on EFI
|
||||
def_bool y
|
||||
|
||||
config LOAD_IPL_KEYS
|
||||
depends on INTEGRITY_PLATFORM_KEYRING
|
||||
depends on S390
|
||||
def_bool y
|
||||
depends on INTEGRITY_PLATFORM_KEYRING
|
||||
depends on S390
|
||||
def_bool y
|
||||
|
||||
config LOAD_PPC_KEYS
|
||||
bool "Enable loading of platform and blacklisted keys for POWER"
|
||||
|
@ -66,9 +66,32 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode)
|
||||
return iint;
|
||||
}
|
||||
|
||||
static void iint_free(struct integrity_iint_cache *iint)
|
||||
#define IMA_MAX_NESTING (FILESYSTEM_MAX_STACK_DEPTH+1)
|
||||
|
||||
/*
|
||||
* It is not clear that IMA should be nested at all, but as long is it measures
|
||||
* files both on overlayfs and on underlying fs, we need to annotate the iint
|
||||
* mutex to avoid lockdep false positives related to IMA + overlayfs.
|
||||
* See ovl_lockdep_annotate_inode_mutex_key() for more details.
|
||||
*/
|
||||
static inline void iint_lockdep_annotate(struct integrity_iint_cache *iint,
|
||||
struct inode *inode)
|
||||
{
|
||||
#ifdef CONFIG_LOCKDEP
|
||||
static struct lock_class_key iint_mutex_key[IMA_MAX_NESTING];
|
||||
|
||||
int depth = inode->i_sb->s_stack_depth;
|
||||
|
||||
if (WARN_ON_ONCE(depth < 0 || depth >= IMA_MAX_NESTING))
|
||||
depth = 0;
|
||||
|
||||
lockdep_set_class(&iint->mutex, &iint_mutex_key[depth]);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void iint_init_always(struct integrity_iint_cache *iint,
|
||||
struct inode *inode)
|
||||
{
|
||||
kfree(iint->ima_hash);
|
||||
iint->ima_hash = NULL;
|
||||
iint->version = 0;
|
||||
iint->flags = 0UL;
|
||||
@ -80,6 +103,14 @@ static void iint_free(struct integrity_iint_cache *iint)
|
||||
iint->ima_creds_status = INTEGRITY_UNKNOWN;
|
||||
iint->evm_status = INTEGRITY_UNKNOWN;
|
||||
iint->measured_pcrs = 0;
|
||||
mutex_init(&iint->mutex);
|
||||
iint_lockdep_annotate(iint, inode);
|
||||
}
|
||||
|
||||
static void iint_free(struct integrity_iint_cache *iint)
|
||||
{
|
||||
kfree(iint->ima_hash);
|
||||
mutex_destroy(&iint->mutex);
|
||||
kmem_cache_free(iint_cache, iint);
|
||||
}
|
||||
|
||||
@ -104,6 +135,8 @@ struct integrity_iint_cache *integrity_inode_get(struct inode *inode)
|
||||
if (!iint)
|
||||
return NULL;
|
||||
|
||||
iint_init_always(iint, inode);
|
||||
|
||||
write_lock(&integrity_iint_lock);
|
||||
|
||||
p = &integrity_iint_tree.rb_node;
|
||||
@ -153,25 +186,18 @@ void integrity_inode_free(struct inode *inode)
|
||||
iint_free(iint);
|
||||
}
|
||||
|
||||
static void init_once(void *foo)
|
||||
static void iint_init_once(void *foo)
|
||||
{
|
||||
struct integrity_iint_cache *iint = (struct integrity_iint_cache *) foo;
|
||||
|
||||
memset(iint, 0, sizeof(*iint));
|
||||
iint->ima_file_status = INTEGRITY_UNKNOWN;
|
||||
iint->ima_mmap_status = INTEGRITY_UNKNOWN;
|
||||
iint->ima_bprm_status = INTEGRITY_UNKNOWN;
|
||||
iint->ima_read_status = INTEGRITY_UNKNOWN;
|
||||
iint->ima_creds_status = INTEGRITY_UNKNOWN;
|
||||
iint->evm_status = INTEGRITY_UNKNOWN;
|
||||
mutex_init(&iint->mutex);
|
||||
}
|
||||
|
||||
static int __init integrity_iintcache_init(void)
|
||||
{
|
||||
iint_cache =
|
||||
kmem_cache_create("iint_cache", sizeof(struct integrity_iint_cache),
|
||||
0, SLAB_PANIC, init_once);
|
||||
0, SLAB_PANIC, iint_init_once);
|
||||
return 0;
|
||||
}
|
||||
DEFINE_LSM(integrity) = {
|
||||
|
@ -243,6 +243,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
|
||||
{
|
||||
const char *audit_cause = "failed";
|
||||
struct inode *inode = file_inode(file);
|
||||
struct inode *real_inode = d_real_inode(file_dentry(file));
|
||||
const char *filename = file->f_path.dentry->d_name.name;
|
||||
struct ima_max_digest_data hash;
|
||||
struct kstat stat;
|
||||
@ -302,6 +303,10 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
|
||||
iint->ima_hash = tmpbuf;
|
||||
memcpy(iint->ima_hash, &hash, length);
|
||||
iint->version = i_version;
|
||||
if (real_inode != inode) {
|
||||
iint->real_ino = real_inode->i_ino;
|
||||
iint->real_dev = real_inode->i_sb->s_dev;
|
||||
}
|
||||
|
||||
/* Possibly temporary failure due to type of read (eg. O_DIRECT) */
|
||||
if (!result)
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <linux/xattr.h>
|
||||
#include <linux/ima.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/iversion.h>
|
||||
|
||||
#include "ima.h"
|
||||
|
||||
@ -207,7 +208,7 @@ static int process_measurement(struct file *file, const struct cred *cred,
|
||||
u32 secid, char *buf, loff_t size, int mask,
|
||||
enum ima_hooks func)
|
||||
{
|
||||
struct inode *inode = file_inode(file);
|
||||
struct inode *backing_inode, *inode = file_inode(file);
|
||||
struct integrity_iint_cache *iint = NULL;
|
||||
struct ima_template_desc *template_desc = NULL;
|
||||
char *pathbuf = NULL;
|
||||
@ -284,6 +285,19 @@ static int process_measurement(struct file *file, const struct cred *cred,
|
||||
iint->measured_pcrs = 0;
|
||||
}
|
||||
|
||||
/* Detect and re-evaluate changes made to the backing file. */
|
||||
backing_inode = d_real_inode(file_dentry(file));
|
||||
if (backing_inode != inode &&
|
||||
(action & IMA_DO_MASK) && (iint->flags & IMA_DONE_MASK)) {
|
||||
if (!IS_I_VERSION(backing_inode) ||
|
||||
backing_inode->i_sb->s_dev != iint->real_dev ||
|
||||
backing_inode->i_ino != iint->real_ino ||
|
||||
!inode_eq_iversion(backing_inode, iint->version)) {
|
||||
iint->flags &= ~IMA_DONE_MASK;
|
||||
iint->measured_pcrs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine if already appraised/measured based on bitmask
|
||||
* (IMA_MEASURE, IMA_MEASURED, IMA_XXXX_APPRAISE, IMA_XXXX_APPRAISED,
|
||||
* IMA_AUDIT, IMA_AUDITED)
|
||||
|
@ -164,6 +164,8 @@ struct integrity_iint_cache {
|
||||
unsigned long flags;
|
||||
unsigned long measured_pcrs;
|
||||
unsigned long atomic_flags;
|
||||
unsigned long real_ino;
|
||||
dev_t real_dev;
|
||||
enum integrity_status ima_file_status:4;
|
||||
enum integrity_status ima_mmap_status:4;
|
||||
enum integrity_status ima_bprm_status:4;
|
||||
|
Loading…
Reference in New Issue
Block a user