]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.19/assoc_array-fix-shortcut-creation.patch
68aca860bf8fec43e2a08629843cb43c8ad88b96
[thirdparty/kernel/stable-queue.git] / queue-4.19 / assoc_array-fix-shortcut-creation.patch
1 From 9863f35dc72aae9495b3646714c056e48247a0e9 Mon Sep 17 00:00:00 2001
2 From: David Howells <dhowells@redhat.com>
3 Date: Thu, 14 Feb 2019 16:20:15 +0000
4 Subject: assoc_array: Fix shortcut creation
5
6 [ Upstream commit bb2ba2d75a2d673e76ddaf13a9bd30d6a8b1bb08 ]
7
8 Fix the creation of shortcuts for which the length of the index key value
9 is an exact multiple of the machine word size. The problem is that the
10 code that blanks off the unused bits of the shortcut value malfunctions if
11 the number of bits in the last word equals machine word size. This is due
12 to the "<<" operator being given a shift of zero in this case, and so the
13 mask that should be all zeros is all ones instead. This causes the
14 subsequent masking operation to clear everything rather than clearing
15 nothing.
16
17 Ordinarily, the presence of the hash at the beginning of the tree index key
18 makes the issue very hard to test for, but in this case, it was encountered
19 due to a development mistake that caused the hash output to be either 0
20 (keyring) or 1 (non-keyring) only. This made it susceptible to the
21 keyctl/unlink/valid test in the keyutils package.
22
23 The fix is simply to skip the blanking if the shift would be 0. For
24 example, an index key that is 64 bits long would produce a 0 shift and thus
25 a 'blank' of all 1s. This would then be inverted and AND'd onto the
26 index_key, incorrectly clearing the entire last word.
27
28 Fixes: 3cb989501c26 ("Add a generic associative array implementation.")
29 Signed-off-by: David Howells <dhowells@redhat.com>
30 Signed-off-by: James Morris <james.morris@microsoft.com>
31 Signed-off-by: Sasha Levin <sashal@kernel.org>
32 ---
33 lib/assoc_array.c | 8 +++++---
34 1 file changed, 5 insertions(+), 3 deletions(-)
35
36 diff --git a/lib/assoc_array.c b/lib/assoc_array.c
37 index c6659cb37033..59875eb278ea 100644
38 --- a/lib/assoc_array.c
39 +++ b/lib/assoc_array.c
40 @@ -768,9 +768,11 @@ all_leaves_cluster_together:
41 new_s0->index_key[i] =
42 ops->get_key_chunk(index_key, i * ASSOC_ARRAY_KEY_CHUNK_SIZE);
43
44 - blank = ULONG_MAX << (level & ASSOC_ARRAY_KEY_CHUNK_MASK);
45 - pr_devel("blank off [%zu] %d: %lx\n", keylen - 1, level, blank);
46 - new_s0->index_key[keylen - 1] &= ~blank;
47 + if (level & ASSOC_ARRAY_KEY_CHUNK_MASK) {
48 + blank = ULONG_MAX << (level & ASSOC_ARRAY_KEY_CHUNK_MASK);
49 + pr_devel("blank off [%zu] %d: %lx\n", keylen - 1, level, blank);
50 + new_s0->index_key[keylen - 1] &= ~blank;
51 + }
52
53 /* This now reduces to a node splitting exercise for which we'll need
54 * to regenerate the disparity table.
55 --
56 2.19.1
57