18 ms·
Regex: badly needs fuzzing
- pcwalton 10y agoAnother counterexample to the idea that modern C++ written by experts is free of memory safety issues.
- deleted 10y ago[deleted]
- mememachine 10y agoIf the solution doesnt make it any easier to avoid memory issues (just forces you to avoid them,) its not an attractive solution
- gcp 10y agoGiven that we're talking about bugs, I don't think this is a valid argument. Being forced to avoid bugs is good, yes? Even if it's not necessarily less hard to make them in the first place (which is arguable, too!). I mean, I spend most of my time coding searching for bugs, not avoiding them.
- pcwalton 10y agoI disagree? It's better to not have memory safety problems than to have them!
- amalag 10y agoAvoiding bugs is a pretty effective way to not have bugs.
- mlmlmasd 10y agoAvoiding bugs is the default in software development in any language, no? If you have pointer DSL that can lead to various bugs, replacing it with a more complex pointer DSL is not a good way to avoid bugs. And I don't think C++ 'smart pointers' and other crap are very simple (relative to C pointers) or much less error-prone. That's just my opinion though.
- marvy 10y agoAvoiding bugs is what you try to do by default in any language, yes. But success is not guaranteed :) I agree that in general, if you have a pointer DSL that can lead to bugs, replacing to with a more complex one just makes things worse, assuming all else stays the same. But! Maybe the extra complexity buys you something. For instance, maybe the complexity allows the compiler to prove that certain classes of bugs are impossible. Now we have a tradeoff. Let's say we want to get a correct program as fast as possible. Then you can quickly write a buggy program in the simple DSL, but you will need to spend some time debugging it. Or you can spend a long time wrestling with the complicated one, but you don't need to debug pointer issues anymore (you still have to fix other bugs of course.) Then the question is: do you save more time in debugging than you pay in "fighting" a complex language. And the answer is always the same: maybe! Maybe you make less pointer bugs in C than most people, and maybe you're more allergic to smart pointers than most people, so for you it's pointless. Certainly pointer bugs are not very rare in the world though. Worse, they're not always noticed right away.
- civility 10y agoTurning off your computer is the only way to avoid bugs. All software has bugs.
- pcwalton 10y agoWe aren't talking about eliminating all bugs. We're talking about eliminating memory safety problems, which frequently result in RCE.
- civility 10y agoWhat you were doing is advocating Rust in a C++ thread, again. Safety first, and all that. Congratulations on getting voted to the top of this topic, but it's tiresome. Let's pretend C++ is a car. I get in my car, and I drive somewhere. Yes, there are hundreds of thousands of accidents per year, but really, most people get where they want to go, and we aren't all dead. I've had my share of fender benders, but no RCE has ever been exploited in 25 years of my C or C++ code. Let's pretend Rust is a car. Half the time I want to go somewhere, I can't even get out of the driveway before I stumble into a limitation of the language or the standard libraries. One time it's overly strict coherence rules that forbid me from doing something that shouldn't break coherence [1]. Some other time it's because the standard library doesn't have a trait for a commonly implemented method, so I can't write a generic function to call that method. Yet another time, I find out you really can't accomplish the task without writing unsafe code, so the compiler really wasn't going to protect me from myself anyways [2]. So yeah, Rust is saving me from car accidents because I don't even make it to the road much less my destination half the time. Do you drive wearing a 5 point harness and a helmet? Do you really think a true expert couldn't make a safe C++ regex library? -- [1] Honestly, I think you guys are screwed on that one. I suspect you're going to have to break backwards compatibility to really fix it, so I believe you'll leave it broken instead. [2] Outside of FFI calls, I have no idea what rules I'm supposed to respect in an unsafe block. I guess I just can't drive my Rust car to that neighborhood then. Very safe indeed.
- dbaupp 10y ago> no RCE has ever been exploited in 25 years of my C or C++ code I'm genuinely curious about you say this with any sort of surety. Do you have any sort of, say, crash reporting from users' computer, or some other way to know if a problem occurred in the wild? (Not that these will actually detect a successful RCE, only failed ones.) Additionally, not being (known to be) exploited doesn't mean that much without more context, e.g. have malicious people/machines/fuzzers actually tried to find exploits in your code?
- _delirium 10y agoNot that I necessarily think it'd avoid the problem even then, but I wouldn't call this modern C++ exactly. For one thing, it's (c) 2002, so written in C++98. And for another, it looks very uh, C-ish (not that uncommon in the C++98 era). In the bad sense of lots of error-prone pointer-based string manipulation, stuff like this: if(STR_COMP(s1, p) >= 0) { do{ ++p; }while(*p); ++p; if(STR_COMP(s1, p) <= 0) return set_->isnot ? next : ++next; }
- sidlls 10y agoWell, yes if the strawman "all modern C++ written by experts is free from memory safety issues" is what you're countering. I find that to be gratuitous and petty, and not a good representation of Rust, however.
- 10293101 10y agoThe position "modern C++ is safe and all C programmers are idiots" is repeated quite often here on HN. To be fair, it is always the same small group of people who do that.
- sidlls 10y agoNot sure what that has to do with anything. The parent is a very vocal Rust proponent and made a ridiculous comment which has been called out by myself and several others. It hasn't anything to do with any "small group of people" talking smack about C programmers. Although that's unfortunate, too.
- eridius 10y agoI don't think it's ridiculous. It seems like almost every discussion about Rust vs C++ here has a few people saying that you don't need Rust's guarantees about memory safety if you're writing modern C++. And that oft-repeated comment is what pcwalton is referencing.
- blub 10y agopcwalton is not framing the problem in a particularly useful way. This is a question of risk management and his argument is basically that one should always reduce the risk of memory management errors to zero. Others say that they can tolerate some risk, as long as it's in acceptable margins, since it's expensive to totally eliminate it. I don't think that lecturing everyone "No, you really want to have 0 risk, you fools" is a successful programming language advocacy strategy.
- 10y ago
- andrepd 10y agoIt's not modern, it's C++98.
- stinos 10y agoDo you have more of these examples?
- anon1385 10y agohttp://www.cvedetails.com/vulnerability-list/vendor_id-452/product_id-3264/opmemc-1/Mozilla-Firefox.html http://www.cvedetails.com/vulnerability-list/vendor_id-452/p... http://www.cvedetails.com/vulnerability-list/vendor_id-452/product_id-3264/opec-1/Mozilla-Firefox.html http://www.cvedetails.com/vulnerability-list/vendor_id-452/p...
- ambrop7 10y agoIf it has memory safety issues then it's not written by experts :)
- dbaupp 10y agoSo there's no such thing as a C++ expert? That statement is dangerously close to a No True Scotsman: IME even people who seem to fit any reasonable definition of expert (committee members, compiler developers) still make memory-safety mistakes.
- civility 10y ago> That statement is dangerously close to a No True Scotsman It also had a smiley in it. I'm pretty sure you missed the joke and don't realize you're preaching to the choir.
- dbaupp 10y agoThis is Poe's law territory, e.g. a lot of your own comments sound very similar to the parent, and there are other emoticons more commonly used to indicate sarcasm/joke.
- civility 10y ago> This is Poe's law territory Heh, I think that's possibly the only virtue to sarcasm: it confuses the pedants. I use friendly smileys or the word "heh" when I'm trying to be jovial, and I'm willing to give that poster the benefit of the doubt. :-) > a lot of your own comments sound very similar to the parent Which comments? > there are other emoticons more commonly used to indicate sarcasm/joke I think any common standard about something like this probably only applies to a narrow clique.
- ska 10y agoIgnoring the straw man, can you explain how c++98 code provides a counterexample for anything in modern c++?
- mackal 10y agoThis isn't modern c++, but whatever.
- randyrand 10y agoNo, but not everything needs to be memory safe. That's what the kernel is there for. You can typically just restart the program. The classic program safety vs programmer time tradeoff.
- AaronFriel 10y agoIf your program isn't memory safe, it's very often the case that someone can make your program run their program, at which point the kernel doesn't know that your program didn't intend to modify itself. W^X/NX bits and other technologies don't totally obviate the issue, as ROP gadgets can be used to defeat it. And so on, there's a whole domain of computer science dedicated to that arms race and no evidence that it's stopping any time soon. On the other hand, a Rust program without unsafe should simply never execute code outside of its defined control flow, it's not possible to hijack any control flow on the stack or heap, and so a running program under arbitrary user input can only ever explore execution paths that exist in the absence of memory unsafety. No ROP gadgets or heap/stack smashing, no overflows leading to overwriting a function definition in memory, no overwriting the parameters of a function to cause impossible branches to be taken, and so on.
- cbhl 10y agoI recall that there was at least one shipping video game where "someone" was "my future self" -- they exploited a buffer overflow after-the-fact in a shipped video game (a EULA dialog?) in order to make it run an updater.
- randyrand 10y agoNot every program is intended to be connected to the internet or have user provided input. I agree, for many programs memory safety matters. But there are a large chunk of programs where it doesnt matter/is not worth the effort.
- msbarnett 10y ago> Not every program is intended to be connected to the internet or have user provided input. While true, I think the vast majority of programs do do one of these two things (and increasingly, both), whereas the majority of programmers seem to think that what they work on "isn't a security issue". It's this disconnect that is giving us the Internet of Crap. Your phone apps, your fridge, your video games, your text editor -- every program I interact with every day -- it's all a security issue
- jasode 10y agoMaybe you're right that it's wrong to think that modern C++17 (unique_ptr, shared_ptr) written by experts is free of memory safety issues. But in this specific case, it looks like old code from 2002[1]. No modern techniques such as std:unique_ptr. Just 1970s C style raw pointer manipulation. I suppose the contemporaneous compiler used by John Maddock would have been C++98?!? [1] one example of a source file mentioned by the bug report: http://www.boost.org/doc/libs/1_63_0/boost/regex/v4/perl_matcher.hpp http://www.boost.org/doc/libs/1_63_0/boost/regex/v4/perl_mat...
- dnljms 10y agoThe main windows compiler would have been Visual C++ 6, which was released before standardization, and had notable differences from C++98. It was also buggy for non-trivial templates. Visual C++ 2002 wasn't much better.
- acconsta 10y ago> modern C++ This library is old enough to drive...
- gok 10y agoI don't fundamentally disagree with you (any C++ bigger than a screenful of code probably has memory safety issues) but contrary to its reputation, I've find Boost to be of really poor code quality.
- tonyedgecombe 10y agoI've find Boost to be of really poor code quality Which is telling because it's raison d'etre is quality and it was written by some pretty smart people.
- flukus 10y ago> modern C++ written by experts is free of memory safety issues Which simply isn't good enough, it takes 10+ years to become expert level at anything, so what are people supposed to do to get to that level?
- nix0n 10y agoGoogle's cache of this bug (loads quite slowly for some reason): https://webcache.googleusercontent.com/search?q=cache:mVrrFLejZEwJ:https://svn.boost.org/trac/boost/ticket/12818+&cd=1&hl=en&ct=clnk&gl=us https://webcache.googleusercontent.com/search?q=cache:mVrrFL...
- amalag 10y agoText only link: http://webcache.googleusercontent.com/search?q=cache:https://svn.boost.org/trac/boost/ticket/12818&num=1&strip=1&vwsrc=0 http://webcache.googleusercontent.com/search?q=cache:https:/...
- zao 10y agoThe trac instance (and legacy SVN server) isn't really designed for slashdot (well, HN) effect traffic, runs on some jiggly piece of rust at some uni somewhere.
- nix0n 10y agoI was commenting on the loadtime of the cached page (amalag found the solution).
- CJefferson 10y agoAny rust lovers out there: Could I ask you do a benchmark comparison and a fuzz comparison. I'd be genuinely interested in the result and if (as you might hope) the Rust::regex is as fast as boost:regex, and never crashes, that would persuade at least me to finally learn some Rust!
- gcp 10y agoThe Rust regex library is written by the same guy who wrote ripgrep. I'd be surprised if it didn't run circles around boost::regex.
- stuckagain 10y agoIf you were interested in performance you probably would not have been using boost::regex to begin with. RE2 is often an order of magnitude faster. You might choose boost if you require backtracking, but that's crazy anyway due to exponential time.
- 0xFFC 10y agoWhat is backtracking?
- bowmessage 10y agohttp://stackoverflow.com/questions/9011592/in-regular-expressions-what-is-a-backtracking-back-referencing http://stackoverflow.com/questions/9011592/in-regular-expres...
- Phritzy 10y agohttps://regex101.com/r/G23xYd/2 https://regex101.com/r/G23xYd/2
- deleted 10y ago[deleted]
- kbenson 10y ago
- revelation 10y agoThey seem to be fuzzing the regex, not just the input it is applied to. This may or may not change the results, but if you're allowing users to input arbitrary regex patterns you have a whole lot of other problems.
- gcp 10y agoHuh? It would be perfectly valid to have it power the regex part of the scripting engine in a browser, for example. If that would then lead to memory safety errors, you just got yourself a 0-day. Regex engines used in browsers are both fast and hardened against these attacks.
- Houshalter 10y agoFinding vulnerabilities in existing regexes would be significantly more dangerous/interesting though. Like say if an exploit was found that could be triggered with a carefully crafted input to an email validator. Half of the servers on the web would be vulnerable! See e.g. https://en.wikipedia.org/wiki/ReDoS https://en.wikipedia.org/wiki/ReDoS If you have to be able to run an arbitrary regex on the victim's machine, that makes it much more limited. You shouldn't be letting users access regex any more than you should let them execute arbitrary code. Sure browsers do both of those things. But only through monumental effort that shouldn't be expected everywhere else.
- AgentME 10y agoI've seen plenty of places that you may want to accept an arbitrary regex from the user. An app could allow the user to set up a filter for messages or usernames by putting in a regex. Or an interpreter for a sandboxed language could provide regex support.
- revelation 10y agoAll manner of problems in the programmers mind become trivial if only we allow users to input essentially code to express exactly what they want. Of course this is basically never a good solution. The issue with allowing arbitrary regex patterns is DoS through exponential blowup. But if you allow running code anyway you might not very much care for that.
- jimrandomh 10y agoPractical upshot: do not feed untrusted regexes into boost::regex.
- jvoorhis 10y agoOr any untrusted user input for that matter?
- Groxx 10y agoUntrusted regexes to anything, where possible. There are fairly well-known ways to use those to run a DoS: https://en.wikipedia.org/wiki/ReDoS https://en.wikipedia.org/wiki/ReDoS
- stuckagain 10y agoI take it you don't use a web browser?
- lomnakkus 10y agoNot exactly sure what you're getting at, but web browsers these days have a lot of protection from malicious pages, including the "JavaScript on this page is using 100% cpu; terminate? Yes/No?" dialogs.
- Groxx 10y agoAnd I dislike it when it locks up, yes. Less impactful than a server-side DoS, but still decidedly ungood.
- kibwen 10y agoNote that it is possible to design regex engines that deliberately avoid these pitfalls (e.g. RE2, which was originally written for Google Code Search, as well as Go's regex engine (written by the RE2 author) and Rust's regex engine). The downside is that these engines are forced to disallow certain exploitable features, such as backtracking.
- bradleyjg 10y agoThe larger question is why every conversation on here even tangentially related to C++, or Go, or almost any programming language for that matter, becomes about Rust. Just because it isn't a commercial product doesn't mean shilling is okay.
- dang 10y agoInsinuation of shilling is not allowed on HN without evidence. Opposite taste in programming languages is not evidence. We detached this comment from https://news.ycombinator.com/item?id=13601628 https://news.ycombinator.com/item?id=13601628 and marked it off-topic.
- foota 10y agoThis is your reminder to treat a regex with similar scrutiny as eval.
- darfs 10y agoAm i the only one, who get slowly angry about that "Use $language but Not this One"-comments? I don't see much value in such comments, srsly. Why don't accept the fact someone decided to write $it, and move on with usefull comments? Enough hn this today.
- davb 10y agoYes, I had a similar thought. The top two comment chains right now are (to paraphrase) "See, modern C++ isn't free of memory issues" and "Maybe we should rewrite it in Rust and compare".
- burntsushi 10y ago> "Maybe we should rewrite it in Rust and compare" That already happened, almost three years ago. It's an interesting comparison point. The OP contains memory corruption bugs in C++'s standard regex library. If Rust claims to prevent these kinds of bugs, does it actually hold up to scrutiny? One way of testing that is throwing a fuzzer against a regex library written in Rust.
- blub 10y agoBoost is not the "C++ standard regex library", it's one of the best known C++ libraries.
- Retra 10y agoWhat comment would you think is useful, and why not make that one instead?
- donovanm 10y agoHmm makes me wonder what the result of running this fuzzing test on other regex libraries would be.
- moosingin3space 10y agoRust's regex crate has fuzzing running against it, and that has lead to a lot of useful small fixes: https://github.com/rust-lang/regex/pull/262 https://github.com/rust-lang/regex/pull/262
- hannob 10y agopcre has been fuzzed by quite a few people a while ago, I remember also having reported a couple of issues. When I tested re2 nothing showed up. oniguruma also had quite a few issues, I tested it with libfuzzer lately. But everything should be fixed now.
- saywatnow 10y agoBadly needs static analysis. coverity is free for open source projects, will find many of the same issues, and produces reports that directly identify the buggy code, rather than the crash which might come thousands of instructions later in a completely different layer, requiring extensive reverse engineering to identify the source. And then when you've fixed one, the other test cases all need to be re-tested because they might have come from the same root cause, despite crashing in different locations. Particularly when the hit rate is very high, fuzzing is a stupidly inefficient way to find bugs.
- daurnimator 10y agoI've found coverity to be very hard to set up with a normal developer workflow on github. ==> I think I've given up on it 3 times. Do you have any guidance around getting it to work?
- MaulingMonkey 10y agoNeeds both. > rather than the crash which might [...] Assert like mad. Break out your debug allocators, your asan, your checked iterators. Fuzzing can be as bad as you say, but it can also give you extremely easy to diagnose repro cases - and catch an incredibly wide range of issues for incredibly little work, in my experience. Static analysis generally won't tell you "Hey, if I almost-but-not-quite exhaust your address space allocating to successfully parsing this file, I can get your next closed-source API call to segfault!" - useful for tracking down each and every possible allocation related to networking deserialization so you can configure sane quotas (such as "array size probably shouldn't be larger than bytes sent, bail out safely instead of trying to allocate that") With most sane setups that come to mind, no false positives either. > And then when you've fixed one, the other test cases all need to be re-tested because they might have come from the same root cause, despite crashing in different locations. Your tooling should do this automatically for you. If it doesn't, get better tooling. AFL. SDL MiniFuzz. Whatever floats your boat. > Particularly when the hit rate is very high, fuzzing is a stupidly inefficient way to find bugs. I've had it be stupidly efficient in terms of programmer time once setup. Occasionally leaving my computer on overnight? Worth.
- luckystartup 10y agoIs it true that most of these bugs wouldn't be possible in Rust? I think Rust might have solved: > heap-buffer-overflows, stack overflow, use of uninitialized data, SIGSEGV, undefined shift, invalid enum value, memory leaks I don't think Rust can protect you from infinite loops. And of course, actual logic bugs where the output is incorrect (including "assert failures").
- amalag 10y ago>I don't think Rust can protect you from infinite loops. That is the Turing Halting Problem!