public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/45867] New: Sparc64: bogus %g4 reference in libgcc __udivti3()
@ 2010-10-02 12:38 blauwirbel at gmail dot com
2010-10-02 13:40 ` [Bug c/45867] reference to %g4 in code generated for sparc64-elf ebotcazou at gcc dot gnu.org
0 siblings, 1 reply; 2+ messages in thread
From: blauwirbel at gmail dot com @ 2010-10-02 12:38 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45867
Summary: Sparc64: bogus %g4 reference in libgcc __udivti3()
Product: gcc
Version: 4.5.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: blauwirbel@gmail.com
Sparc64 GCC (at least 4.2.4 and 4.5.0 cross compilers) generates incorrect code
for the minimal test case below.
I found the bug because of obscure crashes in OpenBIOS inside libgcc, in
__udivti3(). The problem can be isolated from __udivti3() to
count_leading_zeros() macro and further to this minimal test case.
As can be seen in the output, there is a strange extra instruction, 'add
%g1, %g4, %g1'. %g4 is not initialized anywhere in the function but any
previous value will be used. Thus the __clz_tab table access can lead to
crashes. This may in theory even have some security implications if %g4 value
could be feasibly controlled by an attacker.
$ cat libgcc2.c
extern const char __clz_tab[256];
char test(void)
{
return __clz_tab[0];
}
$ sparc64-elf-gcc-4.2.4 -save-temps -S libgcc2.c -O2
$ cat libgcc2.s
.file "libgcc2.c"
.section ".text"
.align 4
.global test
.type test, #function
.proc 04
test:
sethi %hi(__clz_tab), %g1
add %g1, %g4, %g1
ldsb [%g1+%lo(__clz_tab)], %o0
jmp %o7+8
sra %o0, 0, %o0
.size test, .-test
.ident "GCC: (GNU) 4.2.4"
$ cat libgcc2.i
# 1 "libgcc2.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "libgcc2.c"
extern const char __clz_tab[256];
char test(void)
{
return __clz_tab[0];
}
$ sparc64-elf-gcc-4.2.4 -v
Using built-in specs.
Target: sparc64-elf
Configured with: ../configure --target=sparc64-elf
--enable-targets=sparc-elf,sparc64-elf --disable-nls --disable-threads
--enable-languages=c --disable-shared --enable-multilib : (reconfigured)
../configure --target=sparc64-elf --enable-targets=sparc-elf,sparc64-elf
--disable-nls --disable-threads --enable-languages=c --disable-shared
--enable-multilib --disable-ssp : (reconfigured) ../configure
--target=sparc64-elf --enable-targets=sparc-elf,sparc64-elf --disable-nls
--disable-threads --enable-languages=c --disable-shared --enable-multilib
--disable-libssp
Thread model: single
gcc version 4.2.4
Same case with 4.5.0:
$ sparc64-elf-gcc-4.5.0 -save-temps -S libgcc2.c -O2
$ cat libgcc2.s
.file "libgcc2.c"
.section ".text"
.align 4
.global test
.type test, #function
.proc 02
test:
sethi %hi(__clz_tab), %g1
add %g1, %g4, %g1
jmp %o7+8
ldsb [%g1+%lo(__clz_tab)], %o0
.size test, .-test
.ident "GCC: (GNU) 4.5.0"
$ cat libgcc2.i
# 1 "libgcc2.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "libgcc2.c"
extern const char __clz_tab[256];
char test(void)
{
return __clz_tab[0];
}
$ sparc64-elf-gcc-4.5.0 -v
Using built-in specs.
COLLECT_GCC=sparc64-elf-gcc-4.5.0
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/sparc64-elf/4.5.0/lto-wrapper
Target: sparc64-elf
Configured with: ../configure --target=sparc64-elf --enable-targets=sparc64-elf
--disable-nls --disable-threads --enable-languages=c --disable-shared
--disable-multilib --disable-libssp
Thread model: single
gcc version 4.5.0 (GCC)
The above are cross compilers, with host:
$ uname -srvmo
Linux 2.6.36-rc5+ #3 SMP Sat Sep 25 17:06:06 UTC 2010 x86_64 GNU/Linux
It doesn't happen with native 3.3.5 from OpenBSD/Sparc64:
$ gcc -save-temps -S libgcc2.c -O2
$ cat libgcc2.s
.file "libgcc2.c"
.section ".text"
.align 4
.align 32
.globl test
.type test, @function
.proc 04
test:
!#PROLOGUE# 0
!#PROLOGUE# 1
sethi %h44(__clz_tab), %g1
or %g1, %m44(__clz_tab), %g1
sllx %g1, 12, %g1
retl
ldsb [%g1+%l44(__clz_tab)], %o0
.size test, .-test
$ cat libgcc2.i
# 1 "libgcc2.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "libgcc2.c"
extern const char __clz_tab[256];
char test(void)
{
return __clz_tab[0];
}
$ gcc -v
Reading specs from /usr/lib/gcc-lib/sparc64-unknown-openbsd4.6/3.3.5/specs
Configured with:
Thread model: single
gcc version 3.3.5 (propolice)
$ uname -mrsv
OpenBSD 4.6 GENERIC#43 sparc64
^ permalink raw reply [flat|nested] 2+ messages in thread
* [Bug c/45867] reference to %g4 in code generated for sparc64-elf
2010-10-02 12:38 [Bug c/45867] New: Sparc64: bogus %g4 reference in libgcc __udivti3() blauwirbel at gmail dot com
@ 2010-10-02 13:40 ` ebotcazou at gcc dot gnu.org
0 siblings, 0 replies; 2+ messages in thread
From: ebotcazou at gcc dot gnu.org @ 2010-10-02 13:40 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45867
Eric Botcazou <ebotcazou at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Target| |sparc64-elf
Status|UNCONFIRMED |RESOLVED
CC| |ebotcazou at gcc dot
| |gnu.org
Resolution| |WORKSFORME
Summary|Sparc64: bogus %g4 |reference to %g4 in code
|reference in libgcc |generated for sparc64-elf
|__udivti3() |
--- Comment #1 from Eric Botcazou <ebotcazou at gcc dot gnu.org> 2010-10-02 13:40:39 UTC ---
> As can be seen in the output, there is a strange extra instruction, 'add
> %g1, %g4, %g1'. %g4 is not initialized anywhere in the function but any
> previous value will be used. Thus the __clz_tab table access can lead to
> crashes. This may in theory even have some security implications if %g4 value
> could be feasibly controlled by an attacker.
The attacker is supposed to be you here. The sparc64-elf compiler defaults to
the CM_EMBMEDANY memory model:
TARGET_CM_EMBMEDANY: 64-bit address space.
The text and data segments have a maximum size of 2GB
(31-bit span) and may be located anywhere in memory.
The global register %g4 contains the start address of
the data segment. Programs are statically linked and
PIC is not supported.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2010-10-02 13:40 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-10-02 12:38 [Bug c/45867] New: Sparc64: bogus %g4 reference in libgcc __udivti3() blauwirbel at gmail dot com
2010-10-02 13:40 ` [Bug c/45867] reference to %g4 in code generated for sparc64-elf ebotcazou at gcc dot gnu.org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).