Live data from Hacker News

Getting Past C

blog.ntpsec.org

171–180 of 504 posts

Re: Getting Past C

#171
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 you will properly test said array implementation correctly.

The number of mitigations added to C compilers and OSes dealing mostly with C and C++ code. ASLR, W^X, /GS, -fstack-protector-all, AddressSanitizer, ... - note the lack of similar tools, or demand for them, for, say, JavaScript - despite it enjoying a similar ubiquity.

I ask this in bad faith: I encourage you to share a single nontrivial codebase which actually creates the abstraction you've described and religiously adheres to using it throughout. As to why this is in bad faith: I'm definining "nontrivial" here to mean using 3rd party APIs - which will operate on C style arrays, not your project specific safe wrappers - and thus by definition won't be "religiously" sticking to said abstractions when using said APIs. By these definitions, the codebase I'm asking for doesn't exist - by definition. Even relaxing the "third party" rule, I haven't actually worked on a nontrivial C or C++ codebase without buffer overflow problems.

Now, e.g. Rust will have the same problems when interacting with C APIs - and nontrivial programs will end up doing so eventually. However, by virtue of the language itself embracing safe-by-default, you're less likely to run into the same problems when consuming Rust APIs.

You can also use third party static analysis tools to ensure you're using a "safe C subset" (such as MIRSA C), but "nobody" does that.

Re: Getting Past C

#172
post #167

Earlier quoted context omitted.

If Rust is not memory safe in safe code, then you've found a bug. Please report it to https://www.rust-lang.org/security.html

Let me clarify: in Rust it is trivial to use memory unsafely. It is not, so far as I have found, trivial to hide that fact because it is required to use "unsafe" syntax decoration" to do so.

The issue here is that that definition of "safe" language basically excludes all practical languages, including languages like Python, because FFI is possible.

In general when talking about safety in a language it's about the level of explicitness required to trigger unsafety.

I like the distinction made in the nomicon (https://doc.rust-lang.org/stable/nomicon/meet-safe-and-unsaf...) -- Rust comprises of two distinct languages. You have everyday Rust, which is completely memory safe, and "unsafe Rust", which looks similar to everyday Rust but is not safe. `unsafe {}` blocks are your FFI between the two. Looking at unsafe blocks as FFI is IMO a very useful mental model especially for understanding the changes to invariants involved.

Re: Getting Past C

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

Because:

1. Buffer overflows aren't considered the most insidious issue in C nowadays. That award would probably go to use after free, which is not so easy to fix.

2. In C, it is easier and faster to do the wrong thing. Compare "char buf[256]; strcpy(buf, foo); ..." to "array_t buf = array_create(strlen(foo) + 1); strcpy(buf.ptr, foo); ... array_destroy(buf);"

3. Buffer overflows do not in fact come up routinely in Rust the way they do in C.

Re: Getting Past C

#174
post #87

Earlier quoted context omitted.

You can't implement certain things in C if you are on the quest for maximum efficiency. Thankfully, one rarely is, because efficiency isn't binary. It's about trade-offs.

I could say exactly the same for Rust, that it's not enough even using unsafe keyword and I need to go into assembly. Someone could even say that assembly is not enough and we need FPGA and then ASIC etc. But it's not the point here. The point is that for ex. you can't get safety from out of bounds access without bound checking, doesn't matter which language you use. And bound checking for certain hot paths is not ac…

> And bound checking for certain hot paths is not acceptable.

I think the history of exploits proves that it's always acceptable for server code. The only possibly justifiable place to omit bounds checking is isolated, high performance numerical code, as used in scientific simulations. But this code isn't exposed to the public, so its vulnerabilities aren't important.

Re: Getting Past C

#175
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 just don't understand why are buffer overflows such a huge problem in C when the same thing is going to come up when trying to work with memory in Rust. False. Buffer overflows in C can overwrite the program's memory, so it can be hijacked and supplanted with the attacker's code. This cannot happen in Rust (unless unsafe code has the vulnerability), or any memory safe language. Sure you can implement a safe array…

How much does that still happen with DEP and such? Don't OSes not let you write to executable regions or execute from stack/heap by default now?

Re: Getting Past C

#176
post #170

Earlier quoted context omitted.

If Rust is not memory safe in safe code, then you've found a bug. Please report it to https://www.rust-lang.org/security.html

If you're relying on any random third-party Rust crates you haven't audited yourself, don't you lose the safety guarantee? A given crate might turn out to have implemented operations on some data-structure using unsafe blocks, and then to have failed to mark its own API functions as unsafe in turn (like the Rust stdlib does, but without the "extensive manual auditing" that the stdlib gets). AFAIK, cargo doesn't have…

That's why I said "safe code," I mean, not using any unsafe.

The issue you're talking about is related, but different.

Re: Getting Past C

#177
post #49

Earlier quoted context omitted.

Because the fact that you have to write that secure abstraction means the majority of people won't do it, and even if they do, the vast amounts of code that you'll interface with in C that doesn't expect it and will happily index out of bounds if you call it incorrectly means you'll always be fighting an uphill battle. I imagine many people do what you did and write abstractions, and then the more they end up dealing…

Because the fact that you have to write that secure abstraction means the majority of people won't do it What's your point? My only argument has been that it's very easy and achievable to avoid buffer overruns in C. The fact that you assert most people won't do it is completely orthogonal to that. And how did you implement this? Are you stitching together chunks of memory, or are you reallocating and copying? If you…

This is the age old debate:

X is possible!

X is not probable!

Its not a winnable debate. You are both different kinds of people. The prior an idealist, the latter a pragmatist. Both philosophies are good, both are correct. Before both of you continue your debate, you should both recognize this difference.

Re: Getting Past C

#178
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 just don't understand why are buffer overflows such a huge problem in C when the same thing is going to come up when trying to work with memory in Rust. False. Buffer overflows in C can overwrite the program's memory, so it can be hijacked and supplanted with the attacker's code. This cannot happen in Rust (unless unsafe code has the vulnerability), or any memory safe language. Sure you can implement a safe array…

[deleted]

Re: Getting Past C

#179
post #36

Earlier quoted context omitted.

> i just don't understand why are buffer overflows such a huge problem in C when the same thing is going to come up when trying to work with memory in Rust. False. Buffer overflows in C can overwrite the program's memory, so it can be hijacked and supplanted with the attacker's code. This cannot happen in Rust (unless unsafe code has the vulnerability), or any memory safe language. Sure you can implement a safe array…

I think he means to work with raw memory so using unsafe keyword and in this case he is right. And you can't implement certain things in Rust if you are on the quest for maximum efficiency without using unsafe.

> And you can't implement certain things in Rust if you are on the quest for maximum efficiency without using unsafe.

Trading efficiency for safety for unaudited code should be difficult. C does not make this difficult. Rust makes this difficult.

Auditing should be supported for this kind of code. C does not support auditing in any meaningful way. Auditing much easier in Rust since it explicitly identifies code that may be unsafe.

In conclusion, I disagree emphatically that C and Rust are somehow equivalent even when you are dropping down to unsafe code.

Re: Getting Past C

#180

Rather than looking for a new language, why not ban programs from writing to executable memory?

This wouldn't protect from bugs where you can maliciously trick a program from reading from other places in memory so it will leak passwords, keys etc. Think heartbleed
Post reply on HN