aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2014-08-26 16:55:23 -0400
committerRusty Russell <rusty@rustcorp.com.au>2014-08-27 08:24:10 -0400
commit7a486d3781295b5298cbf9556928a76d26896863 (patch)
tree7a4d6592ed62a04c125d654f5ea6c15669c67b36
parentfc9740cebc3ab7c65f3c5f6ce0caf3e4969013ca (diff)
param: check for tainting before calling set op.
This means every set op doesn't need to call it, and it can move into params.c. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r--include/linux/moduleparam.h16
-rw-r--r--kernel/params.c22
2 files changed, 11 insertions, 27 deletions
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index 9531f9f9729e..593501996574 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -374,22 +374,6 @@ static inline void destroy_params(const struct kernel_param *params,
374#define __param_check(name, p, type) \ 374#define __param_check(name, p, type) \
375 static inline type __always_unused *__check_##name(void) { return(p); } 375 static inline type __always_unused *__check_##name(void) { return(p); }
376 376
377/**
378 * param_check_unsafe - Warn and taint the kernel if setting dangerous options.
379 *
380 * This gets called from all the standard param setters, but can be used from
381 * custom setters as well.
382 */
383static inline void
384param_check_unsafe(const struct kernel_param *kp)
385{
386 if (kp->flags & KERNEL_PARAM_FL_UNSAFE) {
387 pr_warn("Setting dangerous option %s - tainting kernel\n",
388 kp->name);
389 add_taint(TAINT_USER, LOCKDEP_STILL_OK);
390 }
391}
392
393extern struct kernel_param_ops param_ops_byte; 377extern struct kernel_param_ops param_ops_byte;
394extern int param_set_byte(const char *val, const struct kernel_param *kp); 378extern int param_set_byte(const char *val, const struct kernel_param *kp);
395extern int param_get_byte(char *buffer, const struct kernel_param *kp); 379extern int param_get_byte(char *buffer, const struct kernel_param *kp);
diff --git a/kernel/params.c b/kernel/params.c
index ad8d04563c3a..041b5899d5e2 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -83,6 +83,15 @@ bool parameq(const char *a, const char *b)
83 return parameqn(a, b, strlen(a)+1); 83 return parameqn(a, b, strlen(a)+1);
84} 84}
85 85
86static void param_check_unsafe(const struct kernel_param *kp)
87{
88 if (kp->flags & KERNEL_PARAM_FL_UNSAFE) {
89 pr_warn("Setting dangerous option %s - tainting kernel\n",
90 kp->name);
91 add_taint(TAINT_USER, LOCKDEP_STILL_OK);
92 }
93}
94
86static int parse_one(char *param, 95static int parse_one(char *param,
87 char *val, 96 char *val,
88 const char *doing, 97 const char *doing,
@@ -109,6 +118,7 @@ static int parse_one(char *param,
109 pr_debug("handling %s with %p\n", param, 118 pr_debug("handling %s with %p\n", param,
110 params[i].ops->set); 119 params[i].ops->set);
111 mutex_lock(&param_lock); 120 mutex_lock(&param_lock);
121 param_check_unsafe(&params[i]);
112 err = params[i].ops->set(val, &params[i]); 122 err = params[i].ops->set(val, &params[i]);
113 mutex_unlock(&param_lock); 123 mutex_unlock(&param_lock);
114 return err; 124 return err;
@@ -233,7 +243,6 @@ char *parse_args(const char *doing,
233#define STANDARD_PARAM_DEF(name, type, format, strtolfn) \ 243#define STANDARD_PARAM_DEF(name, type, format, strtolfn) \
234 int param_set_##name(const char *val, const struct kernel_param *kp) \ 244 int param_set_##name(const char *val, const struct kernel_param *kp) \
235 { \ 245 { \
236 param_check_unsafe(kp); \
237 return strtolfn(val, 0, (type *)kp->arg); \ 246 return strtolfn(val, 0, (type *)kp->arg); \
238 } \ 247 } \
239 int param_get_##name(char *buffer, const struct kernel_param *kp) \ 248 int param_get_##name(char *buffer, const struct kernel_param *kp) \
@@ -266,8 +275,6 @@ int param_set_charp(const char *val, const struct kernel_param *kp)
266 return -ENOSPC; 275 return -ENOSPC;
267 } 276 }
268 277
269 param_check_unsafe(kp);
270
271 maybe_kfree_parameter(*(char **)kp->arg); 278 maybe_kfree_parameter(*(char **)kp->arg);
272 279
273 /* This is a hack. We can't kmalloc in early boot, and we 280 /* This is a hack. We can't kmalloc in early boot, and we
@@ -305,8 +312,6 @@ EXPORT_SYMBOL(param_ops_charp);
305/* Actually could be a bool or an int, for historical reasons. */ 312/* Actually could be a bool or an int, for historical reasons. */
306int param_set_bool(const char *val, const struct kernel_param *kp) 313int param_set_bool(const char *val, const struct kernel_param *kp)
307{ 314{
308 param_check_unsafe(kp);
309
310 /* No equals means "set"... */ 315 /* No equals means "set"... */
311 if (!val) val = "1"; 316 if (!val) val = "1";
312 317
@@ -336,8 +341,6 @@ int param_set_invbool(const char *val, const struct kernel_param *kp)
336 bool boolval; 341 bool boolval;
337 struct kernel_param dummy; 342 struct kernel_param dummy;
338 343
339 param_check_unsafe(kp);
340
341 dummy.arg = &boolval; 344 dummy.arg = &boolval;
342 ret = param_set_bool(val, &dummy); 345 ret = param_set_bool(val, &dummy);
343 if (ret == 0) 346 if (ret == 0)
@@ -364,8 +367,6 @@ int param_set_bint(const char *val, const struct kernel_param *kp)
364 bool v; 367 bool v;
365 int ret; 368 int ret;
366 369
367 param_check_unsafe(kp);
368
369 /* Match bool exactly, by re-using it. */ 370 /* Match bool exactly, by re-using it. */
370 boolkp = *kp; 371 boolkp = *kp;
371 boolkp.arg = &v; 372 boolkp.arg = &v;
@@ -485,8 +486,6 @@ int param_set_copystring(const char *val, const struct kernel_param *kp)
485{ 486{
486 const struct kparam_string *kps = kp->str; 487 const struct kparam_string *kps = kp->str;
487 488
488 param_check_unsafe(kp);
489
490 if (strlen(val)+1 > kps->maxlen) { 489 if (strlen(val)+1 > kps->maxlen) {
491 pr_err("%s: string doesn't fit in %u chars.\n", 490 pr_err("%s: string doesn't fit in %u chars.\n",
492 kp->name, kps->maxlen-1); 491 kp->name, kps->maxlen-1);
@@ -563,6 +562,7 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
563 return -EPERM; 562 return -EPERM;
564 563
565 mutex_lock(&param_lock); 564 mutex_lock(&param_lock);
565 param_check_unsafe(attribute->param);
566 err = attribute->param->ops->set(buf, attribute->param); 566 err = attribute->param->ops->set(buf, attribute->param);
567 mutex_unlock(&param_lock); 567 mutex_unlock(&param_lock);
568 if (!err) 568 if (!err)