This is an archive of the discontinued LLVM Phabricator instance.

stop short-circuiting the SSP code for sspstrong
ClosedPublic

Authored by strcat on Jul 22 2016, 6:12 PM.

Details

Summary

The StackProtector::RequiresStackProtector method is supposed to add layout information for alloca instructions that need to be protected by the canary. This is supposed to protect normal local variables (including function pointers, etc.) from linear overflows.

However, this method contains an early return for sspstrong and sspreq in the code for handling calls to alloca and variable length arrays (not regular arrays, with the IR Clang generates):

// SSP-Strong: Enable protectors for any call to alloca, regardless
// of size.
if (Strong)
  return true;

The method has special handling for sspstrong/sspreq following this early return, but it's not being used. It ends up returning early, resulting in the function being protected with a canary but without marking the arrays it's trying to protect (not only the alloca/VLA triggering the issue) so they get treated as normal local variables.

Sample code:

#include <string.h>
#include <alloca.h>

int foo(char *bar) {
    char *buf = alloca(20);
    strcpy(buf, bar);
    return strlen(buf);
}

Compiler output at -O0:

--- old_x86.s	2016-07-22 08:44:37.534862251 -0400
+++ new_x86.s	2016-07-22 08:44:18.778486803 -0400
@@ -17,12 +17,12 @@
 	subq	$48, %rsp
 	movq	%fs:40, %rax
 	movq	%rax, -8(%rbp)
-	movq	%rdi, -24(%rbp)
-	leaq	-44(%rbp), %rdi
-	movq	%rdi, -16(%rbp)
-	movq	-24(%rbp), %rsi
+	movq	%rdi, -48(%rbp)
+	leaq	-28(%rbp), %rdi
+	movq	%rdi, -40(%rbp)
+	movq	-48(%rbp), %rsi
 	callq	strcpy
-	movq	-16(%rbp), %rdi
+	movq	-40(%rbp), %rdi
 	callq	strlen
 	movq	%fs:40, %rcx
 	cmpq	-8(%rbp), %rcx

Diff Detail

Event Timeline

strcat updated this revision to Diff 65202.Jul 22 2016, 6:12 PM
strcat retitled this revision from to stop short-circuiting the SSP code for sspstrong.
strcat updated this object.
strcat added reviewers: hfinkel, probinson, void.
strcat added a subscriber: llvm-commits.
strcat updated this revision to Diff 67422.Aug 9 2016, 3:18 PM

For my sanity: we're trying to remove this if (Strong) check, yeah?

If so, I think your patch is backwards. :)

For my sanity: we're trying to remove this if (Strong) check, yeah?

If so, I think your patch is backwards. :)

Yeah, screwed it up when updating it. Whoops.

strcat updated this revision to Diff 71961.Sep 20 2016, 11:36 AM
strcat edited edge metadata.

Cool; just making sure. :)

Generally, we try to include regression tests for things like this, so can you please add a testcase for this to test/CodeGen/X86/stack-protector.ll, as well? Once that's added, I think this looks good.

I'm not really sure how to write a sane test for this, since it only changes the stack offsets. I can't see a way to test it beyond hard-wiring the exact expected assembly, which seems too aggressive since it could change for valid reasons. Maybe I'm missing an easy way to test this.

george.burgess.iv edited edge metadata.

Ahh, I see. Yeah, the tests for this seem to try really hard to not explicitly state offsets. Looks like we may be able to write a unittest instead, but that feels like a lot just to cover this case, so LGTM.

Thanks for the patch!

This revision is now accepted and ready to land.Sep 20 2016, 12:59 PM
This revision was automatically updated to reflect the committed changes.