2014-02-21 20:11:01

by Kees Cook

[permalink] [raw]
Subject: [PATCH] kallsyms: fix absolute addresses for kASLR

From: Andy Honig <[email protected]>

Currently symbols that are absolute addresses are incorrectly
displayed in /proc/kallsyms if the kernel is loaded with kASLR.

The problem was that the scripts/kallsyms.c file which generates
the array of symbol names and addresses uses an relocatable value
for all symbols, even absolute symbols. This patch fixes that.

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

Signed-off-by: Andy Honig <[email protected]>
Signed-off-by: Kees Cook <[email protected]>
---
scripts/kallsyms.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 10085de886fe..276e84b8a8e5 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -330,8 +330,7 @@ static void write_src(void)
printf("\tPTR\t_text + %#llx\n",
table[i].addr - _text);
else
- printf("\tPTR\t_text - %#llx\n",
- _text - table[i].addr);
+ printf("\tPTR\t%#llx\n", table[i].addr);
} else {
printf("\tPTR\t%#llx\n", table[i].addr);
}
--
1.7.9.5


--
Kees Cook
Chrome OS Security


2014-02-25 01:37:10

by Rusty Russell

[permalink] [raw]
Subject: Re: [PATCH] kallsyms: fix absolute addresses for kASLR

Kees Cook <[email protected]> writes:
> From: Andy Honig <[email protected]>
>
> Currently symbols that are absolute addresses are incorrectly
> displayed in /proc/kallsyms if the kernel is loaded with kASLR.
>
> The problem was that the scripts/kallsyms.c file which generates
> the array of symbol names and addresses uses an relocatable value
> for all symbols, even absolute symbols. This patch fixes that.

Hi Andy, Kees,

This is not a good patch. See the commit where this was
introduced:

[PATCH] relocatable kernel: Fix kallsyms on avr32 after relocatable kernel changes

o On some platforms like avr32, section init comes before .text and
not necessarily a symbol's relative position w.r.t _text is positive.
In such cases assembler detects the overflow and emits warning. This
patch fixes it.

Did you just break avr32?

And absolute symbols are supposed to be handled in the other branch:

for (i = 0; i < table_cnt; i++) {
if (toupper(table[i].sym[0]) != 'A') {
if (_text <= table[i].addr)
printf("\tPTR\t_text + %#llx\n",
table[i].addr - _text);
else
printf("\tPTR\t_text - %#llx\n",
_text - table[i].addr);
} else {
printf("\tPTR\t%#llx\n", table[i].addr);
}
}

__per_cpu_start is not an absolute symbol anyway.

You need to fix this properly.
Rusty.

> 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
>
> Signed-off-by: Andy Honig <[email protected]>
> Signed-off-by: Kees Cook <[email protected]>
> ---
> scripts/kallsyms.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
> index 10085de886fe..276e84b8a8e5 100644
> --- a/scripts/kallsyms.c
> +++ b/scripts/kallsyms.c
> @@ -330,8 +330,7 @@ static void write_src(void)
> printf("\tPTR\t_text + %#llx\n",
> table[i].addr - _text);
> else
> - printf("\tPTR\t_text - %#llx\n",
> - _text - table[i].addr);
> + printf("\tPTR\t%#llx\n", table[i].addr);
> } else {
> printf("\tPTR\t%#llx\n", table[i].addr);
> }

2014-02-26 06:15:27

by Kees Cook

[permalink] [raw]
Subject: Re: [PATCH] kallsyms: fix absolute addresses for kASLR

On Mon, Feb 24, 2014 at 5:29 PM, Rusty Russell <[email protected]> wrote:
> Kees Cook <[email protected]> writes:
>> From: Andy Honig <[email protected]>
>>
>> Currently symbols that are absolute addresses are incorrectly
>> displayed in /proc/kallsyms if the kernel is loaded with kASLR.
>>
>> The problem was that the scripts/kallsyms.c file which generates
>> the array of symbol names and addresses uses an relocatable value
>> for all symbols, even absolute symbols. This patch fixes that.
>
> Hi Andy, Kees,
>
> This is not a good patch. See the commit where this was
> introduced:
>
> [PATCH] relocatable kernel: Fix kallsyms on avr32 after relocatable kernel changes
>
> o On some platforms like avr32, section init comes before .text and
> not necessarily a symbol's relative position w.r.t _text is positive.
> In such cases assembler detects the overflow and emits warning. This
> patch fixes it.
>
> Did you just break avr32?
>
> And absolute symbols are supposed to be handled in the other branch:
>
> for (i = 0; i < table_cnt; i++) {
> if (toupper(table[i].sym[0]) != 'A') {
> if (_text <= table[i].addr)
> printf("\tPTR\t_text + %#llx\n",
> table[i].addr - _text);
> else
> printf("\tPTR\t_text - %#llx\n",
> _text - table[i].addr);
> } else {
> printf("\tPTR\t%#llx\n", table[i].addr);
> }
> }
>
> __per_cpu_start is not an absolute symbol anyway.
>
> You need to fix this properly.
> Rusty.

Hm, yeah, it seems we need another class of variable. The per_cpu
stuff is technically relative, but it's not relocated, since it's not
relative to the text location. We'll see how to do this more sanely.

Thanks!

-Kees

--
Kees Cook
Chrome OS Security