Live data from Hacker News

Try to make sudo less vulnerable to Rowhammer attacks

github.com

61–70 of 147 posts

Re: Try to make sudo less vulnerable to Rowhammer attacks

#61
Someone in a comment suggested ...

> gcc -DRND1=0x$(openssl rand -hex 4) ...

That would cause grief to reproducible distro initiatives.

It is perfectly good enough for the error code enumeration to be statically randomized into hard coded constants. The attacker is very unlikely to flip every single bit of one valid value so that it resembles another valid value.

Even if the values were randomized at compile time, if the executable is readable to the attacker, the attacker can learn what those values are.

If the executable is not readable to the attacker, the attacker can just pull a copy of the executable from the distro package: executables are installed from widely used binary packages, not freshly compiled for every system.

Re: Try to make sudo less vulnerable to Rowhammer attacks

#62
post #18

Feels like a language with opaque enums and pattern matching could implement this kind of thing behind the scenes.

Once you assign the values in the C enum, a switch statement is "opaque".

Just inefficient; a jump table optimization is impossible on the values. Speed is sacrificed for security. A jump table itself could be row-hammered to jump where the attacker wants!

Re: Try to make sudo less vulnerable to Rowhammer attacks

#63
post #40

Couldn't compilers be configured to use such values for for any enum type? And maybe even auto-insert the appropriate check in the final unchecked else anywhere that enum type is otherwise exhaustively checked?

The problem with C and C++ is that enum values are explicitly incrementing, even when the user does not specify a literal value for each one. So if anything depends on a specific value (e.g., disk or network formats), this will break it. I think Rust enum values are similar, but I'm not a language expert.

Rust enums are incrementing too so that they can generate machine code with dense jump tables. If you also want the discriminant value for something, you opt into that with e.g. #[repr(u8)] and you can even override the values. Note that unlike in many other languages, casting from a number to the enum is a falliable operation because not all values are valid.

Making something like this into a panic is not a good fit for Rust as-is. Because enums are proven to have only correct values, not only is code written to assume pattern matches cannot panic, but compilers are free to optimize around only having valid values as well. That goes not only for the enum discriminant, but for any associated values being properly initialized values of their respective types.

In a sense, Rust lets you write code as if invalid values never happen, so there's less to check for in your code. It's understandable from the perspective of the abstraction needed for computer code to be "correct" and not just temporarily getting away with Undefined Behavior. There are simpler ways to violate it than just rowhammer, write straight to process memory for example, which can also violate invariants that compilers assumed while optimizing.

If you wanted to compile Rust (or anything else) with a hardening mode that does check what should be redundant values, it would be a lot slower and code that never panicked before would now panic, but it would probably be a worthwhile tradeoff for some programs to opt into. After all, if you built for CHERI or arm64e and got a machine exception from an unauthenticated pointer, you'd be thrilled you mitigated a vulnerability even if it violated your higher-level language model. Defense in depth and all that.

Maybe someone feels motivated enough to write an RFC and prototype for this. It just wouldn't stop at enum values, it should mean all sorts of other things too, such as not eliding any other checks that appear redundant given assumptions like immutability. That's what makes it slow and hard to reason about.

Re: Try to make sudo less vulnerable to Rowhammer attacks

#64

Couldn't compilers be configured to use such values for for any enum type? And maybe even auto-insert the appropriate check in the final unchecked else anywhere that enum type is otherwise exhaustively checked?

Yes; gcc and clang could, in principle, support an extension like:

  __attribute__((rand)) enum e { FOO, BAR, ... };
which randomizes the values, as an extension.

You only need this in specific places, like setuid programs.

Randomization can be bad because it wrecks build reproducibility; it would have to be tied to the GNU Build ID.

If such an enum is used in any interface between files, the randomization has to be the same in every translation unit.

Maybe the syntax could specify a seed: rand(42).

Re: Try to make sudo less vulnerable to Rowhammer attacks

#67
post #58

Earlier quoted context omitted.

This is for local sudo privilege escalation. If the attacker is already running code on your system, you kind of lost anyway.

Not really. An example out of top of my head, where this still might be useful are login nodes (used in many research clusters to allow users to enter and sumbit jobs) or shared web-hosting servers (few of those definitely still exist). There legitimate non-privileged users can run their programs and the end goal is to prevent them from getting root.

Another common one is for example minecraft / source engine game server hosts as they commonly allow customers to install mods.

Re: Try to make sudo less vulnerable to Rowhammer attacks

#68
post #39

Earlier quoted context omitted.

Not exactly; these constants in sudo are an enum of sorts (actually preprocessor macros). It's not just bool (and won't just be bool in many situations). It is cool to see GCC exploring automatic protection in this space; I just don't think it is relevant to what sudo did here.

Hardbool lets you use custom true and false representations with higher hamming distances. The sudo patch uses custom representations for their enum that have higher hamming distances. The only difference is that hardbool is for true/false and this patch is for AUTH_SUCCESS/AUTH_FAILURE/AUTH_ERROR etc. But that's irrelevant. It's the exact same technique.

> The only difference is that hardbool is for true/false and this patch is for AUTH_SUCCESS/AUTH_FAILURE/AUTH_ERROR etc. But that's irrelevant.

It's very relevant! The problematic comparison in this code isn't true/false! A feature that only protects true/false does not help here.

Re: Try to make sudo less vulnerable to Rowhammer attacks

#70

Does anyone have any opinions on doas vs sudo? I've heard doas recommended as being more minimalistic, and various advantages that brings. What are the pros and cons between the two?

My opinion is to have neither. Requiring users to switch to an account that has different privileges is evidence of poor design of the operating system. Having a root user who has full privileges over the entire system is also poor design as it is the opposite of the principle of least privilege. If a user has the privilege to do something they should be able to do it with their normal account.
Post reply on HN