Skip to content

Commit

Permalink
bfq: Check kstrtoul() return value
Browse files Browse the repository at this point in the history
Make sysfs writes fail for invalid numbers instead of storing
uninitialized data copied from the stack. This patch removes
all uninitialized_var() occurrences from the BFQ source code.

Acked-by: Paolo Valente <paolo.valente@linaro.org>
Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
  • Loading branch information
Bart Van Assche authored and Jens Axboe committed Sep 1, 2017
1 parent dfb79af commit 2f79136
Showing 1 changed file with 37 additions and 15 deletions.
52 changes: 37 additions & 15 deletions block/bfq-iosched.c
Original file line number Diff line number Diff line change
Expand Up @@ -4802,13 +4802,15 @@ static ssize_t bfq_var_show(unsigned int var, char *page)
return sprintf(page, "%u\n", var);
}

static void bfq_var_store(unsigned long *var, const char *page)
static int bfq_var_store(unsigned long *var, const char *page)
{
unsigned long new_val;
int ret = kstrtoul(page, 10, &new_val);

if (ret == 0)
*var = new_val;
if (ret)
return ret;
*var = new_val;
return 0;
}

#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
Expand Down Expand Up @@ -4849,8 +4851,12 @@ static ssize_t \
__FUNC(struct elevator_queue *e, const char *page, size_t count) \
{ \
struct bfq_data *bfqd = e->elevator_data; \
unsigned long uninitialized_var(__data); \
bfq_var_store(&__data, (page)); \
unsigned long __data; \
int ret; \
\
ret = bfq_var_store(&__data, (page)); \
if (ret) \
return ret; \
if (__data < (MIN)) \
__data = (MIN); \
else if (__data > (MAX)) \
Expand All @@ -4877,8 +4883,12 @@ STORE_FUNCTION(bfq_slice_idle_store, &bfqd->bfq_slice_idle, 0, INT_MAX, 2);
static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)\
{ \
struct bfq_data *bfqd = e->elevator_data; \
unsigned long uninitialized_var(__data); \
bfq_var_store(&__data, (page)); \
unsigned long __data; \
int ret; \
\
ret = bfq_var_store(&__data, (page)); \
if (ret) \
return ret; \
if (__data < (MIN)) \
__data = (MIN); \
else if (__data > (MAX)) \
Expand All @@ -4894,9 +4904,12 @@ static ssize_t bfq_max_budget_store(struct elevator_queue *e,
const char *page, size_t count)
{
struct bfq_data *bfqd = e->elevator_data;
unsigned long uninitialized_var(__data);
unsigned long __data;
int ret;

bfq_var_store(&__data, (page));
ret = bfq_var_store(&__data, (page));
if (ret)
return ret;

if (__data == 0)
bfqd->bfq_max_budget = bfq_calc_max_budget(bfqd);
Expand All @@ -4919,9 +4932,12 @@ static ssize_t bfq_timeout_sync_store(struct elevator_queue *e,
const char *page, size_t count)
{
struct bfq_data *bfqd = e->elevator_data;
unsigned long uninitialized_var(__data);
unsigned long __data;
int ret;

bfq_var_store(&__data, (page));
ret = bfq_var_store(&__data, (page));
if (ret)
return ret;

if (__data < 1)
__data = 1;
Expand All @@ -4939,9 +4955,12 @@ static ssize_t bfq_strict_guarantees_store(struct elevator_queue *e,
const char *page, size_t count)
{
struct bfq_data *bfqd = e->elevator_data;
unsigned long uninitialized_var(__data);
unsigned long __data;
int ret;

bfq_var_store(&__data, (page));
ret = bfq_var_store(&__data, (page));
if (ret)
return ret;

if (__data > 1)
__data = 1;
Expand All @@ -4958,9 +4977,12 @@ static ssize_t bfq_low_latency_store(struct elevator_queue *e,
const char *page, size_t count)
{
struct bfq_data *bfqd = e->elevator_data;
unsigned long uninitialized_var(__data);
unsigned long __data;
int ret;

bfq_var_store(&__data, (page));
ret = bfq_var_store(&__data, (page));
if (ret)
return ret;

if (__data > 1)
__data = 1;
Expand Down

0 comments on commit 2f79136

Please sign in to comment.