Skip to content

Commit ca219be

Browse files
committed
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
2 parents 21e80f3 + b836c4d commit ca219be

File tree

8 files changed

+101
-36
lines changed

8 files changed

+101
-36
lines changed

certs/Kconfig

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,21 @@ config SECONDARY_TRUSTED_KEYRING
8888
help
8989
If set, provide a keyring to which extra keys may be added, provided
9090
those keys are not blacklisted and are vouched for by a key built
91-
into the kernel or already in the secondary trusted keyring.
91+
into the kernel, machine keyring (if configured), or already in the
92+
secondary trusted keyring.
93+
94+
config SECONDARY_TRUSTED_KEYRING_SIGNED_BY_BUILTIN
95+
bool "Only allow additional certs signed by keys on the builtin trusted keyring"
96+
depends on SECONDARY_TRUSTED_KEYRING
97+
help
98+
If set, only certificates signed by keys on the builtin trusted
99+
keyring may be loaded onto the secondary trusted keyring.
100+
101+
Note: The machine keyring, if configured, will be linked to the
102+
secondary keyring. When enabling this option, it is recommended
103+
to also configure INTEGRITY_CA_MACHINE_KEYRING_MAX to prevent
104+
linking code signing keys with imputed trust to the secondary
105+
trusted keyring.
92106

93107
config SYSTEM_BLACKLIST_KEYRING
94108
bool "Provide system-wide ring of blacklisted keys"

crypto/asymmetric_keys/restrict.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ int restrict_link_by_signature(struct key *dest_keyring,
102102

103103
if (use_builtin_keys && !test_bit(KEY_FLAG_BUILTIN, &key->flags))
104104
ret = -ENOKEY;
105+
else if (IS_BUILTIN(CONFIG_SECONDARY_TRUSTED_KEYRING_SIGNED_BY_BUILTIN) &&
106+
!strcmp(dest_keyring->description, ".secondary_trusted_keys") &&
107+
!test_bit(KEY_FLAG_BUILTIN, &key->flags))
108+
ret = -ENOKEY;
105109
else
106110
ret = verify_signature(key, sig);
107111
key_put(key);

fs/overlayfs/super.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1499,7 +1499,7 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
14991499
#ifdef CONFIG_FS_POSIX_ACL
15001500
sb->s_flags |= SB_POSIXACL;
15011501
#endif
1502-
sb->s_iflags |= SB_I_SKIP_SYNC | SB_I_IMA_UNVERIFIABLE_SIGNATURE;
1502+
sb->s_iflags |= SB_I_SKIP_SYNC;
15031503
/*
15041504
* Ensure that umask handling is done by the filesystems used
15051505
* for the the upper layer instead of overlayfs as that would

security/integrity/Kconfig

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ config INTEGRITY_ASYMMETRIC_KEYS
3434
bool "Enable asymmetric keys support"
3535
depends on INTEGRITY_SIGNATURE
3636
default n
37-
select ASYMMETRIC_KEY_TYPE
38-
select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
39-
select CRYPTO_RSA
40-
select X509_CERTIFICATE_PARSER
37+
select ASYMMETRIC_KEY_TYPE
38+
select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
39+
select CRYPTO_RSA
40+
select X509_CERTIFICATE_PARSER
4141
help
4242
This option enables digital signature verification using
4343
asymmetric keys.
@@ -53,14 +53,14 @@ config INTEGRITY_TRUSTED_KEYRING
5353
keyring.
5454

5555
config INTEGRITY_PLATFORM_KEYRING
56-
bool "Provide keyring for platform/firmware trusted keys"
57-
depends on INTEGRITY_ASYMMETRIC_KEYS
58-
depends on SYSTEM_BLACKLIST_KEYRING
59-
help
60-
Provide a separate, distinct keyring for platform trusted keys, which
61-
the kernel automatically populates during initialization from values
62-
provided by the platform for verifying the kexec'ed kerned image
63-
and, possibly, the initramfs signature.
56+
bool "Provide keyring for platform/firmware trusted keys"
57+
depends on INTEGRITY_ASYMMETRIC_KEYS
58+
depends on SYSTEM_BLACKLIST_KEYRING
59+
help
60+
Provide a separate, distinct keyring for platform trusted keys, which
61+
the kernel automatically populates during initialization from values
62+
provided by the platform for verifying the kexec'ed kerned image
63+
and, possibly, the initramfs signature.
6464

6565
config INTEGRITY_MACHINE_KEYRING
6666
bool "Provide a keyring to which Machine Owner Keys may be added"
@@ -69,10 +69,10 @@ config INTEGRITY_MACHINE_KEYRING
6969
depends on SYSTEM_BLACKLIST_KEYRING
7070
depends on LOAD_UEFI_KEYS || LOAD_PPC_KEYS
7171
help
72-
If set, provide a keyring to which Machine Owner Keys (MOK) may
73-
be added. This keyring shall contain just MOK keys. Unlike keys
74-
in the platform keyring, keys contained in the .machine keyring will
75-
be trusted within the kernel.
72+
If set, provide a keyring to which Machine Owner Keys (MOK) may
73+
be added. This keyring shall contain just MOK keys. Unlike keys
74+
in the platform keyring, keys contained in the .machine keyring will
75+
be trusted within the kernel.
7676

7777
config INTEGRITY_CA_MACHINE_KEYRING
7878
bool "Enforce Machine Keyring CA Restrictions"
@@ -97,14 +97,14 @@ config INTEGRITY_CA_MACHINE_KEYRING_MAX
9797
.platform keyring.
9898

9999
config LOAD_UEFI_KEYS
100-
depends on INTEGRITY_PLATFORM_KEYRING
101-
depends on EFI
102-
def_bool y
100+
depends on INTEGRITY_PLATFORM_KEYRING
101+
depends on EFI
102+
def_bool y
103103

104104
config LOAD_IPL_KEYS
105-
depends on INTEGRITY_PLATFORM_KEYRING
106-
depends on S390
107-
def_bool y
105+
depends on INTEGRITY_PLATFORM_KEYRING
106+
depends on S390
107+
def_bool y
108108

109109
config LOAD_PPC_KEYS
110110
bool "Enable loading of platform and blacklisted keys for POWER"

security/integrity/iint.c

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,32 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode)
6666
return iint;
6767
}
6868

69-
static void iint_free(struct integrity_iint_cache *iint)
69+
#define IMA_MAX_NESTING (FILESYSTEM_MAX_STACK_DEPTH+1)
70+
71+
/*
72+
* It is not clear that IMA should be nested at all, but as long is it measures
73+
* files both on overlayfs and on underlying fs, we need to annotate the iint
74+
* mutex to avoid lockdep false positives related to IMA + overlayfs.
75+
* See ovl_lockdep_annotate_inode_mutex_key() for more details.
76+
*/
77+
static inline void iint_lockdep_annotate(struct integrity_iint_cache *iint,
78+
struct inode *inode)
79+
{
80+
#ifdef CONFIG_LOCKDEP
81+
static struct lock_class_key iint_mutex_key[IMA_MAX_NESTING];
82+
83+
int depth = inode->i_sb->s_stack_depth;
84+
85+
if (WARN_ON_ONCE(depth < 0 || depth >= IMA_MAX_NESTING))
86+
depth = 0;
87+
88+
lockdep_set_class(&iint->mutex, &iint_mutex_key[depth]);
89+
#endif
90+
}
91+
92+
static void iint_init_always(struct integrity_iint_cache *iint,
93+
struct inode *inode)
7094
{
71-
kfree(iint->ima_hash);
7295
iint->ima_hash = NULL;
7396
iint->version = 0;
7497
iint->flags = 0UL;
@@ -80,6 +103,14 @@ static void iint_free(struct integrity_iint_cache *iint)
80103
iint->ima_creds_status = INTEGRITY_UNKNOWN;
81104
iint->evm_status = INTEGRITY_UNKNOWN;
82105
iint->measured_pcrs = 0;
106+
mutex_init(&iint->mutex);
107+
iint_lockdep_annotate(iint, inode);
108+
}
109+
110+
static void iint_free(struct integrity_iint_cache *iint)
111+
{
112+
kfree(iint->ima_hash);
113+
mutex_destroy(&iint->mutex);
83114
kmem_cache_free(iint_cache, iint);
84115
}
85116

@@ -104,6 +135,8 @@ struct integrity_iint_cache *integrity_inode_get(struct inode *inode)
104135
if (!iint)
105136
return NULL;
106137

138+
iint_init_always(iint, inode);
139+
107140
write_lock(&integrity_iint_lock);
108141

109142
p = &integrity_iint_tree.rb_node;
@@ -153,25 +186,18 @@ void integrity_inode_free(struct inode *inode)
153186
iint_free(iint);
154187
}
155188

156-
static void init_once(void *foo)
189+
static void iint_init_once(void *foo)
157190
{
158191
struct integrity_iint_cache *iint = (struct integrity_iint_cache *) foo;
159192

160193
memset(iint, 0, sizeof(*iint));
161-
iint->ima_file_status = INTEGRITY_UNKNOWN;
162-
iint->ima_mmap_status = INTEGRITY_UNKNOWN;
163-
iint->ima_bprm_status = INTEGRITY_UNKNOWN;
164-
iint->ima_read_status = INTEGRITY_UNKNOWN;
165-
iint->ima_creds_status = INTEGRITY_UNKNOWN;
166-
iint->evm_status = INTEGRITY_UNKNOWN;
167-
mutex_init(&iint->mutex);
168194
}
169195

170196
static int __init integrity_iintcache_init(void)
171197
{
172198
iint_cache =
173199
kmem_cache_create("iint_cache", sizeof(struct integrity_iint_cache),
174-
0, SLAB_PANIC, init_once);
200+
0, SLAB_PANIC, iint_init_once);
175201
return 0;
176202
}
177203
DEFINE_LSM(integrity) = {

security/integrity/ima/ima_api.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
243243
{
244244
const char *audit_cause = "failed";
245245
struct inode *inode = file_inode(file);
246+
struct inode *real_inode = d_real_inode(file_dentry(file));
246247
const char *filename = file->f_path.dentry->d_name.name;
247248
struct ima_max_digest_data hash;
248249
struct kstat stat;
@@ -302,6 +303,10 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
302303
iint->ima_hash = tmpbuf;
303304
memcpy(iint->ima_hash, &hash, length);
304305
iint->version = i_version;
306+
if (real_inode != inode) {
307+
iint->real_ino = real_inode->i_ino;
308+
iint->real_dev = real_inode->i_sb->s_dev;
309+
}
305310

306311
/* Possibly temporary failure due to type of read (eg. O_DIRECT) */
307312
if (!result)

security/integrity/ima/ima_main.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <linux/xattr.h>
2626
#include <linux/ima.h>
2727
#include <linux/fs.h>
28+
#include <linux/iversion.h>
2829

2930
#include "ima.h"
3031

@@ -207,7 +208,7 @@ static int process_measurement(struct file *file, const struct cred *cred,
207208
u32 secid, char *buf, loff_t size, int mask,
208209
enum ima_hooks func)
209210
{
210-
struct inode *inode = file_inode(file);
211+
struct inode *backing_inode, *inode = file_inode(file);
211212
struct integrity_iint_cache *iint = NULL;
212213
struct ima_template_desc *template_desc = NULL;
213214
char *pathbuf = NULL;
@@ -284,6 +285,19 @@ static int process_measurement(struct file *file, const struct cred *cred,
284285
iint->measured_pcrs = 0;
285286
}
286287

288+
/* Detect and re-evaluate changes made to the backing file. */
289+
backing_inode = d_real_inode(file_dentry(file));
290+
if (backing_inode != inode &&
291+
(action & IMA_DO_MASK) && (iint->flags & IMA_DONE_MASK)) {
292+
if (!IS_I_VERSION(backing_inode) ||
293+
backing_inode->i_sb->s_dev != iint->real_dev ||
294+
backing_inode->i_ino != iint->real_ino ||
295+
!inode_eq_iversion(backing_inode, iint->version)) {
296+
iint->flags &= ~IMA_DONE_MASK;
297+
iint->measured_pcrs = 0;
298+
}
299+
}
300+
287301
/* Determine if already appraised/measured based on bitmask
288302
* (IMA_MEASURE, IMA_MEASURED, IMA_XXXX_APPRAISE, IMA_XXXX_APPRAISED,
289303
* IMA_AUDIT, IMA_AUDITED)

security/integrity/integrity.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ struct integrity_iint_cache {
164164
unsigned long flags;
165165
unsigned long measured_pcrs;
166166
unsigned long atomic_flags;
167+
unsigned long real_ino;
168+
dev_t real_dev;
167169
enum integrity_status ima_file_status:4;
168170
enum integrity_status ima_mmap_status:4;
169171
enum integrity_status ima_bprm_status:4;

0 commit comments

Comments
 (0)