Skip to contentSkip to conversation

unaligned access using bash on glibc 2.5

parisc-linux John David Anglin 2 participants 6 messages May 1, 2007 – May 2, 2007 5 messages not in the archive

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw
Quoted 5 lines
Quoted 4 lines · Carlos O'Donell
Quoted 3 lines · Aurelien Jarno

We have just switched to a glibc 2.5 using LT + TLS in Debian. This causes unaligned memory access when using bash:

Quoted 8 lines
Quoted 3 lines
Quoted 1 line

bash(19279): unaligned access to 0x000e1bb2 at ip=0x407cb76b

Why doesn't this ip match the runtime disassembly you have below?

Well I don't really now. The address return by the kernel is not aligned, so that's strange. Note that this does not correspond to the same execution. I run it once to get the entry in the kernel log, and once with unaligned=signal to get the SIGBUS in gdb.

The two least significant bits in ip contain the priviledge level of the executing code. They have to be masked off to get the address of a faulting instruction.

Dave

Signature · 6 lines
J. David Anglin                                  [email protected]
National Research Council of Canada              (613) 990-0752 (FAX: 952-6602)
_______________________________________________
parisc-linux mailing list
[email protected]
http://lists.parisc-linux.org/mailman/listinfo/parisc-linux

A message that is not in the archive (sent off-list or not yet received): [email protected]

A message that is not in the archive (sent off-list or not yet received): [email protected]

#4 lore raw
Quoted 25 lines · Carlos O'Donell
Quoted 3 lines · John David Anglin

The two least significant bits in ip contain the priviledge level of the executing code. They have to be masked off to get the address of a faulting instruction.

You'll be pleasantly suprised to know we tracked this down to a missing save/restore of the PIC register on a library call.

  0x40bcb744 <closedir+44>:       copy r20,r22
  0x40bcb748 <closedir+48>:       b,l 0x40bb4aa0,rp
  0x40bcb74c <closedir+52>:       copy r3,r26

See this lonely b,l without a PIC register save/restore? That's the problem. It's a jump to a stub, which calls free, but free tailcalls into __internal_free, and the PIC register isn't restored by free or by closedir.

FWIW I see this aswell when compiling glibc with gcc mainline:

10: 6b d3 3f c1 stw r19,-20(sp)
../sysdeps/unix/closedir.c:52
14: e8 40 00 00 b,l 1c <__closedir+0x1c>,rp
14: R_PARISC_PCREL17F free
18: 0c a0 10 85 ldw 0(r5),r5
../sysdeps/unix/closedir.c:54

Quoted 7 lines
  1c:   08 05 02 5a     copy r5,r26
  20:   08 13 02 44     copy r19,r4

Why isn't there a save/restore of the PIC register around the call to free? Clearly r19 is being used, notice the save/restore starting on "20:".

In case you want to have a closer look, please find attached the preprocessed file. I will try to reduce the testcase later today.

The problem does not appear at -O0, and start to appears with -O1.

Cheers,
Aurelien

Signature · 4 lines
  .''`.  Aurelien Jarno	            | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   [email protected]         | [email protected]
   `-    people.debian.org/~aurel32 | www.aurel32.net

_______________________________________________
parisc-linux mailing list
[email protected]
http://lists.parisc-linux.org/mailman/listinfo/parisc-linux

#5 lore raw
In reply to a message not in the archive
Quoted 25 lines · Carlos O'Donell
Quoted 3 lines · John David Anglin

The two least significant bits in ip contain the priviledge level of the executing code. They have to be masked off to get the address of a faulting instruction.

You'll be pleasantly suprised to know we tracked this down to a missing save/restore of the PIC register on a library call.

  0x40bcb744 <closedir+44>:       copy r20,r22
  0x40bcb748 <closedir+48>:       b,l 0x40bb4aa0,rp
  0x40bcb74c <closedir+52>:       copy r3,r26

See this lonely b,l without a PIC register save/restore? That's the problem. It's a jump to a stub, which calls free, but free tailcalls into __internal_free, and the PIC register isn't restored by free or by closedir.

FWIW I see this aswell when compiling glibc with gcc mainline:

10: 6b d3 3f c1 stw r19,-20(sp)
../sysdeps/unix/closedir.c:52
14: e8 40 00 00 b,l 1c <__closedir+0x1c>,rp
14: R_PARISC_PCREL17F free
18: 0c a0 10 85 ldw 0(r5),r5
../sysdeps/unix/closedir.c:54

Quoted 6 lines
  1c:   08 05 02 5a     copy r5,r26
  20:   08 13 02 44     copy r19,r4

Why isn't there a save/restore of the PIC register around the call to free? Clearly r19 is being used, notice the save/restore starting on "20:".

Note that the asm code starting on line 20 comes from an asm directive in the preprocessed source.

Signature · 8 lines
  .''`.  Aurelien Jarno	            | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   [email protected]         | [email protected]
   `-    people.debian.org/~aurel32 | www.aurel32.net
_______________________________________________
parisc-linux mailing list
[email protected]
http://lists.parisc-linux.org/mailman/listinfo/parisc-linux

A message that is not in the archive (sent off-list or not yet received): [email protected]

#7 lore raw
Quoted 34 lines · Aurelien Jarno
Quoted 25 lines · Carlos O'Donell
Quoted 3 lines · John David Anglin

The two least significant bits in ip contain the priviledge level of the executing code. They have to be masked off to get the address of a faulting instruction.

You'll be pleasantly suprised to know we tracked this down to a missing save/restore of the PIC register on a library call.

  0x40bcb744 <closedir+44>:       copy r20,r22
  0x40bcb748 <closedir+48>:       b,l 0x40bb4aa0,rp
  0x40bcb74c <closedir+52>:       copy r3,r26

See this lonely b,l without a PIC register save/restore? That's the problem. It's a jump to a stub, which calls free, but free tailcalls into __internal_free, and the PIC register isn't restored by free or by closedir.

FWIW I see this aswell when compiling glibc with gcc mainline:

10: 6b d3 3f c1 stw r19,-20(sp)
../sysdeps/unix/closedir.c:52
14: e8 40 00 00 b,l 1c <__closedir+0x1c>,rp
14: R_PARISC_PCREL17F free
18: 0c a0 10 85 ldw 0(r5),r5
../sysdeps/unix/closedir.c:54

Quoted 7 lines
  1c:   08 05 02 5a     copy r5,r26
  20:   08 13 02 44     copy r19,r4

Why isn't there a save/restore of the PIC register around the call to free? Clearly r19 is being used, notice the save/restore starting on "20:".

Quoted 4 lines

In case you want to have a closer look, please find attached the preprocessed file. I will try to reduce the testcase later today.

The problem does not appear at -O0, and start to appears with -O1.

Some more progress. The following change in the preprocessed source code "fixes" the problem:

- extern __thread int __libc_errno __attribute__ ((tls_model ("initial-exec")));
+ extern __thread int __libc_errno;

Signature · 8 lines
  .''`.  Aurelien Jarno	            | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   [email protected]         | [email protected]
   `-    people.debian.org/~aurel32 | www.aurel32.net
_______________________________________________
parisc-linux mailing list
[email protected]
http://lists.parisc-linux.org/mailman/listinfo/parisc-linux
#8 lore raw
In reply to a message not in the archive
Quoted 29 lines · Aurelien Jarno
Quoted 28 lines · Carlos O'Donell
Quoted 3 lines · John David Anglin

The two least significant bits in ip contain the priviledge level of the executing code. They have to be masked off to get the address of a faulting instruction.

You'll be pleasantly suprised to know we tracked this down to a missing save/restore of the PIC register on a library call.

  0x40bcb744 <closedir+44>:       copy r20,r22
  0x40bcb748 <closedir+48>:       b,l 0x40bb4aa0,rp
  0x40bcb74c <closedir+52>:       copy r3,r26

See this lonely b,l without a PIC register save/restore? That's the problem. It's a jump to a stub, which calls free, but free tailcalls into __internal_free, and the PIC register isn't restored by free or by closedir.

FWIW I see this aswell when compiling glibc with gcc mainline:

10: 6b d3 3f c1 stw r19,-20(sp)
../sysdeps/unix/closedir.c:52
14: e8 40 00 00 b,l 1c <__closedir+0x1c>,rp
14: R_PARISC_PCREL17F free
18: 0c a0 10 85 ldw 0(r5),r5
../sysdeps/unix/closedir.c:54

  1c:   08 05 02 5a     copy r5,r26
  20:   08 13 02 44     copy r19,r4
Quoted 8 lines
Quoted 4 lines

Why isn't there a save/restore of the PIC register around the call to free? Clearly r19 is being used, notice the save/restore starting on "20:".

In case you want to have a closer look, please find attached the preprocessed file. I will try to reduce the testcase later today.

Please find the reduced testcase below. When the value is assigned to __libc_errno, the value of r19 has been overrided by the call to free().

extern __thread int __libc_errno __attribute__ ((tls_model ("initial-exec"))); extern void free (void *__ptr) __attribute__ ((__nothrow__));

int
__closedir (int *p)
{
int i;

  i = *p;
  free (p);

register unsigned long __res asm("r28"); register unsigned long __r26 __asm__("r26") = (unsigned long)(p); asm volatile("copy %%r19, %%r4\n" "ble 0x100(%%sr2, %%r0)\n" "ldi %1, %%r20\n" "copy %%r4, %%r19\n" : "=r" (__res) : "i" (0 + 6) , "r" (__r26)

                            : "memory", "%r1", "%r2", "%r4", "%r20", "%r29", "%r31" , "%r21", "%r22", "%r23", "%r24", "%r25" );
  __libc_errno = 25;

return __res;
}

Signature · 8 lines
  .''`.  Aurelien Jarno	            | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   [email protected]         | [email protected]
   `-    people.debian.org/~aurel32 | www.aurel32.net
_______________________________________________
parisc-linux mailing list
[email protected]
http://lists.parisc-linux.org/mailman/listinfo/parisc-linux

A message that is not in the archive (sent off-list or not yet received): [email protected]

#10 lore raw
Quoted 3 lines · Aurelien Jarno

Please find the reduced testcase below. When the value is assigned to __libc_errno, the value of r19 has been overrided by the call to free().

And a smaller one:

extern __thread int __libc_errno __attribute__ ((tls_model ("initial-exec"))); extern void free (void *__ptr) __attribute__ ((__nothrow__));

void test(int *p)
{
free (p);
__libc_errno = 25;
}

00000000 <test>:
test():

   0:   6b c2 3f d9     stw rp,-14(sp)
   4:   6f c4 00 80     stw,ma r4,40(sp)
   8:   e8 40 00 00     b,l 10 <test+0x10>,rp
                        8: R_PARISC_PCREL17F    free
   c:   6b d3 3f c1     stw r19,-20(sp)
  10:   2a 60 00 00     addil L%0,r19,r1
                        10: R_PARISC_LTOFF_TP21L        __libc_errno
  14:   48 3c 00 00     ldw 0(r1),ret0
                        14: R_PARISC_LTOFF_TP14R        __libc_errno
  18:   34 15 00 32     ldi 19,r21
  1c:   03 60 08 b4     mfctl tr3,r20
  20:   0b 94 0a 14     add,l r20,ret0,r20
  24:   0e 95 12 80     stw r21,0(r20)
  28:   4b c2 3f 59     ldw -54(sp),rp
  2c:   e8 40 c0 00     bv r0(rp)
  30:   4f c4 3f 81     ldw,mb -40(sp),r4
Signature · 8 lines
  .''`.  Aurelien Jarno	            | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   [email protected]         | [email protected]
   `-    people.debian.org/~aurel32 | www.aurel32.net
_______________________________________________
parisc-linux mailing list
[email protected]
http://lists.parisc-linux.org/mailman/listinfo/parisc-linux