Live data from Hacker News

Google broke a conditional statement that verifies passwords on Chrome OS

arstechnica.com

221–230 of 276 posts

Re: Google broke a conditional statement that verifies passwords on Chrome OS

#221

Earlier quoted context omitted.

That is just gaming your coverage stats, there are still the different branches they just aren't visible now.

That's not true. Compare `( a() || b() || c() ) ? yes() : no()` to `( a() | b() | c() ) ? yes() : no()`. In the second case, there are two paths through the code: a() b() c() yes() a() b() c() no() But in the first case, there are more paths: a() /* true */ yes() a() /* false */ b() /* true */ yes() a() /* false */ b() /* false */ c() /* true */ yes() a() /* false */ b() /* false */ c() /* false */ no() That is becau…

The code is correct if you hit yes() and no() correctly depending on three conditions. There are 8 possibilities in both cases and thus you need 8 tests in both cases. Shortcircuiting is optimization, it doesn't reduce complexity of the logic.

Re: Google broke a conditional statement that verifies passwords on Chrome OS

#222

Edit: Someone has explained the issue below I don't understand how that broke anything? The C++ codegen for && and & is the same: bool good(bool a, bool b) { return a && b; } good(bool, bool): mov eax, edi and eax, esi ret bool bad(bool a, bool b) { return a & b; } bad(bool, bool): mov eax, edi and eax, esi ret [0] https://godbolt.org/z/84MMqTehs

I made what I think is a minimal example here: https://godbolt.org/z/dcnzonjar

Interestingly I couldn't get it to fail on GCC (even with -fnoexceptions and -Ofast), only on Clang. Maybe someone else has some info as to why this is?

There is a clear difference in the assembly output for the correct and incorrect implementations, with a testb instruction run much earlier in the correct version. You can see this at line 22 of the output, if you highlight it the && in the source is highlighted in bold.

Re: Google broke a conditional statement that verifies passwords on Chrome OS

#223
post #182

Earlier quoted context omitted.

I am utterly confused. How would the compiler know that has_value() guarantees that the ->label dereferencing work, since this is a bitwise operation ?

I would imagine has_value is checking to see if a pointer is NULL, and -> is dereferencing that same pointer. When the optimizer sees the two together it realizes the former is useless.

by this logic the compiler would optimize any short-circuiting because it KNOWS the programmer WOULD NEVER deference an invalid pointer

Re: Google broke a conditional statement that verifies passwords on Chrome OS

#224

Earlier quoted context omitted.

You can use `and` and its siblings instead of && and similar in C++11. Most people here, and in other boards, will try to convince you that it hurts readability because 'that‘s how we always did it' (read I‘m used to it and don‘t like change).

> that‘s how we always did it ... which, frankly, is a very good reason. Don't needlessly change something people are used to. Why is the blinker control on the left side and the wiper control on the right side? Because that's what people expect.

No it's because this way your left hand only deals with blinker, and your right one wih the gear shift. Separation of concerns. It's reversed in the UK of course.

Re: Google broke a conditional statement that verifies passwords on Chrome OS

#225
post #102

Earlier quoted context omitted.

"Not as weak as Java" is not a very interesting benchmark, as Java also has a poor type system. C++'s type system is pitiable relative to those of Rust, Haskell, OCaml, and SML. Moreover, in addition to being less expressive than them, C++'s type system is also weak , in formal sense, by allowing many implicit type conversions - which is one of the issues that I was complaining about. The fact that it "has to be in p…

Java has a poor type system, but not as poor as that of C++.

This is uttely false. I desume you haven't used C++ in the last 10 years, or at least you didn't delve deep enough into it to really understand how powerful (while bonkers) the C++ type system is.

C++ has a much, MUCH more stronger type system with true generics, value types, const-correctness, compile time reflection and dispatching, ...

In Java, everything is a reference, except when it's not (which is a design mistake that .NET fixed, IMHO). Some stuff in Java is plain "magic", like type erasure and boxing, while C++ might well be drowning in its own sea of utter madness but at least tries to be somewhat consistent (for instance, there are no "magic" types, when you do `int { 3U }` you are "constructing" an integer, when you do `bool x { 33 }` you applying the implicitly defined `bool(int)` constructor from bool. You can define your own conversions, and you can define your own custom types that behave and can be used like built-in ones (see smart pointers, iterators, ...).

Java _seems_ stronger typed because it generally doesn't allow integer promotions and implicit conversions, but these are concepts that are orthogonal to the type system, `bool` and `char` are different, distinct types and if you specialize a template for T, it won't apply to `char` unless a conversion happens, and if it does so, it is still operating on `bool`, not char - it is constructing a type from another, the fact this happens is simply hidden from you, like Java and boxing (which ironically is an implicit conversion).

The Java delegates pretty much everything to the JVM, and that's reflected in the language design. Java is a simple language that does not do a lot at compile time, relying on runtime facilities to mitigate these shortcomings. See for instance how everything can always decay to a reference to Object, implicitly, everywhere, requiring casts (i.e. runtime assertions) to restore type safety - that's basically a safer `void*`.

1995's Java was clearly too limited, I understand they wanted a fresh start from the ugliness of '90s C++, but they straight removed too much for the sake of simplicity. The current crop of languages, which largely rejected the Java model is kind of a symbol of what went wrong with Java, IMHO.

The fact certain features had been "hacked" on top of the language using what was already there (see generics, boxing, ...), often introducing features that act like "magic", and can't be overridden by the user is bad, and shows how limited the original language was. The same way you can't override operators, you can't define custom boxing rules for your types (mostly because you won't be able to define custom value types until Valhalla is released).

Modern C++ allows you to write safe and solid code using compile-time features and the type system. While stuff like , SFINAE, template metaprogramming and such are definitely not "nice", they are extremely powerful and if used correctly eliminate completely certain issues from ever happening. If you only use smart pointers, references, containers, moves and by-value semantics you won't get crashes from nulls, ever. You won't have memory leaks, and after lots of fighting with the compiler, there's a high chance your code will work straight away (unless you messed up the logic). This is not that far from Rust, as far as my experience goes - I still hope for Rust to mostly replace C++ in the end, but for now C++20 is a very solid substitute and a good choice (and feels much more modern and powerful than Java could or has ever been).

Re: Google broke a conditional statement that verifies passwords on Chrome OS

#226

Earlier quoted context omitted.

> you might want the behaviour shown here of not short-circuiting. Or you might want to create a bitwise function that also allows calling on single-bit (i.e. boolean) values. In both cases, I think the risk-benefit ratio is way too skewed towards the risk of creating ugly, hard to detect bugs. When I don't want short circuiting from happening, I just assign the RHS of the expression to a variable beforehand; if I wa…

You could make the opposite argument that short-circuiting is the surprising behavior [1] and you should make it explicit with an if. [1] and in this very thread many people were actually surprised by it!

Short circuiting for logical operators has existed at least since the first C versions in the early '70s. It's maybe not intuitive, it's probably a crummy idea, but that's how basically everything based on C works (including modern languages like Go and Rust), so there's not that much that can be done about that.

Also, after seeing how weird JavaScript is in comparison, I have to say that C++ definitely isn't the strangest kid in the block when accounting for weirdness and unintuitive behaviours.

Re: Google broke a conditional statement that verifies passwords on Chrome OS

#228
post #227

So what happens to people who are affected by this? Are they just out of luck and have to find another device or try to unbrick their chromebook somehow?

EDIT: Per the Android Police article, looks like there is a way to update now without powerwashing. Disregard the below paragraph.

If they stored any data locally it's lost unless Google releases a way to allow a computer in this state to repair itself. Fortunately for many users the ChromeOS convention is to keep important things stored on the cloud. But that's not much comfort to those who chose to have experienced data loss due to this.

The description of 'bricking' in this case is unwarranted. Their device is fine following a 'powerwash', essentially a factory reset.

Re: Google broke a conditional statement that verifies passwords on Chrome OS

#229
post #214

Earlier quoted context omitted.

UB is not an event that happens. UB is a rule that allows compilers to assume that situations defined as UB never happen. It's UB to access an optional that has no value, so if the compiler sees optional accessed unconditionally, it may assume the optional must have had a value, and delete all code that contradicts this conclusion. Compilers don't do this out of spite. It's an optimization that removes redundant chec…

Yeah, I know what UB is, and that's why I'm saying that this is not UB. Have you even read what I wrote?

I recommend stepping back for a moment and asking yourself: Why is it that you, the person who believe they "know what UB is" and is sure "this is not UB" did not understand what's going on here, while the other people reading who explained why it's UB have understood exactly what's going on ?

Doesn't it seem most likely that you in fact do not understand Undefined Behaviour and didn't understand what's going on ?

Re: Google broke a conditional statement that verifies passwords on Chrome OS

#230

Just reading the title it sounded very much like "Single Point of Failure: The (Fictional) Day Google Forgot To Check Passwords": https://www.youtube.com/watch?v=y4GB_NDU43Q

This actually happened for real with Dropbox about 10 years ago: https://techcrunch.com/2011/06/20/dropbox-security-bug-made-...
Post reply on HN