Live data from Hacker News

Neverflow: C macros that guard against buffer overflows

github.com

41–50 of 150 posts

Re: Neverflow: C macros that guard against buffer overflows

#41

Why use C and keep reinventing things that C++ provides?

the obvious answer is that one does not want some things that C++ entails, three examples: - name mangling - larger gap between source code and ISA - impedance mismatch when working with C APIs that being said, some do not want more macros either

> name mangling

Can be turned off on demand for relevant symbols.

> larger gap between source code and ISA

There's already a huge gap between C code and machine code (see: Undefined Behavior). C hasn't been a "portable assembler" for a very long time.

> impedance mismatch when working with C APIs

C++ has no problem working with C APIs.

Re: Neverflow: C macros that guard against buffer overflows

#42

Why use C and keep reinventing things that C++ provides?

But this isn't something the C++ language provides, which is hilarious.

C++ keeps C's crap array type as its native array type. You need to reach into the C++ standard library to get this awkward library type, std::array and then finally you get an array type that remembers how big it is and has some basic features like swap.

Re: Neverflow: C macros that guard against buffer overflows

#43
post #25

Even without array bounds checking, a bit of discipline and smart conventions will go a long way of reducing errors: 1. Define a macro function for retrieving the length of an array: #define LEN(arr) (sizeof (arr) / sizeof (arr)[0]) 2. Don't introduce macro constants for array lengths; hard code the length in the declaration and use LEN to retrieve it. Example: int a[100]; ... for (i = 0; i 3. Define a macro function…

Your allocation macro can lead to heap underflows if the multiplication wraps around. Which can definitely be exploitable.

You should either add overflow checking to the macro or even better just use the damn libc api and call calloc. Or if you really insist on avoiding zeroing overhead, there's reallocarray(NULL, ...) if you use a reasonably modern libc.

Re: Neverflow: C macros that guard against buffer overflows

#44
post #8

The problem with C and buffer overflows isn't that you can't guard against them, or that there is no existing, reusable code to do so — it's that none of this functionality is standardized. Adding another one to the existing 41383 ways of doing this is in fact the exact opposite of what's needed. Ideally C needs one way of doing this, and that would be described in the standard. But that's not how C "rolls", and we'l…

There is value in actually understanding what someone is doing in regards to protecting against buffer overflows, instead of relying on well established patterns.

Re: Neverflow: C macros that guard against buffer overflows

#45
post #40

Earlier quoted context omitted.

People using C will not change to your language-du-jour, please stop.

> People using C will not change to your language-du-jour, please stop. Two years ago, your argument would have implied that Rust would never be allowed into the Linux kernel, and yet here we are.

I wonder if Linus it taking the time to teach himself Rust.

Re: Neverflow: C macros that guard against buffer overflows

#46

Runtime bounds check tied to fprintf and abort via macros. Allocation by calloc.

The calloc part is one of the most common blind spots I see among C programmers. I try to avoid the malloc(n * sizeof (...)) pattern as much as possible. Sure there are lots of cases where it can never overflow, and you might save a bit of overhead from the zeroing and overflow checking, but most of that overhead might also be imaginary depending on allocator internals, and even kernel internals. It's the sort of thi…

> But now every caller in the future has to be aware of this possibility.

Can you clarify: what possibility should you be aware off with malloc that you don't need to be aware of with calloc?

Re: Neverflow: C macros that guard against buffer overflows

#47

Why use C and keep reinventing things that C++ provides?

If one is ready to switch languages, then the clear winner is rust over C++, and I say that as someone who avoided diving into Rust for years because it seemed completely overhyped and with too much cryptic syntax. C still wins by far when writing libraries that will be used by lots of other people. Doesn't matter what language they are using, they will be able to add in a library written in C very easily. However, C…

Rust is by far not mature enough for serious development. Recent shenanigans with crablang are a strong sign of it going down the route of Java, i.e a corporate developed language with offshoots, which will end up with Rust being in the same crappy state.

Re: Neverflow: C macros that guard against buffer overflows

#48
post #6

Earlier quoted context omitted.

Huh I misinterpreted the error messages in the example, I thought those were compiler output. This is quite cool then. EDIT: although, it seems like this looses much of its power once you start passing these buffers around to functions that do not use these macros.

> this looses much of its power once you start passing these buffers around to functions that do not use these macros. Alas it's even worse: once you pass buffers around to functions, you can't use these macros!

0.0.2 update is live, and solves this issue. Check for updated README.

Re: Neverflow: C macros that guard against buffer overflows

#49

Earlier quoted context omitted.

The calloc part is one of the most common blind spots I see among C programmers. I try to avoid the malloc(n * sizeof (...)) pattern as much as possible. Sure there are lots of cases where it can never overflow, and you might save a bit of overhead from the zeroing and overflow checking, but most of that overhead might also be imaginary depending on allocator internals, and even kernel internals. It's the sort of thi…

> But now every caller in the future has to be aware of this possibility. Can you clarify: what possibility should you be aware off with malloc that you don't need to be aware of with calloc?

Multiplying array length by sizeof(element type) can overflow.

Of course, you can write your own malloc_array() that uses __builtin_mul_overflow() and doesn't come with calloc's drawback (the cost of zeroing the allocated memory).

Re: Neverflow: C macros that guard against buffer overflows

#50
post #8

The problem with C and buffer overflows isn't that you can't guard against them, or that there is no existing, reusable code to do so — it's that none of this functionality is standardized. Adding another one to the existing 41383 ways of doing this is in fact the exact opposite of what's needed. Ideally C needs one way of doing this, and that would be described in the standard. But that's not how C "rolls", and we'l…

C never has just one way to do something. myArr[5] == 5[myArr] == (insert pointer arithmetic that I won't write here without a compiler check). I think that part of C's beauty is that it gives you freedom. Freedom to shoot yourself in the foot, freedom to write hyper efficient code, and freedom to choose another tool.

I agree that this will never be implemented as a standard, but I think that's a good thing. Higher level languages push against their boundaries non stop. Java has libraries and frameworks that fundamentally change the syntax and functionality of the language. C knows what it is. If you want something that it can't do it promises that you can either build it yourself or switch to a different tool.

All of this to say, C has a single suggested way of doing this: using a different language. That's part of why we built them

Post reply on HN