Unsecure optimization?
Unsecure optimization?
Posted Jan 22, 2016 14:51 UTC (Fri) by nybble41 (subscriber, #55106)In reply to: Unsecure optimization? by madscientist
Parent article: OpenSSH and the dangers of unused code
What you actually have to do is implement your own volatile_memset() function which takes a "volatile void*" and is guaranteed to overwrite the target memory area. Or (somewhat less portably) you can trick the compiler into thinking that the memory is actually used:
memset(&x, 0, sizeof x);
__asm__ ("" :: "m" (x));
No code is generated for the empty __asm__ block, but the compiler must make sure the data is available at that point just the same. The nice thing about implementing it this way is that the compiler can still optimize the memset() call, for example by replacing it with inline store instructions, but the effect will be preserved. Of course, the __asm__ block is not standard C and your mileage with other compilers will vary.
Posted Jan 22, 2016 15:25 UTC (Fri)
by PaXTeam (guest, #24616)
[Link] (5 responses)
Posted Jan 22, 2016 15:54 UTC (Fri)
by nybble41 (subscriber, #55106)
[Link] (4 responses)
The constraint I used, `"m" (x)`, specifies that the content of `x` is read, not just the address, so no `"memory"` clause is necessary.The GCC documentation actually suggests the "m" constraint as an alternative to "memory" when you need to access memory but wish to avoid the overhead of a full memory barrier (See https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Clob..., just before section 6.44.3.3.)
Posted Jan 22, 2016 16:24 UTC (Fri)
by PaXTeam (guest, #24616)
[Link] (3 responses)
error: memory input 0 is not directly addressable
Posted Jan 22, 2016 17:45 UTC (Fri)
by nybble41 (subscriber, #55106)
[Link] (2 responses)
What kind of expression were you trying to use? I don't have a copy of GCC 4.5 handy (it is eight years old, after all), but that form is documented in the manual for GCC 4.5.4 (https://gcc.gnu.org/onlinedocs/gcc-4.5.4/gcc/Extended-Asm...), with the same notes about being an alternative to the "memory" constraint. GCC 4.9 accepts it at least for variables of integer, array, struct, and union types. The expression does need to be an lvalue, of course.
Posted Jan 22, 2016 19:44 UTC (Fri)
by PaXTeam (guest, #24616)
[Link] (1 responses)
$ gcc-4.5.4 -O2 -x c -c - -o /dev/null <<EOF
void foo(int x) {
<stdin>: In function 'foo':
PS: gcc 4.5 is from 2010.
Posted Jan 22, 2016 20:57 UTC (Fri)
by nybble41 (subscriber, #55106)
[Link]
It looks like those versions have a bug in the implementation of the "m" constraint for array types. It works if you wrap the array in a struct:
__asm__ ("" :: "m" (*(struct { __typeof(buf) x; } *)&buf));
A bit awkward, but it does work in at least GCC 4.4, 4.9, and 5.3 as well as Clang 3.6, and the extra syntax could be hidden with a macro.
> PS: gcc 4.5 is from 2010.
So it is. And 4.5.4 is from 2012. So why does the copyright statement in the documentation for 4.5.4 (https://gcc.gnu.org/onlinedocs/gcc-4.5.4/gcc/) indicate that it was last updated in 2008?
Unsecure optimization?
Unsecure optimization?
Unsecure optimization?
Unsecure optimization?
Unsecure optimization?
#include <string.h>
char buf[10];
int i;
for (i=0; i<sizeof(buf); ++i)
buf[i]=x++;
memset(buf,0,sizeof(buf));
// asm("" : : "r"(buf));
asm("" : : "m"(buf));
// asm("" : : : "memory");
}
EOF
<stdin>:10:18: error: memory input 0 is not directly addressable
Unsecure optimization?