4 ms·
The Debian patch with diff highlighting: https://gist.github.com/jwilk/561ae35894756aae1e31503d0c52db7e https://gist.github.com/jwilk/561ae35894756aae1e31503d0
by jwilk 9y ago
The Debian patch with diff highlighting:
https://gist.github.com/jwilk/561ae35894756aae1e31503d0c52db7e https://gist.github.com/jwilk/561ae35894756aae1e31503d0c52db...
AFAICS, it does this:
1) Fixes use of uninitialized memory.
2) Fixes double-free in the signal handler.
3) Makes sure that the device is opened only once.
I still don't understand what exactly the bug is supposed to be. I also don't understand what is the purpose of 3). With this fix applied, it's still possible for a user to open arbitrary file for writing with root privileges, which is bad.
- GrayShade 9y agoHow did you find the Debian patch? http://git.deb.at/w/pkg/beep.git http://git.deb.at/w/pkg/beep.git doesn't seem to have any changes.
- lathiat 9y agoProbably not in that repo as the upload was done by the security team. Best way to get the source is to run “apt-get source beep” on a Debian system.
- jwilk 9y agoOr if you don't have a Debian stable system at hand: Go to https://packages.debian.org/stable/beep https://packages.debian.org/stable/beep and download files from the "Download Source Package" section. If you're only interested in the patch, get this one: http://security.debian.org/debian-security/pool/updates/main/b/beep/beep_1.3-4+deb9u1.debian.tar.xz http://security.debian.org/debian-security/pool/updates/main...
- avian 9y ago> it's still possible for a user to open arbitrary file for writing with root privileges, which is bad. It appears that way at first, but: O_WRONLY mode will not create a new file, so you can't make files as root. If you open an existing file, it will fail later on the console device-specific ioctl. If that's the catch here, it does not seem trivial to exploit.
- justincormack 9y agoNot all the legacy ioctls are single device only.
- deleted 9y ago[deleted]
- jwilk 9y agoYeah, you can't create new files that way; but opening an existing file can have side effects (think of tape devices or named pipes).
- terom 9y agoMy speculation on the race condition fixed in the patch: The while loop in `main` calls `play_beep` multiple times. Each call to `play_beep` opens the `--device` and sets the global `console_fd`, and then sets the global `console_type` based on the `ioctl(EVIOCGSND)` error, before calling `do_beep`. This normally prevents the user from writing to arbitrary files with `--device`, because without the `ioctl(EVIOCGSND)` succeeding, `do_beep` with `BEEP_TYPE_CONSOLE` only does a (harmless?) `ioctl(KIOCSOUND)`, not a `write` with the `struct input_event`. However, the signal handler calls `do_beep` directly using the globals set by `play_beep`... So I image that with something along the lines of `beep --device=./symlink-to-tty ... --new ...`, you can rewrite the symlink to point to an arbitrary file during the first `play_beep`, and then race the open/ioctl in the second `play_beep` with the signal handler such that `do_beep` gets called with `console_fd` pointing to your arbitrary file, and with `console_type` still set to `BEEP_TYPE_EVDEV`, resulting in a `write` to your arbitrary file. Exploiting that for privesc would require control over the `struct input_event` for the `write`... `handle_signal` calls `do_beep` with a fixed `freq` of 0, so all of the initialized fields are set to fixed values... However, there's an unitialized `struct timeval` at the beginning of the `struct input_event`, and it's allocated on the stack... Seems like a curious security vulnerability, I'll assume the debian security team must have a working PoC in order to actually call it out as a local privesc vulnerability... I'd love to see the actual PoC eventually :)
- jwilk 9y agoYeah, that makes sense. I took the liberty of pasting this comment to the upstream bug tracker: https://github.com/johnath/beep/issues/11#issuecomment-378868637 https://github.com/johnath/beep/issues/11#issuecomment-37886...
- terom 9y agoThere's now a PoC exploiting this race, seemingly placing the 32-bit -l option value into the uninitialized part of the `struct input_event` to modify a shell script that runs as root: https://gist.github.com/fkt/5f8f9560ef54e11ff7df8bec09dc8f9a https://gist.github.com/fkt/5f8f9560ef54e11ff7df8bec09dc8f9a Remains to be seen if the PoC actually works though, I've been unable to win the race so far, although the varying ioctl errors indicate it might be close?