From: Rusty Russell <rusty@rustcorp.com.au>
To: linux-ia64@vger.kernel.org
Subject: Re: [patch 10/20] kallsyms: fix absolute addresses for kASLR
Date: Thu, 06 Mar 2014 02:57:43 +0000 [thread overview]
Message-ID: <87k3c8yr9u.fsf@rustcorp.com.au> (raw)
Kees Cook <keescook@chromium.org> writes:
> [+x86 folks]
>
> On Tue, Mar 4, 2014 at 7:57 AM, Linus Torvalds
> <torvalds@linux-foundation.org> wrote:
>> On Mon, Mar 3, 2014 at 3:55 PM, Kees Cook <keescook@chromium.org> wrote:
>>> This got NAKed, please don't apply -- this patch works for x86 and
>>> ARM, but may cause problems for others:
>>
>> I'd much rather fix x86 and ARM, than worry about avr32.
>>
>> Priorities, people.
>>
>> Somebody who knows how "fix this properly" is supposed to work?
>
> I have not yet had a chance to more carefully examine the options, but
> AIUI, the problem is that (at least) the "per cpu" variables are
> neither absolute nor relative addresses from a relocation perspective.
> They're relative to the per cpu area, but the linker tools don't know
> about that state. So, I think, to fix this correctly, we need to teach
> the linker tools about this third state. This may also help
> arch/x86/tools/relocs, which is currently using a whitelist for
> mis-identified variables.
Well, __per_cpu_start points into a real section, within the discarded
init region. Makes me wonder why it's zero in /proc/kallsyms (it is on
my Ubuntu system here too).
... digging ...
Ah, the zero-based percpu patches, of course. Gah.
How's this? Did I break IA64?
=kallsyms: make zero-based __per_cpu_start & __per_cpu_end absolute symbols.
Andy reported that x86-64 with CONFIG_RANDOMIZE_BASE has bogus values
for __per_cpu_start and __per_cpu_end in /proc/kallsyms:
Several kallsyms output in different boot states for comparison:
$ egrep '_(stext|_per_cpu_(start|end))' /root/kallsyms.nokaslr
0000000000000000 D __per_cpu_start
0000000000014280 D __per_cpu_end
ffffffff810001c8 T _stext
$ egrep '_(stext|_per_cpu_(start|end))' /root/kallsyms.kaslr1
000000001f200000 D __per_cpu_start
000000001f214280 D __per_cpu_end
ffffffffa02001c8 T _stext
$ egrep '_(stext|_per_cpu_(start|end))' /root/kallsyms.kaslr2
000000000d400000 D __per_cpu_start
000000000d414280 D __per_cpu_end
ffffffff8e4001c8 T _stext
$ egrep '_(stext|_per_cpu_(start|end))' /root/kallsyms.kaslr-fixed
0000000000000000 D __per_cpu_start
0000000000014280 D __per_cpu_end
ffffffffadc001c8 T _stext
x86-64 pretends that the per_cpu section is at address 0, and thus the
__per_cpu_start and __per_cpu_end resolve to 0 and <smallnum>.
kallsyms encodes the addresses in the kallsyms_addresses[] as relative
to _text: this means they get automatically relocated when the kernel
gets moved. But that's clearly wrong for the case where these are
fixed addresses.
/proc/kallsyms already handles absolute symbols, so just make
__per_cpu_start and __per_cpu_end absolute, and add them to the
inclusive list so kallsyms doesn't filter them out.
We make the change to absolute symbols in the PERCPU_VADDR linker
script macro, which is only used by x86 (when !CONFIG_X86_32) and
ia64, to place the per-cpu section at a specific address. This means
that using PERCPU_VADDR is wrong if you don't want an absolute
address, so we remove the comment about the vaddr arg being optional.
The comment on PERCPU_VADDR says __per_cpu_load is an absolute symbol,
but it isn't (and I don't think it should be). Delete that.
Reported-by: Andy Honig <ahonig@google.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index bc2121fa9132..c70e6242d1d6 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -674,6 +674,16 @@
*(.discard.*) \
}
+#define __PERCPU_INPUT(cacheline) \
+ *(.data..percpu..first) \
+ . = ALIGN(PAGE_SIZE); \
+ *(.data..percpu..page_aligned) \
+ . = ALIGN(cacheline); \
+ *(.data..percpu..readmostly) \
+ . = ALIGN(cacheline); \
+ *(.data..percpu) \
+ *(.data..percpu..shared_aligned) \
+
/**
* PERCPU_INPUT - the percpu input sections
* @cacheline: cacheline size
@@ -686,20 +697,13 @@
*/
#define PERCPU_INPUT(cacheline) \
VMLINUX_SYMBOL(__per_cpu_start) = .; \
- *(.data..percpu..first) \
- . = ALIGN(PAGE_SIZE); \
- *(.data..percpu..page_aligned) \
- . = ALIGN(cacheline); \
- *(.data..percpu..readmostly) \
- . = ALIGN(cacheline); \
- *(.data..percpu) \
- *(.data..percpu..shared_aligned) \
+ __PERCPU_INPUT(cacheline) \
VMLINUX_SYMBOL(__per_cpu_end) = .;
/**
* PERCPU_VADDR - define output section for percpu area
* @cacheline: cacheline size
- * @vaddr: explicit base address (optional)
+ * @vaddr: explicit base address
* @phdr: destination PHDR (optional)
*
* Macro which expands to output section for percpu area.
@@ -707,24 +711,25 @@
* @cacheline is used to align subsections to avoid false cacheline
* sharing between subsections for different purposes.
*
- * If @vaddr is not blank, it specifies explicit base address and all
- * percpu symbols will be offset from the given address. If blank,
- * @vaddr always equals @laddr + LOAD_OFFSET.
+ * @vaddr specifies explicit base address and all
+ * percpu symbols will be offset from the given address.
*
* @phdr defines the output PHDR to use if not blank. Be warned that
* output PHDR is sticky. If @phdr is specified, the next output
* section in the linker script will go there too. @phdr should have
* a leading colon.
*
- * Note that this macros defines __per_cpu_load as an absolute symbol.
- * If there is no need to put the percpu section at a predetermined
- * address, use PERCPU_SECTION.
+ * Note that this macros define __per_cpu_start and __per_cpu_end as
+ * absolute addresses. If there is no need to put the percpu section
+ * at a predetermined address, use PERCPU_SECTION.
*/
#define PERCPU_VADDR(cacheline, vaddr, phdr) \
VMLINUX_SYMBOL(__per_cpu_load) = .; \
.data..percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load) \
- LOAD_OFFSET) { \
- PERCPU_INPUT(cacheline) \
+ VMLINUX_SYMBOL(__per_cpu_start) = ABSOLUTE(.); \
+ __PERCPU_INPUT(cacheline) \
+ VMLINUX_SYMBOL(__per_cpu_end) = ABSOLUTE(.); \
} phdr \
. = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data..percpu);
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 10085de886fe..d6782918fe17 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -138,6 +138,7 @@ static int read_symbol(FILE *in, struct sym_entry *s)
if (strcmp(sym, "__kernel_syscall_via_break") &&
strcmp(sym, "__kernel_syscall_via_epc") &&
strcmp(sym, "__kernel_sigtramp") &&
+ strncmp(sym, "__per_cpu", strlen("__per_cpu")) &&
strcmp(sym, "__gp"))
return -1;
next reply other threads:[~2014-03-06 2:57 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-06 2:57 Rusty Russell [this message]
2014-03-06 19:15 ` [patch 10/20] kallsyms: fix absolute addresses for kASLR Kees Cook
2014-03-06 21:25 ` Kees Cook
2014-03-07 0:34 ` Kees Cook
2014-03-07 3:32 ` Rusty Russell
2014-03-07 5:37 ` Kees Cook
2014-03-11 0:48 ` Rusty Russell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87k3c8yr9u.fsf@rustcorp.com.au \
--to=rusty@rustcorp.com.au \
--cc=linux-ia64@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.