Earlier quoted context omitted.
Even if there were basic unit & regression tests, this bug might not have been caught. This bug should have gone through detailed security review and should probably also undergo fuzzing.
You can bet your bottom banana that the GRU, the NSA, Chinese state security, and the mob have all thoroughly fuzzed sudo and are sitting on the results. It just seems SO EASY to add a test for this problem, literally the relevant test input is one slash by itself, or any string ending in a slash! So simple! If I sent a change like this at work, no matter how trivial, that said it fixed this bug but I didn't send any…
Heap-based buffer overflow in Sudo
311–320 of 328 posts
Re: Heap-based buffer overflow in Sudo
#312Earlier quoted context omitted.
Much of the point of suggesting Mirage was to get away from C - my position is that the correctness costs of C's undefined behaviour (as implemented by real-world C compilers), limited testing support, poor dependency management and so on are too high.
One of my goals with Cosmopolitan is to attract developers who build high-level languages. MirageOS depends on OCaml which depends on C. We need a sturdy foundation at the lowest levels that can enable these visions by helping high-level environments be successful. Cosmopolitan can be that foundation. For example, the codebase has 192 test programs. Much focus has been placed on using the Undefined Behavior Sanitizer…
How so? The OCaml compiler is written in OCaml and bootstraps itself.
Re: Heap-based buffer overflow in Sudo
#313Earlier quoted context omitted.
su pulls in random set of currently configured PAM modules, due to requiring authentication. Anyone checked what buggy horrors await in all those modules? And it's not a static set of old trusty modules either. The fresh new complicated stuff is being added, like systemd-homed, and so on. pam_systemd and pam_systemd_home have by itself the size of all other 46 PAM modules combined (on my Arch system).
How do you measure the sizes of these modules? I counted lines from source code and systemd pam code was a 1k-2k lines of C total and pam is 30k lines of C.
I mean last time I had sshd hanging and randomly losing access to remote machines due to systemd's newest PAM improvements (homed), when I put the process under gdb, it shown dbus stuff, so it's certainly more than 1-2kloc.
Re: Heap-based buffer overflow in Sudo
#314Earlier quoted context omitted.
I mean, it's literally in the name: Pluggable Authentication Module. It's a very good idea to expose a common interface for user authentication to hide the vagaries of the underlying authentication mechanisms. It's far more useful to explain why or how PAM is bad, because no one (sane) will agree that the idea of PAM is bad.
Module should be implemented as a separate process running under unprivileged user and communication should be done via pipes. It's UNIX-way. If I understand it correctly, currently module is implemented as a shared library executing under root sharing all the memory with other modules and main program. This exposes way too many opportunities to exploit any vulnerability.
Re: Heap-based buffer overflow in Sudo
#315Earlier quoted context omitted.
> Fair enough but what do you recommend? why do you need to have sudo? I'm perfectly fine without it. sudo is maybe useful in the case where others on the system don't need to know the a password to run as someone else (including root) but need to be able to do that anyway. sudo seems to have gotten a big installation bases through ubuntu and everybody thinks it's normal now, but really for me it's not.
sudo doesn't have to grant full root access to everyone in the group. It can be set up such that certain users only have the ability to run specified commands as root, which is handy for orgs where you might have a group of tier 1 techs that you want to be able to run certain scripts (written by tier 2 or 3, of course) that require root, but you don't trust the engineers enough to have root access to everything.
Re: Heap-based buffer overflow in Sudo
#316Earlier quoted context omitted.
Perl had a fix for this called suidperl , which was a wrapper which enabled Taint mode and other strict checks ( https://perldoc.perl.org/perlsec ). I don't know of any other language or interpreter that go this far for security by default, so Perl might be the most secure language in this regard. However, suidperl was dropped in 5.12. My main point was that you could rewrite sudo in all sorts of languages, but sayin…
Thank you for pointing that out :) If someone would get serious about security, auditing every setuid binary would certainly be something on their list (if they use any). If they really want the functionality, rewriting it to cover just enough of the required functionality wouldn't be unheard of.
Re: Heap-based buffer overflow in Sudo
#317Earlier quoted context omitted.
Yes, that's probably a good idea. But it comes with costs. Someone has to learn Rust and then convert all of these programs. And it also has the issue that Rust programs are only memory safe if the unsafe keyword is not used anywhere in the program (correct me if wrong?). So it looks like the effort to do such thing, while noble, and valiant, is essentially an experiment with an uncertain pay-off that could turn out…
> But it comes with costs. Someone has to learn Rust and then convert all of these programs. Someone has to learn compiler engineering and then design and implement a 'safe' ABI. Unlike learning Rust, this is probably worthy of a research paper. > Rust programs are only memory safe if the unsafe keyword is not used anywhere in the program If you use unsafe, then you take some of the responsibility for maintaining mem…
Yes, all good points. What I'm getting at is that it seems like nobody has yet re-written sudo in this safe way. And it's not just a matter of re-writing it. If (when) someone comes along with this re-write there's "if this person goes away, will we find someone else to maintain it?" and all those other very conservative social forces at play.
I think any new programming language community has these sorts of adoption hurdles to face. And I'm sure the rust community is working hard to build up that pool of developers and I think that's all really positive so I don't want to sound like I'm subtracting from it at all. I'm just also an interested spectator of PL and systems programming research/new directions :)
> If you use unsafe, then you take some of the responsibility for maintaining memory safety. However, you can audit the unsafe parts of the code, and it will compose with the compiler-provided guarantees for the rest of the code. Besides, one can easily avoid unsafe code for safety-critical tools like these.
Thanks, yep. That's why I think that generally Rust is a good idea, and rewriting the TCB in it is a worthwhile project. In regards to safety it looks like a step in the right direction. We're just quibbling about the cost/benefit analysis of how big of a step it is compared to above-mentioned issues that all new programming languages face. Personally, I've no doubt that even with all that factored in, it's still a net positive.
> Miri does not support most interaction with the outside world [1]. It is focused more on detecting UB in unsafe code when it is exercised by tests, than on having your code running in production through Miri. Moreover, I wouldn't call a thousand-fold slowdown [2] "relatively lightweight"
Thanks for the clarifications, you're definitely more up to speed on that project than I am! But yeah, what I meant there was not that the implementation of miri was something to use as-is, more that it's an interesting direction in PL/systems programming research (imo). And some of the ideas there, especially where runtime cost _in principle_ can be made to be relatively lightweight are interesting. I've seen some other research where C implementations with bounds-checking have been implemented part-statically and where the remaining checks are done at run-time with fat-pointers.
OK, bounds checking isn't memory safety, but the paper was a while ago. Maybe it was this one https://www.comp.nus.edu.sg/~ryap/Projects/LowFat/ ?
So I mean, it sounds like you might be able to get to a place where you can use some bits of unsafe in rust, but maybe the program overall could still be safe because the compiler can have a mode where run-time checks (which can be statically eliminated in a lot of cases) are included.
But hey, I'm just a relatively amateur outside-observer of all this, maybe that's a totally impossible pipe dream? :)
Re: Heap-based buffer overflow in Sudo
#318What variant of `doas` do people run as an alternative? I see Duncaen/OpenDoas, slicer69/doas, multiplexd/doas on GitHub. None seem super widely used as judged by watches/stars/forks.
I would say that the concept and implementation in C is inherently insecure. Switching to something less reviewed because there is a sudo vulnerability is not a guarantee that you are now "safer" especially if those ports are not reviewed. As far as I can say, never ever use slicer69/doas, I've found 3 critical security vulnerabilities in it, the author does not understand C or how it should work in general. Here are…
Re: Heap-based buffer overflow in Sudo
#319Earlier quoted context omitted.
wow, I never realized sudo is from 1980[0]! I thought it was a product of the late '90s. It's actually incredible it has managed to stay around this long. [0] https://www.sudo.ws/history.html
Pffft, `sed` is from 1974: https://en.wikipedia.org/wiki/Sed And `ed` dates from 1969: https://en.wikipedia.org/wiki/Ed_(text_editor)
On the other side, I remember howtos/manuals/READMEs in the early '00s referring to su(1) and only sometimes saying "..these days you should be using sudo(8)", so it always felt like something "new" :)
Re: Heap-based buffer overflow in Sudo
#320Earlier quoted context omitted.
A Turing Award winner once said, “Program testing can be used to show the presence of bugs, but never to show their absence!"
Sounds like a very smart person. Much of the value in the test is showing that the old revision fails it. If I were fixing this bug, first thing I would do is write the test and make sure the existing code fails. If it doesn't fail, that means I don't understand the problem yet. Then I fix the problem and commit both the fix and the test. I don't just discard the test, because it is valuable to know that in the futur…