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