Live data from Hacker News

Heap-based buffer overflow in Sudo

qualys.com

311–320 of 328 posts

Re: Heap-based buffer overflow in Sudo

#311
post #74

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…

Does the project have a testing framework in place? How is the project built and distributed? Can testing be integrated into its CI/CD pipeline? Is there a CI/CD pipeline? Adding frameworks and infrastructure to a project is one of those things that is a lot more work than it appears to be. They should do it, for sure, but I wouldn’t dismiss it as trivial on a decades-old system that was never built for it.

Re: Heap-based buffer overflow in Sudo

#312
post #302
post #251

Earlier 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…

> OCaml which depends on C

How so? The OCaml compiler is written in OCaml and bootstraps itself.

Re: Heap-based buffer overflow in Sudo

#313
post #207
post #170

Earlier 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.

ls -l in /lib/security

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

#314

Earlier 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.

PAM using app can fork a process for this, so it's not too horrible, but it increases complexity.

Re: Heap-based buffer overflow in Sudo

#315
post #294

Earlier 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.

It is almost always the case that a sufficiently malicious user can find a way to turn that into full blown root access.

Re: Heap-based buffer overflow in Sudo

#316

Earlier 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.

I agree. But really the security best practice is to remove setuid from all binaries, and rely on RBAC rules (such as with SELinux). That would solve more security issues than anything else, but this is way more effort than most people are willing to invest in security.

Re: Heap-based buffer overflow in Sudo

#317

Earlier 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…

> 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.

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

#318

What 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…

Oh dear... Thank you for that info.

Re: Heap-based buffer overflow in Sudo

#319

Earlier 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)

ah, yes, but those _felt_ as old as dirt.

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

#320
post #186

Earlier 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…

I agree. Keeping the test around provides a safety net (a bug repellent of sorts) for the next person the comes along. The test also serves as a documented history of the bugs of the past. The problem is that test does not guarantee the injection of future bugs of a different type. I don't think any amount of testing will. That's not to say we shouldn't write test, we should just be aware of the limits of testing.
Post reply on HN