Live data from Hacker News

Since Linux 6.9, LUKS suspend stopped wiping disk-encryption keys from memory

mathstodon.xyz

111–120 of 247 posts

Re: Since Linux 6.9, LUKS suspend stopped wiping disk-encryption keys from memory

#111

I am far from a security expert, but from the number of "we missed a single line C check across files during refactoring" critical security bugs discovered on a regular basis these days, the whole premise of a "giant secure open source C codebase" seems questionable. It is not specific to C of course, but invariants are arguably even harder to enforce and track consistently (esp under changes to code) in C. Unsure if…

To translate to Rust, it would have been "we missed a single line Rust check"...

This is a bug involving intersecting concerns and a deficit of cross-domain knowledge. It probably would have been the same in Lisp or assembly language.

Re: Since Linux 6.9, LUKS suspend stopped wiping disk-encryption keys from memory

#112

I am far from a security expert, but from the number of "we missed a single line C check across files during refactoring" critical security bugs discovered on a regular basis these days, the whole premise of a "giant secure open source C codebase" seems questionable. It is not specific to C of course, but invariants are arguably even harder to enforce and track consistently (esp under changes to code) in C. Unsure if…

While I can see the shortcomings of C and generally don't recommend it for new projects I don't see this particular bug as a good example of something Rust's borrow checker or some other language's type system will catch. I don't think even static analyzers can catch this. It's basically something like this: original: DoTheThing() new: DoTheThingSlightlyDifferentButKeepMyCredentialsAlive() fix: DoTheThingSlightlyDiff…

This is in effect a state machine, and when you have a type system more complex than C's you can encode state transitions in the type system (either by having state transitions explicitly return a new return type or by using sum types). You still need to architect the system to encode the invariants in types. No language will fix all logic bugs for free. But you can leverage language features to reduce their number.

Re: Since Linux 6.9, LUKS suspend stopped wiping disk-encryption keys from memory

#113

I am far from a security expert, but from the number of "we missed a single line C check across files during refactoring" critical security bugs discovered on a regular basis these days, the whole premise of a "giant secure open source C codebase" seems questionable. It is not specific to C of course, but invariants are arguably even harder to enforce and track consistently (esp under changes to code) in C. Unsure if…

The whole premise of a "giant secure open source C codebase" seems questionable Because code review is sometimes not much different from an idealized version of the halting problem, where you would have access to a formalized version of a specification. In other words, there is no strict definition of what is a security issue.

On the other hand, it is (both halting and spec adherence) are checkable under compute and space constraints though? :) I'd say the biggest hurdle are means to describe the spec in way that is easy enough for a human to produce to make it feasible.

Not a DB person either, but things like TLA+ seem very hard to write even with LLMs. Behavioral tests with an enumerable number of random paths to take (aka model checking - eg jepsen) seem more feasible. Although you can't check internal properties of the system (string `pass` or any of it's copies or parts are not held anywhere in memory at any point between lines A and B) unless we can check that two memory dumps are indistinguishable with different pass strings (assuming we abstracted away storage devices in a test environment).. Also not sure if it's "easy enough" to write such tests either.

Maybe the reason is that OS domain objects / primitives are too complex and not "isolatable" enough / lack a clear contract at all? (Hence multi file refactorings that break invariants.)

Re: Since Linux 6.9, LUKS suspend stopped wiping disk-encryption keys from memory

#114

Earlier quoted context omitted.

While I can see the shortcomings of C and generally don't recommend it for new projects I don't see this particular bug as a good example of something Rust's borrow checker or some other language's type system will catch. I don't think even static analyzers can catch this. It's basically something like this: original: DoTheThing() new: DoTheThingSlightlyDifferentButKeepMyCredentialsAlive() fix: DoTheThingSlightlyDiff…

This is in effect a state machine, and when you have a type system more complex than C's you can encode state transitions in the type system (either by having state transitions explicitly return a new return type or by using sum types). You still need to architect the system to encode the invariants in types. No language will fix all logic bugs for free. But you can leverage language features to reduce their number.

> You still need to architect the system to encode the invariants in types.

That's the problem though, right? If it's pointed out we all agree the "do not keep credentials alive" is a property that should hold and we can leverage whatever the environment offers to help preserve it. I fully agree modern languages have amazing support for this, but in C you can still run tests. Let's just say I don't think the language's inability to express logic of this kind held all those involved back from testing for it. I personally find "we just didn't think of it" much more likely.

That said, I am not a fan of C and recommend leveraging whatever fantastic modern tooling is available to you.

Re: Since Linux 6.9, LUKS suspend stopped wiping disk-encryption keys from memory

#115
post #62

Earlier quoted context omitted.

Correct. The point being made is: If one isn't re-entering their passphrase after suspend, how are they surprised that the encryption keys are somewhere in memory during suspend? edit: I see now that the prompt was being given and the keys still resided in memory.

The reason this bug is unexpected is that the user is expecting to have to enter their password (because they expect the key to be wiped on suspend), and then _they are_ asked for their password. But there was a copy of the key elsewhere in kernel memory that was never cleared.

Ah, my bad. Yes, if the user was being presented with the prompt on wake, I see the problem.

I have never had that setup so I was confused.

Re: Since Linux 6.9, LUKS suspend stopped wiping disk-encryption keys from memory

#116
post #84

Earlier quoted context omitted.

Okay, yes, sure. It definitely is the most-used encryption software for Windows. But I would never trust it a second, being proprietary and known for issues. You likely know that, but for the benefit of others: 38C3 - Windows BitLocker: Screwed without a Screwdriver https://media.ccc.de/v/38c3-windows-bitlocker-screwed-withou... https://www.youtube.com/watch?v=5eNtT2p12cM

The issues you linked with BitLocker are obvious properties of BitLocker-with-SecureBoot-only architecture. If you configure Linux that way, you get similar issues (for example, it's pretty easy to mis-configure TPM sealed disk encryption on Linux to still allow a recovery shell, which will run with the disk unsealed). BitLocker with a password (the equivalent of the LUKS configuration in question) does not share the…

Bitlocker with a password has always felt like a second class citizen to me. You have to dig into a bunch of group policies to use it. Maybe most people don't even realize it exists.

Re: Since Linux 6.9, LUKS suspend stopped wiping disk-encryption keys from memory

#117

It's because of vulnerabilities like this that I enable Intel's "total memory encryption" feature. No plaintext leaves the CPU package. DIMM swap attacks become useless. Moreover, it's basically free: the cryptography happens directly in the memory controller, in hardware, inline with the bus transactions the CPU is doing anyway .

I don't see how that solves this problem. there is a string in memory that gets saved on suspend. that string when read by the CPU has the same properties it had before. if the CPU is using rot-13, the string is still rot-13 and the attacker doesn't need to spend the compute needed to crack rot-13, the CPU will simply do that as normal.

Re: Since Linux 6.9, LUKS suspend stopped wiping disk-encryption keys from memory

#118

I am far from a security expert, but from the number of "we missed a single line C check across files during refactoring" critical security bugs discovered on a regular basis these days, the whole premise of a "giant secure open source C codebase" seems questionable. It is not specific to C of course, but invariants are arguably even harder to enforce and track consistently (esp under changes to code) in C. Unsure if…

While I can see the shortcomings of C and generally don't recommend it for new projects I don't see this particular bug as a good example of something Rust's borrow checker or some other language's type system will catch. I don't think even static analyzers can catch this. It's basically something like this: original: DoTheThing() new: DoTheThingSlightlyDifferentButKeepMyCredentialsAlive() fix: DoTheThingSlightlyDiff…

I agree re Rust vs C - this is not (only) a language issue. What would (roughly) the invariant be here?

In another thread comment below i argue that maybe the system (OS) itself is so complex that it lacks clear contract / the contract evolves too quickly over time (as other parts of the code need to change the given piece of code to extend it to their use case) and that defies clear encoding?

Or we lack easy enough means to describe specs? I tried reading jepsen spec earlier today and despite it being an "integration test" of sorts, it is far from "simple".

Can an entire OS or a system of comparable complexity be decomposed into objects simple enough that their entire intended behavior (with all edge cases) can be explained in a paragraph of human text + half a screen of dense behavioral "spec" - if i do X and do Y, Z should come out / hold _no matter what happens in-between_. Or that's what asserts + fuzzing is effectively supposed to do? Is there a clear distinction between invalid input and failed invariant in typical C code? I guess error code vs seg fault?

Re: Since Linux 6.9, LUKS suspend stopped wiping disk-encryption keys from memory

#119

Earlier quoted context omitted.

Correct. The point being made is: If one isn't re-entering their passphrase after suspend, how are they surprised that the encryption keys are somewhere in memory during suspend? edit: I see now that the prompt was being given and the keys still resided in memory.

Well, potentially a key might be stored in TPM. But I don't think that's better

I would hope that it is harder to get into the TPM than into the RAM.
Post reply on HN