User-space code aborts on some (but not all) misaligned accesses

Robin Murphy robin.murphy at arm.com
Wed May 24 10:36:23 PDT 2017


On 24/05/17 18:27, Ard Biesheuvel wrote:
> On 24 May 2017 at 09:56, Mason <slash.tmp at free.fr> wrote:
>> On 24/05/2017 17:45, Robin Murphy wrote:
>>
>>> On 24/05/17 16:26, Mason wrote:
>>>
>>>> Consider the following user-space code, split over two files
>>>> to defeat the optimizer.
>>>>
>>>> This test program maps a page of memory not managed by Linux,
>>>> and writes 4 words to misaligned addresses within that page.
>>>>
>>>> $ cat store.c
>>>> void store_at_addr_plus_0(void *addr, int val)
>>>> {
>>>>      __builtin_memcpy(addr + 0, &val, sizeof val);
>>>> }
>>>> void store_at_addr_plus_1(void *addr, int val)
>>>> {
>>>>      __builtin_memcpy(addr + 1, &val, sizeof val);
>>>> }
>>>>
>>>> $ cat testcase.c
>>>> #include <fcntl.h>
>>>> #include <sys/mman.h>
>>>> #include <stdio.h>
>>>> void store_at_addr_plus_0(void *addr, int val);
>>>> void store_at_addr_plus_1(void *addr, int val);
>>>> int main(void)
>>>> {
>>>>      int fd = open("/dev/mem", O_RDWR | O_SYNC);
>>>>      void *ptr = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0xc0000000);
>>>>      store_at_addr_plus_0(ptr + 0, fd); puts("X");   // store at ptr + 0 => OK
>>>>      store_at_addr_plus_0(ptr + 1, fd); puts("X");   // store at ptr + 1 => OK
>>>>      store_at_addr_plus_1(ptr + 3, fd); puts("X");   // store at ptr + 4 => OK
>>>>      store_at_addr_plus_1(ptr + 0, fd); puts("X");   // store at ptr + 1 => ABORT
>>>>      return 0;
>>>> }
>>>>
>>>> With optimizations turned off, the program works as expected.
>>>>
>>>> $ arm-linux-gnueabihf-gcc-6.3.1 -Wall -O0 testcase.c store.c -o misaligned_stores
>>>> $ ./misaligned_stores
>>>> X
>>>> X
>>>> X
>>>> X
>>>>
>>>> But if optimizations are enabled, the program aborts on the last store.
>>>>
>>>> $ arm-linux-gnueabihf-gcc-6.3.1 -Wall -O1 testcase.c store.c -o misaligned_stores
>>>> # ./misaligned_stores
>>>> X
>>>> X
>>>> X
>>>> Bus error
>>>> [ 8736.457254] Alignment trap: not handling instruction f8c01001 at [<000104aa>]
>>> ^^^
>>>
>>> Note where that message comes from: The alignment fault fixup code
>>> doesn't recognise this instruction encoding, so it doesn't get fixed up.
>>> It's that simple.
> 
> Well spotted. I missed that bit, but it makes perfect sense. Mason,
> care to propose a patch to the alignment fixup code that adds the
> missing encoding?

No need for that - anything that could be executing 32-bit Thumb
encodings also supports (and will be using) the v6 unaligned access
model by definition. I would assume that the "regular" loads/stores are
deliberately unhandled for that reason (i.e. it would never be correct
to fix up).

Robin.



More information about the linux-arm-kernel mailing list