Alignment trap in stackgap under arm eabi.

[email protected] Mon, 25 Jan 2016 23:16:52 +0100 (CET)
Newsgroups gmane.linux.lib.dietlibc
Message-ID <1164825114.1901027.1453760212730.JavaMail.ngmail@webmail11.arcor-online.net>
Hi,

I've noticed an Alignment trap starting a little program on an arm eabi
system (armv5 soft float).
I could track it down to the following code in 'lib/stackgap.c':

...
int stackgap(int argc,char* argv[],char* envp[]) {
  long* auxvec=(long*)envp;
#if defined(WANT_STACKGAP) || defined(WANT_SSP) || defined(WANT_TLS)
  char* rand;
  char* tlsdata;
  while (*auxvec) ++auxvec; ++auxvec;	/* skip envp to get to auxvec */
  _auxvec=auxvec;
#ifdef WANT_STACKGAP
  unsigned short s;
#endif
#if defined(WANT_STACKGAP) || defined(WANT_SSP)
  volatile char* gap;
  rand=find_in_auxvec(auxvec,25);
  if (!rand) {
    char myrand[10];
    int fd=open("/dev/urandom",O_RDONLY);
    read(fd,myrand,10);
    close(fd);
    rand=myrand;
  }
#endif
#ifdef WANT_STACKGAP
  s=*(unsigned short*)(rand+8);
#endif
#ifdef WANT_SSP
  __guard=*(unsigned long*)rand;
#endif
...

Here the call to 'find_in_auxvec(auxvec,25)' searches the entry '25' in
the 'auxvec' table and returns its value that should be the address of
a 16 random bytes block of memory prepared by the kernel.
The problem is that the returned address is blindly used on the line:

 __guard=*(unsigned long*)rand;

In case the address is not 4-bytes aligned the 32 bits memory access
will trigger the alignment trap.
My fix was to align the 'rand' pointer right after the assignment:

 rand=find_in_auxvec(auxvec,25);
 rand=(char*)((unsigned)(rand + 3)&(~0x3));

Another possible problem is the array 'char myrand[10]': it could also be
not 4-byte aligned; I think it would be better to declare it as
unsigned long myrand[4].

giorgio


Giorgio, [email protected]