kmodloader: fix bad realloc usage
[project/ubox.git] / kmodloader.c
1 /*
2 * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
3 * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License version 2.1
7 * as published by the Free Software Foundation
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15 #define _GNU_SOURCE
16 #include <sys/syscall.h>
17 #include <sys/mman.h>
18 #include <sys/utsname.h>
19
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <sys/syscall.h>
23 #include <sys/types.h>
24 #include <values.h>
25 #include <errno.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <libgen.h>
31 #include <glob.h>
32 #include <elf.h>
33 #include <ctype.h>
34
35 #include <libubox/avl.h>
36 #include <libubox/avl-cmp.h>
37 #include <libubox/utils.h>
38 #include <libubox/ulog.h>
39 #include <libubox/kvlist.h>
40
41 #define DEF_MOD_PATH "/modules/%s/"
42 /* duplicated from in-kernel include/linux/module.h */
43 #define MODULE_NAME_LEN (64 - sizeof(unsigned long))
44
45 enum {
46 SCANNED,
47 PROBE,
48 LOADED,
49 BLACKLISTED,
50 };
51
52 struct module {
53 char *name;
54 char *depends;
55 char *opts;
56
57 int size;
58 int usage;
59 int state;
60 int error;
61 int refcnt; /* number of references from module_node.m */
62 };
63
64 struct module_node {
65 struct avl_node avl;
66 struct module *m;
67 bool is_alias;
68 };
69
70 static struct avl_tree modules;
71 static KVLIST(options, kvlist_strlen);
72
73 static char **module_folders = NULL;
74
75 static void free_module(struct module *m);
76
77 static int init_module_folders(void)
78 {
79 int n = 0;
80 struct stat st;
81 struct utsname ver;
82 char *s, *e, *p, path[330], ldpath[256];
83
84 e = ldpath;
85 s = getenv("LD_LIBRARY_PATH");
86
87 if (s)
88 e += snprintf(ldpath, sizeof(ldpath), "%s:", s);
89
90 e += snprintf(e, sizeof(ldpath) - (e - ldpath), "/lib");
91
92 uname(&ver);
93
94 for (s = p = ldpath; p <= e; p++) {
95 if (*p != ':' && *p != '\0')
96 continue;
97
98 *p = 0;
99 snprintf(path, sizeof(path), "%s" DEF_MOD_PATH, s, ver.release);
100
101 if (!stat(path, &st) && S_ISDIR(st.st_mode)) {
102 module_folders = realloc(module_folders, sizeof(p) * (n + 2));
103
104 if (!module_folders) {
105 ULOG_ERR("out of memory\n");
106 return -1;
107 }
108
109 module_folders[n++] = strdup(path);
110 }
111
112 s = p + 1;
113 }
114
115 if (!module_folders) {
116 ULOG_ERR("no module folders for kernel version %s found\n", ver.release);
117 return -1;
118 }
119
120 module_folders[n] = NULL;
121 return 0;
122 }
123
124 static struct module *find_module(const char *name)
125 {
126 struct module_node *mn;
127 mn = avl_find_element(&modules, name, mn, avl);
128 if (mn)
129 return mn->m;
130 else
131 return NULL;
132 }
133
134 static void free_modules(void)
135 {
136 struct module_node *mn, *tmp;
137
138 avl_remove_all_elements(&modules, mn, avl, tmp) {
139 struct module *m = mn->m;
140
141 m->refcnt -= 1;
142 if (m->refcnt == 0)
143 free_module(m);
144 free(mn);
145 }
146 }
147
148 static char* get_module_path(char *name)
149 {
150 char **p;
151 static char path[256];
152 struct stat s;
153
154 if (!stat(name, &s) && S_ISREG(s.st_mode))
155 return name;
156
157 for (p = module_folders; *p; p++) {
158 snprintf(path, sizeof(path), "%s%s.ko", *p, name);
159 if (!stat(path, &s) && S_ISREG(s.st_mode))
160 return path;
161 }
162
163 return NULL;
164 }
165
166 static char* get_module_name(char *path)
167 {
168 static char name[MODULE_NAME_LEN];
169 char *t;
170
171 strncpy(name, basename(path), sizeof(name) - 1);
172
173 t = strstr(name, ".ko");
174 if (t)
175 *t = '\0';
176
177 return name;
178 }
179
180 static int elf64_find_section(char *map, const char *section, unsigned int *offset, unsigned int *size)
181 {
182 const char *secnames;
183 Elf64_Ehdr *e;
184 Elf64_Shdr *sh;
185 int i;
186
187 e = (Elf64_Ehdr *) map;
188 sh = (Elf64_Shdr *) (map + e->e_shoff);
189
190 secnames = map + sh[e->e_shstrndx].sh_offset;
191 for (i = 0; i < e->e_shnum; i++) {
192 if (!strcmp(section, secnames + sh[i].sh_name)) {
193 *size = sh[i].sh_size;
194 *offset = sh[i].sh_offset;
195 return 0;
196 }
197 }
198
199 return -1;
200 }
201
202 static int elf32_find_section(char *map, const char *section, unsigned int *offset, unsigned int *size)
203 {
204 const char *secnames;
205 Elf32_Ehdr *e;
206 Elf32_Shdr *sh;
207 int i;
208
209 e = (Elf32_Ehdr *) map;
210 sh = (Elf32_Shdr *) (map + e->e_shoff);
211
212 secnames = map + sh[e->e_shstrndx].sh_offset;
213 for (i = 0; i < e->e_shnum; i++) {
214 if (!strcmp(section, secnames + sh[i].sh_name)) {
215 *size = sh[i].sh_size;
216 *offset = sh[i].sh_offset;
217 return 0;
218 }
219 }
220
221 return -1;
222 }
223
224 static int elf_find_section(char *map, const char *section, unsigned int *offset, unsigned int *size)
225 {
226 int clazz = map[EI_CLASS];
227 int endian = map[EI_DATA];
228
229 #if __BYTE_ORDER == __LITTLE_ENDIAN
230 if (endian != ELFDATA2LSB)
231 #elif __BYTE_ORDER == __BIG_ENDIAN
232 if (endian != ELFDATA2MSB)
233 #else
234 #error "unsupported endian"
235 #endif
236 {
237 ULOG_ERR("invalid endianess: %d\n", endian);
238 return -1;
239 }
240
241 if (clazz == ELFCLASS32)
242 return elf32_find_section(map, section, offset, size);
243 else if (clazz == ELFCLASS64)
244 return elf64_find_section(map, section, offset, size);
245
246 ULOG_ERR("unknown elf format %d\n", clazz);
247
248 return -1;
249 }
250
251 static struct module_node *
252 alloc_module_node(const char *name, struct module *m, bool is_alias)
253 {
254 struct module_node *mn;
255 char *_name;
256
257 mn = calloc_a(sizeof(*mn),
258 &_name, strlen(name) + 1);
259 if (mn) {
260 mn->avl.key = strcpy(_name, name);
261 mn->m = m;
262 mn->is_alias = is_alias;
263 avl_insert(&modules, &mn->avl);
264 m->refcnt += 1;
265 }
266 return mn;
267 }
268
269 static struct module *
270 alloc_module(const char *name, const char * const *aliases, int naliases, const char *depends, int size)
271 {
272 struct module *m;
273 char *_name, *_dep;
274 int i;
275
276 m = calloc_a(sizeof(*m),
277 &_name, strlen(name) + 1,
278 &_dep, depends ? strlen(depends) + 2 : 0);
279 if (!m)
280 return NULL;
281
282 m->name = strcpy(_name, name);
283 m->opts = 0;
284
285 if (depends) {
286 m->depends = strcpy(_dep, depends);
287 while (*_dep) {
288 if (*_dep == ',')
289 *_dep = '\0';
290 _dep++;
291 }
292 }
293 m->size = size;
294
295 m->refcnt = 0;
296 alloc_module_node(m->name, m, false);
297 for (i = 0; i < naliases; i++)
298 alloc_module_node(aliases[i], m, true);
299
300 return m;
301 }
302
303 static void free_module(struct module *m)
304 {
305 if (m->opts)
306 free(m->opts);
307 free(m);
308 }
309
310 static int scan_loaded_modules(void)
311 {
312 size_t buf_len = 0;
313 char *buf = NULL;
314 FILE *fp;
315
316 fp = fopen("/proc/modules", "r");
317 if (!fp) {
318 ULOG_ERR("failed to open /proc/modules\n");
319 return -1;
320 }
321
322 while (getline(&buf, &buf_len, fp) > 0) {
323 struct module m;
324 struct module *n;
325
326 m.name = strtok(buf, " ");
327 m.size = atoi(strtok(NULL, " "));
328 m.usage = atoi(strtok(NULL, " "));
329 m.depends = strtok(NULL, " ");
330
331 if (!m.name || !m.depends)
332 continue;
333
334 n = find_module(m.name);
335 if (!n) {
336 /* possibly a module outside /lib/modules/<ver>/ */
337 n = alloc_module(m.name, NULL, 0, m.depends, m.size);
338 }
339 n->usage = m.usage;
340 n->state = LOADED;
341 }
342 free(buf);
343 fclose(fp);
344
345 return 0;
346 }
347
348 static struct module* get_module_info(const char *module, const char *name)
349 {
350 int fd = open(module, O_RDONLY);
351 unsigned int offset, size;
352 char *map = MAP_FAILED, *strings, *dep = NULL;
353 const char **aliases = NULL;
354 const char **aliasesr;
355 int naliases = 0;
356 struct module *m = NULL;
357 struct stat s;
358
359 if (fd < 0) {
360 ULOG_ERR("failed to open %s\n", module);
361 goto out;
362 }
363
364 if (fstat(fd, &s) == -1) {
365 ULOG_ERR("failed to stat %s\n", module);
366 goto out;
367 }
368
369 map = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
370 if (map == MAP_FAILED) {
371 ULOG_ERR("failed to mmap %s\n", module);
372 goto out;
373 }
374
375 if (elf_find_section(map, ".modinfo", &offset, &size)) {
376 ULOG_ERR("failed to load the .modinfo section from %s\n", module);
377 goto out;
378 }
379
380 strings = map + offset;
381 while (true) {
382 char *sep;
383 int len;
384
385 while (!strings[0])
386 strings++;
387 if (strings >= map + offset + size)
388 break;
389 sep = strstr(strings, "=");
390 if (!sep)
391 break;
392 len = sep - strings;
393 sep++;
394 if (!strncmp(strings, "depends=", len + 1))
395 dep = sep;
396 else if (!strncmp(strings, "alias=", len + 1)) {
397 aliasesr = realloc(aliases, sizeof(sep) * (naliases + 1));
398 if (!aliasesr) {
399 ULOG_ERR("out of memory\n");
400 goto out;
401 }
402
403 aliases = aliasesr;
404 aliases[naliases++] = sep;
405 }
406 strings = &sep[strlen(sep)];
407 }
408
409 m = alloc_module(name, aliases, naliases, dep, s.st_size);
410
411 if (m)
412 m->state = SCANNED;
413
414 out:
415 if (map != MAP_FAILED)
416 munmap(map, s.st_size);
417
418 if (fd >= 0)
419 close(fd);
420
421 free(aliases);
422
423 return m;
424 }
425
426 static int scan_module_folder(const char *dir)
427 {
428 int gl_flags = GLOB_NOESCAPE | GLOB_MARK;
429 struct utsname ver;
430 char *path;
431 glob_t gl;
432 int j, rv = 0;
433
434 uname(&ver);
435 path = alloca(strlen(dir) + sizeof("*.ko") + 1);
436 sprintf(path, "%s*.ko", dir);
437
438 if (glob(path, gl_flags, NULL, &gl) < 0)
439 return -1;
440
441 for (j = 0; j < gl.gl_pathc; j++) {
442 char *name = get_module_name(gl.gl_pathv[j]);
443 struct module *m;
444 char *opts;
445
446 if (!name)
447 continue;
448
449 m = find_module(name);
450 if (m)
451 continue;
452
453 m = get_module_info(gl.gl_pathv[j], name);
454 if (!m) {
455 rv |= -1;
456 continue;
457 }
458
459 opts = kvlist_get(&options, name);
460 if (!opts)
461 continue;
462
463 if (*opts == '\x01')
464 m->state = BLACKLISTED;
465 else
466 m->opts = strdup(opts);
467 }
468
469 globfree(&gl);
470
471 return rv;
472 }
473
474 static int scan_module_folders(void)
475 {
476 int rv = 0;
477 char **p;
478
479 if (init_module_folders())
480 return -1;
481
482 for (p = module_folders; *p; p++)
483 rv |= scan_module_folder(*p);
484
485 return rv;
486 }
487
488 static int print_modinfo(char *module)
489 {
490 int fd = open(module, O_RDONLY);
491 unsigned int offset, size;
492 struct stat s;
493 char *map = MAP_FAILED, *strings;
494 int rv = -1;
495
496 if (fd < 0) {
497 ULOG_ERR("failed to open %s\n", module);
498 goto out;
499 }
500
501 if (fstat(fd, &s) == -1) {
502 ULOG_ERR("failed to stat %s\n", module);
503 goto out;
504 }
505
506 map = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
507 if (map == MAP_FAILED) {
508 ULOG_ERR("failed to mmap %s\n", module);
509 goto out;
510 }
511
512 if (elf_find_section(map, ".modinfo", &offset, &size)) {
513 ULOG_ERR("failed to load the .modinfo section from %s\n", module);
514 goto out;
515 }
516
517 strings = map + offset;
518 printf("module:\t\t%s\n", module);
519 while (true) {
520 char *dup = NULL;
521 char *sep;
522
523 while (!strings[0])
524 strings++;
525 if (strings >= map + offset + size)
526 break;
527 sep = strstr(strings, "=");
528 if (!sep)
529 break;
530 dup = strndup(strings, sep - strings);
531 sep++;
532 if (strncmp(strings, "parm", 4)) {
533 if (strlen(dup) < 7)
534 printf("%s:\t\t%s\n", dup, sep);
535 else
536 printf("%s:\t%s\n", dup, sep);
537 }
538 strings = &sep[strlen(sep)];
539 if (dup)
540 free(dup);
541 }
542
543 rv = 0;
544
545 out:
546 if (map != MAP_FAILED)
547 munmap(map, s.st_size);
548
549 if (fd >= 0)
550 close(fd);
551
552 return rv;
553 }
554
555 static int deps_available(struct module *m, int verbose)
556 {
557 char *dep;
558 int err = 0;
559
560 if (!m->depends || !strcmp(m->depends, "-") || !strcmp(m->depends, ""))
561 return 0;
562
563 dep = m->depends;
564
565 while (*dep) {
566 m = find_module(dep);
567
568 if (verbose && !m)
569 ULOG_ERR("missing dependency %s\n", dep);
570 if (verbose && m && (m->state != LOADED))
571 ULOG_ERR("dependency not loaded %s\n", dep);
572 if (!m || (m->state != LOADED))
573 err++;
574 dep += strlen(dep) + 1;
575 }
576
577 return err;
578 }
579
580 static int insert_module(char *path, const char *options)
581 {
582 void *data = 0;
583 struct stat s;
584 int fd, ret = -1;
585
586 if (stat(path, &s)) {
587 ULOG_ERR("missing module %s\n", path);
588 return ret;
589 }
590
591 fd = open(path, O_RDONLY);
592 if (fd < 0) {
593 ULOG_ERR("cannot open %s\n", path);
594 return ret;
595 }
596
597 data = malloc(s.st_size);
598 if (!data) {
599 ULOG_ERR("out of memory\n");
600 goto out;
601 }
602
603 if (read(fd, data, s.st_size) == s.st_size) {
604 ret = syscall(__NR_init_module, data, (unsigned long) s.st_size, options);
605 if (errno == EEXIST)
606 ret = 0;
607 }
608 else
609 ULOG_ERR("failed to read full module %s\n", path);
610
611 out:
612 close(fd);
613 free(data);
614
615 return ret;
616 }
617
618 static void load_moddeps(struct module *_m)
619 {
620 char *dep;
621 struct module *m;
622
623 if (!strcmp(_m->depends, "-") || !strcmp(_m->depends, ""))
624 return;
625
626 dep = _m->depends;
627
628 while (*dep) {
629 m = find_module(dep);
630
631 if (!m)
632 ULOG_ERR("failed to find dependency %s\n", dep);
633 if (m && (m->state != LOADED)) {
634 m->state = PROBE;
635 load_moddeps(m);
636 }
637
638 dep = dep + strlen(dep) + 1;
639 }
640 }
641
642 static int load_modprobe(bool allow_load_retry)
643 {
644 int loaded, skipped, failed;
645 struct module_node *mn;
646 struct module *m;
647 bool load_retry = false;
648 static bool first_iteration = true;
649
650 avl_for_each_element(&modules, mn, avl) {
651 if (mn->is_alias)
652 continue;
653 m = mn->m;
654 if (m->state == PROBE)
655 load_moddeps(m);
656 }
657
658 do {
659 loaded = 0;
660 skipped = 0;
661 failed = 0;
662 avl_for_each_element(&modules, mn, avl) {
663 if (mn->is_alias)
664 continue;
665 m = mn->m;
666 if ((m->state == PROBE) && (!deps_available(m, 0)) && (!m->error || load_retry)) {
667 if (!insert_module(get_module_path(m->name), (m->opts) ? (m->opts) : (""))) {
668 m->state = LOADED;
669 m->error = 0;
670 loaded++;
671 continue;
672 }
673
674 m->error = 1;
675 }
676
677 if (m->error)
678 failed++;
679 else if (m->state == PROBE)
680 skipped++;
681 }
682
683 if (allow_load_retry) {
684 /* if we can't load anything else let's try to load failed modules */
685 load_retry = loaded ? (failed && !skipped) : (failed && !load_retry && !first_iteration);
686 }
687
688 first_iteration = false;
689 } while (loaded || load_retry);
690
691 return skipped + failed;
692 }
693
694 static int print_insmod_usage(void)
695 {
696 ULOG_INFO("Usage:\n\tinsmod filename [args]\n");
697
698 return -1;
699 }
700
701 static int print_modprobe_usage(void)
702 {
703 ULOG_INFO(
704 "Usage:\n"
705 "\tmodprobe [-q] [-v] filename\n"
706 "\tmodprobe -a [-q] [-v] filename [filename...]\n"
707 );
708
709 return -1;
710 }
711
712 static int print_usage(char *arg)
713 {
714 ULOG_INFO("Usage:\n\t%s module\n", arg);
715
716 return -1;
717 }
718
719 static int main_insmod(int argc, char **argv)
720 {
721 char *name, *cur, *options;
722 int i, ret, len;
723
724 if (argc < 2)
725 return print_insmod_usage();
726
727 name = get_module_name(argv[1]);
728 if (!name) {
729 ULOG_ERR("cannot find module - %s\n", argv[1]);
730 return -1;
731 }
732
733 if (scan_loaded_modules())
734 return -1;
735
736 if (find_module(name)) {
737 ULOG_ERR("module is already loaded - %s\n", name);
738 return -1;
739
740 }
741
742 free_modules();
743
744 for (len = 0, i = 2; i < argc; i++)
745 len += strlen(argv[i]) + 1;
746
747 options = malloc(len);
748 if (!options) {
749 ULOG_ERR("out of memory\n");
750 ret = -1;
751 goto err;
752 }
753
754 options[0] = 0;
755 cur = options;
756 for (i = 2; i < argc; i++) {
757 if (options[0]) {
758 *cur = ' ';
759 cur++;
760 }
761 cur += sprintf(cur, "%s", argv[i]);
762 }
763
764 if (init_module_folders()) {
765 fprintf(stderr, "Failed to find the folder holding the modules\n");
766 ret = -1;
767 goto err;
768 }
769
770 if (get_module_path(argv[1])) {
771 name = argv[1];
772 } else if (!get_module_path(name)) {
773 fprintf(stderr, "Failed to find %s. Maybe it is a built in module ?\n", name);
774 ret = -1;
775 goto err;
776 }
777
778 ret = insert_module(get_module_path(name), options);
779 if (ret)
780 ULOG_ERR("failed to insert %s\n", get_module_path(name));
781
782 err:
783 free(options);
784 return ret;
785 }
786
787 static int main_rmmod(int argc, char **argv)
788 {
789 struct module *m;
790 char *name;
791 int ret;
792
793 if (argc != 2)
794 return print_usage("rmmod");
795
796 if (scan_loaded_modules())
797 return -1;
798
799 name = get_module_name(argv[1]);
800 m = find_module(name);
801 if (!m) {
802 ULOG_ERR("module is not loaded\n");
803 return -1;
804 }
805 ret = syscall(__NR_delete_module, m->name, 0);
806
807 if (ret)
808 ULOG_ERR("unloading the module failed\n");
809
810 free_modules();
811
812 return ret;
813 }
814
815 static int main_lsmod(int argc, char **argv)
816 {
817 struct module_node *mn;
818 struct module *m;
819 char *dep;
820
821 if (scan_loaded_modules())
822 return -1;
823
824 avl_for_each_element(&modules, mn, avl) {
825 if (mn->is_alias)
826 continue;
827 m = mn->m;
828 if (m->state == LOADED) {
829 printf("%-20s%8d%3d ",
830 m->name, m->size, m->usage);
831 if (m->depends && strcmp(m->depends, "-") && strcmp(m->depends, "")) {
832 dep = m->depends;
833 while (*dep) {
834 printf("%s", dep);
835 dep = dep + strlen(dep) + 1;
836 if (*dep)
837 printf(",");
838 }
839 }
840 printf("\n");
841 }
842 }
843
844 free_modules();
845
846 return 0;
847 }
848
849 static int main_modinfo(int argc, char **argv)
850 {
851 struct module *m;
852 char *name;
853
854 if (argc != 2)
855 return print_usage("modinfo");
856
857 if (scan_module_folders())
858 return -1;
859
860 name = get_module_name(argv[1]);
861 m = find_module(name);
862 if (!m) {
863 ULOG_ERR("cannot find module - %s\n", argv[1]);
864 return -1;
865 }
866
867 name = get_module_path(m->name);
868 if (!name) {
869 ULOG_ERR("cannot find path of module - %s\n", m->name);
870 return -1;
871 }
872
873 print_modinfo(name);
874
875 return 0;
876 }
877
878 static int main_modprobe(int argc, char **argv)
879 {
880 struct module_node *mn;
881 struct module *m;
882 int exit_code = 0;
883 int load_fail;
884 int log_level = LOG_WARNING;
885 int opt;
886 bool quiet = false;
887 bool use_all = false;
888
889 while ((opt = getopt(argc, argv, "aqv")) != -1 ) {
890 switch (opt) {
891 case 'a':
892 use_all = true;
893 break;
894 case 'q': /* shhhh! */
895 quiet = true;
896 break;
897 case 'v':
898 log_level = LOG_DEBUG;
899 break;
900 default: /* '?' */
901 return print_modprobe_usage();
902 break;
903 }
904 }
905
906 if (optind >= argc)
907 return print_modprobe_usage(); /* expected module after options */
908
909 /* after print_modprobe_usage() so it won't be filtered out */
910 ulog_threshold(log_level);
911
912 if (scan_module_folders())
913 return -1;
914
915 if (scan_loaded_modules())
916 return -1;
917
918 do {
919 char *name;
920
921 name = get_module_name(argv[optind]);
922 m = find_module(name);
923
924 if (m && m->state == BLACKLISTED) {
925 if (!quiet)
926 ULOG_INFO("%s is blacklisted\n", name);
927 } else if (m && m->state == LOADED) {
928 if (!quiet)
929 ULOG_INFO("%s is already loaded\n", name);
930 } else if (!m) {
931 if (!quiet)
932 ULOG_ERR("failed to find a module named %s\n", name);
933 exit_code = -1;
934 } else {
935 m->state = PROBE;
936 }
937
938 optind++;
939 } while (use_all && optind < argc);
940
941 load_fail = load_modprobe(true);
942 if (load_fail) {
943 ULOG_ERR("%d module%s could not be probed\n",
944 load_fail, (load_fail == 1) ? ("") : ("s"));
945
946 avl_for_each_element(&modules, mn, avl) {
947 if (mn->is_alias)
948 continue;
949 m = mn->m;
950 if ((m->state == PROBE) || m->error)
951 ULOG_ERR("- %s\n", m->name);
952 }
953
954 exit_code = -1;
955 }
956
957 free_modules();
958
959 return exit_code;
960 }
961
962 static int main_loader(int argc, char **argv)
963 {
964 int gl_flags = GLOB_NOESCAPE | GLOB_MARK;
965 char *dir = "/etc/modules.d/";
966 struct module_node *mn;
967 struct module *m;
968 glob_t gl;
969 char *path;
970 int ret = 0, fail, j;
971
972 if (argc > 1)
973 dir = argv[1];
974
975 path = malloc(strlen(dir) + 2);
976 if (!path) {
977 ULOG_ERR("out of memory\n");
978 return -1;
979 }
980
981 strcpy(path, dir);
982 strcat(path, "*");
983
984 if (scan_module_folders()) {
985 ret = -1;
986 goto free_path;
987 }
988
989 if (scan_loaded_modules()) {
990 ret = -1;
991 goto free_path;
992 }
993
994 ULOG_INFO("loading kernel modules from %s\n", path);
995
996 if (glob(path, gl_flags, NULL, &gl) < 0)
997 goto out;
998
999 for (j = 0; j < gl.gl_pathc; j++) {
1000 FILE *fp = fopen(gl.gl_pathv[j], "r");
1001 size_t mod_len = 0;
1002 char *mod = NULL;
1003
1004 if (!fp) {
1005 ULOG_ERR("failed to open %s\n", gl.gl_pathv[j]);
1006 continue;
1007 }
1008
1009 while (getline(&mod, &mod_len, fp) > 0) {
1010 char *nl = strchr(mod, '\n');
1011 struct module *m;
1012 char *opts;
1013
1014 if (nl)
1015 *nl = '\0';
1016
1017 opts = strchr(mod, ' ');
1018 if (opts)
1019 *opts++ = '\0';
1020
1021 m = find_module(get_module_name(mod));
1022 if (!m || m->state == LOADED || m->state == BLACKLISTED)
1023 continue;
1024
1025 if (opts) {
1026 if (m->opts) {
1027 char *prev = m->opts;
1028
1029 fail = asprintf(&m->opts, "%s %s", prev, opts);
1030 free(prev);
1031 if (fail < 0) {
1032 ULOG_ERR("out of memory for opts %s\n", opts);
1033 free(mod);
1034 fclose(fp);
1035 ret = -1;
1036 goto out;
1037 }
1038 } else {
1039 m->opts = strdup(opts);
1040 }
1041 }
1042 m->state = PROBE;
1043 if (basename(gl.gl_pathv[j])[0] - '0' <= 9)
1044 load_modprobe(false);
1045
1046 }
1047 free(mod);
1048 fclose(fp);
1049 }
1050
1051 fail = load_modprobe(true);
1052
1053 if (fail) {
1054 ULOG_ERR("%d module%s could not be probed\n",
1055 fail, (fail == 1) ? ("") : ("s"));
1056
1057 avl_for_each_element(&modules, mn, avl) {
1058 if (mn->is_alias)
1059 continue;
1060 m = mn->m;
1061 if ((m->state == PROBE) || (m->error))
1062 ULOG_ERR("- %s - %d\n", m->name, deps_available(m, 1));
1063 }
1064 } else {
1065 ULOG_INFO("done loading kernel modules from %s\n", path);
1066 }
1067
1068 out:
1069 globfree(&gl);
1070 free_path:
1071 free(path);
1072
1073 return ret;
1074 }
1075
1076 static inline char weight(char c)
1077 {
1078 return c == '_' ? '-' : c;
1079 }
1080
1081 static int avl_modcmp(const void *k1, const void *k2, void *ptr)
1082 {
1083 const char *s1 = k1;
1084 const char *s2 = k2;
1085
1086 while (*s1 && (weight(*s1) == weight(*s2)))
1087 {
1088 s1++;
1089 s2++;
1090 }
1091
1092 return (unsigned char)weight(*s1) - (unsigned char)weight(*s2);
1093 }
1094
1095 static void
1096 load_options(void)
1097 {
1098 static char buf[512];
1099 char *s;
1100 FILE *f;
1101
1102 f = fopen("/etc/modules.conf", "r");
1103 if (!f)
1104 return;
1105
1106 while ((s = fgets(buf, sizeof(buf), f)) != NULL) {
1107 char *c, *cmd, *mod;
1108
1109 while (isspace(*s))
1110 s++;
1111
1112 c = strchr(s, '#');
1113 if (c)
1114 *c = 0;
1115
1116 while (isspace(*s))
1117 s++;
1118
1119 c = s + strlen(s);
1120 while (c > s && isspace(c[-1])) {
1121 c[-1] = 0;
1122 c--;
1123 }
1124
1125 cmd = strsep(&s, " \t");
1126 if (!cmd || !*cmd)
1127 continue;
1128
1129 while (isspace(*s))
1130 s++;
1131
1132 mod = strsep(&s, " \t");
1133 if (!mod || !*mod)
1134 continue;
1135
1136 if (!strcmp(cmd, "blacklist")) {
1137 kvlist_set(&options, mod, "\x01");
1138 continue;
1139 }
1140
1141 if (!strcmp(cmd, "options")) {
1142 char *prev = kvlist_get(&options, mod);
1143 char *val = NULL;
1144
1145 while (isspace(*s))
1146 s++;
1147
1148 if (!*s)
1149 continue;
1150
1151 if (prev && prev[0] == '\x01')
1152 continue;
1153
1154 if (!prev) {
1155 kvlist_set(&options, mod, s);
1156 continue;
1157 }
1158
1159 if (asprintf(&val, "%s %s", prev, s) < 0)
1160 continue;
1161
1162 kvlist_set(&options, mod, val);
1163 free(val);
1164 continue;
1165 }
1166 }
1167 }
1168
1169 int main(int argc, char **argv)
1170 {
1171 char *exec = basename(*argv);
1172
1173 avl_init(&modules, avl_modcmp, false, NULL);
1174 if (!strcmp(exec, "insmod"))
1175 return main_insmod(argc, argv);
1176
1177 if (!strcmp(exec, "rmmod"))
1178 return main_rmmod(argc, argv);
1179
1180 if (!strcmp(exec, "lsmod"))
1181 return main_lsmod(argc, argv);
1182
1183 if (!strcmp(exec, "modinfo"))
1184 return main_modinfo(argc, argv);
1185
1186 load_options();
1187
1188 if (!strcmp(exec, "modprobe"))
1189 return main_modprobe(argc, argv);
1190
1191 ulog_open(ULOG_KMSG, LOG_USER, "kmodloader");
1192 return main_loader(argc, argv);
1193 }