Live data from Hacker News

How to zero a buffer

daemonology.net

41–50 of 216 posts

Re: How to zero a buffer

#42
post #8

Earlier quoted context omitted.

If you're not worried about writing in a language which is widely supported, just use memset_s and tell people to find a C11 compiler.

Or have your build system add memset_s.c to their compile on systems that don't have it.

[deleted]

Re: How to zero a buffer

#43
post #40

Earlier quoted context omitted.

No, but the major differences I find are: 1. The FreeBSD base system is developed intact, so there are far fewer kernel/library versioning issues. 2. FreeBSD, possibly because of its academic heritage, tends to take a more careful "let's study this problem and make sure we come up with the right solution" approach. This means that FreeBSD development is often slower, but once a feature is added it is more likely to a…

Thanks. That fits my general idea of FreeBSD. I've mostly wondered about how they technically compare though. Facebook seems to think Linux is generally faster for example[1]. I'd love to follow this more closely but I haven't found a LWN equivalent for the BSDs. [1] https://lwn.net/Articles/608954/

I think the best answer there is "it depends". Facebook has an open job posting which states that "Our goal over the next few years is for the Linux kernel network stack to rival or exceed that of FreeBSD" [1], so clearly there's at least one place in Facebook where Linux does not provide the best performance...

[1] https://www.facebook.com/careers/department?req=a0IA000000Cz...

Re: How to zero a buffer

#44
When I allocate the key on the heap, the memset is carried (heavily optimized and inlined). When I allocate key on the stack, it disappears. Using gcc -03:

    #include 

    void doSecure(void)  
    {  
        /*char key[32];*/  
        char *key = (char*) malloc(sizeof(char)*32);

        memset(key,sizeof(char),32);  
    }

    int main(void)  
    {  
        doSecure();

        return 0;  
    }

    -- key on stack

    main:  
    .LFB13:  
        .cfi_startproc  
        xorl	%eax, %eax  
        ret  
        .cfi_endproc

    -- key on heap

    main:  
    .LFB13:  
        .cfi_startproc  
        subq	$8, %rsp  
        .cfi_def_cfa_offset 16  
        movl	$32, %edi  
        call	malloc  
        movabsq	$72340172838076673, %rdx  
        movq	%rdx, (%rax)  
        movq	%rdx, 8(%rax)  
        movq	%rdx, 16(%rax)  
        movq	%rdx, 24(%rax)  
        xorl	%eax, %eax  
        addq	$8, %rsp  
        .cfi_def_cfa_offset 8  
        ret  
        .cfi_endproc

Re: How to zero a buffer

#45
post #23

Nice teaser at the end there. Does it have something to do with the fact that the OS may have paged the memory containing the sensitive data to disk?

I figured the article would be about how you have to write random data to the buffer to truly "zero" it, otherwise the ghost of the data can still be read using some trick.

Re: How to zero a buffer

#47
While this completely subverts our intention, it is perfectly legal: The observable behaviour of the program is unchanged by the optimization.

This begs the question of what is "observable behaviour" - execution time, which is definitely "observable" and the basis of timing-based attacks, can certainly change depending on what the optimiser decides to do.

I think this and similar cases of "fighting the optimiser" should really be solved with per-function (or even per-statement) optimisation settings; both GCC and MSVC support #pragma's to do this, although it's nonstandard.

Re: How to zero a buffer

#49

While this completely subverts our intention, it is perfectly legal: The observable behaviour of the program is unchanged by the optimization. This begs the question of what is "observable behaviour" - execution time, which is definitely "observable" and the basis of timing-based attacks, can certainly change depending on what the optimiser decides to do. I think this and similar cases of "fighting the optimiser" sho…

The term "observable behaviour" is defined in the standard: Essentially, I/O to files and interactive devices, plus accesses to volatile objects.

Re: How to zero a buffer

#50

While this completely subverts our intention, it is perfectly legal: The observable behaviour of the program is unchanged by the optimization. This begs the question of what is "observable behaviour" - execution time, which is definitely "observable" and the basis of timing-based attacks, can certainly change depending on what the optimiser decides to do. I think this and similar cases of "fighting the optimiser" sho…

The trouble with that is that you then have to define what a "legal optimization" is in order for a "don't optimize me" pragma to have any meaning. That can be notoriously difficult and annoying. For example, a common trick in languages with no irreducible control flow is to generate SSA from the AST to avoid having to compute dominance, which in some compiler backends can make things like simple dead code elimination hard to not perform.
Post reply on HN