Live data from Hacker News

Getting Past C

blog.ntpsec.org

241–250 of 504 posts

Re: Getting Past C

#241
post #128

Earlier quoted context omitted.

The lack of generics means your array implementation is either going to either: - be implemented with macros and token pasting, and result in a ton of mental overhead because you'll have a pile of types like array_foo for an array of `foo`s, and array_bar for an array of `bar`s, along with a pile of corresponding `foo * array_foo_get(array_foo, size_t)` and `bar * array_bar_get(array_bar, size_t)` functions. - or, ha…

You're missing main glaring issue with parametric polymorphism, bloat.

While "unnecessary"/extra generated code is a trade-off one has to consider when choosing to use the specialize/monomorphise-everything implementation of parametric polymorphism (it isn't the only one), it isn't a problem in this case: the types themselves are a compile-time abstraction and don't exist at runtime, and the functions are all tiny (a branch, a memory access and a function call/abort).

Additionally, all the functions should be inlined anyway because the function call overhead will likely be as much or more than the actual code, and, more importantly, inlining enables other optimisations (removing the branch, vectorising the memory access, etc.). Once inlined, the code will be the same as the manual/macro-based approach of writing `if` statements around each array[index] access.

Re: Getting Past C

#242

Earlier quoted context omitted.

C is the new "goto". Y'all please, please note that dreta said "... an array implementation that prevents that from ever happening..."

Final word on the subject - what we have is people who are trying to make Open Software Reputation Points by finding a problem and fixing it, rather than waiting to find a real problem and fixing that. When the figure of "ten minutes" was used - that's really what it should be as a mean or median figure, with some long-tail outliers for knotty cases. While I am (somewhat) sympathetic, I don't miss what it is - it's m…

I see where you're going with this. I normally would agree. In this case, we have a large, C program that evolved over time for a complicated feature set. That they trimmed that much fat out might already be saying something about how much risk might be in that code. It's also been around a long time in important infrastructure plus will continue to be. Converting it to something that's safer in most ways, esp dynamic memory & types, to reduce number of vulnerabilities in near and long-term makes sense.

So long as one can convert it in a straight-forward way that preserves the current meaning of the program's statements. If not, the port might introduce new problems.

Edit: Btw, send me an email (see profile). Got something you might be interested in. One or two things.

Re: Getting Past C

#243

Earlier quoted context omitted.

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

Neither C nor C++ knows, at the language level, the size of an array, unless that size is fixed. The subscript checking variants of C and C++ have to use "fat pointers" which carry along size information. The overhead for this is large and nobody uses that. Fat pointers used to be a feature you could turn on in gcc, but it's somewhat abandoned now.

> Neither C nor C++ knows, at the language level, the size of an array, unless that size is fixed.

Neither does Rust.

> The subscript checking variants of C and C++ have to use "fat pointers" which carry along size information.

So do Rust's Slices.

> The overhead for this is large and nobody uses that.

People use std::vector all the time for this purpose in C++. It has about the performance you'd expect, with very little overhead except where you want it in bounds-checking.

I don't think there's actually a performance difference here. Rust's default is safer because it requires dropping to unsafe code to do something dangerous, but the same optimizations are available in both.

Re: Getting Past C

#244
post #76

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…

How do you suppose runtime bounds checks are done in Rust? They certainly also incur a performance penalty in not-trivial cases. Also, "safe by grep audit" means "safe according to a human." The argument of course is that it lowers the surface area of what a human must be trusted to verify. I'm still not convinced by that argument, because human error is a thing. And for actual systems programming, "very rare" may no…

"Actual systems programming" mostly does not involve unsafe code.

For example, most OS code is _not_ interrupt hooks or malloc but the rest of the OS. Most of Postgres is not reading data quickly, but higher-level abstractions.

Large-scale systems programming will always be mostly higher-level abstractions, because that's the only way to write large programs. Name any "systems programming" OSS project, choose a random C file, and you'll see that most code does not require pointer arithmetic except because that's how you do things in C.

You don't bit-twiddle for 200k lines of code, so being able to limit dangerous stuff like that to the 5k lines that actually need it makes work an order of magnitude easier.

Re: Getting Past C

#245
> One such cleanup: we’ve made a strong start on banishing unions and type punning from the code. These are not going to translate into any language with the correctness properties we want.

Really? This sounds like idiomatic rust to me (heavy with enums).

Re: Getting Past C

#246

After reading this post the idea of a C-to-C translator that injects bound checking, etc. comes to mind. Such translator could be used by OS distributions to provide safety in the least intrusive way and possibly completely automatically for many C codebases they have in their repositories. Translating into Go or Rust, on the other hand, cannot scale beyond some individual projects, that decide to undertake such effo…

CompSci keeps making them, even open-sourcing some, but little uptake or improvements from the FOSS crowd. Here's two of the top ones:

http://sva.cs.illinois.edu/

https://github.com/jtcriswell/safecode-llvm37

https://www.cs.rutgers.edu/~santosh.nagarakatte/softbound/

Re: Getting Past C

#247
post #161
post #140

Earlier quoted context omitted.

No, you just allocate enough space to store an extra int at the start for the length, and return a typed pointer to the actual data. Then you need an accessor that checks bounds, if you want safe access. Both of these problems are solved by simple macros.

So you want the array to have type foo * ? Ignoring that this doesn't let the compiler help the programmer with arrays (you still have to manually remember to use the accessor, not []), you also have to manually remember which pointers are pointers and which are arrays, and this representation doesn't work for pointing into subsections of an array (a similar problem to C-style strings), nor does it work well for putt…

agree -- inability to do variable-sized arrays on the stack is the root of the problem.

Re: Getting Past C

#248

Earlier quoted context omitted.

A more relevant point that would disqualify Haskell is the fact that its runtime (or rather, the GHC's runtime) is nowhere near predictable enough for the realtime guarantees that time synchronisation software would require. A Haskell DSL that outputs some safer low-level code would be a more likely choice (for example http://hackage.haskell.org/package/atom ), but Rust is both more popular and has more commercial su…

When opting for a DSL that compiles to low-level the "Haskell" part is less important. I've heard the idea of DSLs over and over again, but who actually does that? I know of course of sed, awk, regex, etc but what part of NTPsec is narrow enough in scope and large enough in volume to justify creating a DSL? (just asking -- I'm not familiar with NTPsec).

Companies that like consistently getting results. Example:

http://ivorylang.org/ivory-introduction.html

Re: Getting Past C

#249
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…

> 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? The CVE database. Just because you 'can' write such an array implementation doesn't mean you will, doesn't mean your third party libs will, doesn't mean any of your legacy code uses it, and certainly doesn't mean…

Hate to tell you, but JavaScript implementations virtually all rely on C or C++ as well.

And it's not limited to the VM itself: check out npm "native extensions" like `json`. Not to mention glibc, or the OSes themselves.

By your definition, nothing is safe. And you're right ;)

Re: Getting Past C

#250

Earlier quoted context omitted.

When opting for a DSL that compiles to low-level the "Haskell" part is less important. I've heard the idea of DSLs over and over again, but who actually does that? I know of course of sed, awk, regex, etc but what part of NTPsec is narrow enough in scope and large enough in volume to justify creating a DSL? (just asking -- I'm not familiar with NTPsec).

Companies that like consistently getting results. Example: http://ivorylang.org/ivory-introduction.html

[deleted]
Post reply on HN