diff options
Diffstat (limited to 'include/linux/nospec.h')
-rw-r--r-- | include/linux/nospec.h | 26 |
1 files changed, 3 insertions, 23 deletions
diff --git a/include/linux/nospec.h b/include/linux/nospec.h index fbc98e2c8228..e791ebc65c9c 100644 --- a/include/linux/nospec.h +++ b/include/linux/nospec.h | |||
@@ -5,6 +5,7 @@ | |||
5 | 5 | ||
6 | #ifndef _LINUX_NOSPEC_H | 6 | #ifndef _LINUX_NOSPEC_H |
7 | #define _LINUX_NOSPEC_H | 7 | #define _LINUX_NOSPEC_H |
8 | #include <asm/barrier.h> | ||
8 | 9 | ||
9 | /** | 10 | /** |
10 | * array_index_mask_nospec() - generate a ~0 mask when index < size, 0 otherwise | 11 | * array_index_mask_nospec() - generate a ~0 mask when index < size, 0 otherwise |
@@ -30,26 +31,6 @@ static inline unsigned long array_index_mask_nospec(unsigned long index, | |||
30 | #endif | 31 | #endif |
31 | 32 | ||
32 | /* | 33 | /* |
33 | * Warn developers about inappropriate array_index_nospec() usage. | ||
34 | * | ||
35 | * Even if the CPU speculates past the WARN_ONCE branch, the | ||
36 | * sign bit of @index is taken into account when generating the | ||
37 | * mask. | ||
38 | * | ||
39 | * This warning is compiled out when the compiler can infer that | ||
40 | * @index and @size are less than LONG_MAX. | ||
41 | */ | ||
42 | #define array_index_mask_nospec_check(index, size) \ | ||
43 | ({ \ | ||
44 | if (WARN_ONCE(index > LONG_MAX || size > LONG_MAX, \ | ||
45 | "array_index_nospec() limited to range of [0, LONG_MAX]\n")) \ | ||
46 | _mask = 0; \ | ||
47 | else \ | ||
48 | _mask = array_index_mask_nospec(index, size); \ | ||
49 | _mask; \ | ||
50 | }) | ||
51 | |||
52 | /* | ||
53 | * array_index_nospec - sanitize an array index after a bounds check | 34 | * array_index_nospec - sanitize an array index after a bounds check |
54 | * | 35 | * |
55 | * For a code sequence like: | 36 | * For a code sequence like: |
@@ -67,12 +48,11 @@ static inline unsigned long array_index_mask_nospec(unsigned long index, | |||
67 | ({ \ | 48 | ({ \ |
68 | typeof(index) _i = (index); \ | 49 | typeof(index) _i = (index); \ |
69 | typeof(size) _s = (size); \ | 50 | typeof(size) _s = (size); \ |
70 | unsigned long _mask = array_index_mask_nospec_check(_i, _s); \ | 51 | unsigned long _mask = array_index_mask_nospec(_i, _s); \ |
71 | \ | 52 | \ |
72 | BUILD_BUG_ON(sizeof(_i) > sizeof(long)); \ | 53 | BUILD_BUG_ON(sizeof(_i) > sizeof(long)); \ |
73 | BUILD_BUG_ON(sizeof(_s) > sizeof(long)); \ | 54 | BUILD_BUG_ON(sizeof(_s) > sizeof(long)); \ |
74 | \ | 55 | \ |
75 | _i &= _mask; \ | 56 | (typeof(_i)) (_i & _mask); \ |
76 | _i; \ | ||
77 | }) | 57 | }) |
78 | #endif /* _LINUX_NOSPEC_H */ | 58 | #endif /* _LINUX_NOSPEC_H */ |