diff options
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 53 |
1 files changed, 25 insertions, 28 deletions
diff --git a/kernel/module.c b/kernel/module.c index 0e2da8695f8..6e48c3a4359 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -2293,12 +2293,17 @@ static void layout_symtab(struct module *mod, struct load_info *info) | |||
2293 | src = (void *)info->hdr + symsect->sh_offset; | 2293 | src = (void *)info->hdr + symsect->sh_offset; |
2294 | nsrc = symsect->sh_size / sizeof(*src); | 2294 | nsrc = symsect->sh_size / sizeof(*src); |
2295 | 2295 | ||
2296 | /* strtab always starts with a nul, so offset 0 is the empty string. */ | ||
2297 | strtab_size = 1; | ||
2298 | |||
2296 | /* Compute total space required for the core symbols' strtab. */ | 2299 | /* Compute total space required for the core symbols' strtab. */ |
2297 | for (ndst = i = strtab_size = 1; i < nsrc; ++i, ++src) | 2300 | for (ndst = i = 0; i < nsrc; i++) { |
2298 | if (is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) { | 2301 | if (i == 0 || |
2299 | strtab_size += strlen(&info->strtab[src->st_name]) + 1; | 2302 | is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { |
2303 | strtab_size += strlen(&info->strtab[src[i].st_name])+1; | ||
2300 | ndst++; | 2304 | ndst++; |
2301 | } | 2305 | } |
2306 | } | ||
2302 | 2307 | ||
2303 | /* Append room for core symbols at end of core part. */ | 2308 | /* Append room for core symbols at end of core part. */ |
2304 | info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1); | 2309 | info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1); |
@@ -2332,15 +2337,15 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) | |||
2332 | mod->core_symtab = dst = mod->module_core + info->symoffs; | 2337 | mod->core_symtab = dst = mod->module_core + info->symoffs; |
2333 | mod->core_strtab = s = mod->module_core + info->stroffs; | 2338 | mod->core_strtab = s = mod->module_core + info->stroffs; |
2334 | src = mod->symtab; | 2339 | src = mod->symtab; |
2335 | *dst = *src; | ||
2336 | *s++ = 0; | 2340 | *s++ = 0; |
2337 | for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) { | 2341 | for (ndst = i = 0; i < mod->num_symtab; i++) { |
2338 | if (!is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) | 2342 | if (i == 0 || |
2339 | continue; | 2343 | is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { |
2340 | 2344 | dst[ndst] = src[i]; | |
2341 | dst[ndst] = *src; | 2345 | dst[ndst++].st_name = s - mod->core_strtab; |
2342 | dst[ndst++].st_name = s - mod->core_strtab; | 2346 | s += strlcpy(s, &mod->strtab[src[i].st_name], |
2343 | s += strlcpy(s, &mod->strtab[src->st_name], KSYM_NAME_LEN) + 1; | 2347 | KSYM_NAME_LEN) + 1; |
2348 | } | ||
2344 | } | 2349 | } |
2345 | mod->core_num_syms = ndst; | 2350 | mod->core_num_syms = ndst; |
2346 | } | 2351 | } |
@@ -2421,25 +2426,17 @@ static inline void kmemleak_load_module(const struct module *mod, | |||
2421 | 2426 | ||
2422 | #ifdef CONFIG_MODULE_SIG | 2427 | #ifdef CONFIG_MODULE_SIG |
2423 | static int module_sig_check(struct load_info *info, | 2428 | static int module_sig_check(struct load_info *info, |
2424 | const void *mod, unsigned long *len) | 2429 | const void *mod, unsigned long *_len) |
2425 | { | 2430 | { |
2426 | int err = -ENOKEY; | 2431 | int err = -ENOKEY; |
2427 | const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; | 2432 | unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; |
2428 | const void *p = mod, *end = mod + *len; | 2433 | unsigned long len = *_len; |
2429 | 2434 | ||
2430 | /* Poor man's memmem. */ | 2435 | if (len > markerlen && |
2431 | while ((p = memchr(p, MODULE_SIG_STRING[0], end - p))) { | 2436 | memcmp(mod + len - markerlen, MODULE_SIG_STRING, markerlen) == 0) { |
2432 | if (p + markerlen > end) | 2437 | /* We truncate the module to discard the signature */ |
2433 | break; | 2438 | *_len -= markerlen; |
2434 | 2439 | err = mod_verify_sig(mod, _len); | |
2435 | if (memcmp(p, MODULE_SIG_STRING, markerlen) == 0) { | ||
2436 | const void *sig = p + markerlen; | ||
2437 | /* Truncate module up to signature. */ | ||
2438 | *len = p - mod; | ||
2439 | err = mod_verify_sig(mod, *len, sig, end - sig); | ||
2440 | break; | ||
2441 | } | ||
2442 | p++; | ||
2443 | } | 2440 | } |
2444 | 2441 | ||
2445 | if (!err) { | 2442 | if (!err) { |