* [PATCH v2 0/3] overflow.h: Add arithmetic shift helper
@ 2018-08-01 0:00 Kees Cook
2018-08-01 0:00 ` [PATCH v2 1/3] " Kees Cook
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Kees Cook @ 2018-08-01 0:00 UTC (permalink / raw)
To: Rasmus Villemoes
Cc: Kees Cook, Jason Gunthorpe, Leon Romanovsky, Bart Van Assche,
Doug Ledford, Dan Carpenter, linux-rdma, linux-kernel
This adds the shift overflow helper, selftests, and first usage.
-Kees
Jason Gunthorpe (1):
overflow.h: Add arithmetic shift helper
Kees Cook (1):
test_overflow: Add shift overflow tests
Leon Romanovsky (1):
RDMA/mlx5: Fix shift overflow in mlx5_ib_create_wq
drivers/infiniband/hw/mlx5/qp.c | 5 +-
include/linux/overflow.h | 31 +++++++
lib/test_overflow.c | 140 +++++++++++++++++++++++++++++++-
3 files changed, 174 insertions(+), 2 deletions(-)
--
2.17.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 1/3] overflow.h: Add arithmetic shift helper
2018-08-01 0:00 [PATCH v2 0/3] overflow.h: Add arithmetic shift helper Kees Cook
@ 2018-08-01 0:00 ` Kees Cook
2018-08-01 1:59 ` Randy Dunlap
` (2 more replies)
2018-08-01 0:00 ` [PATCH v2 2/3] test_overflow: Add shift overflow tests Kees Cook
2018-08-01 0:00 ` [PATCH v2 3/3] RDMA/mlx5: Fix shift overflow in mlx5_ib_create_wq Kees Cook
2 siblings, 3 replies; 13+ messages in thread
From: Kees Cook @ 2018-08-01 0:00 UTC (permalink / raw)
To: Rasmus Villemoes
Cc: Kees Cook, Jason Gunthorpe, Leon Romanovsky, Jason Gunthorpe,
Leon Romanovsky, Bart Van Assche, Doug Ledford, Dan Carpenter,
linux-rdma, linux-kernel
From: Jason Gunthorpe <jgg@mellanox.com>
Add shift_overflow() helper to assist driver authors in ensuring that
shift operations don't cause overflows or other odd conditions.
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
[kees: tweaked comments and commit log, dropped unneeded assignment]
Signed-off-by: Kees Cook <keescook@chromium.org>
---
include/linux/overflow.h | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/include/linux/overflow.h b/include/linux/overflow.h
index 8712ff70995f..69fc366ce865 100644
--- a/include/linux/overflow.h
+++ b/include/linux/overflow.h
@@ -202,6 +202,37 @@
#endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */
+/** check_shift_overflow() - Calculate a left-shifted value and check overflow
+ *
+ * @a: Value to be shifted
+ * @b: How many bits left to shift
+ * @d: Pointer to where to store the result
+ *
+ * Computes *@d = (@a << @s)
+ *
+ * Returns true if '*d' cannot hold the result or when 'a << s' doesn't
+ * make sense. Example conditions:
+ * - 'a << s' causes bits to be lost when stored in *d.
+ * - 's' is garbage (e.g. negative) or so large that the result of
+ * 'a << s' is guaranteed to be 0.
+ * - 'a' is negative.
+ * - 'a << s' sets the sign bit, if any, in '*d'.
+ *
+ * '*d' will hold the results of the attempted shift, but is not
+ * considered "safe for use" if false is returned.
+ */
+#define check_shift_overflow(a, s, d) ({ \
+ typeof(a) _a = a; \
+ typeof(s) _s = s; \
+ typeof(d) _d = d; \
+ u64 _a_full = _a; \
+ unsigned int _to_shift = \
+ _s >= 0 && _s < 8 * sizeof(*d) ? _s : 0; \
+ *_d = (_a_full << _to_shift); \
+ (_to_shift != _s || *_d < 0 || _a < 0 || \
+ (*_d >> _to_shift) != _a); \
+})
+
/**
* array_size() - Calculate size of 2-dimensional array.
*
--
2.17.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 2/3] test_overflow: Add shift overflow tests
2018-08-01 0:00 [PATCH v2 0/3] overflow.h: Add arithmetic shift helper Kees Cook
2018-08-01 0:00 ` [PATCH v2 1/3] " Kees Cook
@ 2018-08-01 0:00 ` Kees Cook
2018-08-01 2:13 ` Jason Gunthorpe
2018-08-01 0:00 ` [PATCH v2 3/3] RDMA/mlx5: Fix shift overflow in mlx5_ib_create_wq Kees Cook
2 siblings, 1 reply; 13+ messages in thread
From: Kees Cook @ 2018-08-01 0:00 UTC (permalink / raw)
To: Rasmus Villemoes
Cc: Kees Cook, Jason Gunthorpe, Leon Romanovsky, Bart Van Assche,
Doug Ledford, Dan Carpenter, linux-rdma, linux-kernel
This adds overflow tests for the new check_shift_overflow() helper to
validate overflow, signedness glitches, storage glitches, etc.
Co-developed-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
lib/test_overflow.c | 140 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 139 insertions(+), 1 deletion(-)
diff --git a/lib/test_overflow.c b/lib/test_overflow.c
index 2278fe05a1b0..face66e8aa37 100644
--- a/lib/test_overflow.c
+++ b/lib/test_overflow.c
@@ -252,7 +252,8 @@ static int __init test_ ## t ## _overflow(void) { \
int err = 0; \
unsigned i; \
\
- pr_info("%-3s: %zu tests\n", #t, ARRAY_SIZE(t ## _tests)); \
+ pr_info("%-3s: %zu arithmetic tests\n", #t, \
+ ARRAY_SIZE(t ## _tests)); \
for (i = 0; i < ARRAY_SIZE(t ## _tests); ++i) \
err |= do_test_ ## t(&t ## _tests[i]); \
return err; \
@@ -287,6 +288,142 @@ static int __init test_overflow_calculation(void)
return err;
}
+static int __init test_overflow_shift(void)
+{
+ int err = 0;
+
+/* Args are: value, shift, type, expected result, overflow expected */
+#define TEST_ONE_SHIFT(a, s, t, expect, of) ({ \
+ int __failed = 0; \
+ typeof(a) __a = (a); \
+ typeof(s) __s = (s); \
+ t __e = (expect); \
+ t __d; \
+ bool __of = check_shift_overflow(__a, __s, &__d); \
+ if (__of != of) { \
+ pr_warn("expected (%s)(%s << %s) to%s overflow\n", \
+ #t, #a, #s, of ? "" : " not"); \
+ __failed = 1; \
+ } else if (!__of && __d != __e) { \
+ pr_warn("expected (%s)(%s << %s) == %s\n", \
+ #t, #a, #s, #expect); \
+ if ((t)-1 < 0) \
+ pr_warn("got %lld\n", (s64)__d); \
+ else \
+ pr_warn("got %llu\n", (u64)__d); \
+ __failed = 1; \
+ } \
+ if (!__failed) \
+ pr_info("ok: (%s)(%s << %s) == %s\n", #t, #a, #s, \
+ of ? "overflow" : #expect); \
+ __failed; \
+})
+
+ /* Sane shifts */
+ err |= TEST_ONE_SHIFT(1, 4, u8, 1 << 4, false);
+ err |= TEST_ONE_SHIFT(1, 7, u8, 1 << 7, false);
+ err |= TEST_ONE_SHIFT(1, 10, u16, 1 << 10, false);
+ err |= TEST_ONE_SHIFT(1, 15, u16, 1 << 15, false);
+ err |= TEST_ONE_SHIFT(1, 30, int, 1 << 30, false);
+ err |= TEST_ONE_SHIFT(1, 30, s32, 1 << 30, false);
+ err |= TEST_ONE_SHIFT(1, 20, unsigned int, 1U << 20, false);
+ err |= TEST_ONE_SHIFT(1, 31, unsigned int, 1U << 31, false);
+ err |= TEST_ONE_SHIFT(1, 20, u32, 1U << 20, false);
+ err |= TEST_ONE_SHIFT(1, 31, u32, 1U << 31, false);
+ err |= TEST_ONE_SHIFT(1, 40, u64, 1ULL << 40, false);
+ err |= TEST_ONE_SHIFT(1, 63, u64, 1ULL << 63, false);
+
+ /* Sane shift: start and end with 0, without a too-wide shift. */
+ err |= TEST_ONE_SHIFT(0, 7, u8, 0, false);
+ err |= TEST_ONE_SHIFT(0, 15, u16, 0, false);
+ err |= TEST_ONE_SHIFT(0, 31, unsigned int, 0, false);
+ err |= TEST_ONE_SHIFT(0, 31, u32, 0, false);
+ err |= TEST_ONE_SHIFT(0, 63, u64, 0, false);
+
+ /* Sane shift: start and end with 0, without reaching signed bit. */
+ err |= TEST_ONE_SHIFT(0, 6, s8, 0, false);
+ err |= TEST_ONE_SHIFT(0, 14, s16, 0, false);
+ err |= TEST_ONE_SHIFT(0, 30, int, 0, false);
+ err |= TEST_ONE_SHIFT(0, 30, s32, 0, false);
+ err |= TEST_ONE_SHIFT(0, 62, s64, 0, false);
+
+ /* Overflow: shifted the bit off the end. */
+ err |= TEST_ONE_SHIFT(1, 8, u8, 0, true);
+ err |= TEST_ONE_SHIFT(1, 16, u16, 0, true);
+ err |= TEST_ONE_SHIFT(1, 32, unsigned int, 0, true);
+ err |= TEST_ONE_SHIFT(1, 32, u32, 0, true);
+ err |= TEST_ONE_SHIFT(1, 64, u64, 0, true);
+
+ /* Overflow: high bit falls off. */
+ /* 10010110 */
+ err |= TEST_ONE_SHIFT(150, 1, u8, 0, true);
+ /* 1000100010010110 */
+ err |= TEST_ONE_SHIFT(34966, 1, u16, 0, true);
+ /* 10000100000010001000100010010110 */
+ err |= TEST_ONE_SHIFT(2215151766U, 1, u32, 0, true);
+ err |= TEST_ONE_SHIFT(2215151766U, 1, unsigned int, 0, true);
+ /* 1000001000010000010000000100000010000100000010001000100010010110 */
+ err |= TEST_ONE_SHIFT(9372061470395238550ULL, 1, u64, 0, true);
+
+ /* Nonsense: negative initial value. */
+ err |= TEST_ONE_SHIFT(-1, 0, s8, 0, true);
+ err |= TEST_ONE_SHIFT(-5, 0, s16, 0, true);
+ err |= TEST_ONE_SHIFT(-10, 0, int, 0, true);
+ err |= TEST_ONE_SHIFT(-100, 0, s32, 0, true);
+ err |= TEST_ONE_SHIFT(-10000, 0, s64, 0, true);
+
+ /* Nonsense: negative shift values. */
+ err |= TEST_ONE_SHIFT(0, -5, s8, 0, true);
+ err |= TEST_ONE_SHIFT(0, -10, s16, 0, true);
+ err |= TEST_ONE_SHIFT(0, -15, int, 0, true);
+ err |= TEST_ONE_SHIFT(0, -20, s32, 0, true);
+ err |= TEST_ONE_SHIFT(0, -30, s64, 0, true);
+
+ /* Overflow: shifted at or beyond entire type's bit width. */
+ err |= TEST_ONE_SHIFT(0, 8, u8, 0, true);
+ err |= TEST_ONE_SHIFT(0, 9, u8, 0, true);
+ err |= TEST_ONE_SHIFT(0, 8, s8, 0, true);
+ err |= TEST_ONE_SHIFT(0, 9, s8, 0, true);
+ err |= TEST_ONE_SHIFT(0, 16, u16, 0, true);
+ err |= TEST_ONE_SHIFT(0, 17, u16, 0, true);
+ err |= TEST_ONE_SHIFT(0, 16, s16, 0, true);
+ err |= TEST_ONE_SHIFT(0, 17, s16, 0, true);
+ err |= TEST_ONE_SHIFT(0, 32, u32, 0, true);
+ err |= TEST_ONE_SHIFT(0, 33, u32, 0, true);
+ err |= TEST_ONE_SHIFT(0, 32, int, 0, true);
+ err |= TEST_ONE_SHIFT(0, 33, int, 0, true);
+ err |= TEST_ONE_SHIFT(0, 32, s32, 0, true);
+ err |= TEST_ONE_SHIFT(0, 33, s32, 0, true);
+ err |= TEST_ONE_SHIFT(0, 64, u64, 0, true);
+ err |= TEST_ONE_SHIFT(0, 65, u64, 0, true);
+ err |= TEST_ONE_SHIFT(0, 64, s64, 0, true);
+ err |= TEST_ONE_SHIFT(0, 65, s64, 0, true);
+
+ /* Overflow: shifted into signed bit. */
+ err |= TEST_ONE_SHIFT(1, 7, s8, 0, true);
+ err |= TEST_ONE_SHIFT(1, 15, s16, 0, true);
+ err |= TEST_ONE_SHIFT(1, 31, int, 0, true);
+ err |= TEST_ONE_SHIFT(1, 31, s32, 0, true);
+ err |= TEST_ONE_SHIFT(1, 63, s64, 0, true);
+
+ /*
+ * Corner case: for unsigned types, we fail when we've shifted
+ * through the entire width of bits. For signed types, we might
+ * want to match this behavior, but that would mean noticing if
+ * we shift through all but the signed bit, and this is not
+ * currently detected (but we'll notice an overflow into the
+ * signed bit). So, for now, we will test this condition but
+ * mark it as not expected to overflow.
+ */
+ err |= TEST_ONE_SHIFT(0, 7, s8, 0, false);
+ err |= TEST_ONE_SHIFT(0, 15, s16, 0, false);
+ err |= TEST_ONE_SHIFT(0, 31, int, 0, false);
+ err |= TEST_ONE_SHIFT(0, 31, s32, 0, false);
+ err |= TEST_ONE_SHIFT(0, 63, s64, 0, false);
+
+ return err;
+}
+
/*
* Deal with the various forms of allocator arguments. See comments above
* the DEFINE_TEST_ALLOC() instances for mapping of the "bits".
@@ -397,6 +534,7 @@ static int __init test_module_init(void)
int err = 0;
err |= test_overflow_calculation();
+ err |= test_overflow_shift();
err |= test_overflow_allocation();
if (err) {
--
2.17.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 3/3] RDMA/mlx5: Fix shift overflow in mlx5_ib_create_wq
2018-08-01 0:00 [PATCH v2 0/3] overflow.h: Add arithmetic shift helper Kees Cook
2018-08-01 0:00 ` [PATCH v2 1/3] " Kees Cook
2018-08-01 0:00 ` [PATCH v2 2/3] test_overflow: Add shift overflow tests Kees Cook
@ 2018-08-01 0:00 ` Kees Cook
2 siblings, 0 replies; 13+ messages in thread
From: Kees Cook @ 2018-08-01 0:00 UTC (permalink / raw)
To: Rasmus Villemoes
Cc: Kees Cook, Leon Romanovsky, stable, syzkaller, Jason Gunthorpe,
Leon Romanovsky, Bart Van Assche, Doug Ledford, Dan Carpenter,
linux-rdma, linux-kernel
From: Leon Romanovsky <leonro@mellanox.com>
[ 61.182439] UBSAN: Undefined behaviour in drivers/infiniband/hw/mlx5/qp.c:5366:34
[ 61.183673] shift exponent 4294967288 is too large for 32-bit type 'unsigned int'
[ 61.185530] CPU: 0 PID: 639 Comm: qp Not tainted 4.18.0-rc1-00037-g4aa1d69a9c60-dirty #96
[ 61.186981] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-2.fc27 04/01/2014
[ 61.188315] Call Trace:
[ 61.188661] dump_stack+0xc7/0x13b
[ 61.190427] ubsan_epilogue+0x9/0x49
[ 61.190899] __ubsan_handle_shift_out_of_bounds+0x1ea/0x22f
[ 61.197040] mlx5_ib_create_wq+0x1c99/0x1d50
[ 61.206632] ib_uverbs_ex_create_wq+0x499/0x820
[ 61.213892] ib_uverbs_write+0x77e/0xae0
[ 61.248018] vfs_write+0x121/0x3b0
[ 61.249831] ksys_write+0xa1/0x120
[ 61.254024] do_syscall_64+0x7c/0x2a0
[ 61.256178] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 61.259211] RIP: 0033:0x7f54bab70e99
[ 61.262125] Code: 00 f3 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89
[ 61.268678] RSP: 002b:00007ffe1541c318 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[ 61.271076] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f54bab70e99
[ 61.273795] RDX: 0000000000000070 RSI: 0000000020000240 RDI: 0000000000000003
[ 61.276982] RBP: 00007ffe1541c330 R08: 00000000200078e0 R09: 0000000000000002
[ 61.280035] R10: 0000000000000000 R11: 0000000000000246 R12: 00000000004005c0
[ 61.283279] R13: 00007ffe1541c420 R14: 0000000000000000 R15: 0000000000000000
Cc: <stable@vger.kernel.org> # 4.7
Fixes: 79b20a6c3014 ("IB/mlx5: Add receive Work Queue verbs")
Cc: syzkaller <syzkaller@googlegroups.com>
Reported-by: Noa Osherovich <noaos@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
drivers/infiniband/hw/mlx5/qp.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index a4f1f638509f..7fc156db643d 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -5365,7 +5365,10 @@ static int set_user_rq_size(struct mlx5_ib_dev *dev,
rwq->wqe_count = ucmd->rq_wqe_count;
rwq->wqe_shift = ucmd->rq_wqe_shift;
- rwq->buf_size = (rwq->wqe_count << rwq->wqe_shift);
+ if (check_shift_overflow(rwq->wqe_count, rwq->wqe_shift,
+ &rwq->buf_size))
+ return -EINVAL;
+
rwq->log_rq_stride = rwq->wqe_shift;
rwq->log_rq_size = ilog2(rwq->wqe_count);
return 0;
--
2.17.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/3] overflow.h: Add arithmetic shift helper
2018-08-01 0:00 ` [PATCH v2 1/3] " Kees Cook
@ 2018-08-01 1:59 ` Randy Dunlap
2018-08-01 2:15 ` Jason Gunthorpe
2018-08-01 7:57 ` Dan Carpenter
2 siblings, 0 replies; 13+ messages in thread
From: Randy Dunlap @ 2018-08-01 1:59 UTC (permalink / raw)
To: Kees Cook, Rasmus Villemoes
Cc: Jason Gunthorpe, Leon Romanovsky, Jason Gunthorpe,
Leon Romanovsky, Bart Van Assche, Doug Ledford, Dan Carpenter,
linux-rdma, linux-kernel
On 07/31/2018 05:00 PM, Kees Cook wrote:
> From: Jason Gunthorpe <jgg@mellanox.com>
>
> Add shift_overflow() helper to assist driver authors in ensuring that
> shift operations don't cause overflows or other odd conditions.
>
> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
> Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
> [kees: tweaked comments and commit log, dropped unneeded assignment]
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
> include/linux/overflow.h | 31 +++++++++++++++++++++++++++++++
> 1 file changed, 31 insertions(+)
>
> diff --git a/include/linux/overflow.h b/include/linux/overflow.h
> index 8712ff70995f..69fc366ce865 100644
> --- a/include/linux/overflow.h
> +++ b/include/linux/overflow.h
> @@ -202,6 +202,37 @@
>
> #endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */
>
> +/** check_shift_overflow() - Calculate a left-shifted value and check overflow
> + *
> + * @a: Value to be shifted
> + * @b: How many bits left to shift
> + * @d: Pointer to where to store the result
> + *
> + * Computes *@d = (@a << @s)
@b)
> + *
> + * Returns true if '*d' cannot hold the result or when 'a << s' doesn't
> + * make sense. Example conditions:
> + * - 'a << s' causes bits to be lost when stored in *d.
> + * - 's' is garbage (e.g. negative) or so large that the result of
> + * 'a << s' is guaranteed to be 0.
> + * - 'a' is negative.
> + * - 'a << s' sets the sign bit, if any, in '*d'.
> + *
> + * '*d' will hold the results of the attempted shift, but is not
> + * considered "safe for use" if false is returned.
> + */
> +#define check_shift_overflow(a, s, d) ({ \
> + typeof(a) _a = a; \
> + typeof(s) _s = s; \
> + typeof(d) _d = d; \
> + u64 _a_full = _a; \
> + unsigned int _to_shift = \
> + _s >= 0 && _s < 8 * sizeof(*d) ? _s : 0; \
> + *_d = (_a_full << _to_shift); \
> + (_to_shift != _s || *_d < 0 || _a < 0 || \
> + (*_d >> _to_shift) != _a); \
> +})
> +
> /**
> * array_size() - Calculate size of 2-dimensional array.
> *
>
--
~Randy
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/3] test_overflow: Add shift overflow tests
2018-08-01 0:00 ` [PATCH v2 2/3] test_overflow: Add shift overflow tests Kees Cook
@ 2018-08-01 2:13 ` Jason Gunthorpe
2018-08-01 5:51 ` Kees Cook
0 siblings, 1 reply; 13+ messages in thread
From: Jason Gunthorpe @ 2018-08-01 2:13 UTC (permalink / raw)
To: Kees Cook
Cc: Rasmus Villemoes, Leon Romanovsky, Bart Van Assche, Doug Ledford,
Dan Carpenter, linux-rdma, linux-kernel
On Tue, Jul 31, 2018 at 05:00:38PM -0700, Kees Cook wrote:
> + /* Overflow: high bit falls off. */
> + /* 10010110 */
> + err |= TEST_ONE_SHIFT(150, 1, u8, 0, true);
> + /* 1000100010010110 */
> + err |= TEST_ONE_SHIFT(34966, 1, u16, 0, true);
> + /* 10000100000010001000100010010110 */
> + err |= TEST_ONE_SHIFT(2215151766U, 1, u32, 0, true);
> + err |= TEST_ONE_SHIFT(2215151766U, 1, unsigned int, 0, true);
> + /* 1000001000010000010000000100000010000100000010001000100010010110 */
> + err |= TEST_ONE_SHIFT(9372061470395238550ULL, 1, u64, 0, true);
This same idea should be repeated with signed outputs and check both
overflow past the end (<<2) and overflow into the signed bit (<<1)
/* Overflow, high bit falls into the sign bit or off the end */
/* 01001011 */
err |= TEST_ONE_SHIFT(75, 1, s8, 0, true);
err |= TEST_ONE_SHIFT(75, 2, s8, 0, true);
And also general type mismatch overflow:
err |= TEST_ONE_SHIFT(0x100, 0, u8, 0, true);
err |= TEST_ONE_SHIFT(0xFF, 0, s8, 0, true);
Thanks,
Jason
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/3] overflow.h: Add arithmetic shift helper
2018-08-01 0:00 ` [PATCH v2 1/3] " Kees Cook
2018-08-01 1:59 ` Randy Dunlap
@ 2018-08-01 2:15 ` Jason Gunthorpe
2018-08-01 4:22 ` Kees Cook
2018-08-01 7:57 ` Dan Carpenter
2 siblings, 1 reply; 13+ messages in thread
From: Jason Gunthorpe @ 2018-08-01 2:15 UTC (permalink / raw)
To: Kees Cook
Cc: Rasmus Villemoes, Leon Romanovsky, Leon Romanovsky,
Bart Van Assche, Doug Ledford, Dan Carpenter, linux-rdma,
linux-kernel
On Tue, Jul 31, 2018 at 05:00:37PM -0700, Kees Cook wrote:
> From: Jason Gunthorpe <jgg@mellanox.com>
>
> Add shift_overflow() helper to assist driver authors in ensuring that
> shift operations don't cause overflows or other odd conditions.
>
> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
> Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
> [kees: tweaked comments and commit log, dropped unneeded assignment]
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
> include/linux/overflow.h | 31 +++++++++++++++++++++++++++++++
> 1 file changed, 31 insertions(+)
>
> diff --git a/include/linux/overflow.h b/include/linux/overflow.h
> index 8712ff70995f..69fc366ce865 100644
> --- a/include/linux/overflow.h
> +++ b/include/linux/overflow.h
> @@ -202,6 +202,37 @@
>
> #endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */
>
> +/** check_shift_overflow() - Calculate a left-shifted value and check overflow
> + *
> + * @a: Value to be shifted
> + * @b: How many bits left to shift
The above @b should be @s
> +#define check_shift_overflow(a, s, d) ({ \
Should I run this series through the rdma tree?
Thanks,
Jason
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/3] overflow.h: Add arithmetic shift helper
2018-08-01 2:15 ` Jason Gunthorpe
@ 2018-08-01 4:22 ` Kees Cook
0 siblings, 0 replies; 13+ messages in thread
From: Kees Cook @ 2018-08-01 4:22 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Rasmus Villemoes, Leon Romanovsky, Leon Romanovsky,
Bart Van Assche, Doug Ledford, Dan Carpenter, linux-rdma, LKML
On Tue, Jul 31, 2018 at 7:15 PM, Jason Gunthorpe <jgg@ziepe.ca> wrote:
> On Tue, Jul 31, 2018 at 05:00:37PM -0700, Kees Cook wrote:
>> From: Jason Gunthorpe <jgg@mellanox.com>
>>
>> Add shift_overflow() helper to assist driver authors in ensuring that
>> shift operations don't cause overflows or other odd conditions.
>>
>> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
>> Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
>> [kees: tweaked comments and commit log, dropped unneeded assignment]
>> Signed-off-by: Kees Cook <keescook@chromium.org>
>> ---
>> include/linux/overflow.h | 31 +++++++++++++++++++++++++++++++
>> 1 file changed, 31 insertions(+)
>>
>> diff --git a/include/linux/overflow.h b/include/linux/overflow.h
>> index 8712ff70995f..69fc366ce865 100644
>> --- a/include/linux/overflow.h
>> +++ b/include/linux/overflow.h
>> @@ -202,6 +202,37 @@
>>
>> #endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */
>>
>> +/** check_shift_overflow() - Calculate a left-shifted value and check overflow
>> + *
>> + * @a: Value to be shifted
>> + * @b: How many bits left to shift
>
> The above @b should be @s
Ooops, copy-paste-o. :)
>
>> +#define check_shift_overflow(a, s, d) ({ \
>
> Should I run this series through the rdma tree?
I'd like to get Rasmus's Ack, but otherwise, yes, that'd be fine.
-Kees
--
Kees Cook
Pixel Security
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/3] test_overflow: Add shift overflow tests
2018-08-01 2:13 ` Jason Gunthorpe
@ 2018-08-01 5:51 ` Kees Cook
0 siblings, 0 replies; 13+ messages in thread
From: Kees Cook @ 2018-08-01 5:51 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Rasmus Villemoes, Leon Romanovsky, Bart Van Assche, Doug Ledford,
Dan Carpenter, linux-rdma, LKML
On Tue, Jul 31, 2018 at 7:13 PM, Jason Gunthorpe <jgg@ziepe.ca> wrote:
> On Tue, Jul 31, 2018 at 05:00:38PM -0700, Kees Cook wrote:
>> + /* Overflow: high bit falls off. */
>> + /* 10010110 */
>> + err |= TEST_ONE_SHIFT(150, 1, u8, 0, true);
>> + /* 1000100010010110 */
>> + err |= TEST_ONE_SHIFT(34966, 1, u16, 0, true);
>> + /* 10000100000010001000100010010110 */
>> + err |= TEST_ONE_SHIFT(2215151766U, 1, u32, 0, true);
>> + err |= TEST_ONE_SHIFT(2215151766U, 1, unsigned int, 0, true);
>> + /* 1000001000010000010000000100000010000100000010001000100010010110 */
>> + err |= TEST_ONE_SHIFT(9372061470395238550ULL, 1, u64, 0, true);
>
> This same idea should be repeated with signed outputs and check both
> overflow past the end (<<2) and overflow into the signed bit (<<1)
>
> /* Overflow, high bit falls into the sign bit or off the end */
> /* 01001011 */
> err |= TEST_ONE_SHIFT(75, 1, s8, 0, true);
> err |= TEST_ONE_SHIFT(75, 2, s8, 0, true);
>
> And also general type mismatch overflow:
>
> err |= TEST_ONE_SHIFT(0x100, 0, u8, 0, true);
> err |= TEST_ONE_SHIFT(0xFF, 0, s8, 0, true);
Ah yes, thanks. I've added these for the next version now.
-Kees
--
Kees Cook
Pixel Security
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/3] overflow.h: Add arithmetic shift helper
2018-08-01 0:00 ` [PATCH v2 1/3] " Kees Cook
2018-08-01 1:59 ` Randy Dunlap
2018-08-01 2:15 ` Jason Gunthorpe
@ 2018-08-01 7:57 ` Dan Carpenter
2018-08-01 8:07 ` Dan Carpenter
2 siblings, 1 reply; 13+ messages in thread
From: Dan Carpenter @ 2018-08-01 7:57 UTC (permalink / raw)
To: Kees Cook
Cc: Rasmus Villemoes, Jason Gunthorpe, Leon Romanovsky,
Jason Gunthorpe, Leon Romanovsky, Bart Van Assche, Doug Ledford,
linux-rdma, linux-kernel
The idea is nice, but I don't like the API. The "_overflow" feels too
specific because maybe we could check for other things in the future.
Normally boolean macros should say they are boolean in the name and I
would prefer if it returned zero on failure.
if (!checked_shift(dest, mask, shift)) {
if (!shift_ok(dest, mask, shift)) {
if (!safe_shift(dest, mask, shift)) {
regards,
dan carpenter
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/3] overflow.h: Add arithmetic shift helper
2018-08-01 7:57 ` Dan Carpenter
@ 2018-08-01 8:07 ` Dan Carpenter
2018-08-01 15:38 ` Kees Cook
2018-08-01 15:48 ` Jason Gunthorpe
0 siblings, 2 replies; 13+ messages in thread
From: Dan Carpenter @ 2018-08-01 8:07 UTC (permalink / raw)
To: Kees Cook
Cc: Rasmus Villemoes, Jason Gunthorpe, Leon Romanovsky,
Jason Gunthorpe, Leon Romanovsky, Bart Van Assche, Doug Ledford,
linux-rdma, linux-kernel
On Wed, Aug 01, 2018 at 10:57:44AM +0300, Dan Carpenter wrote:
> The idea is nice, but I don't like the API. The "_overflow" feels too
> specific because maybe we could check for other things in the future.
> Normally boolean macros should say they are boolean in the name and I
> would prefer if it returned zero on failure.
>
> if (!checked_shift(dest, mask, shift)) {
> if (!shift_ok(dest, mask, shift)) {
> if (!safe_shift(dest, mask, shift)) {
Huh... It turns out I put the argument order different as well.
If we wanted to keep it returning 1 on failure then some other names
are:
if (shift_failed(dest, mask, shift)) {
if (shift_error(dest, mask, shift)) {
if (shift_overflow(dest, mask, shift)) {
regards,
dan carpenter
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/3] overflow.h: Add arithmetic shift helper
2018-08-01 8:07 ` Dan Carpenter
@ 2018-08-01 15:38 ` Kees Cook
2018-08-01 15:48 ` Jason Gunthorpe
1 sibling, 0 replies; 13+ messages in thread
From: Kees Cook @ 2018-08-01 15:38 UTC (permalink / raw)
To: Dan Carpenter
Cc: Rasmus Villemoes, Jason Gunthorpe, Leon Romanovsky,
Jason Gunthorpe, Leon Romanovsky, Bart Van Assche, Doug Ledford,
linux-rdma, LKML
On Wed, Aug 1, 2018 at 1:07 AM, Dan Carpenter <dan.carpenter@oracle.com> wrote:
> On Wed, Aug 01, 2018 at 10:57:44AM +0300, Dan Carpenter wrote:
>> The idea is nice, but I don't like the API. The "_overflow" feels too
>> specific because maybe we could check for other things in the future.
>> Normally boolean macros should say they are boolean in the name and I
>> would prefer if it returned zero on failure.
>>
>> if (!checked_shift(dest, mask, shift)) {
>> if (!shift_ok(dest, mask, shift)) {
>> if (!safe_shift(dest, mask, shift)) {
>
> Huh... It turns out I put the argument order different as well.
>
> If we wanted to keep it returning 1 on failure then some other names
> are:
>
> if (shift_failed(dest, mask, shift)) {
> if (shift_error(dest, mask, shift)) {
> if (shift_overflow(dest, mask, shift)) {
This is following the existing check_{add,mul}_overflow() helpers,
which are based on the gcc helpers. I'd like to keep things
consistent.
-Kees
--
Kees Cook
Pixel Security
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/3] overflow.h: Add arithmetic shift helper
2018-08-01 8:07 ` Dan Carpenter
2018-08-01 15:38 ` Kees Cook
@ 2018-08-01 15:48 ` Jason Gunthorpe
1 sibling, 0 replies; 13+ messages in thread
From: Jason Gunthorpe @ 2018-08-01 15:48 UTC (permalink / raw)
To: Dan Carpenter
Cc: Kees Cook, Rasmus Villemoes, Leon Romanovsky, Leon Romanovsky,
Bart Van Assche, Doug Ledford, linux-rdma, linux-kernel
On Wed, Aug 01, 2018 at 11:07:24AM +0300, Dan Carpenter wrote:
> On Wed, Aug 01, 2018 at 10:57:44AM +0300, Dan Carpenter wrote:
> > The idea is nice, but I don't like the API. The "_overflow" feels too
> > specific because maybe we could check for other things in the future.
> > Normally boolean macros should say they are boolean in the name and I
> > would prefer if it returned zero on failure.
> >
> > if (!checked_shift(dest, mask, shift)) {
> > if (!shift_ok(dest, mask, shift)) {
> > if (!safe_shift(dest, mask, shift)) {
>
> Huh... It turns out I put the argument order different as well.
>
> If we wanted to keep it returning 1 on failure then some other names
> are:
>
> if (shift_failed(dest, mask, shift)) {
> if (shift_error(dest, mask, shift)) {
> if (shift_overflow(dest, mask, shift)) {
I think this ship has sailed, the convention for these tests is
already established in overflow.h. ie:
check_add_overflow
check_sub_overflow
check_mul_overflow
Jason
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2018-08-01 15:48 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-01 0:00 [PATCH v2 0/3] overflow.h: Add arithmetic shift helper Kees Cook
2018-08-01 0:00 ` [PATCH v2 1/3] " Kees Cook
2018-08-01 1:59 ` Randy Dunlap
2018-08-01 2:15 ` Jason Gunthorpe
2018-08-01 4:22 ` Kees Cook
2018-08-01 7:57 ` Dan Carpenter
2018-08-01 8:07 ` Dan Carpenter
2018-08-01 15:38 ` Kees Cook
2018-08-01 15:48 ` Jason Gunthorpe
2018-08-01 0:00 ` [PATCH v2 2/3] test_overflow: Add shift overflow tests Kees Cook
2018-08-01 2:13 ` Jason Gunthorpe
2018-08-01 5:51 ` Kees Cook
2018-08-01 0:00 ` [PATCH v2 3/3] RDMA/mlx5: Fix shift overflow in mlx5_ib_create_wq Kees Cook
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).