On Friday, February 28, 2003, at 12:50 AM, Jeroen C. van Gelderen wrote:

You are going trough a lot of trouble. What is your threat model?

Nothing special, just taking the typical step of zeroing out memory. I just wanted to find a way to do it without using the va_list technique.



On Thursday, Feb 27, 2003, at 23:18 US/Eastern, Patrick Chkoreff wrote:
void
clear_bytes(char magic, char p[], int n)
{
    int i;

p[0] &= magic;

    for (i = 0; i < n-1; i++) {
        p[i+1] &= p[i];

    for (i = 0; i < n; i++)
        if (p[i] != magic)
            exit(magic);
}

Well... a theorem prover could infer that exit() isn't called if magic is zero. If magic isn't used after clear_bytes is called on it then the whole function call can be translated to:


void
clear_bytes(char magic, char p[], int n)
{
    int i;

if(0==magic) return;

[...]

}

This is a valid optimization.


That is a very astute observation. The [...] you mention would handle the weird case of checking that all the bytes of the array happen to equal the nonzero magic byte. For example, if you passed in magic == 37, and all the bytes happened to be 37, then the exit call would not be reached.

So the full exact optimized code that did not actually affect the memory bytes would be:

void
clear_bytes(char magic, char p[], int n)
{
    int i;

    if  (magic != 0)
        for (i = 0; i < n; i++)
            if (p[i] != magic)
                exit(magic);
}


So yeah, a theorem prover could possibly figure this out. After all, you and I did. :-)




Alternatively the two loops could be fused and and the calculation could happen in registers without ever hitting main memory. This is exactly valid when the contents of p[] are not accessed again after clear_bytes().

Good point. That's even more likely than the theorem prover issue above. I could write the fused code but I'm too lazy right now.



In order to guarantee that this works, you must pass in 0 as the
value of the 'magic' parameter, and you also must establish that 0
value using a method that is completely undecidable even to the most
intelligent compiler optimizer theoretically possible.

Why not use the value of a convenient system call, such as time(3)?

Because I need a way of generating a 0 in a way a compiler cannot predict. If I said this:


int i = funky_system_call();

Then I need a way to map i into 0 under the compiler's radar. Well these techniques certainly will NOT work:

    char magic = i - i;
    char magic = i ^ i;

... etc.

In all cases the compiler will know that magic == 0, and it can hack and optimize everything away.

But as you said, that point is moot if the compiler fuses the loops.


It is impossible for a compiler to optimize away any of this code,
because you can always find a way from OUTSIDE the program to make
magic take on a nonzero value and thus reach the abort condition.

Unlikely maybe, not impossible.

True. Probably much more likely even that the va_list trick.



..... and I see your second message has arrived ....




subscribe: send blank email to [EMAIL PROTECTED]
unsubscribe: send blank email to [EMAIL PROTECTED]
digest: send an email to [EMAIL PROTECTED]
with "set [EMAIL PROTECTED] digest=on" in the message body



Reply via email to