[HN Gopher] The first stable release of a memory safe sudo imple...
___________________________________________________________________
The first stable release of a memory safe sudo implementation
Author : goranmoomin
Score : 293 points
Date : 2023-11-06 10:58 UTC (10 hours ago)
(HTM) web link (www.memorysafety.org)
(TXT) w3m dump (www.memorysafety.org)
| jackmott wrote:
| I remember a couple of years ago a root exploit in Sudo that was
| the result of failing to check for a sentinel value, thinking
| "that is a bug that wouldn't happen in Rust, even though it isn't
| related to memory safety!"
|
| Rust enums are sum types, and imho are one of the few
| unambiguously good language feature ideas. I miss them any time I
| use a language where they are not built in. F# is another nice
| language where they are first class and where I first got
| familiar with them
| Karellen wrote:
| > Rust enums are sum types,
|
| I wouldn't mind so much if they just called them "sum types" or
| "tagged unions", or even some other new name. Reusing the
| existing name "enum" from other languages, but differently from
| the way _all_ those other languages have used it for 45 gorram
| years, is freaking maddening.
| cyber_kinetist wrote:
| Swift and Scala also uses the enum keyword to define sum
| types, and their history goes earlier than Rust, so now you
| have multiple languages to yell at!
| n_plus_1_acc wrote:
| That's inherited from OCaml I think.
|
| https://www.ocamlwiki.com/wiki/Enum
| ode wrote:
| Nobody in the OCaml community commonly refers to them as
| Enum's today or any time recently (maybe they were at the
| time Rust was created though? IDK).
|
| They're usually called 'variants'.
| debugnik wrote:
| I don't think so, OCaml consistently calls them "variant
| types". I don't know who wrote that page, but that wiki
| didn't even exist before September and it isn't endorsed by
| ocaml.org, so I suggest you don't consider it
| authoritative.
| garblegarble wrote:
| I'm assuming this project's aim is to replace sudo, in which case
| hand-waving away "Leaving out less commonly used features" is a
| bit worrying. What are these features? How uncommonly are they
| used? In which way will it fail if a configuration uses those
| features?
|
| Edit: Looks like their github readme outlines _some_ of these
| limitations, https://github.com/memorysafety/sudo-rs#differences-
| from-ori...
| fermuch wrote:
| It seems like those changes are noted here:
| https://github.com/memorysafety/sudo-rs#differences-from-ori...
| garblegarble wrote:
| The text seems to imply that's not a list of features not
| implemented, it's a list of features not implemented that
| don't output a clear error
| dtx1 wrote:
| Having so many different feeatures in one of the most basic
| unix tools is much more of a red flag.
| garblegarble wrote:
| For sure! But that mistake has already been made, and has
| been in the wild for years, so removing those features (and
| proposing yourself as a replacement for the original) is now
| a breaking change
| mprovost wrote:
| OpenBSD replaced sudo with doas (with a vastly reduced
| feature set) several years ago, and without breaking
| everything. Sure there are use cases where you absolutely
| need some feature of sudo, but you can always install it.
| garblegarble wrote:
| That seems like the Right Way to do it...
|
| As annoying as it is to have to update every sudo
| reference -> doas, it forces you to think about
| everywhere you're using it, rather than waiting to see
| what breaks and then trying to fix it.
| codetrotter wrote:
| > As annoying as it is to have to update every sudo
| reference -> doas, it forces you to think about
| everywhere you're using it, rather than waiting to see
| what breaks and then trying to fix it.
|
| In my scripts I never call sudo or doas. Instead, if the
| script needs to do something as root, I write the whole
| script so that it expects to itself be run as root.
|
| And then when I want to run my script, I run it as root
| doas ./somescript.zsh
| PrimeMcFly wrote:
| That's a much worse approach from a security pov.
| codetrotter wrote:
| No. That's a blanket statement on your part that you
| cannot make because you don't know what my scripts look
| like, or what commands they call.
| xyzzy_plugh wrote:
| No, it's never better to run whole scripts as root when
| root is only required for part of it. Unless every
| expression in your script requires root, the blanket
| statement holds.
|
| In my experience, and in my own scripts, it is better to
| explicitly check if you are being run as root, advise
| against it and exit (with maybe some break glass flags)
| and invoke sudo when escalated privileges are required.
| PrimeMcFly wrote:
| Yes, it's a blanket statement, better it's an absolute
| statement because it's absolutely true.
|
| You're taking a shortcut due to convenience and it's bad
| security practice.
|
| It's that simple.
| josefx wrote:
| I just constantly run as root since there is always a
| chance that I might need root permissions for something.
| /s
| samus wrote:
| OpenBSD is much more open (pun not intended!) about
| breaking parts of userspace to push through beneficial
| changes. After all, they control their own userspace and
| can fix up most things before they even become an issue.
| Linux is only the kernel.
| cpach wrote:
| In that case, shouldn't Linux distros be even _more_ free
| to break things...? In theory they can bundle any
| userland tools they want.
|
| AFAIK sudo isn't really tightly coupled to the kernel
| itself.
| samus wrote:
| They could, but their users really won't like that. They
| have their workflows that they got used to. In practice
| it's gonna be GNU Coreutils and Glibc and the other usual
| suspects. If they bundle something more exotic, it better
| be for a very good reason. For example musl on Alpine or
| what Android does.
| Fnoord wrote:
| OpenBSD uses BSD_Auth instead of PAM. So you cannot use
| your YubiKey with doas via PAM on the Linux ports. At
| least not in the same way, as they do not support caching
| it seems.
| xorcist wrote:
| > without breaking everything
|
| Except all exiting use of sudo ...
|
| It's such an entrenched tool that I'm sure there a
| compatible replacement could be useful.
|
| Personally I would appreciate someone to take on the mess
| that is PAM. It was much too complex from the start and
| it hasn't become better over the years.
| PrimeMcFly wrote:
| OpenBSD is mainly used by hobbyists and not sysadmins,
| which is why there are not complaints about the missing
| functionality.
| kristjank wrote:
| OpenBSD is mainly used where other Unices can be used,
| and provides widely used software like OpenSSH, OpenBGPD
| and OpenSMTPD. To say that it's a hobby project strikes
| me as very ignorant. That said, it is not very easy to
| convince the developers that a function is missing
| because it's a pretty opinionated project, and they might
| not share the user's definition of needed functionality.
| Thankfully, they're nowhere near ebassi levels of
| functionality deletion disorder.
| PrimeMcFly wrote:
| > OpenBSD is mainly used where other Unices can be used,
|
| That's a pretty general statement, and I'd say to that
| not really. It's very much a hobbyist OS. A few people
| use it at home as firewalls, a few small businesses
| maybe, but it's mostly hobbyists and developers.
|
| > To say that it's a hobby project strikes me as very
| ignorant.
|
| I mean, I've been familiar with the project for over 20
| years, so I don't think I'm ignorant at all. The
| developers primarily make the OS for themselves and
| people with the same ideas and priorities.
|
| > That said, it is not very easy to convince the
| developers that a function is missing because it's a
| pretty opinionated project, and they might not share the
| user's definition of needed functionality.
|
| Right, the devs prioritize their own needs, and can do so
| because it's a hobbyist OS.
| speed_spread wrote:
| Priorities. If a fundamental security tool's design limits
| it's trustworthiness, it greatly reduces it's usefulness
| and "breaking" it's interface is thus warranted.
| SonOfLilit wrote:
| I've lived through the transition to systemd. I'm sure
| sysadmins will be able to manage this one. And I'm sure great
| technical documentation exists, this was a PR release, not
| where I'd look for a list of missing features.
| jacquesm wrote:
| I still run into trouble on a fairly regular basis on account
| of systemd. Especially the log files continue to cause all
| kinds of issues.
| happymellon wrote:
| What issues do you run into with the log files?
|
| I have plenty of ideological problems with the design of
| the logs, but not actually ran into problems in the real
| world.
| djbusby wrote:
| I'm still mad I can't just `tail -f`
| eptcyka wrote:
| journalctl -f?
| abofh wrote:
| Have you tried reading them? They're often helpful
| gary_0 wrote:
| One feature they didn't mention they left out was the ability
| to run `make me a sandwich` (https://github.com/sudo-
| project/sudo/blob/main/Makefile.in#L...)
| queuebert wrote:
| Is that a Slashdot reference?
| tecleandor wrote:
| Old XKCD joke (maybe coming from an older joke)...
|
| https://xkcd.com/149/
| gary_0 wrote:
| That XKCD joke was all over the Internet in 2006. Now get
| off my lawn.
| tecleandor wrote:
| Well, that comic is from 2006 so not that far away :P ;)
| kelnos wrote:
| Huh, it took 6 years for the joke to get added:
| https://github.com/sudo-
| project/sudo/commit/c1d6e86d67aa60d7...
| hpb42 wrote:
| One of those left out features is `sudoedit` or `sudo -e`. I
| use this a lot when editing files in /etc or any file that my
| user does not have permissions. The flag first copies the file
| to a temporary location with permissions for my user to edit,
| then opens my text editor (defined via $SUDO_EDITOR env var) as
| _my user_, without any sudo permissions. After I close the
| editor, the file is copied back with the original permissions
| only if there were any changes.
|
| The cool thing is running the editor via my user, which loads
| my user's configuration/plugins, instead of the root user's.
| tambourine_man wrote:
| In Vim:
|
| :w !sudo tee %
|
| Which I map to :w!!
|
| Of course, if you're not using Vim, you're doing it wrong :)
| phanimahesh wrote:
| It is a little less useful if the file is not readable by
| your user, and once you authenticate anything within your
| vim can also silently run other sudo commands since on most
| distros sudo remembers the autnentication for a while.
|
| Now that I think of it, not sure how sudoedit behaves wrt
| this cached auth.
| KMnO4 wrote:
| I think you can use the sudo -k flag to clear the cached
| auth
| Zardoz84 wrote:
| I usully use "sudo -E EDITOR_OF_MY_CHOICE"
| liftm wrote:
| Many editors can execute shell commands, so this isn't the
| same at all.
| Denvercoder9 wrote:
| That makes your editor run as root, which is a bad idea for
| many reasons (aside from security, any mistake now has the
| potential mess with the whole system).
| josephg wrote:
| This would be a great use case for a capability security
| model. Essentially what you really want is the sudo command
| to acquire a temporary capability token to edit that specific
| file. Then run your editor and pass it the capability. (And
| revoke the capability when the editor process closes).
|
| It's a pity this isn't more straight forward to implement on
| Linux.
| quotemstr wrote:
| > Essentially what you really want is the sudo command to
| acquire a temporary capability token to edit that specific
| file.
|
| This should be doable with an XDG portal model, right?
| yakubin wrote:
| It's doable by opening the file in a privileged process
| (sudo) and passing the file descriptor to a non-
| privileged process.
|
| Maybe one could make a sudoedit that opens a file in sudo
| process and then spawns a non-privileged editor process
| which inherits the file descriptor and is given the
| /dev/fd/ path on the command line, so it stays none the
| wiser about the whole process.
| vlovich123 wrote:
| Sounds like a bit of recipe for accidentally handing
| access to an unintended privileged fd through inheritance
| (ignoring the /dev/fd one) such that a compromised
| unprivileged SUDO_EDITOR value gives you sudo access.
| Maybe not likely, but I'd really be hesitant about any
| feature that relies on implicit fd inheritance...
| yakubin wrote:
| Close all other fds between fork and exec then (you can
| look at the code of base::LaunchProcess in Chromium for
| an example). It's a minuscule amount of code to audit
| compared to XDG portals. And it's backwards-compatible
| with decades of unix programs.
|
| For a more complicated solution: spawn a zygote process
| early with a unix socket which you'll use to send the fd
| later. Zygote at start drops provileges. When it receives
| the fd, it closes the socket and execs the editor.
| vlovich123 wrote:
| I'm not saying it's not possible to do correctly. But do
| you not agree that the first is hard to correctly (can
| overlook an fd) while the latter is a lot of complexity?
|
| There is the CLOEXEC flag which is the intended way to
| manage this but it's not the default and you have to be
| diligent about setting it which again carries its own set
| of challenges.
|
| What you'd really want is CLOEXEC implicitly on all fds
| and having to explicitly opt in for fd inheritance.
| yakubin wrote:
| That would be ideal, but we'd need a new syscall for
| that.
| sophacles wrote:
| Rust stdlib opens all fds with CLOEXEC set. You have to
| explicitly disable it when you want the child to inhert
| the fd.
| kelnos wrote:
| Another option could be to open a UNIX socket in the
| privileged sudo process, spawn an unprivileged child
| process 'shim' that connects to that socket, and then the
| sudo process can pass the file descriptor over the
| socket. Since the child shim is 'clean', it should have
| nothing more than stdin/out/err open, plus now this
| passed FD. Then the shim can spawn the target program and
| allow it to inherit just the passed FD.
|
| I think the larger issue is that I doubt many (if any?)
| editors allow opening a file via an inherited file
| descriptor! I guess some will read stdin (the shim could
| close stdin and then dup2() it into its place), but then
| there's no way to save the file back when finished.
| arijun wrote:
| Are there no overwrite/seek bugs in Unix that could be
| exploited in that case? It seems to me like only using sudo
| for a cp command would reduce the attack surface.
| lucideer wrote:
| > _One of those left out features_
|
| They indicate that many omittted features are by design, but
| this particular one is implied to be planned:
|
| > _Some functionality is not yet supported; in particular
| sudoedit_
| aumerle wrote:
| So now any program that's running as your user, even your
| browser, can edit any file you edit with sudo. It just has to
| watch for your editor to quit and win a race with sudo to
| modify the file before sudo reads it.
| quotemstr wrote:
| There's a gulf between being 99% compatible with something and
| being a 100% drop-in. If the author of program B wants to
| replace A, he should go the extra mile and implement every
| feature of A so as to erase technical excuses for stasis. B
| needs to put aside his ego, swallow his pride, and implement
| all the features of A, even the ones her personally dislikes,
| because the effect of doing otherwise will be that B doesn't
| replace A. We have to work backwards from out desired outcomes.
| marcus0x62 wrote:
| Perhaps, but if the goal is security of a critical tool,
| losing some attack surface (features) if they aren't widely
| used is a win. Other projects, like ntpsec[0] have taken this
| approach with good results. Although, I agree with another
| commenter in this thread[1] that this effort would have been
| better directed at something with an inherently small attack
| surface like doas.
|
| 0 - https://www.ntpsec.org/accomplishments.html
|
| 1 - https://news.ycombinator.com/item?id=38161016#38162736
| godshatter wrote:
| The features they are leaving out were presumably added for
| a reason. If someone is on a system that is using sudo-rs
| as a drop-in replacement (not under their control) and they
| need to use one of those less widely-used features, how
| secure is the work-around they have to use instead? I'm
| hoping this factored in to their analysis.
|
| Sometimes reimplementing something and leaving out lesser-
| used features to "reduce the attack surface" can sound an
| awful lot like "let them pound sand".
| nucleardog wrote:
| Did you know you can set up an OpenVPN tunnel with no
| encryption or authentication?
|
| I'm sure for someone out there that's a make-or-break
| feature, but for the vast majority trying to use OpenVPN
| it's a massive, insecure footgun. (Hell, how many bugs
| have protocol negotiation led to in OpenVPN/SSL/etc?)
|
| Compare that to Wireguard that just says... it's
| encrypted. Full stop. Carry on.
|
| A lot of this tooling and technology was developed in a
| different era with different priorities. Security, and
| especially network security, was not such a huge focus
| 30-40 years ago. Priorities have shifted. The operating
| environment is a lot more homogeneous (when's the last
| time you dealt with a layer 2 protocol besides
| ethernet?), while the risk of poor security has grown
| immensely.
|
| It's absolutely fair to critically evaluate these
| features and determine which can be removed to simplify
| and improve the products for the vast majority of users.
| If a small fraction of users stay on sudo, but the
| majority are able to move to a more secure option...
| that's a win. This is exactly what Wireguard provides
| versus OpenVPN.
| marcus0x62 wrote:
| Sure, and those people are free to continue to use the
| C-based implementation of sudo, implement the features
| themselves and submit patches to the maintainers of the
| rust sudo implementation, etc. But, the idea that a
| feature, once implemented, is sacrosanct and can never be
| deprecated is insane, especially for a piece of critical
| security infrastructure.
| infamouscow wrote:
| Having disdain for real-world business requirements is
| probably why Rust sees so little use in the real world.
| db48x wrote:
| It's actually mostly just a matter of time and money. They
| implemented the most commonly-used features first, because
| those are the most important ones. The majority of people
| could probably swap sudo-rs in for their existing sudo
| implementation today with nothing lost. Others will need one
| of those "enterprise features" and so they should either wait
| or pitch in.
| sigio wrote:
| One of the features I use in some (larger) environments, which
| isn't on the roadmap or implemented is LDAP support in sudo-rs.
| Using the regular sudo, this allows you to manage the sudo
| permissions for the entire network from the central LDAP
| configuration, and even make rules that are
| time/host/user/command limited in a central location with no
| chance of simple syntax-errors wiping out your entire
| configuration, just that single rule is being ignored in this
| case.
| lynx23 wrote:
| doas is 43184 bytes, and does everything I need. That sudo
| exploit was a wakeup call. If you haven't moved away from it yet,
| give opendoas (Debian package) a try.
| hannob wrote:
| Do you use doas on Linux? It is not protected against tty
| pushback attack: https://github.com/Duncaen/OpenDoas/issues/106
|
| That's a pretty severe unsolved security issue.
| zokier wrote:
| It's solved; TIOCSTI is disabled by default since Linux 6.2 h
| ttps://git.kernel.org/pub/scm/linux/kernel/git/torvalds/lin..
| .
| hannob wrote:
| The thing you linked says "default y" to "Allow legacy
| TIOCSTI usage". So yeah, you can disable it, no, it's not
| the default.
|
| There's also a related issue with TIOCLINUX and the paste
| functionality. (That will however be solved in an upcoming
| kernel version. I wrote the patch for it :-)
| fdsfsdfdsffgg wrote:
| > Apache-2.0+MIT vs GPL-2.0
|
| So, you may get a memory-safe su/sudo-rs, but those who
| distribute it in a binary form won't be obliged to show you the
| source code it was built from (potentially including some
| modifications).
| wiz21c wrote:
| Moving away from the GPL is a very bad idea for such critical
| component. Exactly for the reason you give.
|
| (this post is just here to insist on the issue)
| mhh__ wrote:
| In general a lot of "[GNU tool] but in rust" projects do seem
| to come very close to violating the GPL, especially in
| spirit.
| tsimionescu wrote:
| In what sense? It is completely in the spirit of the GPL to
| reimplement a GPL tool from scratch with the same behavior
| and a different license. After all, that's how the free
| Unixes came about (though admittedly those were BSD
| licensed typically).
| zorked wrote:
| Kinda? Historically there were indeed concerns about
| reimplementation and copyright. One of the ways that the
| GNU Project tried to fight claims was to reimplement the
| tools using dynamically-allocated memory (instead of
| Unix's traditional fixed-size buffers) to make sure the
| implementation was sufficiently different. Other ways
| were making the implementation Posixly correct, adding
| internationalization or trying to pick different
| approaches (like using more modern algorithms for
| sorting). The GNU tools were better, not just direct
| ports, and that's why it was common to install them in
| systems like Solaris or HP-UX.
| iudqnolq wrote:
| Arguably writing in Rust will force a similar magnitude
| difference to those examples. For example, you'll
| probably replace that modern sorting algorithm with a
| call to .sort
| mustache_kimono wrote:
| > Kinda? Historically there were indeed concerns about
| reimplementation and copyright.
|
| Free software projects should welcome multiple
| implementations and interoperability, because these are
| the mother's milk of free software. It's frankly
| incoherent, given values of free software, that a
| reimplementation of, for example, Unix coreutils (GNU)
| would find fault with a reimplementation of itself
| (uutils).
|
| Notwithstanding how philosophically incoherent it is, a
| desire, now that Linux and free software have some market
| power, to be a bully back, to grasp for monopoly power,
| to play AT&T, is really distasteful. What's exciting
| about free software is not the artifact, Linux or
| coreutils or sudo, but that anyone can create new and
| interesting alternatives. That users get to make choices
| about which implementation to use. The existence of
| FreeBSD does not make Linux worse. It makes it better!
| The "solution" to an MIT licensed coreutils is a GNU
| licensed fork which is 10x better. Instead, we get
| complaints which amount to a kind of free software
| entitlement, an endless pissing and moaning about how
| other people won't do new things your way.
|
| This is a major problem in the way that most normies view
| the GNU and the GPL. In the past, I may not have chosen
| the GPL for my own projects, but I'd be pleased to
| contribute to a GPL project. Now, I'd have a hard
| contributing to a GPL project, because of just how toxic
| this attitude (no other license matters but ours) is.
| oynqr wrote:
| Pretty sure you'd have to clean room the whole thing.
| Which these Rust implementation might not have. This is
| not legal advice.
| mhh__ wrote:
| I can't remember enough to name names but one obviously
| didn't to the point that it mentioned what the GNU code
| does in comments.
| mustache_kimono wrote:
| I'm really not certain this is enough to be a copyright
| problem.
|
| For instance, GNU and POSIX both publish their specs for
| the coreutils. If a coder were to take a look at the
| actual GNU code (which BTW is _published_ for everyone to
| see), copyright law has a well trodden distinction
| between the idea and the expression -- that is, ideas are
| not copyrightable. If the "idea" simply amounts to what
| would be a more a detailed specification, I'm not sure
| there is a problem, like ... GNU uses this kernel
| facility for X. The problem would be vast amounts of
| "expression", especially "creative expression", directly
| copied and reimplemented in Rust. If the code is meat and
| potatoes, not 10xer galaxy brain fare ("I wrote a custom
| allocator which is suspiciously like the custom allocator
| implemented by GNU"), there shouldn't be an issue.
|
| Think about what copyright to a play, or a novel, or a
| screenplay is. Now imagine a comment in the text/source:
| "This is how Toni Morrison did her characterizations in
| Beloved". This obviously isn't a copyright violation,
| unless you're copying the actual expression or a
| translation of the actual expression found in Beloved.
| nindalf wrote:
| But it wasn't GPL to begin with -
| https://www.sudo.ws/about/license/
| Nullabillity wrote:
| Sudo is ISC-ish[0] (very permissive), not GPL. Su does indeed
| seem to be GPL though.
|
| [0]: https://www.sudo.ws/about/license/
| fdsfsdfdsffgg wrote:
| There are su and runuser in util-linux (GPL-2.0) [1].
|
| [1]: https://github.com/util-linux/util-
| linux/tree/master/login-u...
| ksherlock wrote:
| The GNU ~~coreutils~~ util-linux version of su would be GPL
| but su is from Unix V1 (1971) so there are AT&T
| implementations, BSD implementiations, etc.
| zigzag312 wrote:
| Is that really bad? You are free to not use such distributions.
|
| Regarding security, malicious actor could show you a different
| source code from what he distributes in a binary form. GPL or
| no GPL.
| EspressoGPT wrote:
| > Is that really bad? You are free to not use such
| distributions.
|
| It's not really bad but it kinda defeats the purpose.
| pbmonster wrote:
| > Regarding security, malicious actor could show you a
| different source code from what he distributes in a binary
| form.
|
| That's why hashes are published by distributors and checked
| by package managers, right?
| zigzag312 wrote:
| That only checks that binaries are the same as what is
| published by distributors.
|
| It doesn't help against a malicious distributor, unless
| package managers also do a deterministic build themselves
| and verify that checksum from self-build binary matches the
| checksum published by a distributor.
| alwayslikethis wrote:
| I wanted to write this comment too, as I have a serious concern
| that the effort to displace GPL tools with Rust rewrites in
| MIT/Apache will one day lead to a proprietary Linux, but the
| original sudo is not in GPL. It's in an ISC/MIT style license
| [1].
|
| 1. https://www.sudo.ws/about/license/
| fdsfsdfdsffgg wrote:
| There are su and runuser in util-linux (GPL-2.0) [1].
|
| [1]: https://github.com/util-linux/util-
| linux/tree/master/login-u...
| pjmlp wrote:
| Look at Android, the only GPL thing left is exactly the Linux
| kernel, and it hasn't been yet replaced by Zirkon because
| reasons.
|
| Look at the FOSS UNIX like RTOS, none of them is GPL.
| pjmlp wrote:
| For better or worse the use of GPL is going away, even the
| future of Linux kernel is not guaranteed.
|
| In the realm of IoT FOSS UNIX like operating systems, all the
| contendants are using a mix of Apache, MIT and BSD licenses,
| including the ZephyrOS sponsored by the Linux Foundation.
|
| When the GPL generation is gone from the face of the Earth, it
| won't last long that UNIX-like OSes get another steward
| alternative to the Linux kernel, with a more appealing license
| to big corps.
| NegativeK wrote:
| How would they be able to drop the GPL from the Linux kernel?
| pjmlp wrote:
| By replacing it with something else, duh.
|
| Linux kernel isn't the first nor the last UNIX clone.
| badrabbit wrote:
| IIRC, all the recent sudo vulns are logic errors, not memory
| safety. I mean, rewrite away but let's not pretend that there
| couldn't be some new bug introduced due to a misunderstanding of
| how something works or just a plain old mistake.
| alpaca128 wrote:
| In the same way a new memory bug could be introduced to the
| original sudo. Shrinking the attack surface with static checks
| seems like a better deal in the long run.
| latexr wrote:
| > let's not pretend that there couldn't be some new bug
| introduced due to a misunderstanding of how something works or
| just a plain old mistake.
|
| Is anyone doing that? I see a lot of claims of memory safety,
| but as far as I can see the project isn't saying other types of
| bugs are for sure eliminated.
| badrabbit wrote:
| That's fair and i support that but it does not address
| historical bug patterns that may be a design issue.
| fanf2 wrote:
| 2021: https://nvd.nist.gov/vuln/detail/CVE-2021-3156
|
| 2019: https://nvd.nist.gov/vuln/detail/CVE-2019-18634
| slacka wrote:
| Would be interesting to see a a Debian derivative that combines
| this with the Rust Implementation Of GNU Coreutils.[1] Could be a
| big win for memory safety and performance.
|
| [1] https://github.com/uutils/coreutils
| guerrilla wrote:
| I wonder how we are from a Rust UNIX userland. At least we
| wouldn't have to implement a C compiler!
| yjftsjthsd-h wrote:
| A Linux distro is going to need to see compiler to self-host
| regardless of the user land. If you can live without Linux,
| there's redox ( https://redox-os.org/ )
| guerrilla wrote:
| Well, I guess if the build system uses that distro or if
| it's a sourve distro.
| nonameiguess wrote:
| I looked into this a few years back when I was making my own
| toy Linux distro, and this is the list of packages provided
| by a typical GNU system that meet POSIX requirements for a
| userspace:
|
| * `bash`
|
| * `bc`
|
| * `binutils`
|
| * `bison`
|
| * `Coreutils`
|
| * `Diffutils`
|
| * `file`
|
| * `Findutils`
|
| * `flex`
|
| * `gawk`
|
| * `glibc`
|
| * `grep`
|
| * `tar`
|
| * `gzip`
|
| * `M4`
|
| * `make`
|
| * `man-db`
|
| * `man-pages`
|
| * `procps-ng`
|
| * `psmisc`
|
| * `sed`
|
| That's a reasonable start, but you also need, minimally,
| something to replace `pciutils`, `IPRoute2`, a bootloader,
| and an init system. For a close to expected experience, add
| in `TexInfo`, `XZ`, `ZStd`, and `bzip2`, plus `shadow` if you
| don't want passwords stored in plaintext.
|
| POSIX doesn't dictate an editor, but you probably want
| something that can run in a terminal. Usually `cURL` and
| either `openssl` or `GnuTLS`, plus `bind-utils`, `ldns`, or
| something equivalent are there for actually using the
| network, something to replicate `gpg` functionality if you're
| going to install signed packages, and of course the package
| manager itself. Cargo is fine for Rust app developers, but
| can't replace an installer of system packages. You likely
| need an `ssh` implementation to replace `OpenSSH`.
|
| I'm sure there's more I'm missing, but this is pretty close
| to what you'd get in a minimal server image.
|
| If you're looking to fully get rid of C and not need a C
| compiler, though, Linux itself is a hurdle. You don't
| necessarily need a kernel quite as fully-featured, but you
| need something that at least implements the POSIX system
| calls. Just about every Linux distro I'm aware of seems to
| also provide Python and Perl these days as a whole lot of
| system utilities and build scripts use them. Presumably,
| rewriting all of Perl and Python in Rust is not feasible, so
| you either need some other interpreted scripting language
| good for system scripting that is written in Rust, or somehow
| make your shell a superset of POSIX but also much closer to a
| real programming language.
|
| Don't underestimate the lift of replacing `libc`, either.
| It's not just the C standard library and interface to system
| calls. It also provides the linking loader that makes it
| possible to even run other programs, all of the locales and
| time zones, the system's name server, profiler, memory
| dumper. A whole lot of stuff.
| mprovost wrote:
| > POSIX doesn't dictate an editor
|
| ed is the standard text editor!
| fanf2 wrote:
| vi is also a standard editor
|
| https://pubs.opengroup.org/onlinepubs/9699919799/utilitie
| s/e...
|
| https://pubs.opengroup.org/onlinepubs/9699919799/utilitie
| s/v...
| coggs wrote:
| As one of the original creators of sudo
| (https://en.wikipedia.org/wiki/Sudo) I've witnessed it getting
| nearly totally rewritten and then incrementally bug-fixed over
| the last 43 years. It must take the prize for the UNIX command
| most highly-scrutinized for security flaws. Flaws which have been
| identified and fixed.
|
| Thousands of developers and security experts have gone over it.
| So part of me wonders - how is it possible for a single dev team
| to totally reimplement it without unknowingly introducing at
| least a bug or two? Is there something to this Rust language
| which magically eliminates all chances of any bug being
| introduced?
| narinxas wrote:
| > Is there something to this Rust language which magically
| eliminates all chances of any bug being introduced?
|
| apperently, yes... and its the type system, but granted
|
| it's only 'memory safety' bugs... the kind of error that C
| languages are really suceptible to.
| noahjk wrote:
| On the surface, sudo seems fairly straightforward, so it's
| interesting to hear how much work has gone into it! Do you have
| any interesting facts or anecdotes you'd care to share?
| nolok wrote:
| The key is in "on the surface". While the common usage of
| sudo is fairly straightforward, you me and most people use
| like 5% of it. The trick is in all the side shows.
| yesimahuman wrote:
| Makes you wonder then why it does so much, if those rarely
| used features increase the surface area of possible
| exploits? This is just a question I've had about *nix
| utilities in general, since sudo is hardly the only tool
| with obscure flags and features
| yjftsjthsd-h wrote:
| Because the long tail of features is useful to someone.
| Mind, I like doas for this reason, but having the more
| feature rich option available makes sense.
| __turbobrew__ wrote:
| This is part of what the openbsd 'doas' was trying to
| solve. They drastically reduced the functionality to
| reduce the attack surface.
| coggs wrote:
| Hackaday interviewed me about the origin story - https://www.
| youtube.com/watch?v=LaAwl3HN5ds&ab_channel=HACKA...
| ralgozino wrote:
| great story! also, TIL that I've been pronouncing `sudo`
| wrong, I was 100% sure that it was supposed to be like
| pseudo, but I guess that is a myth :)
|
| It's so great to be able to listen and learn from the
| people that invented these important building blocks
| themselves, I feel lucky. Thanks for sharing.
| folmar wrote:
| > sudo seems fairly straightforward
|
| `su` is straightforward, `sudo` is a very powerful piece of
| software and the configuration has a lot of edge cases.
| SoftTalker wrote:
| Yes, have a read of the sudoers man page and marvel at the
| complexity of the configuration, and wonder about your
| chances of getting it right if you are not well-
| experienced. This is the config file with the infamous
| paragraph:
|
| _The sudoers grammar will be described below in Extended
| Backus-Naur Form (EBNF). Don't despair if you are
| unfamiliar with EBNF; it is fairly simple, and the
| definitions below are annotated._
|
| OpenBSD replaced sudo with their own "doas" command a few
| years ago; the doas.conf manual page is about 100 lines;
| sudoers is over 2,000.
| nolok wrote:
| In memory safety ? Yes, the language is much better at being
| safe by default. But it does nothing for logics bugs.
|
| The thing is, replacing from C (sudo or anything else), the
| number of exploit due to null pointer or buffer abuse or ...
| represent easily 50% of it.
| lionkor wrote:
| Is that because theyre easy to find, or because theyre the
| worst?
| yakubin wrote:
| They're easy to make.
| tialaramex wrote:
| A lot of the most serious security vulnerabilities are
| memory safety because e.g. remote code execution is very
| often along the lines of "LOL, I smash buffer with machine
| code, it gets executed" and that's a memory safety problem.
|
| For sudo you have potential for some very serious logic
| bugs, where the program does exactly what the programmer
| wrote, but what they wrote was not what they intended.
|
| Rust's type safety makes it less vulnerable to these
| mistakes than some languages, but there is no magic. In C
| obviously a UID, a PID, a duration, an inode number, a file
| descriptor, a counter are all just integers. In Rust you
| _could_ make all those distinct types (the "New type
| idiom"), and out of the box the Duration and the File
| Descriptor are in fact provided as distinct types. So, some
| improvement.
| Someone wrote:
| > In C obviously a UID, a PID, a duration, an inode
| number, a file descriptor, a counter are all just
| integers. In Rust you _could_ make all those distinct
| types
|
| For various kinds of IDs you can do that in C, too:
| struct UID { int value; };
|
| A C compiler can pass these in registers to functions
| (https://wintermade.it/blog/posts/value-struct.html). So,
| performance impact should be zero.
|
| It may be not as nice as other languages, but it isn't
| bad, either. If you use C++, it can be made a bit nicer,
| and you _could_ also have such structs that you can
| calculate with.
| elteto wrote:
| You can technically do this but then you have to write
| wrapper functions for all relevant syscalls or libc
| functions to unpack the structure and call the actual
| thing. Lots of work.
| jerf wrote:
| "But it does nothing for logics bugs."
|
| "Nothing" is too strong. It does not _solve_ logic bugs, but
| type systems stronger than C can solve some logic bugs too.
|
| Even something as simple as having some concept of "private"
| and "public" and some boundaries between them can help. I'm
| writing some code right now in Go, hardly a super strong type
| system, but I've still put some basic barriers in place like,
| you can have a read-only view of the global state, but the
| only way to write to it is to a per-user view of that state,
| and the only way to witness the changes to the underlying
| value is through one of those per-user write handles. This
| eliminates a large class of logic errors in which one
| accidentally reads the original global state when you should
| be using the per-user modified state or vice versa. This is a
| rewrite of some older code, and this error is so rampant in
| that code as to be almost invisible and probably in practice
| unfixable in the original code. (Which was solved in practice
| by only every dealing with one user at a time, and if there
| was multiple users, it simply ran the process completely from
| scratch once per user. It tried to cache its way out of
| repetition of the most expensive stuff, but, the cache keys
| had some of the same conceptual underlying problems, so it
| just wasn't as good as it should be.)
|
| You can't solve everything this way. Rust's stronger type
| system offers more options, but you can't solve everything
| with that either. But with good use of types, there _are_
| still classes of mistakes you can eliminate, and classes of
| other mistakes you can inhibit.
|
| (There are some tradeoffs, though; with bad types you can
| alse mandate _incorrect_ usage. But I think in the case of
| something like a sudo replacement we can reasonably assume
| fairly high skill developers and that there will be a lot of
| high skill oversight, as evidenced by the fact they 've
| already sought out a third-party security review.)
| timschmidt wrote:
| Enums, Option and Result types, absence of null, not to
| mention that the type system, borrow checker, and static
| everything by default, rewards encoding application state and
| state transitions using all these mechanics, such that they
| can be verified at compile time. I'd say the language does
| quite a lot to address logic bugs as well as memory safety.
| It can't protect a determined developer from themselves, but
| it provides incredibly useful tools to anyone who can work
| out how to use them.
| ajuc wrote:
| Static-everything is such a gimmick in my opinion. It
| sounds great until you try to do something useful with your
| code. It's almost never the case that people actually want
| to hard-code stuff in the source code.
|
| Almost always you read configuration files at run-time
| (like sudo does) and change your behavior depending on run-
| time information - so you will have run-time errors.
| kstrauser wrote:
| "Static" here means that variables are const by default,
| and you can't modify one without explicitly marking it as
| mutable.
|
| In your case, a config object would be mutable inside the
| function that loads it from disk into memory, then read-
| only everywhere else by default.
| ajuc wrote:
| I use rust, and it does have static by default in many
| places (for example it's hard to do the traditional OOP
| virtual polymorphism or to keep objects of various types
| in one container) and it makes it pretty hard for me to
| write "nice" looking code.
|
| It usually devolves into a lot of nested if-else and
| switch (match) instructions.
| kstrauser wrote:
| I haven't run into that so much myself. What I _have_ run
| into is trying to write C-but-in-Rust, for which the
| compiler yells at me to please knock it off. It got way
| easier when I gave up and committed to doing things the
| Rust way.
|
| Not saying you haven't done that, just sharing my
| personal experience with it.
| GTP wrote:
| If your program doesn't have a way of reloading its
| configuration at runtime, then even that first object
| created by reading the configuration from file can be
| immutable.
| kstrauser wrote:
| Yep! What I mean, though, is that the loading function
| itself will need to mutate the object as it reads
| settings from disk and updates the in-memory data
| structure. Once that's done, you can pass that around as
| a read-only object.
| cyber_kinetist wrote:
| Even if I don't like the design of Rust's borrow checker I
| still do appreciate how Enums/Option/Result types and
| pattern matching can make your code more robust. Really
| wish I can bring some of them to C++... I frequently use a
| poor-man's version of Result types with a `TRY()`
| preprocessor macro, but I'm often jealous of what Rust has
| in its toolbelt.
| antoinealb wrote:
| Isn't Rust's result type basically the same as Abseil's
| Status, or am I missing something ?
| https://abseil.io/docs/cpp/guides/status
| steveklabnik wrote:
| Generally the same idea, yes. Your parent mentioned a key
| difference though: "and pattern matching." enums in Rust
| have much stronger language support.
|
| But there are also differences, for example, errors must
| be absl::StatusCode, whereas enums in Rust allow for
| arbitrary error payloads.
|
| Also don't discount ecosystem usage: everyone uses Result
| in Rust, abeseil isn't used by most things, and
| std::expected has its own issues (though I can appreciate
| how tough making those calls is) and only landed in
| C++23, so it's not as widely used as Result either.
| adastra22 wrote:
| Sibling comment mentioned pattern matching, but didn't
| point out the important point that the rustc compiler
| makes sure all patterns matches are exhaustive.
|
| To use a C example, if you add a new definition/variant
| to an enum, suddenly all switch statements over that enum
| will fail to compile (unless there is a default: branch).
|
| This does eliminate a large swatch of logic errors,
| though by no means all.
| bunderbunder wrote:
| This gets said a lot, but I am coming to believe that the
| case is overstated. For two reasons:
|
| 1. Valgrind exists. It's not perfect, but it does arguably do
| a pretty good job as long as you're writing modern C. The
| biggest gap I'm aware of is that it can't really help you
| with global pre-allocated buffers. But I don't think that any
| language or tool can effectively protect you from information
| leakage if you're doing that sort of thing, not even Rust.
|
| 2. Memory-safe is not the same thing as secure. Programs
| written in memory-safe languages are rotten with security
| vulnerabilities, too. Rust's happening to be a memory-safe
| language that doesn't use garbage collection does not render
| it immune to this situation. It has some protections around
| concurrent usage of data that do add additional safety under
| certain circumstances (assuming you don't switch them off),
| but I doubt it's a panacea. I worry, though, that the Rust
| community's tendency to pitch this stuff as a security
| panacea could breed a culture of complacency that negates the
| advantages that Rust does bring to the table for systems
| programming languages. People tend to take unnecessary risks
| when they believe they're invincible.
| shakow wrote:
| > Valgrind exists
|
| You may be right on an infinite frictionless plane, but
| unfortunately that does not work in real life, cf. e.g.
| https://msrc.microsoft.com/blog/2019/07/why-rust-for-safe-
| sy...
|
| > Memory-safe is not the same thing as secure.
|
| And safety belts do not help you if your car is on fire,
| still it's better to wear it.
| adgjlsfhk1 wrote:
| The fundamental problem with valgrind is it only looks at
| what happened, not what could happen. Valgrind is great at
| making sure you don't have memory safety issues for
| "normal" inputs, but is basically useless at making sure
| your code doesn't have memory safety vulnerabilities when
| fed atypical inputs.
| chlorion wrote:
| It's true that it doesn't eliminate all bugs in general,
| but it can completely eliminate buffer overflows for
| example.
|
| There is no excuse to not at least have bounds checking.
| This is one of the most basic memory safety problems and
| it's _trivial_ to prevent.
|
| Just preventing this small issue will prevent a non-trivial
| fraction of bugs. I don't have sudo's bug list on hand but
| I wouldn't be surprised if 25% or more are caused by buffer
| overflows.
|
| So even if it doesn't prevent all logic bugs, it cuts out a
| pretty big chunk of the bug list.
|
| >assuming you don't switch them off
|
| You can't switch them off.
|
| >Rust community's tendency to pitch this stuff as a
| security panacea
|
| I've not seen anyone claim this so far.
| elteto wrote:
| Many vulnerabilities rely on crafting very particular
| inputs that trigger memory corruption in programs. Unless
| you happen to have fed that same input to your program when
| running it under Valgrind then Valgrind is useless for this
| case.
| jchw wrote:
| Advanced type systems and borrow checking/memory safe languages
| DO go a long way, but obviously, No. The best developers can do
| pulling a RiiR is try to follow best practices and learn from
| past mistakes. We've certainly come a long way in 43 years.
| Ditching C string handling eliminates a ton of bugs before you
| factor in the memory safety. Heck, you have to admit: someone
| setting out to make a secure sudo replacement could do a lot
| better nowadays even using just C. The OpenBSD project does a
| pretty good job demonstrating this imo. If you make a
| programming language that doesn't have many of the sharp edges
| OpenBSD code avoids, you could probably get yourself a head
| start, but clearly it also is going to take plenty of care and
| experience too, and a programming language can't really grant
| you that.
|
| I think it's at least worth humoring. It probably shouldn't be
| shipping as a default any time soon, though...
| lionkor wrote:
| No, but maybe it feels better to know memory bugs aren't there
| (but all others are, and worse than in sudo)
| stefs wrote:
| > Is there something to this Rust language which magically
| eliminates all chances of any bug being introduced?
|
| no, altough it has features that prevent or reduce the
| probability of some types of bugs - one example of this being
| memory safety bugs. rust can't prevent logic bugs.
|
| the rust reimplementation probably has more bugs than the
| original, but a theoretically better chance to achieve fewer
| bugs in the long run.
|
| is rewriting mature linux infrastructure in rust a good idea?
| many people agree that no, it's probably not a good idea
| outside of special use cases.
| pohl wrote:
| I think a better question might be whether it prevents
| categories of bugs that are more likely to be exploitable than,
| say, the logic errors that no language could ever prevent?
|
| Also, it sounds like your seasoned eyes would be valuable in
| reviewing this code.
| hoherd wrote:
| Rust aside, one thing to consider is that a reimplementation of
| an existing piece of software does offer the benefit of being
| able to test the old version and the new version side by side
| for consistent behavior. You could have an entire class of test
| cases that is just "do X with the old version, and then do X
| with the new version, and just make sure the result is the
| same." There is also the entire bug history of the old version
| that can be investigated during reimplementation. If the old
| version has specific tests for each resolved bug, those can
| also be run against the new version to ensure it has consistent
| behavior.
|
| In this case though, it's only a partial reimplementation:
| "Leaving out less commonly used features so as to reduce attack
| surface", which would complicate that approach.
| WesolyKubeczek wrote:
| While I don't negate your experience and I genuinely anticipate
| that this project is going to rediscover some pain, there's
| something to be said about the fact that we don't have to
| replicate the life work of Newton, Leibniz, Maxwell, etc to
| really "get" classical physics. It fits now into the high
| school curriculum, and if you pass it, you can be fairly decent
| at it; with a little additional effort, you can get real
| freaking good at what took those people their whole freaking
| lifetimes.
|
| This is because we can stand on those giants' shoulders and
| have the benefit of hindsight and not have to also repeat each
| and every of their blunders, and have better technology and
| learning methodology to boot.
|
| So I presume if you yourself wanted to rewrite sudo from the
| first principles, you, with all your experience and knowledge
| already there, would spend a lot less time doing it, and it
| would be way cleaner and simpler.
|
| So while I'm not dunking on your effort and experience, I'm
| just pointing out that it's not impossible to take your
| experience and turn it into something better over a smaller
| timespan.
| tptacek wrote:
| Whatever else happened in those 43 years, we had a widely-
| exploitable memory corruption vulnerability (Baron Samedit) as
| recently as 2021.
| ndr wrote:
| And it looks like it was a buffer overflow:
|
| https://blog.qualys.com/vulnerabilities-threat-
| research/2021...
|
| Would Rust prevent this?
| jvanderbot wrote:
| Yes buffer overflows are one of the explicitly addressed
| vulnerabilities of Rust's bounds checker, which is always
| on, if memory serves. I haven't touched Rust in a year.
| adastra22 wrote:
| You can get around the bounds checker with unsafe code.
| But yes, by default an overflow should result in a panic
| and program termination.
| Filligree wrote:
| You _can_ , but unsafe code is discouraged in general,
| even given a slight performance cost.
|
| For performance-insensitive, security-critical code,
| there really shouldn't be any such code in the entire
| program--and it would be easy to verify that with a
| presubmit.
| qerti wrote:
| This comment reminds me of "What you're referring to as
| Linux, is in fact, GNU/Linux, or as I've recently taken
| to calling it..."
| adastra22 wrote:
| Look into the crates you use and you'll find tons of
| unsafe code, especially around custom data structures
| doing buffer pointer arithmetic and stuff. If it's
| wrapped in a safe interface, you'd never know.
| Hedepig wrote:
| Yes it would be prevented by the borrow checker.
| SpaghettiCthulu wrote:
| Not by the borrow checker. It would be prevented by
| bounds checking on slices, arrays, strings, etc.
| chlorion wrote:
| The borrow checker does not prevent out of bounds access
| of arrays (or vectors or whatever you want to call them).
|
| The borrow checker is intended to protect against
| "temporal memory unsafety". It can tell you that you are
| using something that has already been freed, or something
| that could be freed while you are using it for example.
|
| Bounds checking is a "spatial memory unsafety" problem,
| it has nothing to do with borrowing and exclusive
| references.
|
| Bounds checking is a trivial problem, for an array that
| has N length, like a char[N], something tried to access a
| value past the end of the array (like char[11] if N=10).
|
| Rust doesn't really do anything special here and
| protecting against buffer overflows does not require any
| novel technology.
|
| An implementation of bounds checking is as simple as an
| "assert(I >= 0 && I < N)", where I is the index and N is
| the length of the array.
|
| In C this is difficult to do because arrays or are just
| pointers (or decay to) and pointers do not carry any
| information about the length. Keeping a separate variable
| containing the length around but this apparently is too
| unergonomic since virtually all C software does not check
| every array access in all parts of the program.
|
| In Rust, its very rare to use raw pointers to work with
| "arrays". Instead there is a "slice" type that models the
| concept of a contiguous sequence of values in memory. The
| important part is that the slice type is a "fat pointer",
| and the fat pointer contains the length or the array. The
| slice type is able to check every access in all parts of
| program.
|
| So all slice accesses are checked by default. and you
| can't "turn it off". If you really want to disable bounds
| checking for some reason, there is an unsafe
| "get_unchecked" function.
|
| There are some sequence types other than slices, arrays
| for example (array is a specific type here). They are
| still checked but they don't have to store the length
| information because it's encoded into it's type.
|
| The Vec type is another one. It is a resizable "array",
| and it stores 3 things, a pointer to the allocation, the
| capacity and the length. That's mostly not relevant here
| though. It checks every access like the other types.
|
| Bounds checking is a very easily preventable error. It
| should not be happening in $CURRENT_YEAR.
| Hedepig wrote:
| Does it not provide some protection against a buffer
| overflow?
| Filligree wrote:
| Indirectly, e.g. by ensuring that you can't modify an
| array while iterating over it. That sort of thing.
| steveklabnik wrote:
| > Would Rust prevent this?
|
| This is often hard to say.
|
| In a very literal sense, you could write this same code, in
| unsafe Rust, so one could argue that Rust does not prevent
| it.
|
| Some may argue that if this program was written in Rust in
| the first place, "concatenate all command line arguments
| into one big string for processing" wouldn't be the way
| you'd go about escaping command line arguments. The issue
| here is about misplacing a null terminator, Rust strongly
| prefers a "start + length" style of representing strings
| instead of null terminators, so you'd never really end up
| in this situation in Rust in the first place.
|
| I'm sure there's other ways to evaluate the situation as
| well. Which one you find compelling is up to you.
| jwilk wrote:
| Discussed on HN:
|
| https://news.ycombinator.com/item?id=25919235 (321
| comments)
| slashdev wrote:
| Yes, unless you use unsafe code.
| khimaros wrote:
| i wonder what fraction of these fixes came with automated texts
| to prevent regressions (and to aid new implementations from
| making the same mistakes).
| sgerenser wrote:
| It can eliminate many bugs, but it certainly wouldn't eliminate
| all bugs. During implementation they realized they were not
| implementing sudo's (undocumented) feature of failing to run if
| the sudoers file is world-writable: https://ferrous-
| systems.com/blog/testing-sudo-rs/.
|
| Of course they did find and fix the bug, but in general Rust
| isn't going to protect you from bugs like this that are
| essentially logic errors.
| Calzifer wrote:
| That is documented. Since the mercurial web interface isn't
| very nice to use I picked a random version. sudo 1.8.6 from
| 2012 writes in the man page "The sudoers file must not be
| world-writable,".
|
| https://www.sudo.ws/repos/sudo/file/SUDO_1_8_6/doc/sudoers.m.
| ..
|
| This is also a very common behaviour for security sensitive
| applications to check config file permissions. Another
| example I remember are ssh private keys.
|
| I might be to harsh but it is not so trustworthy they still
| made this error and still miss the documentation.
| jrmg wrote:
| I'm not sure why people are downvoting you. I suspect they
| may be clicking the link and thinking 'that's not
| documentation it's source code', not realizing it actually
| _is_ documentation.
|
| The language it's in is 'mdoc' - a markup format for man
| pages: https://man.freebsd.org/cgi/man.cgi?mdoc
|
| It's the source code for the man page, which is about as
| documentationey as you can get.
| sgerenser wrote:
| Interesting, the posting I linked to indicated this
| behavior wasn't documented. It's certainly not surprising
| and as you mentioned, it's equivalent to openssh requiring
| specific permissions on private key files.
| grayhatter wrote:
| Thank you for working to create one of the tools which is
| obviously on the list of the most valuable and beneficial to
| computer security. Perhaps only second to netfilter.
|
| And I'm really sorry so many people have decided they're going
| to imply something is wrong or broken with it for their own
| clout. Or because they've bought into the lie that no code
| written in C can be safe or correct.
|
| For what it's worth, I and all the engineers I willingly
| associate with (read: the ones who I respect) all have said the
| exact same thing. Switching to rust here, just 'cause, isn't
| going to meaningfully increase anyone's security. But what are
| you gonna do. Other than ask people to be honest?
|
| Annoying fanboys aside... again, *thank you*! The computer
| security world is meaningfully better because of your work, and
| that's something the RIIR fad will never be able to replace :)
| godelski wrote:
| You gotta start somewhere right? I mean its not like you got it
| right the first time. Don't everyone go switching over just
| yet, but people can't scrutinize something that doesn't exist.
| amai wrote:
| > How is it possible for a single dev team to totally
| reimplement it without unknowingly introducing at least a bug
| or two
|
| This is possible if every bug fixed has an associated test. If
| they use this battery of tests to test their new implementation
| it should be as good as the original implementation.
| rnijveld wrote:
| I can only thank you for the work you've done in creating sudo,
| I think it's an invaluable tool in the general day to day use
| for so many people. As someone working on sudo-rs, our goal
| with creating it never was to invalidate any of the work
| previously done, and we are very much aware that our
| implementation will not be bug free, especially not at the
| start.
|
| For me personally, creating this Rust version allowed me to
| work on something that I would normally not be able to work on,
| given how I would not rate my confidence in writing relatively
| safe C code very high. If nothing else, at least we already
| found a few bugs in the original sudo because of this work.
| Despite the 43 years of bugfixing, such a piece of software is
| unlikely to ever be free of bugs, even if just for the changing
| surroundings.
|
| Other than that, having some alternatives can never hurt, as
| long as we keep cooperating and trying to learn from each
| others work (and from each others mistakes).
| kristopolous wrote:
| So let's settle this. Does sudo rhyme with judo or voodoo?
| jjgreen wrote:
| su(peruser) do, so soodoo
| alkonaut wrote:
| I'm sure there is a logic bug or two in the new implementation.
| Whether you want to take the risk of new logic bugs for the
| benefit of removing several whole categories of bugs (both
| known and unknown!) is the question and tradeoff in each case
| like this. This too requires scrutiny, but I'd be a _lot_ more
| comfortable running a Rust program with 2 years of scrutiny
| than any C program with 40.
| AndyKelley wrote:
| By making it simpler and not having a ton of rarely used
| features, and by using a programming language that makes it
| more difficult to write bugs.
| feldrim wrote:
| I'd love to see a verification / validation parameter/flag/tool
| that allows the user to dry-run the current sudo configuration
| and print out the parts unsupported by sudo-rs.
|
| Portability helpers for projects like these enable a frictionless
| change.
| cyber_kinetist wrote:
| I think the two bullet points they listed for their project
| (other than using Rust) are often overlooked:
|
| - Leaving out less commonly used features so as to reduce attack
| surface
|
| - Developing an extensive test suite which even managed to find
| bugs in the original sudo
|
| Which are the most important aspects when writing any safety-
| critical code, even moreso than rewriting in Rust!
| lambdaone wrote:
| This is good work, and I'm not quite sure why people are
| complaining about it; there clearly won't be any replacement of
| the traditional C sudo by this unless it's driven by distros and
| the community making it happen.
|
| Multiple implementations make it much easier to do fuzzing and
| generate automatic test suites that may be used to improve all
| the versions of this critical utility.
| thiht wrote:
| As they say in the article, their test suite was even able to
| uncover 2 bugs in the original sudo. That's definitely a win.
| brundolf wrote:
| By now we've gotten several projects that re-implement a core
| unix util in a safe language, often also with better performance
| due to concurrency, better standard primitives, etc
|
| Have any of these ever been adopted by a distro as the default
| implementation? Is that something that might happen? I.e. I would
| never bother to upgrade my sudo command or my grep command, but
| getting better defaults would be better
|
| Obviously they would have to be perfect drop-in equivalents,
| which some of these projects don't try to be, but others of them
| do
| steveklabnik wrote:
| In 2021, uutils was far enough along and compatible enough to
| boot debian. I haven't heard of anyone actually moving to them
| fully yet.
| charcircuit wrote:
| Having sudo itself makes an OS less secure since malware can use
| it to easily get root. Sure a rust version may be more secure,
| but even better would be deleting it entirely.
| AnonC wrote:
| How else would you do things as root or superuser without
| exposing everything? If your sudo configuration is ALL = ALL
| (or is a variant of this), then sudo opens everything up for
| use/abuse. But if you carefully construct the configuration to
| allow only certain commands, it's much better than just giving
| out the root password to users.
| charcircuit wrote:
| >How else would you do things as root
|
| Nothing a user is supposed to do should require elevating to
| root to do.
|
| >it's much better than just giving out the root password to
| users.
|
| This is even worse. Access control should be set up properly
| instead of having users assume the identity of other
| accounts.
| markhahn wrote:
| Polishing a turd?
|
| Seriously, better reimplementations are great. But weren't you
| shocked to read about all those weird sudo features? I mean, the
| normal stuff is very weird, subtle, and therefore fragile.
|
| Anyone who uses sudo "deeply" should probably think about whether
| there are other ways.
| declan_roberts wrote:
| I don't know why anyone is enamored with a rewrite of something
| as critical as sudo in a memory safe language, as if memory-
| safety somehow magically makes all of the other types of bugs
| disappear.
|
| No thanks. Keep this far away from all of my systems.
| datadeft wrote:
| Doas is a much simpler tool for the same thing. I am not sure why
| it is not used more.
| dang wrote:
| Recent and related:
|
| _Sudo-rs ' first security audit_ -
| https://news.ycombinator.com/item?id=38131442 - Nov 2023 (58
| comments)
| kelnos wrote:
| > _Leaving out less commonly used features so as to reduce attack
| surface_
|
| In principle I think this is a great idea, but when it comes to
| encouraging adoption, I think this might be a mistake. I would
| love to use this, but I'm not going to install it myself and make
| sure it stays updated. Realistically, I'm only going to use it if
| Debian decides to replace their sudo-c package with sudo-rs. And
| I just don't see Debian (known for being fairly conservative with
| changes and updates) doing that when sudo-rs doesn't implement
| sudo-c's full feature set.
___________________________________________________________________
(page generated 2023-11-06 21:00 UTC)