diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2010-08-12 01:04:10 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2010-08-11 09:34:11 -0400 |
commit | 2e9fb9953df91ef6310da22182ca8f4496907502 (patch) | |
tree | 096a7b4c2cff57e6fb520f1abdc740260c57471f /kernel/params.c | |
parent | d2800800d795350435936b08afb402ed9aab1e66 (diff) |
params: don't hand NULL values to param.set callbacks.
An audit by Dongdong Deng revealed that most driver-author-written param
calls don't handle val == NULL (which happens when parameters are specified
with no =, eg "foo" instead of "foo=1").
The only real case to use this is boolean, so handle it specially for that
case and remove a source of bugs for everyone else.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Cc: Dongdong Deng <dongdong.deng@windriver.com>
Cc: Américo Wang <xiyou.wangcong@gmail.com>
Diffstat (limited to 'kernel/params.c')
-rw-r--r-- | kernel/params.c | 20 |
1 files changed, 3 insertions, 17 deletions
diff --git a/kernel/params.c b/kernel/params.c index 0b30ecd53a52..3c4a9f1b095e 100644 --- a/kernel/params.c +++ b/kernel/params.c | |||
@@ -58,6 +58,9 @@ static int parse_one(char *param, | |||
58 | /* Find parameter */ | 58 | /* Find parameter */ |
59 | for (i = 0; i < num_params; i++) { | 59 | for (i = 0; i < num_params; i++) { |
60 | if (parameq(param, params[i].name)) { | 60 | if (parameq(param, params[i].name)) { |
61 | /* Noone handled NULL, so do it here. */ | ||
62 | if (!val && params[i].set != param_set_bool) | ||
63 | return -EINVAL; | ||
61 | DEBUGP("They are equal! Calling %p\n", | 64 | DEBUGP("They are equal! Calling %p\n", |
62 | params[i].set); | 65 | params[i].set); |
63 | return params[i].set(val, ¶ms[i]); | 66 | return params[i].set(val, ¶ms[i]); |
@@ -181,7 +184,6 @@ int parse_args(const char *name, | |||
181 | tmptype l; \ | 184 | tmptype l; \ |
182 | int ret; \ | 185 | int ret; \ |
183 | \ | 186 | \ |
184 | if (!val) return -EINVAL; \ | ||
185 | ret = strtolfn(val, 0, &l); \ | 187 | ret = strtolfn(val, 0, &l); \ |
186 | if (ret == -EINVAL || ((type)l != l)) \ | 188 | if (ret == -EINVAL || ((type)l != l)) \ |
187 | return -EINVAL; \ | 189 | return -EINVAL; \ |
@@ -203,12 +205,6 @@ STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, strict_strtoul); | |||
203 | 205 | ||
204 | int param_set_charp(const char *val, struct kernel_param *kp) | 206 | int param_set_charp(const char *val, struct kernel_param *kp) |
205 | { | 207 | { |
206 | if (!val) { | ||
207 | printk(KERN_ERR "%s: string parameter expected\n", | ||
208 | kp->name); | ||
209 | return -EINVAL; | ||
210 | } | ||
211 | |||
212 | if (strlen(val) > 1024) { | 208 | if (strlen(val) > 1024) { |
213 | printk(KERN_ERR "%s: string parameter too long\n", | 209 | printk(KERN_ERR "%s: string parameter too long\n", |
214 | kp->name); | 210 | kp->name); |
@@ -309,12 +305,6 @@ static int param_array(const char *name, | |||
309 | kp.arg = elem; | 305 | kp.arg = elem; |
310 | kp.flags = flags; | 306 | kp.flags = flags; |
311 | 307 | ||
312 | /* No equals sign? */ | ||
313 | if (!val) { | ||
314 | printk(KERN_ERR "%s: expects arguments\n", name); | ||
315 | return -EINVAL; | ||
316 | } | ||
317 | |||
318 | *num = 0; | 308 | *num = 0; |
319 | /* We expect a comma-separated list of values. */ | 309 | /* We expect a comma-separated list of values. */ |
320 | do { | 310 | do { |
@@ -381,10 +371,6 @@ int param_set_copystring(const char *val, struct kernel_param *kp) | |||
381 | { | 371 | { |
382 | const struct kparam_string *kps = kp->str; | 372 | const struct kparam_string *kps = kp->str; |
383 | 373 | ||
384 | if (!val) { | ||
385 | printk(KERN_ERR "%s: missing param set value\n", kp->name); | ||
386 | return -EINVAL; | ||
387 | } | ||
388 | if (strlen(val)+1 > kps->maxlen) { | 374 | if (strlen(val)+1 > kps->maxlen) { |
389 | printk(KERN_ERR "%s: string doesn't fit in %u chars.\n", | 375 | printk(KERN_ERR "%s: string doesn't fit in %u chars.\n", |
390 | kp->name, kps->maxlen-1); | 376 | kp->name, kps->maxlen-1); |