12 ms·
Try to make sudo less vulnerable to Rowhammer attacks
- trebligdivad 3y agoHaving to code like this everywhere would be hell! Scroll to the top for the reference to the Mayhem attack it's trying to guard against.
- hlandau 3y agoThis is deeply interesting. I've sometimes contemplated the possibility of doing things like this to guard against memory errors causing mis-entry to particularly critical control flow paths - this is certainly an example of that. But never heard of anyone actually trying to do this until now. A "how to write rowhammer-resistant code" writeup would definitely be useful here - even if it is definitely something people cannot do for anything, I can certainly see cases where there is a case for it.
- Palomides 3y agoit's a long-known hazard in embedded and highly reliable systems, there are terms like "single-event upset" that might lead you in interesting directions
- addaon 3y agoSingle event upsets are well-understood and easy (although not necessarily cheap) to mitigate in hardware -- ECC for RAM, CRCs for data in flight, and voting (or lockstep if detection is sufficeint) for computation. The challenge with Rowhammer is that it involves multiple, correlated bit flips; and depending on details of your system the correlations may be disguised by various remapping layers.
- wongarsu 3y agoI remember someone making a rust library for hardened bools, though with the idea of protecting against protecting against random bitflips, not targeted rowhammer attacks (though it should work about the same). The feedback from the rust subreddit was basically protecting the bool but not the if statement is of limited use. Potentially it can even make it worse, since there is now more code being executed that might become bitflipped. That inspired me to make a crate that periodically checksums your program code while it's running, to make sure it hasn't changed. Got it working on Windows and Linux, but then it ended up like most side projects. Maybe I should polish it up and publish it.
- 4gotunameagain 3y agoSeems like an interesting compiler level protection, a decorator for enums so that they are compiled to values with maximum hamming distance between them.
- rcthompson 3y agoCouldn'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?
- f_devd 3y agoYes it's possible, but it's not desirable. It wouldn't be backwards compatible, and not safe for shared libraries. It's better suited for a linter-type error/warning.
- andrewaylett 3y agoIt's not plausible in C, for the reasons you mention, but it might be more possible in other languages -- Rust, for example, only guarantees specific representations when instructed and doesn't allow for shared libraries without a specified representation, so it wouldn't have either issue for most application code. Dynamically-typed languages similarly should be able to choose enum values at runtime in many cases.
- rcthompson 3y ago> Dynamically-typed languages similarly should be able to choose enum values at runtime in many cases. I wonder, is choosing random enum values at runtime more secure against Rowhammer than just having fixed values that were chosen randomly once and compiled in, since presumably the attacking code now has no way to know which bits it needs to flip? If so, it might even be desirable to implement this as a "secure enum" in a compiled language.
- mcculley 3y agoFrom the commit: “The values used were chosen such that it takes a large number of bit flips to change from allowed to denied. Using random values doesn't really protect against this attack.” It would be neat to see an algorithm that generates suitable values.
- nraynaud 3y agoInteresting it’s the exact opposite of Gray code’s goal, I suppose this has been studied, with fixed size words maximal distance problems are tractable.
- defrost 3y agoThis wikipedia article must surely be inaccurate: https://en.wikipedia.org/wiki/Row_hammer https://en.wikipedia.org/wiki/Row_hammer The initial research into the row hammer effect, published in June 2014, described the nature of disturbance errors and indicated the potential for constructing an attack, but did not provide any examples of a working security exploit. [1] [1] (June 24, 2014). "Flipping Bits in Memory Without Accessing Them: An Experimental Study of DRAM Disturbance Errors" By my recollection there was a discussion of rowhammer and making it work on a (original) Freenode channel circa 2010 (or earlier) in response to a related thread on a reddit security hacking subreddit. ie: it was being discussed in public channels some four years prior to a paper cited as "initial research". Addendum: Mind you, lots of things get kicked about and implemented before actual papers appear on them for the first time in public.
- rcthompson 3y agoWell, that quote from Wikipedia says the published paper didn't include a working exploit. That might be true even if a working exploit was available after the paper was written and submitted but before it was published. (I don't know if this is the case here, but this sort of thing is common in scientific publishing.)
- defrost 3y agoTo clarify: Mind you, lots of things get kicked about and implemented before actual papers appear on them for the first time in public. I was thinking of many examples I know where a technique is developed and used in industry (mineral exploration | remote imaging | secret spook stuff) and much later (five years or more) gets a first mention in acedemia .. where they may or may not get a robust working version happening .. just a rickety proof of concept.
- deleted 3y ago[deleted]
- xgk 3y agoThe possibility of flipping bits in DRAM in a Rowhammer like fashion, was known in the DRAM industry since at least the 1990s (sorry, no reference handy), and Rowhammer-like access was used in DRAM quality testing. As silicon density increased, the issue became more urgent.
- TheAdamist 3y agoIs there any reason for the void cast here? Theres no return value in use. (void)strlcpy(des_pass, pass,sizeof(des_pass));
- mandarax8 3y agostrlcpy returns a size_t, so just to silence the discarded return value warning https://linux.die.net/man/3/strlcpy https://linux.die.net/man/3/strlcpy
- formerly_proven 3y agotfw hardware becoming so unreliable people start using 32-bit maximum distance codes for enumerations with like four values.
- kator 3y ago[flagged]
- School-Cotton 3y agoRust makes a particular class of bugs harder to write. That’s it. It doesn’t magically eliminate all bugs. “Susceptible to rowhammer” is not in the class of bugs that Rust helps with. No experienced Rust programmer actually believes it magically prevents all bugs or magically makes security-sensitive code immune to side channel attacks, so I don’t think anyone is being lulled into a false sense of security, no.
- delusional 3y agoWhat about the Non-experienced Rust programmer? A lot of open source code are written by inexperienced people who understand the nuances of computer science primarily through hype. I think those are the kinds of people OP was asking about.
- Waterluvian 3y agoThat’s not a rust problem. Misunderstanding and misusing a tool is an inexperienced person problem. It’s one thing you pay veterans more for.
- IshKebab 3y agoI don't think there are going to be a large number of inexperienced Rust programmers. Inexperienced programmers write Javascript or Python, not Rust.
- odyssey7 3y agoSome novices do in fact write Rust, just like how many of them gain experience in C and C++ during undergrad. With any luck, universities will adopt something safer like Rust…
- randomdata 3y ago
- foota 3y agoFeels like a language with opaque enums and pattern matching could implement this kind of thing behind the scenes.
- kazinator 3y agoOnce 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!
- HankB99 3y agoI thought that Rowhammer was a thing of the past. Out of curiosity I found code to test for this and ran it on some of my hosts. My old desktop - I7-4770K/DDR3 - was susceptible. My old server - Xeon X3460/DDR3+ECC - was not. I upgraded the desktop with components based on a Ryzen 7 7700X/DDR5. It tested not susceptible. I'm not sure if that's a result of RAM designed not to be susceptible or that (I think) DDR5 RAM uses modules with on die ECC. I was not able to test any of my Raspberry Pis because the test code used some facility available on the AMD64 architecture that is not available on the ARM64 processors. The newer Pi 4B and 5 use modules with on die ECC. It seems to me that ECC should prevent Rowhammer susceptibility. That should prevent it on server grade H/W for anything still in service and newer consumer systems. I have no idea if Rowhammer affects other architectures than AMD64.
- trebligdivad 3y agoRowhammer is not architecture specific, since it's the DRAM rather than the CPU. The paper linked in the patch references other works showing every defence at rowhammer can be bypassed somehow (I've not followed them all) - e.g. it specifically says that ECC and the like can be bypassed.
- HankB99 3y agoInteresting. I did not expect that Rowhammer was architecture specific, only that the test I found was. I also did not expect that the various defenses, including ECC, could be bypassed.
- adrian_b 3y agoIt cannot be completely bypassed. The attacker cannot control precisely which bits will be erroneous. When much more than 2 bits become erroneous, in a small fraction of the cases no error will be detected but a wrong value will be read at the next access. However, in the majority of the cases an error will be detected, either non-correctable, or correctable in which case the corrected value will be wrong. Despite the fact that wrong corrections are possible, in a system with ECC that is configured correctly it should be impossible for a RowHammer attack to escape detection, unlike for a system without ECC memory. On a computer that is not defective, memory errors happen very seldom, typically one error after many months. Even only 2 correctable errors that happen in the same day represent an event that can be explained only by either a RowHammer attack or by a memory module that has become defective. Therefore, a well configured computer with ECC memory should alert immediately its administrator when 2 on more errors happen in the same day, even if they had been correctable errors, because this requires immediate action, either stopping a RowHammer attack or replacing the defective memory module. It would be pretty much impossible for any RowHammer attack to attain its target without triggering 2 or more ECC errors, which will reveal the attack attempt. Only when there is no ECC the attack can proceed undetected for a time long enough to be successful.
- jareklupinski 3y agoi enjoyed this part: #define AUTH_SUCCESS 0x52a2925 /\* 0101001010100010100100100101 */ #define AUTH_FAILURE 0xad5d6da /* 1010110101011101011011011010 */ #define AUTH_INTR 0x69d61fc8 /* 1101001110101100001111111001000 */ #define AUTH_ERROR 0x1629e037 /* 0010110001010011110000000110111 */ #define AUTH_NONINTERACTIVE 0x1fc8d3ac /* 11111110010001101001110101100 \*/ going to see how i can work this into a project :)
- trebligdivad 3y agoThat's the section that made me post this snippet; crazy isn't it?!
- jareklupinski 3y agocan't edit original post, but i just realized after lining up the monospace how #define AUTH_SUCCESS 0x52a2925 /* 0101001010100010100100100101 */ #define AUTH_FAILURE 0xad5d6da /* 1010110101011101011011011010 */ #define AUTH_INTR 0x69d61fc8 /* 1101001110101100001111111001000 */ #define AUTH_ERROR 0x1629e037 /* 0010110001010011110000000110111 */ #define AUTH_NONINTERACTIVE 0x1fc8d3ac /* 11111110010001101001110101100 */ AUTH_FAILURE is still just !AUTH_SUCCESS (and almost a palindrome)
- kelnos 3y agoIt sorta is, but isn't actually, sadly. I mean, if they were 28-bit values, they'd be binary complements, but they're actually 32-bit values, so they're really: #define AUTH_SUCCESS 0x052a2925 /* 00000101001010100010100100100101 */ #define AUTH_FAILURE 0x0ad5d6da /* 00001010110101011101011011011010 */ Doing a '!' operation in C on one of them won't yield the other value unless you also zero out the top 4 bits. Close enough, though... I still enjoy the symmetry as you did. Anyway, I'm curious why three of the values they chose have all zeroes for the top 4 bits. I wonder if there's a security-related reason for that.
- zaroth 3y agoI think the theory is that means the most number of bits need to be flipped. Because rowhammer is attacking the physical memory structure, it can’t function at the level that knows what AUTH_SUCCESS is. This attack just targets raw bits, so we need to protect these crucial state variables from bit-flips.
- stressinduktion 3y agoRelated, hardbool, it seems gcc can automatically handle this soon. https://blog.adacore.com/adacore-enhances-gcc-security-with-innovative-features https://blog.adacore.com/adacore-enhances-gcc-security-with-... and https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-hardbool-type-attribute https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.ht...
- loeg 3y agoNot 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.
- IshKebab 3y agoHardbool 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.
- loeg 3y ago> 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.
- jesprenj 3y agoGood job, though it doesn't really help when you have a buffer overflow leading to RCE in a suid binary (remember sudoedit CVE?)
- dist-epoch 3y agoEven without an explicit attack, today's memory is pretty fragile, I'm regularly seeing bit flips.
- PrimeMcFly 3y ago> I'm regularly seeing bit flips. How?
- dist-epoch 3y agoFor example 7zip decompression CRC failures that resolve on a second try. It would be longer to explain how, but I tracked it multiple times to a single bit flip in the decompressed output.
- TillE 3y agoI've also seen that, often enough that a hardware issue is extraordinarily unlikely. It's almost certainly just a boring old software bug.
- dist-epoch 3y agoPopular compressors like 7zip are some of the best tested software on the planet, because corruption is immediately detected. And we know hardware bugs are real, that's the whole point of rowhammer. You might want to look at Facebook research: > “Silent data corruptions are not limited to rare one in a million occurrences within a large-scale infrastructure. These errors are systemic and are not as well understood as the other failure modes like Machine Check Exceptions.” A large part of the responsibility should be shared by device makers, Facebook says. https://www.nextplatform.com/2021/03/01/facebook-architects-around-silent-data-corruption/ https://www.nextplatform.com/2021/03/01/facebook-architects-...
- PrimeMcFly 3y agoThanks, that's pretty interesting. I'd actually be really interested if you would care to explain how, I think others would find it interesting also. I'm not even sure how I would approach trying to do that.
- asah 3y agoI wonder how this might work with bit-dense systems (e.g. databases like PostgreSQL) where every bit has meaning and it's wildly impractical to reassign bitpatterns like this.
- kzrdude 3y agoWhen do these values get into memory, shouldn't they be in registers generally? Maybe it's when the program loaded to memory to execute, but is that part rowhammerable?
- kevincox 3y agoIf a task is preempted it will have its registers saved to memory. So you can never assume that some state won't live in memory at some point.
- frozenport 3y agoReally struggle to understand the thread from Rowhammer. It would seem to be particularly dangerous, but then I don't see everybody getting pwned.
- kazinator 3y agoSomeone 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.
- thulle 3y ago> It is perfectly good enough for the error code enumeration to be statically randomized into hard coded constants. A comment points out that they aren't randomized: > The values used were chosen such that it takes a large number of bit flips to change from allowed to denied. Using random values doesn't really protect against this attack.
- SkyMarshal 3y agoDoes 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?
- charcircuit 3y agoMy 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.
- forty 3y agoI'm happy that my mistakenly typed rm -rf / fail when I use my non root user (normal account) even though I also have root for when I do want to mess things up.
- DANmode 3y agoIf your use of sudo featureset is minimal, it's true that doas can act as "reduced attack surface" replacement. Cons: humans (and some software) expecting "sudo" will work while interacting with your system.
- pid1wow 3y agoGiven that the most common use of sudo is to give yourself root to run a command, and malware looking to elevate root can just rig up ~/.bashrc, what use is this patch? What use cases does it apply to and how common are they?
- wongarsu 3y agoSudo has much more fine-grained abilities for more surgical use-cases, like giving users the ability to only execute certain commands as a certain user, with detailed logging and auditing. It has a pretty involved config file (the pdf docu for it is 80 pages long), a plugin system, a seperate log format and log server, etc I also believe those use-cases aren't that common anymore since multi-user systems fell out of favor. There is an argument that most of us could use a vastly simpler tool instead to reduce the attack surface. But that tool wouldn't be sudo, because sudo is built around supporting all these use cases.
- bpye 3y agodoas [0, 1] in OpenBSD is somewhat simpler. [0] - https://man.openbsd.org/doas.1 https://man.openbsd.org/doas.1 [1] - https://man.openbsd.org/doas.conf.5 https://man.openbsd.org/doas.conf.5
- _visgean 3y agoHaha I have done exactly that as a joke in highschool https://github.com/Visgean/fakesudo https://github.com/Visgean/fakesudo
- eth0up 3y agoMoron disclaimer: I may not be one entirely, but I frequently emulate one. As a full-time Linux user, I haven't used sudo for years. Rather, I do 'su root'. However, I noticed several years ago (Debian) that upgrades would iterate twice, seemingly accommodating two accounts. Emulating a moron as I do, I never exerted the effort to learn why. I simply began, after 'su root', entering 'sudo su', which despite always having sudo disabled, seems to make me proper root. I'll often use synaptic package manager when I want a cleaner, easier interface to explore packages. If I only 'su root' it won't open unless I append .... something similar to 'pkex' to the end, but if I do 'sudo su', I can run it using only 'synaptic'. Regardless, I refuse to use sudo otherwise, even when I'm emulating something sentient. Be afraid. There are morons using Linux, and some are quite productive despite.
- poizan42 3y agoYou should use 'su - root' to get a root login shell. Otherwise you will still keep your old environment, including $HOME and $USER. (The man page recommends using --login over the single dash, but it also says they are equivalent. Maybe I'm too much of a moron to understand the difference, but the single dash is less typing)
- deleted 3y ago[deleted]
- commandersaki 3y agoPeter Gutmann goes over this type of mitigation in the context of glitch attacks: https://www.youtube.com/live/IyeDSyvYvZs?si=wkapFNXp8-N28vEb&t=5537 https://www.youtube.com/live/IyeDSyvYvZs?si=wkapFNXp8-N28vEb...
- aaron695 3y ago[dead]
- deadliftdouche 3y agoI don't understand, isn't this pointless? I could just change some other data structure or variable, hell, I'll just change the sudo input buffer size and do a stack overflow, or a memcpy size into a heap overflow, or what stops me changing a jne (Jump if Not Equal) instruction to a jg (Jump if Greater) and bypassing the if's?
- deadliftdouche 3y agoI'd argue its worse than pointless, at best it does nothing and at worse it seems to make the code harder to understand and audit, which could result in more future vulnerabilities.
- Beldin 3y agoThe associated paper abstract claims to have broken sudo by rowhammering register values. It stands to reason that these mitigations thwart the found attacks - the commit message points to the paper as the reason for these mitigations, after all. Preventing known attacks is not pointless at all.
- kevincox 3y agoI think the point is that if your known attack I'd "target was shot in the right hand" making them wear a protective glove on their right hand isn't a good defense. You would want two protective gloves, a helmet and bulletproof vest.
- userbinator 3y agoIndeed. Trying to write code that can essentially work correctly with arbitrary memory corruption is not something that should even be attempted.
- zaroth 3y agoThis got me thinking - why we live with rowhammer and how do you take it seriously. This is such a crazy hack to get some protection around key variables - by requiring 32-bit manipulation. Why isn’t this just “done” on the phy layer, or somehow detected automatically in-flight? Does the compiler protect against it? At what performance penalty? It’s really much nicer just not thinking too much about it and going on believing our bits.
- userbinator 3y agoNo. Do not want. Rowhammer is a hardware problem ---- defective RAM --- not a software one. The sooner everyone starts returning defective RAM and putting pressure on the hardware manufacturers to maintain correctness, the sooner we can stop this descent into insanity. "They can always work around it in software" is the attitude that let Rowhammer exist, and continuing to fulfill that expectation will only make things worse.
- mikewarot 3y agoCame here to say the same thing... take my up-vote. ;-)
- bogantech 3y ago> Rowhammer is a hardware problem ---- defective RAM --- not a software one. It always amazes me how people can be so confident yet so wrong. It's a problem of physics - there's various ways to try to mitigate it but the only way to completely avoid it would probably be to use SRAM and that is going to be extremely expensive when talking 16GB and not nearly dense enough. It's not some conspiracy by "Big RAM"
- oasisaimlessly 3y ago> there's various ways to try to mitigate it but the only way to completely avoid it would probably be to use SRAM Why wouldn't storing a cryptographically-secure checksum on every RAM row work?
- theamk 3y agoThere are plenty of problems of physics in the RAM design, and it's hardware designers jobs to find the operating regime where those problems do not matter. I mean, if you had a DRAM labeled "DDR4-3200" but it can only work at a much lower speed (say DDR4-2400), it's clearly a problem of physics - the gate capacitance is too high, the driver transistors are not strong enough. And yet my reaction would be to take that RAM back to store and get my money back, not to defend manufacturers which claim false things about their chips.
- 3y ago
- vlasky 3y agoThis software mitigation technique for Rowhammer could also be useful for improving the reliability of programs running on microcontrollers in high radiation environments, e.g. satellite in Earth orbit. By maximising the Hamming distance between binary values used in enumerations (enum variables) and boolean variables, one could detect if the code has entered an invalid execution path and then trigger a watchdog reset, e.g. an else statement or a switch statement with a fall through case that would not normally be reachable.