]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.4.177/assoc_array-fix-shortcut-creation.patch
Linux 4.4.177
[thirdparty/kernel/stable-queue.git] / releases / 4.4.177 / assoc_array-fix-shortcut-creation.patch
1 From c5fe03ac40ae7f2d86ce613f3d7e24569ec60f01 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 5cd093589c5a..3b46c5433b7a 100644
38 --- a/lib/assoc_array.c
39 +++ b/lib/assoc_array.c
40 @@ -781,9 +781,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