]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-3.18/bcache-improve-sysfs_strtoul_clamp.patch
Fixes for 4.19
[thirdparty/kernel/stable-queue.git] / queue-3.18 / bcache-improve-sysfs_strtoul_clamp.patch
1 From 000433ed7f83bccfdf998357396a7afc81d3d203 Mon Sep 17 00:00:00 2001
2 From: Coly Li <colyli@suse.de>
3 Date: Sat, 9 Feb 2019 12:52:59 +0800
4 Subject: bcache: improve sysfs_strtoul_clamp()
5
6 [ Upstream commit 596b5a5dd1bc2fa019fdaaae522ef331deef927f ]
7
8 Currently sysfs_strtoul_clamp() is defined as,
9 82 #define sysfs_strtoul_clamp(file, var, min, max) \
10 83 do { \
11 84 if (attr == &sysfs_ ## file) \
12 85 return strtoul_safe_clamp(buf, var, min, max) \
13 86 ?: (ssize_t) size; \
14 87 } while (0)
15
16 The problem is, if bit width of var is less then unsigned long, min and
17 max may not protect var from integer overflow, because overflow happens
18 in strtoul_safe_clamp() before checking min and max.
19
20 To fix such overflow in sysfs_strtoul_clamp(), to make min and max take
21 effect, this patch adds an unsigned long variable, and uses it to macro
22 strtoul_safe_clamp() to convert an unsigned long value in range defined
23 by [min, max]. Then assign this value to var. By this method, if bit
24 width of var is less than unsigned long, integer overflow won't happen
25 before min and max are checking.
26
27 Now sysfs_strtoul_clamp() can properly handle smaller data type like
28 unsigned int, of cause min and max should be defined in range of
29 unsigned int too.
30
31 Signed-off-by: Coly Li <colyli@suse.de>
32 Signed-off-by: Jens Axboe <axboe@kernel.dk>
33 Signed-off-by: Sasha Levin <sashal@kernel.org>
34 ---
35 drivers/md/bcache/sysfs.h | 13 ++++++++++---
36 1 file changed, 10 insertions(+), 3 deletions(-)
37
38 diff --git a/drivers/md/bcache/sysfs.h b/drivers/md/bcache/sysfs.h
39 index 0526fe92a683..e7a3c12aa66f 100644
40 --- a/drivers/md/bcache/sysfs.h
41 +++ b/drivers/md/bcache/sysfs.h
42 @@ -80,9 +80,16 @@ do { \
43
44 #define sysfs_strtoul_clamp(file, var, min, max) \
45 do { \
46 - if (attr == &sysfs_ ## file) \
47 - return strtoul_safe_clamp(buf, var, min, max) \
48 - ?: (ssize_t) size; \
49 + if (attr == &sysfs_ ## file) { \
50 + unsigned long v = 0; \
51 + ssize_t ret; \
52 + ret = strtoul_safe_clamp(buf, v, min, max); \
53 + if (!ret) { \
54 + var = v; \
55 + return size; \
56 + } \
57 + return ret; \
58 + } \
59 } while (0)
60
61 #define strtoul_or_return(cp) \
62 --
63 2.19.1
64