Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date: Wed, 9 Sep 2015 18:20:34 +0200
From: magnum <john.magnum@...hmail.com>
To: john-dev@...ts.openwall.com
Subject: Re: Large stack alignment

On 2015-09-09 14:55, JimF wrote:
> On 9/9/2015 5:03 AM, magnum wrote:
>> On 2015-09-08 21:45, magnum wrote:
>>
>>> /*
>>> * I had to place this in a separate function to avoid having the
>>> unaligned
>>> * branch optimized away (even using -O0), since gcc is totally
>>> convinced it
>>> * simply can't be unaligned!
>>> */
>>> void out(char *pt)
>>> {
>>>     if ((size_t)pt & 31)
>>>         printf("%s unaligned!\n", pt);
>>>     else
>>>         puts(pt);
>>> }
>>
>> Come to think of it, this is troubling: It suggests that the macro
>> form of mem_align() might also be optimized away, doesn't it?!
>>
>> Also, I'm puzzled anything is optimized away at -O0. But it was -
>> there wasn't even any "%s unaligned!\n" string in the assembly output.
>>
> I believe this is going to be 2 different cases, but I honestly can not
> say for 100% sure.  In the macro case, we have an lparam expression
> which sets an undefined variable. It must be run.

Yes, it looks like we are safe. gcc-4.8 reliably optimizes the test away 
using the attached test program, but not the macro.

magnum

/*
 * Tested with:
 * gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)
 *
 * Without the mem_align() macro, the "if ((size_t)pt & 0xff)" is optimized
 * away by the compiler (even using -O0) and unaligned pointers are seen
 * but not printed as such.
 *
 * The scope of this test program was to see if even the mem_align() macro
 * may be optimized away, but that does not seem to be the case.
 */

#include <stdio.h>
#include <string.h>
#ifdef _OPENMP
#include <omp.h>
#endif

#define mem_align(a,b) (void*)(((char*)(a))+(((b)-1)-(((size_t)((char*)(a))-1)&((b)-1))))

int main(int argc, char **argv)
{
	int i;

#ifdef _OPENMP
#pragma omp parallel for
#endif
	for (i = 0; i < argc; i++) {
#if 1
		__attribute__ ((aligned(256))) char pt[1024];
#else
		__attribute__ ((aligned(256))) char _pt[1024];
		char *pt = mem_align(_pt, 256);
#endif

		sprintf(pt, "%p ", pt);
		strcat(pt, argv[i]);
        if ((size_t)pt & 0xff)
                printf("%s unaligned!\n", pt);
        else
                puts(pt);
	}
	return 0;
}

Powered by blists - more mailing lists

Your e-mail address:

Powered by Openwall GNU/*/Linux - Powered by OpenVZ