Live data from Hacker News

Address Sanitizer Internals

blog.gistre.epita.fr

21–30 of 30 posts

Re: Address Sanitizer Internals

#21

Earlier quoted context omitted.

ASAN is only a probabilistic sanitizer, but adding deterministic checks, like out-of-bounds checks or integer overflow checks, is the same in C/C++ compiled with the appropriate options as what is done in any programming language where these checks are done by default. In that case there are no false positives or negatives.

Pray tell: what magic C/C++ compiler options do I add to enable deterministic OOB checks that never produce any false positives or negatives?

If you had bothered to search the gcc or clang manual, you would have found e.g. "-fsanitize=bounds-strict".

There is nothing magic about this option. With it C or C++ is compiled exactly like any other programming language where array bounds checking is implicit.

That means that whenever a new value is computed for a pointer or index that will be used to access an array, the value is compared with the bounds associated with that array.

Such a comparison cannot give false positives or negatives, any address is either within bounds or outside bounds.

This is something that is completely independent of the programming language. Out-of-bounds checking has nothing to do with the syntax or with any explicit features of a programming language. It is just a compilation technique, which can be applied or it can be omitted at the compilation of any programming language, regardless whether the language is C or C++ or Ada or Rust.

The only difference is that in better programming language specifications it is required that any conforming compiler must by default insert bounds checks, while in the C and C++ standards the behavior of the compiler is unspecified and the existing compilers have a bad default behavior, so it is the responsibility of the programmer to use the right compiler options.

Re: Address Sanitizer Internals

#22

Earlier quoted context omitted.

Pray tell: what magic C/C++ compiler options do I add to enable deterministic OOB checks that never produce any false positives or negatives?

If you had bothered to search the gcc or clang manual, you would have found e.g. "-fsanitize=bounds-strict". There is nothing magic about this option. With it C or C++ is compiled exactly like any other programming language where array bounds checking is implicit. That means that whenever a new value is computed for a pointer or index that will be used to access an array, the value is compared with the bounds associa…

Weird, the following program compiles and runs without complaint under `-fsanitize=bounds-strict,address,undefined` and outputs the rather fetching output `��1�I��^H��H���PTE1�1�H�Ǧ@`:

    #include 

    int main(int argc, char **argv) {
        printf("%s\n", argv[-8]);
    }
(https://godbolt.org/z/ef8KMGnce - feel free to try other values to dump out environment variables and other stack crap)

Oh, but maybe that's because the compiler has no model of how `argv` works. Fine, try this?

    #include 
    
    int foo(volatile char *x) {
        return x[0] + x[-64];
    }
    
    int main(int argc, char **argv) {
        char x[1] = {42};
        printf("%d\n", foo(x));
    }
(https://godbolt.org/z/TMzehfGah)

Happily loads way out of bounds, no problem whatsoever - no runtime error, no sanitizer complaints, nothing.

Sanitizers are great, but they are not perfect. They are not a replacement for real array bounds checking; other languages that do real bounds checking do so by carrying the bounds with the object which is categorically impossible under the standard C ABIs.

Re: Address Sanitizer Internals

#23

Earlier quoted context omitted.

If you had bothered to search the gcc or clang manual, you would have found e.g. "-fsanitize=bounds-strict". There is nothing magic about this option. With it C or C++ is compiled exactly like any other programming language where array bounds checking is implicit. That means that whenever a new value is computed for a pointer or index that will be used to access an array, the value is compared with the bounds associa…

Weird, the following program compiles and runs without complaint under `-fsanitize=bounds-strict,address,undefined` and outputs the rather fetching output `��1�I��^H��H���PTE1�1�H�Ǧ@`: #include int main(int argc, char **argv) { printf("%s\n", argv[-8]); } ( https://godbolt.org/z/ef8KMGnce - feel free to try other values to dump out environment variables and other stack crap) Oh, but maybe that's because the compil…

You did not use arrays, so there were no bounds to be checked.

The C language indeed allows the use of pointers having arbitrary values that cannot be checked in any way.

However it is trivial to avoid the use of such pointers and any decent programmer will never use such pointers, because they are never needed.

Unfortunately, it is difficult to forbid the use of such pointers, because there are too many legacy programs.

That however cannot be an excuse for any programmer who is writing a new program. If someone uses pointers in such a way, that cannot happen through an unwilling mistake, so it is their fault and they have no right to blame the programming language.

Re: Address Sanitizer Internals

#24
post #19

"For this article, you’ll need the following knowledge: Basic C understanding (Memory, Stack, Heap, Syscall)." Obviously, since C doesn't prescribe any kind of heap, stack or syscall behavior (or if they even exist), I assume the author meant something like "Basic understanding of how C is often implemented on certain operating systems and hardware".

Yes, because asan only makes sense in the context of specific (kinds of) implementations.

Re: Address Sanitizer Internals

#25
post #9

Earlier quoted context omitted.

I've never seen that particular claim either, but I did previously believe that asan would reliably detect an out-of-bounds write if and when it occurs. So I learned something new from the OP (that this type of false negative is possible).

Yeah, I'm just responding to the guy who is probably the most internet-famous C++ hater in the world. I guess he likes to make up stuff too. The article is good.

adrian_b's comments in this thread are the kind of thing I referred to (my point wasn't that ASan specifically is presented as a panacea but rather various sanitizers in general.)

Re: Address Sanitizer Internals

#26
post #9

Earlier quoted context omitted.

I've never seen that particular claim either, but I did previously believe that asan would reliably detect an out-of-bounds write if and when it occurs. So I learned something new from the OP (that this type of false negative is possible).

ASAN, i.e. "-fsanitize=address" is a completely different and unrelated sanitizer than checking out-of-bounds accesses, like "-fsanitize=bounds-strict". Checking out-of-bounds accesses must detect any out-of-bounds access done at run time. It is done by comparing the pointers or indices used for access with the array bounds. (At least for gcc: "Initializers of variables with static storage are not instrumented.") Out…

If you want bounds checked C, use Dlang's -betterC. Its no use trying to convert C to something it isn't.

Re: Address Sanitizer Internals

#27
post #25

Earlier quoted context omitted.

Yeah, I'm just responding to the guy who is probably the most internet-famous C++ hater in the world. I guess he likes to make up stuff too. The article is good.

adrian_b's comments in this thread are the kind of thing I referred to (my point wasn't that ASan specifically is presented as a panacea but rather various sanitizers in general.)

Adrian's comments are nuanced and truthful. He said gcc offers an out-of-bounds sanitizer and listed some limitations. He does not say it makes C++ memory safe.

Re: Address Sanitizer Internals

#28
post #25

Earlier quoted context omitted.

adrian_b's comments in this thread are the kind of thing I referred to (my point wasn't that ASan specifically is presented as a panacea but rather various sanitizers in general.)

Adrian's comments are nuanced and truthful. He said gcc offers an out-of-bounds sanitizer and listed some limitations. He does not say it makes C++ memory safe.

There’s nothing remotely nuanced nor truthful about this comment: https://news.ycombinator.com/item?id=40696242

He’s saying that with a compiler flag you can get the same kind of safety as in Ada or Rust. Later downthread he clarifies to say that you only get this safety if you stop using pointers, which he considers “trivial” to do.

This is the same guy who commented a few months back saying the following:

“All decent C compilers have compilation options so that at run-time any undefined actions, including integer overflow and out-of-bounds accesses, will be trapped.”

There is, put simply, no flag that will trap on “any undefined actions”, period. That’s not what sanitizers are capable of. That’s the kind of overhyped comment that isn’t helpful when trying to understand what sanitizers are actually useful for.

Re: Address Sanitizer Internals

#29

Earlier quoted context omitted.

Adrian's comments are nuanced and truthful. He said gcc offers an out-of-bounds sanitizer and listed some limitations. He does not say it makes C++ memory safe.

There’s nothing remotely nuanced nor truthful about this comment: https://news.ycombinator.com/item?id=40696242 He’s saying that with a compiler flag you can get the same kind of safety as in Ada or Rust. Later downthread he clarifies to say that you only get this safety if you stop using pointers , which he considers “trivial” to do. This is the same guy who commented a few months back saying the following: “All dec…

Thank you for your truthful and not unnecessarily nuanced comment!

Re: Address Sanitizer Internals

#30

Earlier quoted context omitted.

Weird, the following program compiles and runs without complaint under `-fsanitize=bounds-strict,address,undefined` and outputs the rather fetching output `��1�I��^H��H���PTE1�1�H�Ǧ@`: #include int main(int argc, char **argv) { printf("%s\n", argv[-8]); } ( https://godbolt.org/z/ef8KMGnce - feel free to try other values to dump out environment variables and other stack crap) Oh, but maybe that's because the compil…

You did not use arrays, so there were no bounds to be checked. The C language indeed allows the use of pointers having arbitrary values that cannot be checked in any way. However it is trivial to avoid the use of such pointers and any decent programmer will never use such pointers, because they are never needed. Unfortunately, it is difficult to forbid the use of such pointers, because there are too many legacy progr…

New programs are unfortunately bound to old APIs. There's not much you can do here to fix the problem.
Post reply on HN