5825dac9f2a5aa01825469a41c1ea05d07c5b1f4
[openwrt/openwrt.git] / package / busybox / patches / 470-insmod_search.patch
1 --- a/modutils/insmod.c
2 +++ b/modutils/insmod.c
3 @@ -9,6 +9,99 @@
4
5 #include "libbb.h"
6 #include "modutils.h"
7 +#include <sys/utsname.h>
8 +#ifndef CONFIG_FEATURE_2_4_MODULES
9 +#include <sys/mman.h>
10 +#include <asm/unistd.h>
11 +#include <sys/syscall.h>
12 +#endif
13 +
14 +static char *g_filename = NULL;
15 +
16 +static int FAST_FUNC check_module_name_match(const char *filename, struct stat *statbuf,
17 + void *userdata, int depth)
18 +{
19 + char *fullname = (char *) userdata;
20 + char *tmp;
21 +
22 + if (fullname[0] == '\0')
23 + return FALSE;
24 +
25 + tmp = bb_get_last_path_component_nostrip(filename);
26 + if (strcmp(tmp, fullname) == 0) {
27 + /* Stop searching if we find a match */
28 + g_filename = xstrdup(filename);
29 + return FALSE;
30 + }
31 +
32 + return TRUE;
33 +}
34 +
35 +static int find_module(char *filename)
36 +{
37 + char *module_dir, real_module_dir[FILENAME_MAX];
38 + int len, slen, ret = ENOENT, k_version;
39 + struct utsname myuname;
40 + const char *suffix;
41 + struct stat st;
42 +
43 + /* check the kernel version */
44 + if ((uname(&myuname) != 0) || (myuname.release[0] != '2'))
45 + return EINVAL;
46 +
47 + k_version = myuname.release[2] - '0';
48 +#if ENABLE_FEATURE_2_4_MODULES
49 + if (k_version <= 4)
50 + suffix = ".o";
51 + else
52 +#endif
53 + suffix = ".ko";
54 +
55 + len = strlen(filename);
56 + slen = strlen(suffix);
57 +
58 + /* check for suffix and absolute path first */
59 + if ((len < slen + 2) || (strcmp(filename + len - slen, suffix) != 0)) {
60 + filename = xasprintf("%s%s", filename, suffix);
61 + } else {
62 + filename = strdup(filename);
63 + if ((stat(filename, &st) == 0) && S_ISREG(st.st_mode)) {
64 + g_filename = filename;
65 + return 0;
66 + }
67 + free(filename);
68 + return ENOENT;
69 + }
70 +
71 + /* next: scan /lib/modules/<release> */
72 + /* Jump through hoops in case /lib/modules/`uname -r`
73 + * is a symlink. We do not want recursive_action to
74 + * follow symlinks, but we do want to follow the
75 + * /lib/modules/`uname -r` dir, So resolve it ourselves
76 + * if it is a link... */
77 + module_dir = concat_path_file(CONFIG_DEFAULT_MODULES_DIR, myuname.release);
78 + if (realpath(module_dir, real_module_dir) != NULL) {
79 + free(module_dir);
80 + module_dir = real_module_dir;
81 + }
82 +
83 + recursive_action(module_dir, ACTION_RECURSE,
84 + check_module_name_match, 0, filename, 0);
85 +
86 + /* Check if we have a complete path */
87 + if (g_filename == NULL)
88 + goto done;
89 +
90 + if ((stat(g_filename, &st) == 0) && S_ISREG(st.st_mode))
91 + ret = 0;
92 + else
93 + free(g_filename);
94 +
95 +done:
96 + free(filename);
97 +
98 + return ret;
99 +}
100
101 int insmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
102 int insmod_main(int argc UNUSED_PARAM, char **argv)
103 @@ -25,9 +118,14 @@ int insmod_main(int argc UNUSED_PARAM, c
104 if (!filename)
105 bb_show_usage();
106
107 - rc = bb_init_module(filename, parse_cmdline_module_options(argv));
108 + rc = find_module(filename);
109 + if (rc || (g_filename == NULL))
110 + goto done;
111 +
112 + rc = bb_init_module(g_filename, parse_cmdline_module_options(argv));
113 if (rc)
114 bb_error_msg("cannot insert '%s': %s", filename, moderror(rc));
115 -
116 + free (g_filename);
117 +done:
118 return rc;
119 }