Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later
2 : /* Helpers for initial module or kernel cmdline parsing
3 : Copyright (C) 2001 Rusty Russell.
4 :
5 : */
6 : #include <linux/kernel.h>
7 : #include <linux/string.h>
8 : #include <linux/errno.h>
9 : #include <linux/module.h>
10 : #include <linux/moduleparam.h>
11 : #include <linux/device.h>
12 : #include <linux/err.h>
13 : #include <linux/slab.h>
14 : #include <linux/ctype.h>
15 : #include <linux/security.h>
16 :
17 : #ifdef CONFIG_SYSFS
18 : /* Protects all built-in parameters, modules use their own param_lock */
19 : static DEFINE_MUTEX(param_lock);
20 :
21 : /* Use the module's mutex, or if built-in use the built-in mutex */
22 : #ifdef CONFIG_MODULES
23 : #define KPARAM_MUTEX(mod) ((mod) ? &(mod)->param_lock : ¶m_lock)
24 : #else
25 : #define KPARAM_MUTEX(mod) (¶m_lock)
26 : #endif
27 :
28 0 : static inline void check_kparam_locked(struct module *mod)
29 : {
30 0 : BUG_ON(!mutex_is_locked(KPARAM_MUTEX(mod)));
31 0 : }
32 : #else
33 : static inline void check_kparam_locked(struct module *mod)
34 : {
35 : }
36 : #endif /* !CONFIG_SYSFS */
37 :
38 : /* This just allows us to keep track of which parameters are kmalloced. */
39 : struct kmalloced_param {
40 : struct list_head list;
41 : char val[];
42 : };
43 : static LIST_HEAD(kmalloced_params);
44 : static DEFINE_SPINLOCK(kmalloced_params_lock);
45 :
46 0 : static void *kmalloc_parameter(unsigned int size)
47 : {
48 : struct kmalloced_param *p;
49 :
50 0 : p = kmalloc(sizeof(*p) + size, GFP_KERNEL);
51 0 : if (!p)
52 : return NULL;
53 :
54 0 : spin_lock(&kmalloced_params_lock);
55 0 : list_add(&p->list, &kmalloced_params);
56 0 : spin_unlock(&kmalloced_params_lock);
57 :
58 0 : return p->val;
59 : }
60 :
61 : /* Does nothing if parameter wasn't kmalloced above. */
62 1 : static void maybe_kfree_parameter(void *param)
63 : {
64 : struct kmalloced_param *p;
65 :
66 1 : spin_lock(&kmalloced_params_lock);
67 1 : list_for_each_entry(p, &kmalloced_params, list) {
68 0 : if (p->val == param) {
69 0 : list_del(&p->list);
70 0 : kfree(p);
71 0 : break;
72 : }
73 : }
74 1 : spin_unlock(&kmalloced_params_lock);
75 1 : }
76 :
77 : static char dash2underscore(char c)
78 : {
79 8086 : if (c == '-')
80 : return '_';
81 : return c;
82 : }
83 :
84 130 : bool parameqn(const char *a, const char *b, size_t n)
85 : {
86 : size_t i;
87 :
88 4055 : for (i = 0; i < n; i++) {
89 12129 : if (dash2underscore(a[i]) != dash2underscore(b[i]))
90 : return false;
91 : }
92 : return true;
93 : }
94 :
95 3642 : bool parameq(const char *a, const char *b)
96 : {
97 7284 : return parameqn(a, b, strlen(a)+1);
98 : }
99 :
100 1 : static bool param_check_unsafe(const struct kernel_param *kp)
101 : {
102 1 : if (kp->flags & KERNEL_PARAM_FL_HWPARAM &&
103 : security_locked_down(LOCKDOWN_MODULE_PARAMETERS))
104 : return false;
105 :
106 1 : if (kp->flags & KERNEL_PARAM_FL_UNSAFE) {
107 0 : pr_notice("Setting dangerous option %s - tainting kernel\n",
108 : kp->name);
109 0 : add_taint(TAINT_USER, LOCKDEP_STILL_OK);
110 : }
111 :
112 : return true;
113 : }
114 :
115 40 : static int parse_one(char *param,
116 : char *val,
117 : const char *doing,
118 : const struct kernel_param *params,
119 : unsigned num_params,
120 : s16 min_level,
121 : s16 max_level,
122 : void *arg,
123 : int (*handle_unknown)(char *param, char *val,
124 : const char *doing, void *arg))
125 : {
126 : unsigned int i;
127 : int err;
128 :
129 : /* Find parameter */
130 3577 : for (i = 0; i < num_params; i++) {
131 3546 : if (parameq(param, params[i].name)) {
132 9 : if (params[i].level < min_level
133 1 : || params[i].level > max_level)
134 : return 0;
135 : /* No one handled NULL, so do it here. */
136 1 : if (!val &&
137 0 : !(params[i].ops->flags & KERNEL_PARAM_OPS_FL_NOARG))
138 : return -EINVAL;
139 : pr_debug("handling %s with %p\n", param,
140 : params[i].ops->set);
141 2 : kernel_param_lock(params[i].mod);
142 1 : if (param_check_unsafe(¶ms[i]))
143 1 : err = params[i].ops->set(val, ¶ms[i]);
144 : else
145 : err = -EPERM;
146 2 : kernel_param_unlock(params[i].mod);
147 1 : return err;
148 : }
149 : }
150 :
151 31 : if (handle_unknown) {
152 : pr_debug("doing %s: %s='%s'\n", doing, param, val);
153 31 : return handle_unknown(param, val, doing, arg);
154 : }
155 :
156 : pr_debug("Unknown argument '%s'\n", param);
157 : return -ENOENT;
158 : }
159 :
160 : /* Args looks like "foo=bar,bar2 baz=fuz wiz". */
161 10 : char *parse_args(const char *doing,
162 : char *args,
163 : const struct kernel_param *params,
164 : unsigned num,
165 : s16 min_level,
166 : s16 max_level,
167 : void *arg,
168 : int (*unknown)(char *param, char *val,
169 : const char *doing, void *arg))
170 : {
171 10 : char *param, *val, *err = NULL;
172 :
173 : /* Chew leading spaces */
174 10 : args = skip_spaces(args);
175 :
176 : if (*args)
177 : pr_debug("doing %s, parsing ARGS: '%s'\n", doing, args);
178 :
179 50 : while (*args) {
180 : int ret;
181 : int irq_was_disabled;
182 :
183 40 : args = next_arg(args, ¶m, &val);
184 : /* Stop at -- */
185 40 : if (!val && strcmp(param, "--") == 0)
186 0 : return err ?: args;
187 80 : irq_was_disabled = irqs_disabled();
188 40 : ret = parse_one(param, val, doing, params, num,
189 : min_level, max_level, arg, unknown);
190 48 : if (irq_was_disabled && !irqs_disabled())
191 0 : pr_warn("%s: option '%s' enabled irq's!\n",
192 : doing, param);
193 :
194 40 : switch (ret) {
195 : case 0:
196 40 : continue;
197 : case -ENOENT:
198 0 : pr_err("%s: Unknown parameter `%s'\n", doing, param);
199 0 : break;
200 : case -ENOSPC:
201 0 : pr_err("%s: `%s' too large for parameter `%s'\n",
202 : doing, val ?: "", param);
203 0 : break;
204 : default:
205 0 : pr_err("%s: `%s' invalid for parameter `%s'\n",
206 : doing, val ?: "", param);
207 0 : break;
208 : }
209 :
210 0 : err = ERR_PTR(ret);
211 : }
212 :
213 : return err;
214 : }
215 :
216 : /* Lazy bastard, eh? */
217 : #define STANDARD_PARAM_DEF(name, type, format, strtolfn) \
218 : int param_set_##name(const char *val, const struct kernel_param *kp) \
219 : { \
220 : return strtolfn(val, 0, (type *)kp->arg); \
221 : } \
222 : int param_get_##name(char *buffer, const struct kernel_param *kp) \
223 : { \
224 : return scnprintf(buffer, PAGE_SIZE, format "\n", \
225 : *((type *)kp->arg)); \
226 : } \
227 : const struct kernel_param_ops param_ops_##name = { \
228 : .set = param_set_##name, \
229 : .get = param_get_##name, \
230 : }; \
231 : EXPORT_SYMBOL(param_set_##name); \
232 : EXPORT_SYMBOL(param_get_##name); \
233 : EXPORT_SYMBOL(param_ops_##name)
234 :
235 :
236 0 : STANDARD_PARAM_DEF(byte, unsigned char, "%hhu", kstrtou8);
237 0 : STANDARD_PARAM_DEF(short, short, "%hi", kstrtos16);
238 0 : STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", kstrtou16);
239 0 : STANDARD_PARAM_DEF(int, int, "%i", kstrtoint);
240 0 : STANDARD_PARAM_DEF(uint, unsigned int, "%u", kstrtouint);
241 0 : STANDARD_PARAM_DEF(long, long, "%li", kstrtol);
242 0 : STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", kstrtoul);
243 0 : STANDARD_PARAM_DEF(ullong, unsigned long long, "%llu", kstrtoull);
244 0 : STANDARD_PARAM_DEF(hexint, unsigned int, "%#08x", kstrtouint);
245 :
246 0 : int param_set_uint_minmax(const char *val, const struct kernel_param *kp,
247 : unsigned int min, unsigned int max)
248 : {
249 : unsigned int num;
250 : int ret;
251 :
252 0 : if (!val)
253 : return -EINVAL;
254 0 : ret = kstrtouint(val, 0, &num);
255 0 : if (ret)
256 : return ret;
257 0 : if (num < min || num > max)
258 : return -EINVAL;
259 0 : *((unsigned int *)kp->arg) = num;
260 0 : return 0;
261 : }
262 : EXPORT_SYMBOL_GPL(param_set_uint_minmax);
263 :
264 1 : int param_set_charp(const char *val, const struct kernel_param *kp)
265 : {
266 1 : if (strlen(val) > 1024) {
267 0 : pr_err("%s: string parameter too long\n", kp->name);
268 0 : return -ENOSPC;
269 : }
270 :
271 1 : maybe_kfree_parameter(*(char **)kp->arg);
272 :
273 : /* This is a hack. We can't kmalloc in early boot, and we
274 : * don't need to; this mangled commandline is preserved. */
275 1 : if (slab_is_available()) {
276 0 : *(char **)kp->arg = kmalloc_parameter(strlen(val)+1);
277 0 : if (!*(char **)kp->arg)
278 : return -ENOMEM;
279 0 : strcpy(*(char **)kp->arg, val);
280 : } else
281 1 : *(const char **)kp->arg = val;
282 :
283 : return 0;
284 : }
285 : EXPORT_SYMBOL(param_set_charp);
286 :
287 0 : int param_get_charp(char *buffer, const struct kernel_param *kp)
288 : {
289 0 : return scnprintf(buffer, PAGE_SIZE, "%s\n", *((char **)kp->arg));
290 : }
291 : EXPORT_SYMBOL(param_get_charp);
292 :
293 0 : void param_free_charp(void *arg)
294 : {
295 0 : maybe_kfree_parameter(*((char **)arg));
296 0 : }
297 : EXPORT_SYMBOL(param_free_charp);
298 :
299 : const struct kernel_param_ops param_ops_charp = {
300 : .set = param_set_charp,
301 : .get = param_get_charp,
302 : .free = param_free_charp,
303 : };
304 : EXPORT_SYMBOL(param_ops_charp);
305 :
306 : /* Actually could be a bool or an int, for historical reasons. */
307 0 : int param_set_bool(const char *val, const struct kernel_param *kp)
308 : {
309 : /* No equals means "set"... */
310 0 : if (!val) val = "1";
311 :
312 : /* One of =[yYnN01] */
313 0 : return strtobool(val, kp->arg);
314 : }
315 : EXPORT_SYMBOL(param_set_bool);
316 :
317 0 : int param_get_bool(char *buffer, const struct kernel_param *kp)
318 : {
319 : /* Y and N chosen as being relatively non-coder friendly */
320 0 : return sprintf(buffer, "%c\n", *(bool *)kp->arg ? 'Y' : 'N');
321 : }
322 : EXPORT_SYMBOL(param_get_bool);
323 :
324 : const struct kernel_param_ops param_ops_bool = {
325 : .flags = KERNEL_PARAM_OPS_FL_NOARG,
326 : .set = param_set_bool,
327 : .get = param_get_bool,
328 : };
329 : EXPORT_SYMBOL(param_ops_bool);
330 :
331 0 : int param_set_bool_enable_only(const char *val, const struct kernel_param *kp)
332 : {
333 0 : int err = 0;
334 : bool new_value;
335 0 : bool orig_value = *(bool *)kp->arg;
336 0 : struct kernel_param dummy_kp = *kp;
337 :
338 0 : dummy_kp.arg = &new_value;
339 :
340 0 : err = param_set_bool(val, &dummy_kp);
341 0 : if (err)
342 : return err;
343 :
344 : /* Don't let them unset it once it's set! */
345 0 : if (!new_value && orig_value)
346 : return -EROFS;
347 :
348 0 : if (new_value)
349 0 : err = param_set_bool(val, kp);
350 :
351 : return err;
352 : }
353 : EXPORT_SYMBOL_GPL(param_set_bool_enable_only);
354 :
355 : const struct kernel_param_ops param_ops_bool_enable_only = {
356 : .flags = KERNEL_PARAM_OPS_FL_NOARG,
357 : .set = param_set_bool_enable_only,
358 : .get = param_get_bool,
359 : };
360 : EXPORT_SYMBOL_GPL(param_ops_bool_enable_only);
361 :
362 : /* This one must be bool. */
363 0 : int param_set_invbool(const char *val, const struct kernel_param *kp)
364 : {
365 : int ret;
366 : bool boolval;
367 : struct kernel_param dummy;
368 :
369 0 : dummy.arg = &boolval;
370 0 : ret = param_set_bool(val, &dummy);
371 0 : if (ret == 0)
372 0 : *(bool *)kp->arg = !boolval;
373 0 : return ret;
374 : }
375 : EXPORT_SYMBOL(param_set_invbool);
376 :
377 0 : int param_get_invbool(char *buffer, const struct kernel_param *kp)
378 : {
379 0 : return sprintf(buffer, "%c\n", (*(bool *)kp->arg) ? 'N' : 'Y');
380 : }
381 : EXPORT_SYMBOL(param_get_invbool);
382 :
383 : const struct kernel_param_ops param_ops_invbool = {
384 : .set = param_set_invbool,
385 : .get = param_get_invbool,
386 : };
387 : EXPORT_SYMBOL(param_ops_invbool);
388 :
389 0 : int param_set_bint(const char *val, const struct kernel_param *kp)
390 : {
391 : /* Match bool exactly, by re-using it. */
392 0 : struct kernel_param boolkp = *kp;
393 : bool v;
394 : int ret;
395 :
396 0 : boolkp.arg = &v;
397 :
398 0 : ret = param_set_bool(val, &boolkp);
399 0 : if (ret == 0)
400 0 : *(int *)kp->arg = v;
401 0 : return ret;
402 : }
403 : EXPORT_SYMBOL(param_set_bint);
404 :
405 : const struct kernel_param_ops param_ops_bint = {
406 : .flags = KERNEL_PARAM_OPS_FL_NOARG,
407 : .set = param_set_bint,
408 : .get = param_get_int,
409 : };
410 : EXPORT_SYMBOL(param_ops_bint);
411 :
412 : /* We break the rule and mangle the string. */
413 0 : static int param_array(struct module *mod,
414 : const char *name,
415 : const char *val,
416 : unsigned int min, unsigned int max,
417 : void *elem, int elemsize,
418 : int (*set)(const char *, const struct kernel_param *kp),
419 : s16 level,
420 : unsigned int *num)
421 : {
422 : int ret;
423 : struct kernel_param kp;
424 : char save;
425 :
426 : /* Get the name right for errors. */
427 0 : kp.name = name;
428 0 : kp.arg = elem;
429 0 : kp.level = level;
430 :
431 0 : *num = 0;
432 : /* We expect a comma-separated list of values. */
433 : do {
434 : int len;
435 :
436 0 : if (*num == max) {
437 0 : pr_err("%s: can only take %i arguments\n", name, max);
438 0 : return -EINVAL;
439 : }
440 0 : len = strcspn(val, ",");
441 :
442 : /* nul-terminate and parse */
443 0 : save = val[len];
444 0 : ((char *)val)[len] = '\0';
445 0 : check_kparam_locked(mod);
446 0 : ret = set(val, &kp);
447 :
448 0 : if (ret != 0)
449 : return ret;
450 0 : kp.arg += elemsize;
451 0 : val += len+1;
452 0 : (*num)++;
453 0 : } while (save == ',');
454 :
455 0 : if (*num < min) {
456 0 : pr_err("%s: needs at least %i arguments\n", name, min);
457 0 : return -EINVAL;
458 : }
459 : return 0;
460 : }
461 :
462 0 : static int param_array_set(const char *val, const struct kernel_param *kp)
463 : {
464 0 : const struct kparam_array *arr = kp->arr;
465 : unsigned int temp_num;
466 :
467 0 : return param_array(kp->mod, kp->name, val, 1, arr->max, arr->elem,
468 0 : arr->elemsize, arr->ops->set, kp->level,
469 0 : arr->num ?: &temp_num);
470 : }
471 :
472 0 : static int param_array_get(char *buffer, const struct kernel_param *kp)
473 : {
474 : int i, off, ret;
475 0 : const struct kparam_array *arr = kp->arr;
476 0 : struct kernel_param p = *kp;
477 :
478 0 : for (i = off = 0; i < (arr->num ? *arr->num : arr->max); i++) {
479 : /* Replace \n with comma */
480 0 : if (i)
481 0 : buffer[off - 1] = ',';
482 0 : p.arg = arr->elem + arr->elemsize * i;
483 0 : check_kparam_locked(p.mod);
484 0 : ret = arr->ops->get(buffer + off, &p);
485 0 : if (ret < 0)
486 : return ret;
487 0 : off += ret;
488 : }
489 0 : buffer[off] = '\0';
490 0 : return off;
491 : }
492 :
493 0 : static void param_array_free(void *arg)
494 : {
495 : unsigned int i;
496 0 : const struct kparam_array *arr = arg;
497 :
498 0 : if (arr->ops->free)
499 0 : for (i = 0; i < (arr->num ? *arr->num : arr->max); i++)
500 0 : arr->ops->free(arr->elem + arr->elemsize * i);
501 0 : }
502 :
503 : const struct kernel_param_ops param_array_ops = {
504 : .set = param_array_set,
505 : .get = param_array_get,
506 : .free = param_array_free,
507 : };
508 : EXPORT_SYMBOL(param_array_ops);
509 :
510 0 : int param_set_copystring(const char *val, const struct kernel_param *kp)
511 : {
512 0 : const struct kparam_string *kps = kp->str;
513 :
514 0 : if (strlen(val)+1 > kps->maxlen) {
515 0 : pr_err("%s: string doesn't fit in %u chars.\n",
516 : kp->name, kps->maxlen-1);
517 0 : return -ENOSPC;
518 : }
519 0 : strcpy(kps->string, val);
520 0 : return 0;
521 : }
522 : EXPORT_SYMBOL(param_set_copystring);
523 :
524 0 : int param_get_string(char *buffer, const struct kernel_param *kp)
525 : {
526 0 : const struct kparam_string *kps = kp->str;
527 0 : return scnprintf(buffer, PAGE_SIZE, "%s\n", kps->string);
528 : }
529 : EXPORT_SYMBOL(param_get_string);
530 :
531 : const struct kernel_param_ops param_ops_string = {
532 : .set = param_set_copystring,
533 : .get = param_get_string,
534 : };
535 : EXPORT_SYMBOL(param_ops_string);
536 :
537 : /* sysfs output in /sys/modules/XYZ/parameters/ */
538 : #define to_module_attr(n) container_of(n, struct module_attribute, attr)
539 : #define to_module_kobject(n) container_of(n, struct module_kobject, kobj)
540 :
541 : struct param_attribute
542 : {
543 : struct module_attribute mattr;
544 : const struct kernel_param *param;
545 : };
546 :
547 : struct module_param_attrs
548 : {
549 : unsigned int num;
550 : struct attribute_group grp;
551 : struct param_attribute attrs[];
552 : };
553 :
554 : #ifdef CONFIG_SYSFS
555 : #define to_param_attr(n) container_of(n, struct param_attribute, mattr)
556 :
557 0 : static ssize_t param_attr_show(struct module_attribute *mattr,
558 : struct module_kobject *mk, char *buf)
559 : {
560 : int count;
561 0 : struct param_attribute *attribute = to_param_attr(mattr);
562 :
563 0 : if (!attribute->param->ops->get)
564 : return -EPERM;
565 :
566 0 : kernel_param_lock(mk->mod);
567 0 : count = attribute->param->ops->get(buf, attribute->param);
568 0 : kernel_param_unlock(mk->mod);
569 0 : return count;
570 : }
571 :
572 : /* sysfs always hands a nul-terminated string in buf. We rely on that. */
573 0 : static ssize_t param_attr_store(struct module_attribute *mattr,
574 : struct module_kobject *mk,
575 : const char *buf, size_t len)
576 : {
577 : int err;
578 0 : struct param_attribute *attribute = to_param_attr(mattr);
579 :
580 0 : if (!attribute->param->ops->set)
581 : return -EPERM;
582 :
583 0 : kernel_param_lock(mk->mod);
584 0 : if (param_check_unsafe(attribute->param))
585 0 : err = attribute->param->ops->set(buf, attribute->param);
586 : else
587 : err = -EPERM;
588 0 : kernel_param_unlock(mk->mod);
589 0 : if (!err)
590 0 : return len;
591 0 : return err;
592 : }
593 : #endif
594 :
595 : #ifdef CONFIG_MODULES
596 : #define __modinit
597 : #else
598 : #define __modinit __init
599 : #endif
600 :
601 : #ifdef CONFIG_SYSFS
602 0 : void kernel_param_lock(struct module *mod)
603 : {
604 1 : mutex_lock(KPARAM_MUTEX(mod));
605 0 : }
606 :
607 0 : void kernel_param_unlock(struct module *mod)
608 : {
609 1 : mutex_unlock(KPARAM_MUTEX(mod));
610 0 : }
611 :
612 : EXPORT_SYMBOL(kernel_param_lock);
613 : EXPORT_SYMBOL(kernel_param_unlock);
614 :
615 : /*
616 : * add_sysfs_param - add a parameter to sysfs
617 : * @mk: struct module_kobject
618 : * @kp: the actual parameter definition to add to sysfs
619 : * @name: name of parameter
620 : *
621 : * Create a kobject if for a (per-module) parameter if mp NULL, and
622 : * create file in sysfs. Returns an error on out of memory. Always cleans up
623 : * if there's an error.
624 : */
625 114 : static __modinit int add_sysfs_param(struct module_kobject *mk,
626 : const struct kernel_param *kp,
627 : const char *name)
628 : {
629 : struct module_param_attrs *new_mp;
630 : struct attribute **new_attrs;
631 : unsigned int i;
632 :
633 : /* We don't bother calling this with invisible parameters. */
634 114 : BUG_ON(!kp->perm);
635 :
636 114 : if (!mk->mp) {
637 : /* First allocation. */
638 20 : mk->mp = kzalloc(sizeof(*mk->mp), GFP_KERNEL);
639 20 : if (!mk->mp)
640 : return -ENOMEM;
641 20 : mk->mp->grp.name = "parameters";
642 : /* NULL-terminated attribute array. */
643 20 : mk->mp->grp.attrs = kzalloc(sizeof(mk->mp->grp.attrs[0]),
644 : GFP_KERNEL);
645 : /* Caller will cleanup via free_module_param_attrs */
646 20 : if (!mk->mp->grp.attrs)
647 : return -ENOMEM;
648 : }
649 :
650 : /* Enlarge allocations. */
651 114 : new_mp = krealloc(mk->mp,
652 : sizeof(*mk->mp) +
653 114 : sizeof(mk->mp->attrs[0]) * (mk->mp->num + 1),
654 : GFP_KERNEL);
655 114 : if (!new_mp)
656 : return -ENOMEM;
657 114 : mk->mp = new_mp;
658 :
659 : /* Extra pointer for NULL terminator */
660 114 : new_attrs = krealloc(mk->mp->grp.attrs,
661 114 : sizeof(mk->mp->grp.attrs[0]) * (mk->mp->num + 2),
662 : GFP_KERNEL);
663 114 : if (!new_attrs)
664 : return -ENOMEM;
665 114 : mk->mp->grp.attrs = new_attrs;
666 :
667 : /* Tack new one on the end. */
668 114 : memset(&mk->mp->attrs[mk->mp->num], 0, sizeof(mk->mp->attrs[0]));
669 : sysfs_attr_init(&mk->mp->attrs[mk->mp->num].mattr.attr);
670 114 : mk->mp->attrs[mk->mp->num].param = kp;
671 114 : mk->mp->attrs[mk->mp->num].mattr.show = param_attr_show;
672 : /* Do not allow runtime DAC changes to make param writable. */
673 114 : if ((kp->perm & (S_IWUSR | S_IWGRP | S_IWOTH)) != 0)
674 50 : mk->mp->attrs[mk->mp->num].mattr.store = param_attr_store;
675 : else
676 64 : mk->mp->attrs[mk->mp->num].mattr.store = NULL;
677 114 : mk->mp->attrs[mk->mp->num].mattr.attr.name = (char *)name;
678 114 : mk->mp->attrs[mk->mp->num].mattr.attr.mode = kp->perm;
679 114 : mk->mp->num++;
680 :
681 : /* Fix up all the pointers, since krealloc can move us */
682 2455 : for (i = 0; i < mk->mp->num; i++)
683 2341 : mk->mp->grp.attrs[i] = &mk->mp->attrs[i].mattr.attr;
684 114 : mk->mp->grp.attrs[mk->mp->num] = NULL;
685 : return 0;
686 : }
687 :
688 : #ifdef CONFIG_MODULES
689 : static void free_module_param_attrs(struct module_kobject *mk)
690 : {
691 : if (mk->mp)
692 : kfree(mk->mp->grp.attrs);
693 : kfree(mk->mp);
694 : mk->mp = NULL;
695 : }
696 :
697 : /*
698 : * module_param_sysfs_setup - setup sysfs support for one module
699 : * @mod: module
700 : * @kparam: module parameters (array)
701 : * @num_params: number of module parameters
702 : *
703 : * Adds sysfs entries for module parameters under
704 : * /sys/module/[mod->name]/parameters/
705 : */
706 : int module_param_sysfs_setup(struct module *mod,
707 : const struct kernel_param *kparam,
708 : unsigned int num_params)
709 : {
710 : int i, err;
711 : bool params = false;
712 :
713 : for (i = 0; i < num_params; i++) {
714 : if (kparam[i].perm == 0)
715 : continue;
716 : err = add_sysfs_param(&mod->mkobj, &kparam[i], kparam[i].name);
717 : if (err) {
718 : free_module_param_attrs(&mod->mkobj);
719 : return err;
720 : }
721 : params = true;
722 : }
723 :
724 : if (!params)
725 : return 0;
726 :
727 : /* Create the param group. */
728 : err = sysfs_create_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp);
729 : if (err)
730 : free_module_param_attrs(&mod->mkobj);
731 : return err;
732 : }
733 :
734 : /*
735 : * module_param_sysfs_remove - remove sysfs support for one module
736 : * @mod: module
737 : *
738 : * Remove sysfs entries for module parameters and the corresponding
739 : * kobject.
740 : */
741 : void module_param_sysfs_remove(struct module *mod)
742 : {
743 : if (mod->mkobj.mp) {
744 : sysfs_remove_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp);
745 : /* We are positive that no one is using any param
746 : * attrs at this point. Deallocate immediately. */
747 : free_module_param_attrs(&mod->mkobj);
748 : }
749 : }
750 : #endif
751 :
752 0 : void destroy_params(const struct kernel_param *params, unsigned num)
753 : {
754 : unsigned int i;
755 :
756 0 : for (i = 0; i < num; i++)
757 0 : if (params[i].ops->free)
758 0 : params[i].ops->free(params[i].arg);
759 0 : }
760 :
761 114 : static struct module_kobject * __init locate_module_kobject(const char *name)
762 : {
763 : struct module_kobject *mk;
764 : struct kobject *kobj;
765 : int err;
766 :
767 114 : kobj = kset_find_obj(module_kset, name);
768 114 : if (kobj) {
769 : mk = to_module_kobject(kobj);
770 : } else {
771 20 : mk = kzalloc(sizeof(struct module_kobject), GFP_KERNEL);
772 20 : BUG_ON(!mk);
773 :
774 20 : mk->mod = THIS_MODULE;
775 20 : mk->kobj.kset = module_kset;
776 20 : err = kobject_init_and_add(&mk->kobj, &module_ktype, NULL,
777 : "%s", name);
778 : #ifdef CONFIG_MODULES
779 : if (!err)
780 : err = sysfs_create_file(&mk->kobj, &module_uevent.attr);
781 : #endif
782 20 : if (err) {
783 0 : kobject_put(&mk->kobj);
784 0 : pr_crit("Adding module '%s' to sysfs failed (%d), the system may be unstable.\n",
785 : name, err);
786 0 : return NULL;
787 : }
788 :
789 : /* So that we hold reference in both cases. */
790 20 : kobject_get(&mk->kobj);
791 : }
792 :
793 : return mk;
794 : }
795 :
796 114 : static void __init kernel_add_sysfs_param(const char *name,
797 : const struct kernel_param *kparam,
798 : unsigned int name_skip)
799 : {
800 : struct module_kobject *mk;
801 : int err;
802 :
803 114 : mk = locate_module_kobject(name);
804 114 : if (!mk)
805 : return;
806 :
807 : /* We need to remove old parameters before adding more. */
808 114 : if (mk->mp)
809 94 : sysfs_remove_group(&mk->kobj, &mk->mp->grp);
810 :
811 : /* These should not fail at boot. */
812 114 : err = add_sysfs_param(mk, kparam, kparam->name + name_skip);
813 114 : BUG_ON(err);
814 114 : err = sysfs_create_group(&mk->kobj, &mk->mp->grp);
815 114 : BUG_ON(err);
816 114 : kobject_uevent(&mk->kobj, KOBJ_ADD);
817 114 : kobject_put(&mk->kobj);
818 : }
819 :
820 : /*
821 : * param_sysfs_builtin - add sysfs parameters for built-in modules
822 : *
823 : * Add module_parameters to sysfs for "modules" built into the kernel.
824 : *
825 : * The "module" name (KBUILD_MODNAME) is stored before a dot, the
826 : * "parameter" name is stored behind a dot in kernel_param->name. So,
827 : * extract the "module" name for all built-in kernel_param-eters,
828 : * and for all who have the same, call kernel_add_sysfs_param.
829 : */
830 1 : static void __init param_sysfs_builtin(void)
831 : {
832 : const struct kernel_param *kp;
833 : unsigned int name_len;
834 : char modname[MODULE_NAME_LEN];
835 :
836 125 : for (kp = __start___param; kp < __stop___param; kp++) {
837 : char *dot;
838 :
839 124 : if (kp->perm == 0)
840 10 : continue;
841 :
842 114 : dot = strchr(kp->name, '.');
843 114 : if (!dot) {
844 : /* This happens for core_param() */
845 8 : strcpy(modname, "kernel");
846 8 : name_len = 0;
847 : } else {
848 106 : name_len = dot - kp->name + 1;
849 106 : strlcpy(modname, kp->name, name_len);
850 : }
851 114 : kernel_add_sysfs_param(modname, kp, name_len);
852 : }
853 1 : }
854 :
855 0 : ssize_t __modver_version_show(struct module_attribute *mattr,
856 : struct module_kobject *mk, char *buf)
857 : {
858 0 : struct module_version_attribute *vattr =
859 0 : container_of(mattr, struct module_version_attribute, mattr);
860 :
861 0 : return scnprintf(buf, PAGE_SIZE, "%s\n", vattr->version);
862 : }
863 :
864 : extern const struct module_version_attribute __start___modver[];
865 : extern const struct module_version_attribute __stop___modver[];
866 :
867 1 : static void __init version_sysfs_builtin(void)
868 : {
869 : const struct module_version_attribute *vattr;
870 : struct module_kobject *mk;
871 : int err;
872 :
873 1 : for (vattr = __start___modver; vattr < __stop___modver; vattr++) {
874 0 : mk = locate_module_kobject(vattr->module_name);
875 0 : if (mk) {
876 0 : err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr);
877 0 : WARN_ON_ONCE(err);
878 0 : kobject_uevent(&mk->kobj, KOBJ_ADD);
879 0 : kobject_put(&mk->kobj);
880 : }
881 : }
882 1 : }
883 :
884 : /* module-related sysfs stuff */
885 :
886 0 : static ssize_t module_attr_show(struct kobject *kobj,
887 : struct attribute *attr,
888 : char *buf)
889 : {
890 : struct module_attribute *attribute;
891 : struct module_kobject *mk;
892 : int ret;
893 :
894 0 : attribute = to_module_attr(attr);
895 0 : mk = to_module_kobject(kobj);
896 :
897 0 : if (!attribute->show)
898 : return -EIO;
899 :
900 0 : ret = attribute->show(attribute, mk, buf);
901 :
902 0 : return ret;
903 : }
904 :
905 0 : static ssize_t module_attr_store(struct kobject *kobj,
906 : struct attribute *attr,
907 : const char *buf, size_t len)
908 : {
909 : struct module_attribute *attribute;
910 : struct module_kobject *mk;
911 : int ret;
912 :
913 0 : attribute = to_module_attr(attr);
914 0 : mk = to_module_kobject(kobj);
915 :
916 0 : if (!attribute->store)
917 : return -EIO;
918 :
919 0 : ret = attribute->store(attribute, mk, buf, len);
920 :
921 0 : return ret;
922 : }
923 :
924 : static const struct sysfs_ops module_sysfs_ops = {
925 : .show = module_attr_show,
926 : .store = module_attr_store,
927 : };
928 :
929 114 : static int uevent_filter(struct kobject *kobj)
930 : {
931 114 : const struct kobj_type *ktype = get_ktype(kobj);
932 :
933 114 : if (ktype == &module_ktype)
934 : return 1;
935 0 : return 0;
936 : }
937 :
938 : static const struct kset_uevent_ops module_uevent_ops = {
939 : .filter = uevent_filter,
940 : };
941 :
942 : struct kset *module_kset;
943 : int module_sysfs_initialized;
944 :
945 0 : static void module_kobj_release(struct kobject *kobj)
946 : {
947 0 : struct module_kobject *mk = to_module_kobject(kobj);
948 0 : complete(mk->kobj_completion);
949 0 : }
950 :
951 : struct kobj_type module_ktype = {
952 : .release = module_kobj_release,
953 : .sysfs_ops = &module_sysfs_ops,
954 : };
955 :
956 : /*
957 : * param_sysfs_init - wrapper for built-in params support
958 : */
959 1 : static int __init param_sysfs_init(void)
960 : {
961 1 : module_kset = kset_create_and_add("module", &module_uevent_ops, NULL);
962 1 : if (!module_kset) {
963 0 : printk(KERN_WARNING "%s (%d): error creating kset\n",
964 : __FILE__, __LINE__);
965 0 : return -ENOMEM;
966 : }
967 1 : module_sysfs_initialized = 1;
968 :
969 1 : version_sysfs_builtin();
970 1 : param_sysfs_builtin();
971 :
972 1 : return 0;
973 : }
974 : subsys_initcall(param_sysfs_init);
975 :
976 : #endif /* CONFIG_SYSFS */
|