Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'x86/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Peter Anvin:
"A pile of fixes related to the VDSO, EFI and 32-bit badsys handling.

It turns out that removing the section headers from the VDSO breaks
gdb, so this puts back most of them. A very simple typo broke
rt_sigreturn on some versions of glibc, with obviously disastrous
results. The rest is pretty much fixes for the corresponding fallout.

The EFI fixes fixes an arithmetic overflow on 32-bit systems and
quiets some build warnings.

Finally, when invoking an invalid system call number on x86-32, we
bypass a bunch of handling, which can make the audit code oops"

* 'x86/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
efi-pstore: Fix an overflow on 32-bit builds
x86/vdso: Error out in vdso2c if DT_RELA is present
x86/vdso: Move DISABLE_BRANCH_PROFILING into the vdso makefile
x86_32, signal: Fix vdso rt_sigreturn
x86_32, entry: Do syscall exit work on badsys (CVE-2014-4508)
x86/vdso: Create .build-id links for unstripped vdso files
x86/vdso: Remove some redundant in-memory section headers
x86/vdso: Improve the fake section headers
x86/vdso2c: Use better macros for ELF bitness
x86/vdso: Discard the __bug_table section
efi: Fix compiler warnings (unused, const, type)

+302 -129
+8 -2
arch/x86/kernel/entry_32.S
··· 423 423 jnz sysenter_audit 424 424 sysenter_do_call: 425 425 cmpl $(NR_syscalls), %eax 426 - jae syscall_badsys 426 + jae sysenter_badsys 427 427 call *sys_call_table(,%eax,4) 428 428 movl %eax,PT_EAX(%esp) 429 + sysenter_after_call: 429 430 LOCKDEP_SYS_EXIT 430 431 DISABLE_INTERRUPTS(CLBR_ANY) 431 432 TRACE_IRQS_OFF ··· 676 675 677 676 syscall_badsys: 678 677 movl $-ENOSYS,PT_EAX(%esp) 679 - jmp resume_userspace 678 + jmp syscall_exit 679 + END(syscall_badsys) 680 + 681 + sysenter_badsys: 682 + movl $-ENOSYS,PT_EAX(%esp) 683 + jmp sysenter_after_call 680 684 END(syscall_badsys) 681 685 CFI_ENDPROC 682 686
+1 -1
arch/x86/kernel/signal.c
··· 363 363 364 364 /* Set up to return from userspace. */ 365 365 restorer = current->mm->context.vdso + 366 - selected_vdso32->sym___kernel_sigreturn; 366 + selected_vdso32->sym___kernel_rt_sigreturn; 367 367 if (ksig->ka.sa.sa_flags & SA_RESTORER) 368 368 restorer = ksig->ka.sa.sa_restorer; 369 369 put_user_ex(restorer, &frame->pretcode);
+18 -6
arch/x86/vdso/Makefile
··· 11 11 12 12 # files to link into the vdso 13 13 vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o vdso-fakesections.o 14 - vobjs-nox32 := vdso-fakesections.o 15 14 16 15 # files to link into kernel 17 16 obj-y += vma.o ··· 66 67 # 67 68 CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \ 68 69 $(filter -g%,$(KBUILD_CFLAGS)) $(call cc-option, -fno-stack-protector) \ 69 - -fno-omit-frame-pointer -foptimize-sibling-calls 70 + -fno-omit-frame-pointer -foptimize-sibling-calls \ 71 + -DDISABLE_BRANCH_PROFILING 70 72 71 73 $(vobjs): KBUILD_CFLAGS += $(CFL) 72 74 ··· 134 134 135 135 targets += vdso32/vdso32.lds 136 136 targets += vdso32/note.o vdso32/vclock_gettime.o $(vdso32.so-y:%=vdso32/%.o) 137 - targets += vdso32/vclock_gettime.o 137 + targets += vdso32/vclock_gettime.o vdso32/vdso-fakesections.o 138 138 139 139 $(obj)/vdso32.o: $(vdso32-images:%=$(obj)/%) 140 140 ··· 150 150 KBUILD_CFLAGS_32 += $(call cc-option, -fno-stack-protector) 151 151 KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls) 152 152 KBUILD_CFLAGS_32 += -fno-omit-frame-pointer 153 + KBUILD_CFLAGS_32 += -DDISABLE_BRANCH_PROFILING 153 154 $(vdso32-images:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_32) 154 155 155 156 $(vdso32-images:%=$(obj)/%.dbg): $(obj)/vdso32-%.so.dbg: FORCE \ 156 157 $(obj)/vdso32/vdso32.lds \ 157 158 $(obj)/vdso32/vclock_gettime.o \ 159 + $(obj)/vdso32/vdso-fakesections.o \ 158 160 $(obj)/vdso32/note.o \ 159 161 $(obj)/vdso32/%.o 160 162 $(call if_changed,vdso) ··· 171 169 sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@' 172 170 173 171 VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) \ 174 - -Wl,-Bsymbolic $(LTO_CFLAGS) 172 + $(call cc-ldoption, -Wl$(comma)--build-id) -Wl,-Bsymbolic $(LTO_CFLAGS) 175 173 GCOV_PROFILE := n 176 174 177 175 # 178 - # Install the unstripped copies of vdso*.so. 176 + # Install the unstripped copies of vdso*.so. If our toolchain supports 177 + # build-id, install .build-id links as well. 179 178 # 180 179 quiet_cmd_vdso_install = INSTALL $(@:install_%=%) 181 - cmd_vdso_install = cp $< $(MODLIB)/vdso/$(@:install_%=%) 180 + define cmd_vdso_install 181 + cp $< "$(MODLIB)/vdso/$(@:install_%=%)"; \ 182 + if readelf -n $< |grep -q 'Build ID'; then \ 183 + buildid=`readelf -n $< |grep 'Build ID' |sed -e 's/^.*Build ID: \(.*\)$$/\1/'`; \ 184 + first=`echo $$buildid | cut -b-2`; \ 185 + last=`echo $$buildid | cut -b3-`; \ 186 + mkdir -p "$(MODLIB)/vdso/.build-id/$$first"; \ 187 + ln -sf "../../$(@:install_%=%)" "$(MODLIB)/vdso/.build-id/$$first/$$last.debug"; \ 188 + fi 189 + endef 182 190 183 191 vdso_img_insttargets := $(vdso_img_sodbg:%.dbg=install_%) 184 192
-3
arch/x86/vdso/vclock_gettime.c
··· 11 11 * Check with readelf after changing. 12 12 */ 13 13 14 - /* Disable profiling for userspace code: */ 15 - #define DISABLE_BRANCH_PROFILING 16 - 17 14 #include <uapi/linux/time.h> 18 15 #include <asm/vgtod.h> 19 16 #include <asm/hpet.h>
+15 -26
arch/x86/vdso/vdso-fakesections.c
··· 2 2 * Copyright 2014 Andy Lutomirski 3 3 * Subject to the GNU Public License, v.2 4 4 * 5 - * Hack to keep broken Go programs working. 6 - * 7 - * The Go runtime had a couple of bugs: it would read the section table to try 8 - * to figure out how many dynamic symbols there were (it shouldn't have looked 9 - * at the section table at all) and, if there were no SHT_SYNDYM section table 10 - * entry, it would use an uninitialized value for the number of symbols. As a 11 - * workaround, we supply a minimal section table. vdso2c will adjust the 12 - * in-memory image so that "vdso_fake_sections" becomes the section table. 13 - * 14 - * The bug was introduced by: 15 - * https://code.google.com/p/go/source/detail?r=56ea40aac72b (2012-08-31) 16 - * and is being addressed in the Go runtime in this issue: 17 - * https://code.google.com/p/go/issues/detail?id=8197 5 + * String table for loadable section headers. See vdso2c.h for why 6 + * this exists. 18 7 */ 19 8 20 - #ifndef __x86_64__ 21 - #error This hack is specific to the 64-bit vDSO 22 - #endif 23 - 24 - #include <linux/elf.h> 25 - 26 - extern const __visible struct elf64_shdr vdso_fake_sections[]; 27 - const __visible struct elf64_shdr vdso_fake_sections[] = { 28 - { 29 - .sh_type = SHT_DYNSYM, 30 - .sh_entsize = sizeof(Elf64_Sym), 31 - } 32 - }; 9 + const char fake_shstrtab[] __attribute__((section(".fake_shstrtab"))) = 10 + ".hash\0" 11 + ".dynsym\0" 12 + ".dynstr\0" 13 + ".gnu.version\0" 14 + ".gnu.version_d\0" 15 + ".dynamic\0" 16 + ".rodata\0" 17 + ".fake_shstrtab\0" /* Yay, self-referential code. */ 18 + ".note\0" 19 + ".eh_frame_hdr\0" 20 + ".eh_frame\0" 21 + ".text";
+46 -18
arch/x86/vdso/vdso-layout.lds.S
··· 6 6 * This script controls its layout. 7 7 */ 8 8 9 + #if defined(BUILD_VDSO64) 10 + # define SHDR_SIZE 64 11 + #elif defined(BUILD_VDSO32) || defined(BUILD_VDSOX32) 12 + # define SHDR_SIZE 40 13 + #else 14 + # error unknown VDSO target 15 + #endif 16 + 17 + #define NUM_FAKE_SHDRS 13 18 + 9 19 SECTIONS 10 20 { 11 21 . = SIZEOF_HEADERS; ··· 28 18 .gnu.version_d : { *(.gnu.version_d) } 29 19 .gnu.version_r : { *(.gnu.version_r) } 30 20 21 + .dynamic : { *(.dynamic) } :text :dynamic 22 + 23 + .rodata : { 24 + *(.rodata*) 25 + *(.data*) 26 + *(.sdata*) 27 + *(.got.plt) *(.got) 28 + *(.gnu.linkonce.d.*) 29 + *(.bss*) 30 + *(.dynbss*) 31 + *(.gnu.linkonce.b.*) 32 + 33 + /* 34 + * Ideally this would live in a C file, but that won't 35 + * work cleanly for x32 until we start building the x32 36 + * C code using an x32 toolchain. 37 + */ 38 + VDSO_FAKE_SECTION_TABLE_START = .; 39 + . = . + NUM_FAKE_SHDRS * SHDR_SIZE; 40 + VDSO_FAKE_SECTION_TABLE_END = .; 41 + } :text 42 + 43 + .fake_shstrtab : { *(.fake_shstrtab) } :text 44 + 45 + 31 46 .note : { *(.note.*) } :text :note 32 47 33 48 .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr 34 49 .eh_frame : { KEEP (*(.eh_frame)) } :text 35 50 36 - .dynamic : { *(.dynamic) } :text :dynamic 37 - 38 - .rodata : { *(.rodata*) } :text 39 - .data : { 40 - *(.data*) 41 - *(.sdata*) 42 - *(.got.plt) *(.got) 43 - *(.gnu.linkonce.d.*) 44 - *(.bss*) 45 - *(.dynbss*) 46 - *(.gnu.linkonce.b.*) 47 - } 48 - 49 - .altinstructions : { *(.altinstructions) } 50 - .altinstr_replacement : { *(.altinstr_replacement) } 51 51 52 52 /* 53 - * Align the actual code well away from the non-instruction data. 54 - * This is the best thing for the I-cache. 53 + * Text is well-separated from actual data: there's plenty of 54 + * stuff that isn't used at runtime in between. 55 55 */ 56 - . = ALIGN(0x100); 57 56 58 57 .text : { *(.text*) } :text =0x90909090, 58 + 59 + /* 60 + * At the end so that eu-elflint stays happy when vdso2c strips 61 + * these. A better implementation would avoid allocating space 62 + * for these. 63 + */ 64 + .altinstructions : { *(.altinstructions) } :text 65 + .altinstr_replacement : { *(.altinstr_replacement) } :text 59 66 60 67 /* 61 68 * The remainder of the vDSO consists of special pages that are ··· 102 75 /DISCARD/ : { 103 76 *(.discard) 104 77 *(.discard.*) 78 + *(__bug_table) 105 79 } 106 80 } 107 81
+2
arch/x86/vdso/vdso.lds.S
··· 6 6 * the DSO. 7 7 */ 8 8 9 + #define BUILD_VDSO64 10 + 9 11 #include "vdso-layout.lds.S" 10 12 11 13 /*
+35 -38
arch/x86/vdso/vdso2c.c
··· 23 23 sym_vvar_page, 24 24 sym_hpet_page, 25 25 sym_end_mapping, 26 + sym_VDSO_FAKE_SECTION_TABLE_START, 27 + sym_VDSO_FAKE_SECTION_TABLE_END, 26 28 }; 27 29 28 30 const int special_pages[] = { ··· 32 30 sym_hpet_page, 33 31 }; 34 32 35 - char const * const required_syms[] = { 36 - [sym_vvar_page] = "vvar_page", 37 - [sym_hpet_page] = "hpet_page", 38 - [sym_end_mapping] = "end_mapping", 39 - "VDSO32_NOTE_MASK", 40 - "VDSO32_SYSENTER_RETURN", 41 - "__kernel_vsyscall", 42 - "__kernel_sigreturn", 43 - "__kernel_rt_sigreturn", 33 + struct vdso_sym { 34 + const char *name; 35 + bool export; 36 + }; 37 + 38 + struct vdso_sym required_syms[] = { 39 + [sym_vvar_page] = {"vvar_page", true}, 40 + [sym_hpet_page] = {"hpet_page", true}, 41 + [sym_end_mapping] = {"end_mapping", true}, 42 + [sym_VDSO_FAKE_SECTION_TABLE_START] = { 43 + "VDSO_FAKE_SECTION_TABLE_START", false 44 + }, 45 + [sym_VDSO_FAKE_SECTION_TABLE_END] = { 46 + "VDSO_FAKE_SECTION_TABLE_END", false 47 + }, 48 + {"VDSO32_NOTE_MASK", true}, 49 + {"VDSO32_SYSENTER_RETURN", true}, 50 + {"__kernel_vsyscall", true}, 51 + {"__kernel_sigreturn", true}, 52 + {"__kernel_rt_sigreturn", true}, 44 53 }; 45 54 46 55 __attribute__((format(printf, 1, 2))) __attribute__((noreturn)) ··· 96 83 97 84 #define NSYMS (sizeof(required_syms) / sizeof(required_syms[0])) 98 85 99 - #define BITS 64 100 - #define GOFUNC go64 101 - #define Elf_Ehdr Elf64_Ehdr 102 - #define Elf_Shdr Elf64_Shdr 103 - #define Elf_Phdr Elf64_Phdr 104 - #define Elf_Sym Elf64_Sym 105 - #define Elf_Dyn Elf64_Dyn 106 - #include "vdso2c.h" 107 - #undef BITS 108 - #undef GOFUNC 109 - #undef Elf_Ehdr 110 - #undef Elf_Shdr 111 - #undef Elf_Phdr 112 - #undef Elf_Sym 113 - #undef Elf_Dyn 86 + #define BITSFUNC3(name, bits) name##bits 87 + #define BITSFUNC2(name, bits) BITSFUNC3(name, bits) 88 + #define BITSFUNC(name) BITSFUNC2(name, ELF_BITS) 114 89 115 - #define BITS 32 116 - #define GOFUNC go32 117 - #define Elf_Ehdr Elf32_Ehdr 118 - #define Elf_Shdr Elf32_Shdr 119 - #define Elf_Phdr Elf32_Phdr 120 - #define Elf_Sym Elf32_Sym 121 - #define Elf_Dyn Elf32_Dyn 90 + #define ELF_BITS_XFORM2(bits, x) Elf##bits##_##x 91 + #define ELF_BITS_XFORM(bits, x) ELF_BITS_XFORM2(bits, x) 92 + #define ELF(x) ELF_BITS_XFORM(ELF_BITS, x) 93 + 94 + #define ELF_BITS 64 122 95 #include "vdso2c.h" 123 - #undef BITS 124 - #undef GOFUNC 125 - #undef Elf_Ehdr 126 - #undef Elf_Shdr 127 - #undef Elf_Phdr 128 - #undef Elf_Sym 129 - #undef Elf_Dyn 96 + #undef ELF_BITS 97 + 98 + #define ELF_BITS 32 99 + #include "vdso2c.h" 100 + #undef ELF_BITS 130 101 131 102 static void go(void *addr, size_t len, FILE *outfile, const char *name) 132 103 {
+169 -30
arch/x86/vdso/vdso2c.h
··· 4 4 * are built for 32-bit userspace. 5 5 */ 6 6 7 - static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name) 7 + /* 8 + * We're writing a section table for a few reasons: 9 + * 10 + * The Go runtime had a couple of bugs: it would read the section 11 + * table to try to figure out how many dynamic symbols there were (it 12 + * shouldn't have looked at the section table at all) and, if there 13 + * were no SHT_SYNDYM section table entry, it would use an 14 + * uninitialized value for the number of symbols. An empty DYNSYM 15 + * table would work, but I see no reason not to write a valid one (and 16 + * keep full performance for old Go programs). This hack is only 17 + * needed on x86_64. 18 + * 19 + * The bug was introduced on 2012-08-31 by: 20 + * https://code.google.com/p/go/source/detail?r=56ea40aac72b 21 + * and was fixed on 2014-06-13 by: 22 + * https://code.google.com/p/go/source/detail?r=fc1cd5e12595 23 + * 24 + * Binutils has issues debugging the vDSO: it reads the section table to 25 + * find SHT_NOTE; it won't look at PT_NOTE for the in-memory vDSO, which 26 + * would break build-id if we removed the section table. Binutils 27 + * also requires that shstrndx != 0. See: 28 + * https://sourceware.org/bugzilla/show_bug.cgi?id=17064 29 + * 30 + * elfutils might not look for PT_NOTE if there is a section table at 31 + * all. I don't know whether this matters for any practical purpose. 32 + * 33 + * For simplicity, rather than hacking up a partial section table, we 34 + * just write a mostly complete one. We omit non-dynamic symbols, 35 + * though, since they're rather large. 36 + * 37 + * Once binutils gets fixed, we might be able to drop this for all but 38 + * the 64-bit vdso, since build-id only works in kernel RPMs, and 39 + * systems that update to new enough kernel RPMs will likely update 40 + * binutils in sync. build-id has never worked for home-built kernel 41 + * RPMs without manual symlinking, and I suspect that no one ever does 42 + * that. 43 + */ 44 + struct BITSFUNC(fake_sections) 45 + { 46 + ELF(Shdr) *table; 47 + unsigned long table_offset; 48 + int count, max_count; 49 + 50 + int in_shstrndx; 51 + unsigned long shstr_offset; 52 + const char *shstrtab; 53 + size_t shstrtab_len; 54 + 55 + int out_shstrndx; 56 + }; 57 + 58 + static unsigned int BITSFUNC(find_shname)(struct BITSFUNC(fake_sections) *out, 59 + const char *name) 60 + { 61 + const char *outname = out->shstrtab; 62 + while (outname - out->shstrtab < out->shstrtab_len) { 63 + if (!strcmp(name, outname)) 64 + return (outname - out->shstrtab) + out->shstr_offset; 65 + outname += strlen(outname) + 1; 66 + } 67 + 68 + if (*name) 69 + printf("Warning: could not find output name \"%s\"\n", name); 70 + return out->shstr_offset + out->shstrtab_len - 1; /* Use a null. */ 71 + } 72 + 73 + static void BITSFUNC(init_sections)(struct BITSFUNC(fake_sections) *out) 74 + { 75 + if (!out->in_shstrndx) 76 + fail("didn't find the fake shstrndx\n"); 77 + 78 + memset(out->table, 0, out->max_count * sizeof(ELF(Shdr))); 79 + 80 + if (out->max_count < 1) 81 + fail("we need at least two fake output sections\n"); 82 + 83 + PUT_LE(&out->table[0].sh_type, SHT_NULL); 84 + PUT_LE(&out->table[0].sh_name, BITSFUNC(find_shname)(out, "")); 85 + 86 + out->count = 1; 87 + } 88 + 89 + static void BITSFUNC(copy_section)(struct BITSFUNC(fake_sections) *out, 90 + int in_idx, const ELF(Shdr) *in, 91 + const char *name) 92 + { 93 + uint64_t flags = GET_LE(&in->sh_flags); 94 + 95 + bool copy = flags & SHF_ALLOC && 96 + strcmp(name, ".altinstructions") && 97 + strcmp(name, ".altinstr_replacement"); 98 + 99 + if (!copy) 100 + return; 101 + 102 + if (out->count >= out->max_count) 103 + fail("too many copied sections (max = %d)\n", out->max_count); 104 + 105 + if (in_idx == out->in_shstrndx) 106 + out->out_shstrndx = out->count; 107 + 108 + out->table[out->count] = *in; 109 + PUT_LE(&out->table[out->count].sh_name, 110 + BITSFUNC(find_shname)(out, name)); 111 + 112 + /* elfutils requires that a strtab have the correct type. */ 113 + if (!strcmp(name, ".fake_shstrtab")) 114 + PUT_LE(&out->table[out->count].sh_type, SHT_STRTAB); 115 + 116 + out->count++; 117 + } 118 + 119 + static void BITSFUNC(go)(void *addr, size_t len, 120 + FILE *outfile, const char *name) 8 121 { 9 122 int found_load = 0; 10 123 unsigned long load_size = -1; /* Work around bogus warning */ 11 124 unsigned long data_size; 12 - Elf_Ehdr *hdr = (Elf_Ehdr *)addr; 125 + ELF(Ehdr) *hdr = (ELF(Ehdr) *)addr; 13 126 int i; 14 127 unsigned long j; 15 - Elf_Shdr *symtab_hdr = NULL, *strtab_hdr, *secstrings_hdr, 128 + ELF(Shdr) *symtab_hdr = NULL, *strtab_hdr, *secstrings_hdr, 16 129 *alt_sec = NULL; 17 - Elf_Dyn *dyn = 0, *dyn_end = 0; 130 + ELF(Dyn) *dyn = 0, *dyn_end = 0; 18 131 const char *secstrings; 19 132 uint64_t syms[NSYMS] = {}; 20 133 21 - uint64_t fake_sections_value = 0, fake_sections_size = 0; 134 + struct BITSFUNC(fake_sections) fake_sections = {}; 22 135 23 - Elf_Phdr *pt = (Elf_Phdr *)(addr + GET_LE(&hdr->e_phoff)); 136 + ELF(Phdr) *pt = (ELF(Phdr) *)(addr + GET_LE(&hdr->e_phoff)); 24 137 25 138 /* Walk the segment table. */ 26 139 for (i = 0; i < GET_LE(&hdr->e_phnum); i++) { ··· 164 51 for (i = 0; dyn + i < dyn_end && 165 52 GET_LE(&dyn[i].d_tag) != DT_NULL; i++) { 166 53 typeof(dyn[i].d_tag) tag = GET_LE(&dyn[i].d_tag); 167 - if (tag == DT_REL || tag == DT_RELSZ || 54 + if (tag == DT_REL || tag == DT_RELSZ || tag == DT_RELA || 168 55 tag == DT_RELENT || tag == DT_TEXTREL) 169 56 fail("vdso image contains dynamic relocations\n"); 170 57 } ··· 174 61 GET_LE(&hdr->e_shentsize)*GET_LE(&hdr->e_shstrndx); 175 62 secstrings = addr + GET_LE(&secstrings_hdr->sh_offset); 176 63 for (i = 0; i < GET_LE(&hdr->e_shnum); i++) { 177 - Elf_Shdr *sh = addr + GET_LE(&hdr->e_shoff) + 64 + ELF(Shdr) *sh = addr + GET_LE(&hdr->e_shoff) + 178 65 GET_LE(&hdr->e_shentsize) * i; 179 66 if (GET_LE(&sh->sh_type) == SHT_SYMTAB) 180 67 symtab_hdr = sh; ··· 195 82 i < GET_LE(&symtab_hdr->sh_size) / GET_LE(&symtab_hdr->sh_entsize); 196 83 i++) { 197 84 int k; 198 - Elf_Sym *sym = addr + GET_LE(&symtab_hdr->sh_offset) + 85 + ELF(Sym) *sym = addr + GET_LE(&symtab_hdr->sh_offset) + 199 86 GET_LE(&symtab_hdr->sh_entsize) * i; 200 87 const char *name = addr + GET_LE(&strtab_hdr->sh_offset) + 201 88 GET_LE(&sym->st_name); 202 89 203 90 for (k = 0; k < NSYMS; k++) { 204 - if (!strcmp(name, required_syms[k])) { 91 + if (!strcmp(name, required_syms[k].name)) { 205 92 if (syms[k]) { 206 93 fail("duplicate symbol %s\n", 207 - required_syms[k]); 94 + required_syms[k].name); 208 95 } 209 96 syms[k] = GET_LE(&sym->st_value); 210 97 } 211 98 } 212 99 213 - if (!strcmp(name, "vdso_fake_sections")) { 214 - if (fake_sections_value) 215 - fail("duplicate vdso_fake_sections\n"); 216 - fake_sections_value = GET_LE(&sym->st_value); 217 - fake_sections_size = GET_LE(&sym->st_size); 100 + if (!strcmp(name, "fake_shstrtab")) { 101 + ELF(Shdr) *sh; 102 + 103 + fake_sections.in_shstrndx = GET_LE(&sym->st_shndx); 104 + fake_sections.shstrtab = addr + GET_LE(&sym->st_value); 105 + fake_sections.shstrtab_len = GET_LE(&sym->st_size); 106 + sh = addr + GET_LE(&hdr->e_shoff) + 107 + GET_LE(&hdr->e_shentsize) * 108 + fake_sections.in_shstrndx; 109 + fake_sections.shstr_offset = GET_LE(&sym->st_value) - 110 + GET_LE(&sh->sh_addr); 218 111 } 219 112 } 113 + 114 + /* Build the output section table. */ 115 + if (!syms[sym_VDSO_FAKE_SECTION_TABLE_START] || 116 + !syms[sym_VDSO_FAKE_SECTION_TABLE_END]) 117 + fail("couldn't find fake section table\n"); 118 + if ((syms[sym_VDSO_FAKE_SECTION_TABLE_END] - 119 + syms[sym_VDSO_FAKE_SECTION_TABLE_START]) % sizeof(ELF(Shdr))) 120 + fail("fake section table size isn't a multiple of sizeof(Shdr)\n"); 121 + fake_sections.table = addr + syms[sym_VDSO_FAKE_SECTION_TABLE_START]; 122 + fake_sections.table_offset = syms[sym_VDSO_FAKE_SECTION_TABLE_START]; 123 + fake_sections.max_count = (syms[sym_VDSO_FAKE_SECTION_TABLE_END] - 124 + syms[sym_VDSO_FAKE_SECTION_TABLE_START]) / 125 + sizeof(ELF(Shdr)); 126 + 127 + BITSFUNC(init_sections)(&fake_sections); 128 + for (i = 0; i < GET_LE(&hdr->e_shnum); i++) { 129 + ELF(Shdr) *sh = addr + GET_LE(&hdr->e_shoff) + 130 + GET_LE(&hdr->e_shentsize) * i; 131 + BITSFUNC(copy_section)(&fake_sections, i, sh, 132 + secstrings + GET_LE(&sh->sh_name)); 133 + } 134 + if (!fake_sections.out_shstrndx) 135 + fail("didn't generate shstrndx?!?\n"); 136 + 137 + PUT_LE(&hdr->e_shoff, fake_sections.table_offset); 138 + PUT_LE(&hdr->e_shentsize, sizeof(ELF(Shdr))); 139 + PUT_LE(&hdr->e_shnum, fake_sections.count); 140 + PUT_LE(&hdr->e_shstrndx, fake_sections.out_shstrndx); 220 141 221 142 /* Validate mapping addresses. */ 222 143 for (i = 0; i < sizeof(special_pages) / sizeof(special_pages[0]); i++) { ··· 259 112 260 113 if (syms[i] % 4096) 261 114 fail("%s must be a multiple of 4096\n", 262 - required_syms[i]); 115 + required_syms[i].name); 263 116 if (syms[i] < data_size) 264 117 fail("%s must be after the text mapping\n", 265 - required_syms[i]); 118 + required_syms[i].name); 266 119 if (syms[sym_end_mapping] < syms[i] + 4096) 267 - fail("%s overruns end_mapping\n", required_syms[i]); 120 + fail("%s overruns end_mapping\n", 121 + required_syms[i].name); 268 122 } 269 123 if (syms[sym_end_mapping] % 4096) 270 124 fail("end_mapping must be a multiple of 4096\n"); 271 - 272 - /* Remove sections or use fakes */ 273 - if (fake_sections_size % sizeof(Elf_Shdr)) 274 - fail("vdso_fake_sections size is not a multiple of %ld\n", 275 - (long)sizeof(Elf_Shdr)); 276 - PUT_LE(&hdr->e_shoff, fake_sections_value); 277 - PUT_LE(&hdr->e_shentsize, fake_sections_value ? sizeof(Elf_Shdr) : 0); 278 - PUT_LE(&hdr->e_shnum, fake_sections_size / sizeof(Elf_Shdr)); 279 - PUT_LE(&hdr->e_shstrndx, SHN_UNDEF); 280 125 281 126 if (!name) { 282 127 fwrite(addr, load_size, 1, outfile); ··· 307 168 (unsigned long)GET_LE(&alt_sec->sh_size)); 308 169 } 309 170 for (i = 0; i < NSYMS; i++) { 310 - if (syms[i]) 171 + if (required_syms[i].export && syms[i]) 311 172 fprintf(outfile, "\t.sym_%s = 0x%" PRIx64 ",\n", 312 - required_syms[i], syms[i]); 173 + required_syms[i].name, syms[i]); 313 174 } 314 175 fprintf(outfile, "};\n"); 315 176 }
+1
arch/x86/vdso/vdso32/vdso-fakesections.c
··· 1 + #include "../vdso-fakesections.c"
+2
arch/x86/vdso/vdsox32.lds.S
··· 6 6 * the DSO. 7 7 */ 8 8 9 + #define BUILD_VDSOX32 10 + 9 11 #include "vdso-layout.lds.S" 10 12 11 13 /*
+1 -1
drivers/firmware/efi/efi-pstore.c
··· 40 40 static inline u64 generic_id(unsigned long timestamp, 41 41 unsigned int part, int count) 42 42 { 43 - return (timestamp * 100 + part) * 1000 + count; 43 + return ((u64) timestamp * 100 + part) * 1000 + count; 44 44 } 45 45 46 46 static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
+3 -3
drivers/firmware/efi/efi.c
··· 353 353 int depth, void *data) 354 354 { 355 355 struct param_info *info = data; 356 - void *prop, *dest; 357 - unsigned long len; 356 + const void *prop; 357 + void *dest; 358 358 u64 val; 359 - int i; 359 + int i, len; 360 360 361 361 if (depth != 1 || 362 362 (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
+1 -1
drivers/firmware/efi/fdt.c
··· 63 63 */ 64 64 prev = 0; 65 65 for (;;) { 66 - const char *type, *name; 66 + const char *type; 67 67 int len; 68 68 69 69 node = fdt_next_node(fdt, prev, NULL);