Commit 56fc82c5 authored by Tejun Heo's avatar Tejun Heo Committed by Ingo Molnar

modpost: NOBITS sections may point beyond the end of the file

Impact: fix link failure on certain toolchains with specific configs

Recent percpu change made x86_64 split .data.init section into three
separate segments - data.init, percpu and data.init2.  data.init2 gets
.data.nosave and .bss.* and is followed by .notes segment.  Depending
on configuration both segments might contain no data, in which case
the tool chain makes the section header to contain offset beyond the
end of the file.

modpost isn't too happy about it and fails build - as reported by
Pawel Dziekonski:

    Building modules, stage 2.
    MODPOST 416 modules
    FATAL: vmlinux is truncated. sechdrs[i].sh_offset=10354688 >
    sizeof(*hrd)=64
    make[1]: *** [__modpost] Error 1

Teach modpost that NOBITS section may point beyond the end of the file
and that .modinfo can't be NOBITS.
Reported-by: default avatarPawel Dziekonski <dzieko@gmail.com>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 130ace11
...@@ -415,8 +415,9 @@ static int parse_elf(struct elf_info *info, const char *filename) ...@@ -415,8 +415,9 @@ static int parse_elf(struct elf_info *info, const char *filename)
const char *secstrings const char *secstrings
= (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
const char *secname; const char *secname;
int nobits = sechdrs[i].sh_type == SHT_NOBITS;
if (sechdrs[i].sh_offset > info->size) { if (!nobits && sechdrs[i].sh_offset > info->size) {
fatal("%s is truncated. sechdrs[i].sh_offset=%lu > " fatal("%s is truncated. sechdrs[i].sh_offset=%lu > "
"sizeof(*hrd)=%zu\n", filename, "sizeof(*hrd)=%zu\n", filename,
(unsigned long)sechdrs[i].sh_offset, (unsigned long)sechdrs[i].sh_offset,
...@@ -425,6 +426,8 @@ static int parse_elf(struct elf_info *info, const char *filename) ...@@ -425,6 +426,8 @@ static int parse_elf(struct elf_info *info, const char *filename)
} }
secname = secstrings + sechdrs[i].sh_name; secname = secstrings + sechdrs[i].sh_name;
if (strcmp(secname, ".modinfo") == 0) { if (strcmp(secname, ".modinfo") == 0) {
if (nobits)
fatal("%s has NOBITS .modinfo\n", filename);
info->modinfo = (void *)hdr + sechdrs[i].sh_offset; info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
info->modinfo_len = sechdrs[i].sh_size; info->modinfo_len = sechdrs[i].sh_size;
} else if (strcmp(secname, "__ksymtab") == 0) } else if (strcmp(secname, "__ksymtab") == 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment