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