mirror of
https://github.com/torvalds/linux.git
synced 2026-07-29 10:41:49 +02:00
Hi
This pull request contains bug fixes discussed in [1] and two fixes (in one commit) from Fabrice for DCP trusted keys backend.. BR, Jarkko [1] https://lore.kernel.org/keyrings/amINZJVhEBwxEixP@kernel.org/ -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRE6pSOnaBC00OEHEIaerohdGur0gUCamem9QAKCRAaerohdGur 0nA1AQD4TMj2MpvOW4XREPB05JXeiYFkeDHKZ07o6tvPsTnuTgEA6pjY/Q5MqjLh gAUHzv5mjA4TvrERvDXC+6oh+wiWrwc= =bpHR -----END PGP SIGNATURE----- Merge tag 'for-next-keys-7.2-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd Pull keys fixes from Jarkko Sakkinen: - An unprivileged keyring whose keys collide through the description-chunk path can drive assoc_array node splitting into an out-of-bounds slot write. Fix it. - Fix the DCP trusted keys backend * tag 'for-next-keys-7.2-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd: assoc_array: trim the final shortcut word using the current chunk end keys: make keyring key-chunk byte order agree with keyring_diff_objects() keys: fix out-of-bounds read in keyring_get_key_chunk() KEYS: trusted: dcp: fix key_len validation and calc_blob_len() return type
This commit is contained in:
commit
aa6fc3defb
|
|
@ -255,7 +255,8 @@ assoc_array_walk(const struct assoc_array *array,
|
|||
sc_segments = shortcut->index_key[sc_level >> ASSOC_ARRAY_KEY_CHUNK_SHIFT];
|
||||
dissimilarity = segments ^ sc_segments;
|
||||
|
||||
if (round_up(sc_level, ASSOC_ARRAY_KEY_CHUNK_SIZE) > shortcut->skip_to_level) {
|
||||
if (shortcut->skip_to_level < round_down(sc_level,
|
||||
ASSOC_ARRAY_KEY_CHUNK_SIZE) + ASSOC_ARRAY_KEY_CHUNK_SIZE) {
|
||||
/* Trim segments that are beyond the shortcut */
|
||||
int shift = shortcut->skip_to_level & ASSOC_ARRAY_KEY_CHUNK_MASK;
|
||||
dissimilarity &= ~(ULONG_MAX << shift);
|
||||
|
|
|
|||
|
|
@ -271,6 +271,7 @@ static unsigned long keyring_get_key_chunk(const void *data, int level)
|
|||
unsigned long chunk = 0;
|
||||
const u8 *d;
|
||||
int desc_len = index_key->desc_len, n = sizeof(chunk);
|
||||
unsigned int offset;
|
||||
|
||||
level /= ASSOC_ARRAY_KEY_CHUNK_SIZE;
|
||||
switch (level) {
|
||||
|
|
@ -284,17 +285,18 @@ static unsigned long keyring_get_key_chunk(const void *data, int level)
|
|||
return (unsigned long)index_key->domain_tag;
|
||||
default:
|
||||
level -= 4;
|
||||
if (desc_len <= sizeof(index_key->desc))
|
||||
offset = sizeof(index_key->desc) + level * sizeof(long);
|
||||
if (desc_len <= offset)
|
||||
return 0;
|
||||
|
||||
d = index_key->description + sizeof(index_key->desc);
|
||||
d += level * sizeof(long);
|
||||
desc_len -= sizeof(index_key->desc);
|
||||
d = index_key->description + offset;
|
||||
desc_len -= offset;
|
||||
if (desc_len > n)
|
||||
desc_len = n;
|
||||
d += desc_len;
|
||||
do {
|
||||
chunk <<= 8;
|
||||
chunk |= *d++;
|
||||
chunk |= *--d;
|
||||
} while (--desc_len > 0);
|
||||
return chunk;
|
||||
}
|
||||
|
|
@ -375,7 +377,7 @@ static int keyring_diff_objects(const void *object, const void *data)
|
|||
return -1;
|
||||
|
||||
differ_plus_i:
|
||||
level += i;
|
||||
level += i - (int)sizeof(a->desc);
|
||||
differ:
|
||||
i = level * 8 + __ffs(seg_a ^ seg_b);
|
||||
return i;
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ static bool skip_zk_test;
|
|||
module_param_named(dcp_skip_zk_test, skip_zk_test, bool, 0);
|
||||
MODULE_PARM_DESC(dcp_skip_zk_test, "Don't test whether device keys are zero'ed");
|
||||
|
||||
static unsigned int calc_blob_len(unsigned int payload_len)
|
||||
static size_t calc_blob_len(unsigned int payload_len)
|
||||
{
|
||||
return sizeof(struct dcp_blob_fmt) + payload_len + DCP_BLOB_AUTHLEN;
|
||||
}
|
||||
|
|
@ -200,7 +200,8 @@ static int encrypt_blob_key(u8 *plain_key, u8 *encrypted_key)
|
|||
static int trusted_dcp_seal(struct trusted_key_payload *p, char *datablob)
|
||||
{
|
||||
struct dcp_blob_fmt *b = (struct dcp_blob_fmt *)p->blob;
|
||||
int blen, ret;
|
||||
size_t blen;
|
||||
int ret;
|
||||
u8 *plain_blob_key;
|
||||
|
||||
blen = calc_blob_len(p->key_len);
|
||||
|
|
@ -242,7 +243,8 @@ static int trusted_dcp_seal(struct trusted_key_payload *p, char *datablob)
|
|||
static int trusted_dcp_unseal(struct trusted_key_payload *p, char *datablob)
|
||||
{
|
||||
struct dcp_blob_fmt *b = (struct dcp_blob_fmt *)p->blob;
|
||||
int blen, ret;
|
||||
size_t blen;
|
||||
int ret;
|
||||
u8 *plain_blob_key = NULL;
|
||||
|
||||
if (b->fmt_version != DCP_BLOB_VERSION) {
|
||||
|
|
@ -253,9 +255,14 @@ static int trusted_dcp_unseal(struct trusted_key_payload *p, char *datablob)
|
|||
}
|
||||
|
||||
p->key_len = le32_to_cpu(b->payload_len);
|
||||
if (p->key_len < MIN_KEY_SIZE || p->key_len > MAX_KEY_SIZE) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
blen = calc_blob_len(p->key_len);
|
||||
if (blen != p->blob_len) {
|
||||
pr_err("DCP blob has bad length: %i != %i\n", blen,
|
||||
pr_err("DCP blob has bad length: %zu != %u\n", blen,
|
||||
p->blob_len);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user