aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2010-08-12 01:04:10 -0400
committerRusty Russell <rusty@rustcorp.com.au>2010-08-11 09:34:11 -0400
commit2e9fb9953df91ef6310da22182ca8f4496907502 (patch)
tree096a7b4c2cff57e6fb520f1abdc740260c57471f
parentd2800800d795350435936b08afb402ed9aab1e66 (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>
-rw-r--r--kernel/params.c20
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, &params[i]); 66 return params[i].set(val, &params[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
204int param_set_charp(const char *val, struct kernel_param *kp) 206int 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);