4 ms·
My 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 `--devic
by terom 9y ago
My 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?