On 20/11/2019 14:46, Martin Liška wrote:
> On 11/20/19 3:37 PM, Matthew Malcomson wrote:
>> Hi Martin,
>>
>> Thanks for the review,
> 
> You're welcome.
> 
>> I'll get working on your comments now, but since I really enjoyed
>> finding this bug in ./configure when I hit it I thought I'd answer this
>> right away.
> 
> Heh :)
> 
>>
>>
>> On 20/11/2019 14:02, Martin Liška wrote:
>>> On 11/7/19 7:37 PM, Matthew Malcomson wrote:
>>>>
>>>> diff --git a/config/bootstrap-hwasan.mk b/config/bootstrap-hwasan.mk
>>>> index
>>>> 4f60bed3fd6e98b47a3a38aea6eba2a7c320da25..91989f4bb1db6ccff564383777757b896645e541
>>>>  
>>>>
>>>> 100644
>>>> --- a/config/bootstrap-hwasan.mk
>>>> +++ b/config/bootstrap-hwasan.mk
>>>> @@ -1,7 +1,11 @@
>>>>    # This option enables -fsanitize=hwaddress for stage2 and stage3.
>>>> +# We need to disable random frame tags for bootstrap since the
>>>> autoconf check
>>>> +# for which direction the stack is growing has UB that a random frame
>>>> tag
>>>> +# breaks.  Running with a random frame tag gives approx. 50% chance of
>>>> +# bootstrap comparison diff in libiberty/alloca.c.
>>>
>>> Here I would like to see what's exactly the problem. I would expect ASAN
>>> will
>>> have exactly the same problem? Can you please isolate it and file a bug.
>>> I bet
>>> a configure script should not expose an undefined behavior.
>>>
>>
>> The configure problem is this snippet below:
>>
>>
>> find_stack_direction ()
>> {
>>     static char *addr = 0;
>>     auto char dummy;
>>     if (addr == 0)
>>       {
>>         addr = &dummy;
>>         return find_stack_direction ();
>>       }
>>     else
>>       return (&dummy > addr) ? 1 : -1;
>> }
>> main ()
>> {
>>     exit (find_stack_direction() < 0);
>> }
>>
>>
>> configure uses this to determine the direction that the stack grows.
>>
>> `find_stack_direction` compares the address of two different objects and
>> uses that to make a decision.
>>
>> With HWASAN random frame tags the answer to the comparison is mostly
>> determined by what random tag was assigned to the object in each frame,
>> rather than the memory layout of the stack -- which means this configure
>> test program can end up getting different answers on different runs.
>>
>> This is not a problem for ASAN since ASAN does not store tags in the
>> pointers of variables.
>>
>>
>> You're right -- I should file a bug on that for configure.
>>
>> For reference the UB clause in the standard is 6.5.8 #5 (relational
>> operators) where there's a sentence at the end saying "In all other
>> cases, the behaviour is undefined".  Essentially, this program is
>> comparing the address of two different objects on the stack, and that's
>> not allowed.
> 
> Well, to be honest, this is quite cute violation of the standard. I would
> have written exactly the same code for the stack direction direction. I 
> understand
> that a top byte will (a.k.a. tag) make the randomness.
> 
> Do you have an idea how can we rewrite the check?
> Thanks,
> Martin
> 

I don't have much of a plan.

The most promising lead I have is that libiberty/alloca.c has a similar 
functionality but with macros to account for a special case.

Instead of just using '&' it uses a macro `ADDRESS_FUNCTION`.
I can use that macro to ensure the libiberty/alloca.c function could 
handle tags, but I'm not sure that architecture specific conditions will 
neatly fit into autoconf.

Reply via email to