Live data from Hacker News

Getting Past C

blog.ntpsec.org

51–60 of 504 posts

Re: Getting Past C

#51

Honestly, why not do it once and for all in a strongly typed pure functional language, validate it, and then tweak the GC parameters to get the performance? Use the safest and most powerful language that you can, if you can.

That would be a theorem prover like Isabelle or Coq. It is orders of magnitude more work.

Re: Getting Past C

#52
post #31

Earlier quoted context omitted.

Libc does not use your safe array. You cannot pass your safe array to read and other syscalls.

As others have noted, one can also write a four line saferead() function.

And once you have written a five line safewrite() function, a hundred-line saferecvfrom() function, a 1500-line safeioctl() function, and all of that, and you have a third-party static analysis tool to prove that you're never calling the unsafe read() or ioctl() functions except from the wrappers, what was the advantage of staying in C in the first place?

Re: Getting Past C

#53

Earlier quoted context omitted.

> Is this abstraction zero-cost? What's the overhead? It will cost a single correctly predicted branch, which is effectively free on modern architectures. Any "safe" language will have to make this conditional branch too (Rust's File::read method will check the size of the slice).

Nope. Iterators in Rust can be used to safely avoid bounds checking in ways that would be impossible to enforce in C.

We were talking about reading into a bounds checked array. Rust does not user iterators for this.

Re: Getting Past C

#54
post #27

Can anybody make a strong case to me as to why are buffer overflows considered an issue in C when it takes like 10 minutes to write and test an array implementation that prevents that from ever happening? I do agree that C has issues (though in my opinion neighter Rust nor Go address almost any of them) i just don't understand why are buffer overflows such a huge problem in C when the same thing is going to come up w…

When writing modern C in a disciplined way, it is not as bad as the Rustophiles will make it out to be, but still a problem.

Scenarios where I frequently end up fixing other people's memory errors:

1. No Error Handling: not checking an error condition on a function that allocates, then using the uninitialized pointer anyway

2. Sloppy Error Handling: jumping to abort from an error without freeing what has already been allocated

3. Faith in \0: still using the old string functions

I'm on the fence about the whole thing, so others may be able to field something more compelling.

Re: Getting Past C

#55

Earlier quoted context omitted.

Because your 'safe' implementation will certainly have a performance cost, and won't be the default. This is why, despite C++ providing std::array, you'll still find buffer overflows in C++ code. C++'s std::array provides the safe 'at' function but you're opting into a performance penalty and it's not the more familiar [] syntax. Rust arrays/ vectors are safe-by-default. To use the unchecked, unsafe version requires…

In addition, the Rust compiler can also remove the built-in indexing checks if it can prove the code is safe. So, say, iterator loops over an array won't have any index checking.

C/ C++ compilers are also capable of doing this, though rust's iterator syntax tends to make it a pretty natural optimization.

Re: Getting Past C

#56
post #42

Earlier quoted context omitted.

No. It then follows that reading things safely is therefore a completely insurmountable problem in C. There is no possible way for me thin wrapper around read that works on bounds checked arrays, and not use "read" cavalierly in my code without thinking. Right?

The track record of two decades of CERT advisories for buffer overflows suggests that doesn't work in practice.

Just because people fail to do something doesn't mean it's not both possible and easy.

Re: Getting Past C

#57

Honestly, why not do it once and for all in a strongly typed pure functional language, validate it, and then tweak the GC parameters to get the performance? Use the safest and most powerful language that you can, if you can.

From my understanding by reading the OP, it's not really performance that's the problem, it's just that there are some (fortunately very small) time-critical sections in the NTP code that cannot tolerate a GC pause. If the language runtime supports disabling GC in critical sections (like Go does), then it's doable. If not, the language is likely automatically disqualified.

Re: Getting Past C

#58
post #52

Earlier quoted context omitted.

As others have noted, one can also write a four line saferead() function.

And once you have written a five line safewrite() function, a hundred-line saferecvfrom() function, a 1500-line safeioctl() function, and all of that, and you have a third-party static analysis tool to prove that you're never calling the unsafe read() or ioctl() functions except from the wrappers, what was the advantage of staying in C in the first place?

I see where you are going, but I don't get how you get from 4 to 5 to 100 to 1500?

Re: Getting Past C

#59
post #26

Earlier quoted context omitted.

Is this abstraction zero-cost? What's the overhead? Can you give me a similar set of primitives to manipulate memory in a temporally safe manner as well? What is the cost of that abstraction? How does it compare to a runtime's GC?

I never made the argument that you shouldn't use a safe GC'd language. I merely made the argument (now flagged for whatever reason) that buffer overflows are an easily solvable issue in C, and if you are having issues with them you really need up your game and learn to create abstractions. As for the cost of the abstraction of bound checked arrays of arbitrary length, I can't imagine it being any slower than rust. I…

Obviously, if you have to check an index length you're going to be doing a branch. However, because the index checks are intrinsic to the Rust compiler, it can remove them when it proves the code is safe. So, for instance, an iteration loop over an array won't have any index checks in the generated machine code.

Re: Getting Past C

#60
post #27

Can anybody make a strong case to me as to why are buffer overflows considered an issue in C when it takes like 10 minutes to write and test an array implementation that prevents that from ever happening? I do agree that C has issues (though in my opinion neighter Rust nor Go address almost any of them) i just don't understand why are buffer overflows such a huge problem in C when the same thing is going to come up w…

I think it breaks down when that array has to interact with system libraries or the C stdlib in any way. A lot of C string functions have weird gotchas related to terminators and sizes, and any IO you're doing will involve raw buffers being passed into or out of a system IO function that doesn't understand custom array types.
Post reply on HN