[HN Gopher] Bringing Memory Safety to sudo and su
       ___________________________________________________________________
        
       Bringing Memory Safety to sudo and su
        
       Author : mritzmann
       Score  : 69 points
       Date   : 2023-04-26 14:39 UTC (8 hours ago)
        
 (HTM) web link (www.memorysafety.org)
 (TXT) w3m dump (www.memorysafety.org)
        
       | jmclnx wrote:
       | Will this replace the current sudo ?
        
         | zimpenfish wrote:
         | There's always doas[1] if you want a simpler, safer version.
         | 
         | [1] https://en.wikipedia.org/wiki/Doas
        
           | Gigachad wrote:
           | Still written in an insecure language.
        
         | dochtman wrote:
         | It's a separate project. We'll see if/when these new Rust-based
         | versions become good enough for people to adopt as their daily
         | driver sudo/su.
        
           | therein wrote:
           | I am sure they'll use the same name, though. Hard to come up
           | with a name for this one.
           | 
           | rsu, rsudo
           | 
           | surs, sudors (and then /etc/sudorsers as the cherry on top)
        
       | hannob wrote:
       | This sounds good, however, I hope they don't try to replicate all
       | of sudo.
       | 
       | sudo fails a basic security principle on Unix systems, and that
       | is that suid binaries should be simple. Their developers have a
       | tendency to add all kinds of stuff that barely anyone ever uses,
       | but that bloats its size.
        
         | rnijveld wrote:
         | Definitely one of the things that is on our radar! Lots of
         | features in sudo are just basically legacy features, remnants
         | from the 90s or 00s that are no longer necessary in a modern
         | setup, but nevertheless exist because in past times they used
         | to be the default or only option. We are particularly aware of
         | how much power a suid binary has, so we do try to be cautious!
        
         | steveklabnik wrote:
         | If you read the README https://github.com/memorysafety/sudo-rs
         | 
         | > Our current target is to build a drop-in replacement for most
         | basic use cases of sudo. ...
         | 
         | > Some parts of the original sudo are explicitly not in scope.
         | Sudo has a large and rich history and some of the features
         | available in the original sudo implementation are largely
         | unused or only available for legacy platforms. In order to
         | determine which features make it we both consider whether the
         | feature is relevant for modern systems, and whether it will
         | receive at very least decent usage. Finally of course a feature
         | should not compromise the safety of the whole program.
         | 
         | So seems like they're on the same wavelength as you are.
        
       | stephc_int13 wrote:
       | This so-called memory safety is looking like a buzzword
       | engineered to be extremely appealing to a type of mildly
       | technical but mostly illiterate about computer security kind of
       | people.
       | 
       | This has been said before, this has been tried before, OOP was
       | also seen as silver bullet at some point, like several others.
       | 
       | Computer security is a deeply complex and dirty field, switching
       | programming language won't help much if programmers are expecting
       | the work to be done for them by the compiler.
       | 
       | If you want robust code : hire experts in the field and pay the
       | price.
       | 
       | Rewriting sudo is almost certainly going to be painful and to
       | increase the vulnerabilities potential.
        
         | cedilla wrote:
         | Alright, I'll take the obvious bait.
         | 
         | The experts in the field are right over there, getting paid to
         | rewrite it in rust.
        
           | stephc_int13 wrote:
           | Experts with Rust? Experts about sudo implementation
           | requirements? Or computer security experts? Because you'll
           | probably need all of that.
        
       | notorandit wrote:
       | > But because it's written in C, sudo has experienced many
       | vulnerabilities related to memory safety issues.
       | 
       | Or because it's not been developed with enough care?
       | 
       | I for one think that there is no unsafe language, only careless
       | programmers.
        
         | rnijveld wrote:
         | I think your expectations are too high. During our initial
         | exploration we actually managed to talk to Todd Miller, the
         | maintainer of sudo. In our (brief) interactions with him he did
         | not sound cavalier like this at all. Instead I think that a lot
         | of the issues with sudo are more about it being a thirty+ year
         | old program and codebase, and sometimes features turn into bugs
         | and security issues all on their own in such time periods. But
         | then again, C just cannot offer the kinds of protections that
         | Rust can, and mistakes will be made eventually by every human,
         | better to have some protection from your mistakes than none at
         | all.
        
         | actionfromafar wrote:
         | Right! Like with airplanes, there are no unsafe airplanes, only
         | careless pilots.
        
           | stephc_int13 wrote:
           | This analogy is completely wrong. The programmer would be the
           | aero engineer, not the pilot.
           | 
           | The pilot would be the sysadmin, maybe?
        
         | justin_oaks wrote:
         | > there is no unsafe language
         | 
         | Perhaps you didn't intend it this way, but that implies that
         | there is no difference in safety between languages. This is a
         | patently absurd idea.
         | 
         | C is clearly less safe than many languages that don't allow
         | unsafe memory practices.
        
       | musicale wrote:
       | A few years back I was annoyed that sudo would consistently crash
       | with a memory error.
        
       | Dolamifa wrote:
       | Can't be more excited for that!
        
       | nhellman wrote:
       | There is also 'doas' from the OpenBSD project. It's a replacement
       | for 'sudo' with fewer features and a smaller codebase, with the
       | aim of a smaller attack surface.
       | 
       | https://en.m.wikipedia.org/wiki/Doas
        
         | smabie wrote:
         | Though written in C for no apparent reason. It's ironic to me
         | how security focused OpenBSD is while at the same time looking
         | down on any other language besides C.
        
           | JohnFen wrote:
           | Just because something is written in C doesn't automatically
           | mean it's unsafe. It's 100% possible to write safe C code.
           | It's just not "automatic".
        
             | Gigachad wrote:
             | Safe C code is like functional communism, we are yet to see
             | a real example. It probably could exist though.
        
               | rhdunn wrote:
               | SQLite? That has an extensive test suite and has been
               | extensively vetted/checked.
        
               | dwattttt wrote:
               | True, but there are quite a few CVEs (of varying
               | severity) https://www.cvedetails.com/vulnerability-
               | list/vendor_id-9237...
               | 
               | Another way to look at that is "SQlite has had these bugs
               | in the past, and our standards are unlikely to be that
               | high". It does deal with a quite complex problem domain,
               | but is still a strong warning re. vulnerabilities in C.
        
           | yjftsjthsd-h wrote:
           | > for no apparent reason
           | 
           | Here's the list of hardware platforms that OpenBSD supports:
           | 
           | https://www.openbsd.org/plat.html
           | 
           | Note that when they say support, they mean that it's fully
           | supported and actually works well, including that OpenBSD is
           | fully self-hosting on that platform (read: "oops, the
           | compiler OOMs on 32-bit" is a no-go).
           | 
           | Now, here's the list of targets that rust supports:
           | 
           | https://doc.rust-lang.org/beta/rustc/platform-support.html
           | 
           | Notice that _all_ the OpenBSD targets are tier 3, and it 's a
           | strict subset of OpenBSD's platoforms. Even if we ignore
           | everything else - a questionable choice - rust is unsuitable
           | for writing core parts of OpenBSD because it can't actually
           | build for all the systems that OpenBSD supports.
        
             | jcranmer wrote:
             | The point GP was (probably) trying to make is that
             | OpenBSD's vision of security is at odds with its insistence
             | on C, a notoriously unsafe and insecure language. There's
             | no reason that the replacement language has to be Rust; it
             | could be Nim or Zig or C# or Java or Vala or OpenBSD Custom
             | Memory-Safe Language.
             | 
             | What it takes for OpenBSD to choose to support whichever
             | language it wants to is primarily a commitment to actually
             | spend its resources to support said language. That the
             | OpenBSD targets for Rust are tier 3 is a sign of its
             | unwillingness to consider moving away from C: what it takes
             | to move from tier 3 to tier 2 is a set of maintainers who
             | have a commitment to be responsive to patches, and an
             | automated CI solution.
             | 
             | (Also note that OpenBSD is the largest Unix "stuck" in tier
             | 3 for Rust. Solaris/Illumos, FreeBSD, and NetBSD all manage
             | to have tier 2 builders. Even Fuchsia and Redox have tier 2
             | support!)
        
               | tedunangst wrote:
               | I think sometimes people forget the openbsd project was
               | not started with a text editor opening an empty file.
        
           | Karellen wrote:
           | OpenBSD doesn't have a Rust compiler in their core system.
           | Having a core utility written in a language that isn't
           | buildable with tools in their core system is a non-starter.
           | 
           | Once they have their own Rust compiler, or are able to import
           | a Rust compiler that supports OpenBSD to the point where bugs
           | on that platform are release-blockers for that compiler, and
           | which is suitably licensed, they should be able to start
           | (re-)writing core tools in Rust.
        
         | hannob wrote:
         | Yeah, but...
         | 
         | Recently learned that it doesn't implement using a new pty,
         | which makes it vulnerable to TIOCSTI and TIOCLINUX ioctl
         | attacks. Which doesn't matter on OpenBSD, because OpenBSD does
         | not have these features. But Linux does, so not ideal.
         | https://github.com/Duncaen/OpenDoas/issues/106
        
         | rnijveld wrote:
         | I'm on the team that is implementing sudo-rs, and we are
         | definitely aware of doas and other similar utilities. Doas does
         | definitely have its usages, especially with the 'just let me
         | run this as root' use case in mind. That said, there is also
         | something to say for the more extensive configurability of
         | sudo, and doas does sometimes have an execution model that
         | might be a little too simple. And having another alternative is
         | never a bad thing in my mind.
        
       | rurban wrote:
       | Memory safety would be good, but why then use a memory unsafe
       | language?
        
         | PeterWhittaker wrote:
         | Correct me if I am wrong, but isn't Rust unsafe only when
         | explicitly using unsafe? Provided this project does not do
         | that, it would be memory safe, no?
        
       | sc68cal wrote:
       | My concern is that while re-implementing sudo in rust would solve
       | bugs due to memory safety and off by one errors, it is a complex
       | piece of software where logic errors can create serious security
       | issues.
       | 
       | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-2280...
        
         | rnijveld wrote:
         | I'm one of the people working on this. While I do think that
         | the memory safety aspect is an important one, I think that one
         | thing where we can win even more is that Rust has a type system
         | that is much more robust than what C offers. If set up right,
         | we can prevent lots of these kinds of bugs right from the
         | start. We can also simplify things in lots of cases by removing
         | unnecessary details no longer relevant in a modern
         | implementation.
        
         | hannob wrote:
         | > it is a complex piece of software
         | 
         | That's the problem. It shouldn't be. I hope the sudo-rs variant
         | does better.
        
           | yjftsjthsd-h wrote:
           | Actually, there's a point: doas is already smaller and safer,
           | so it would probably be easier to port to a new language as
           | well as having less attack surface in the first place. Of
           | course, it's still necessary to work with sudo as well
           | because it genuinely supports a lot more features and some of
           | them are even useful, but if you want the low hanging
           | fruit...
        
           | ape4 wrote:
           | They should just replace /etc/sudoers.d with a Domain
           | Specific Language ;) /s
        
         | throwawaaarrgh wrote:
         | [flagged]
        
           | jcranmer wrote:
           | Rust protects against most memory safety vulnerabilities:
           | use-after-free, out-of-bounds accesses, returning dangling
           | pointers. Probably the memory safety vulnerability it's the
           | least protective against is using uninitialized memory. And
           | recall that memory safety vulnerabilities are the vast
           | majority of software vulnerabilities--somewhere in the 70+%
           | range.
           | 
           | But Rust doesn't _only_ touch memory safety, it also has some
           | measure of protection for other vulnerabilities. It 's
           | somewhat stricter on integer overflow vulnerabilities.
           | Newtypes can be used to provide protection against validation
           | vulnerabilities (e.g., SQL injection). Send and Sync traits
           | can provide some measure of protection against data races: it
           | takes a little bit of effort to use an object on a different
           | thread if it's not able to be used from multiple threads. You
           | don't hear as much about these protection efforts because,
           | quite frankly, memory safety is so important that it alone is
           | sufficient to drive many decisions.
        
           | woodruffw wrote:
           | "Free-after-use" is not a vulnerability class; it's "use-
           | after-free." And Rust's borrow checker provides temporal
           | memory safety; you could even say that it _primarily_ exists
           | to prevent temporal vulnerability classes like UAFs.
        
           | Rusky wrote:
           | This isn't how people seriously approach memory safety.
           | 
           | Memory safety is a critical _starting point_ , because
           | without it you can no longer trust the logic you wrote in
           | your program to behave in any particular bounded way. Memory
           | safety bugs undermine everything else.
        
           | IshKebab wrote:
           | Fortunately Rust also has a very good type system and strict
           | ownership system that greatly reduces the chance of logic
           | bugs too.
           | 
           | Imagine not using seatbelts because they don't help if
           | someone shoots you in the face.
        
         | steveklabnik wrote:
         | You are not wrong, but logic errors are a pervasive concept
         | that applies to all code bases. Logic errors in the existing
         | codebase, as you've demonstrated, can _also_ cause issues. The
         | pro-Rust argument here would be  "letting the compiler handle
         | memory safety for you frees up your attention to focus on those
         | logic errors even more."
         | 
         | Time will tell!
        
           | tptacek wrote:
           | That's not really responsive to the concern. The issue is
           | that we've already had decades of experience with the
           | existing sudo codebase looking for logic vulnerabilities.
           | And, in fact, that's what the overwhelming majority of sudo
           | vulnerabilities are; they're not generally memory safety
           | bugs. So rewriting in a new language to get rid of memory
           | safety vulnerabilities is not, in fact, an obviously good
           | tradeoff.
        
             | steveklabnik wrote:
             | I don't _directly_ disagree with what you 're saying here
             | either. All of these things need to be weighed against each
             | other. I am not familiar with sudo's codebase, and so I
             | can't speak to if I personally agree with Prossimo or you
             | here.
             | 
             | What I _will_ say is that I certainly agree that memory
             | safety _on its own_ would be a weaker justification for the
             | reasons you cite. But this analysis doesn 't take into
             | account the relative usefulness of various language
             | features for preventing logic errors. For example, I find
             | that enums really help catch edge cases that are easy to
             | forget about, causing bugs. Tagged unions are obviously a
             | thing in C codebases but aren't as easy to use nor
             | integrated into the language in useful ways, like
             | exhaustiveness checking. You're absolutely right that, at
             | the moment, the sudo codebase is more well understood, but
             | one could make the argument that C's various weaknesses in
             | areas like the typesystem means that as this codebase
             | matures, and becomes well known itself, logic errors become
             | more tractable.
             | 
             | One could _also_ make an argument that a new codebase is a
             | good idea, even disregarding the C vs Rust factors. For
             | example, they 're not going for "100% drop-in replacement
             | for sudo," they're going for "a drop in replacement for
             | common cases." Sudo has users who I assume would be upset
             | at removing features they rely on, whereas this project has
             | no userbase, and therefore, can do whatever they'd like.
             | Removing a bunch of code can also help reduce logic errors,
             | as it's impossible to have logic errors in code that
             | doesn't exist, obviously. Of course, this article focuses
             | on the memory safety aspects and not the others, maybe
             | that's a marketing mis-step. Then again, what's important
             | here is the engineering, not the marketing.
             | 
             | So yeah. It's not obviously a slam dunk either way, it
             | really depends on how one personally weighs all sorts of
             | factors. As I said above, time will tell.
        
               | tptacek wrote:
               | While I appreciate Rust's correctness features and dearly
               | miss `match` statements, as a software security
               | professional with (I think I can say) a lot of experience
               | looking for the kinds of vulnerabilities we're talking
               | about here: I do not buy this theory of Rust's security
               | advantage, like, at all. People have been saying things
               | like this about strongly typed languages of varying sorts
               | (Haskell was once a favorite) for over a decade, and it
               | hasn't panned out. I think you'll find, if you look at
               | the last (say) 10 meaningful sudo vulnerabilities, that
               | there isn't a clear story about how enums would have
               | steered you away from the problem.
               | 
               | Certainly, if there's an appetite for a reduced-fat
               | version of sudo that caters to the 80-90% use case, I'm
               | all for a Go, Rust, or whatever version of that thing.
               | But then, C programmers were making the same argument 15
               | years ago, and nobody was able to sell the reduced-fat
               | sudo (or, for the matter, the reduced-fat ssh, which
               | we're all still dealing with). If it works out, great.
               | 
               | If it ends up gradually becoming a 1:1 equivalent to
               | sudo, wartfeatures, and all, that's less great.
        
               | steveklabnik wrote:
               | > I do not buy this theory of Rust's security advantage,
               | like, at all.
               | 
               | Don't worry, you've made that overwhelmingly clear.
               | 
               | (I also know that I am _not_ a security engineer, and
               | respect your overall expertise here tremendously.)
               | 
               | > that there isn't a clear story about how enums would
               | have steered you away from the problem.
               | 
               | Yeah man, I picked an example solely based on something
               | that's done in both languages, but differently, because I
               | thought it would be illustrative of the general idea. I
               | am not claiming that enums will magically fix CVEs in
               | sudo, that would be ridiculous. I'm saying "if we're
               | saying memory safety is irrelevant, and logic errors are
               | what matters, you should compare the tools that let you
               | model your problem." Maybe Rust's features are truly
               | irrelevant here, but as you say, I dearly miss match
               | statements when I'm working in a language without them,
               | so I suspect they do help in the general case of this
               | argument, even if they don't for this one specific
               | codebase.
               | 
               | > People have been saying things like this about strongly
               | typed languages of varying sorts (Haskell was once a
               | favorite) for over a decade, and it hasn't panned out.
               | 
               | I actually agree with this, but I don't think that the
               | typesystem aspects are the cause here. Programming
               | language adoption is weird, complex, organic, and really
               | hard to see the future of. I think it's taken decades to
               | "productize" more advanced type systems, and it's really
               | only relatively recently (like, I'm not gonna try and pin
               | down an exact moment, but like, let's say "the last ten
               | years" but I suspect even that may not be far enough
               | back) that we've seen larger adoption of this stuff. I
               | don't even personally consider static typing to be
               | strictly better than dynamic typing!
               | 
               | Oh and, if we're gonna nitpick examples, Haskell was
               | never going to be a language to do that, one that
               | expressly doesn't try to pursue popularity and broad
               | usage. Those people (and I remember them too) were wrong
               | then, and wrong now. But that's not (only) the fault of
               | the type system.
               | 
               | That said, while I agree with the description of the
               | history, I don't see how the trend points to this being
               | impossible, but rather than we're now living in the time
               | of truly being able to answer the question one way or the
               | other. And the only way you do it is by putting in the
               | work.
        
               | tptacek wrote:
               | I'm aware that there is more to Rust than enums, and that
               | you were using that as an example of a correctness
               | feature that is part of a gestalt of correctness
               | features. My point is that people have been arguing that
               | more expressive languages with stronger type systems will
               | be better able to model problems and thus avoid logic
               | vulnerabilities, and that hasn't panned out at all.
               | 
               | Since I don't think there's any evidence to support your
               | point that's a Google query away from you, I guess
               | something you could present that would weaken my argument
               | is an example of a recent meaningful sudo vulnerability
               | where idiomatic Rust, written in the manner that a
               | typical Rust programmer would use to solve the relevant
               | problem, would have foreclosed on that vulnerability.
               | Obviously: we pre-agree about memory corruption
               | vulnerabilities here.
        
               | steveklabnik wrote:
               | To be honest, on these issues, I'm not invested in
               | winning an argument about it. I can see good arguments
               | for why this would be beneficial, and I think they make
               | sense. But I also know there's good arguments for why
               | this would _not_ be, and I can think they make sense too.
               | I want to see both sides represented here, because I
               | think it 's interesting, and seeing both sides is good.
               | That's good enough for me.
               | 
               | If in five years (or whatever) no distros use this new
               | tool, it's had zero impact on things, I'll go "damn,
               | tptacek is right," and that's an outcome I am totally
               | fine with.
        
         | phkahler wrote:
         | >> it is a complex piece of software where logic errors can
         | create serious security issues.
         | 
         | I know many unix commands have a lot of capabilities I never
         | use, sudo? Not much logic other than "run this as root if user
         | has permission" is there? OTOH I never thought about how a cli
         | app can escalate privilige without already having it....
        
           | wongarsu wrote:
           | The escalating privileges part is easy: the file
           | /usr/bin/sudo is owned by root and has the setuid flag set,
           | meaning it gets executed with the permissions of the file
           | owner instead of those of the caller.
           | 
           | The complexity has more to do with the fact that it has 28
           | command line flags, plus a fairly complex config file to
           | configure who is allowed to do what, impersonating which
           | user, and whether they need a password to do so. All of that
           | dealing with security critical stuff like what exactly should
           | carry over and what should be reset (all configurable ofc).
           | 
           | su is very simple by comparison (and you can do `sudo -s`
           | anyways to get the same result as calling su without
           | parameters).
        
       | PeterWhittaker wrote:
       | Good plan. Reimplementing in Rust using a carefully planned
       | milestone-based approach should result in feature parity with
       | fewer security vulnerabilities.
        
         | temporarara wrote:
         | There is zero guarantee about that. The result could have fewer
         | vulnerabilities, but it's not an easy thing to do. I'd say
         | there definitely are some vulnerabilities left in sudo code,
         | but over the years all the obvious bugs have already been
         | eliminated and rewriting it in a new language can reintroduce a
         | lot of those. Now, if the people doing this are competent and
         | have time and money in their hands, rust enables doing some
         | things better and basically lets you forget about basic and
         | advanced memory bugs, so the final product may well be a good
         | (better) one.
         | 
         | But just using another language to reimplement something in
         | order to make it "safer" in some abstract manner does not
         | guarantee anything. Good coding practices combined with
         | "elementary" and highly-portable language like C can also
         | result in victory that can't really be challenged. We'll see.
        
       ___________________________________________________________________
       (page generated 2023-04-26 23:03 UTC)