Earlier quoted context omitted.
> In particular, it is not safe to call exit, free, ioctl, putchar, or perror from a signal handler. Why is it accepted by the compiler, then?
It can't be done in general. A signal handler is just a function that at runtime is connected to a signal. With some work many or most unsafe handlers in the wild can be detected, but so can many other problems, I guess.
Beep security update
41–50 of 103 posts
Re: Beep security update
#42Earlier quoted context omitted.
> In particular, it is not safe to call exit, free, ioctl, putchar, or perror from a signal handler. Why is it accepted by the compiler, then?
This is a really good point actually, aren't there static analysis tools that can figure out things like this? I know in JS we have linters to stop you from doing things that are most likely not very smart. I find this very useful, a lot more useful than to say "If you don't even read the manpages there is no help in sight". Maybe the compiler should not do it but perhaps you could run a linter against packages that…
Re: Beep security update
#43https://github.com/johnath/beep/issues/11#issuecomment-37838...
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.
Re: Beep security update
#44Earlier quoted context omitted.
Nitpick: on my machine, that's: sudo echo -e "\07"
Simply displaying a character doesn't need sudo at all anyway, so just echo -e "\07"
I think some terminal emulators (eg Konsole) will just read char 7 and play a system defined WAV or other workaround but your more classic terminals (eg xterm) would potentially have difficulties calling the system bell.
[1] for reference: Xorg terminals are also classed as remote terminals (eg check the TTY column in `w` to see how Linux assigns pseudo-tty's to terminal emulators inside X).
Re: Beep security update
#45I'd love to hear the backstory. Who on _earth_ goes looking for vulnerabilities in beep?!
Re: Beep security update
#46Earlier quoted context omitted.
How would you differentiate a function that takes an argument of some kind and handles signals from one that just takes an argument of that kind (e.g. for debugging, logging, or some other sort of introspection)? Edit: to be clear -- I'm not asking this just to be snarky :-). Inferring functional information from nothing but semantic information with no functional implication is a very complicated problem that has ve…
To be clear: I wasn't suggesting that making everything context aware would be possible in either C or Posix. It would most likely require a complete rewrite of all APIs to begin with - including the C standard library. It would no longer resemble posix after that.
void handle_signal(struct signal_handler_arg *arg)
which does signal handlingand this:
void check_signal_info(struct signal_handler_arg *arg)
which validates a struct signal_handler, is called outside a signal handler, and doesn't do any signal handling.Similarly, you would not be able to verify that this is okay:
void handle_signalstruct signal_handler_arg *arg)
{
...
some_global_state->some_cb(...);
}
If some_cb is populated at runtime, how do you know (at compile-time) that it's been populated with a function that's safe to call inside a signal?Re: Beep security update
#47I'd love to hear the backstory. Who on _earth_ goes looking for vulnerabilities in beep?!
Edit: also, there's a challenge about this in the program's README :-)
"Decide for yourself, of course, but it looks safe to me - there's only one buffer and fgets doesn't let it overflow, there's only one file opening, and while there is a potential race condition there, it's with /dev/console. If someone can exploit this race by replacing /dev/console, you've got bigger problems. :)"
Re: Beep security update
#48Earlier quoted context omitted.
It can't be done in general. A signal handler is just a function that at runtime is connected to a signal. With some work many or most unsafe handlers in the wild can be detected, but so can many other problems, I guess.
Perhaps a better question is why signal handlers have these restrictions, and why they don't behave more like e.g. threads.
Re: Beep security update
#49I'd love to hear the backstory. Who on _earth_ goes looking for vulnerabilities in beep?!
If I had to guess, I'd say they were doing it because it is often installed with suid root. Edit: also, there's a challenge about this in the program's README :-) "Decide for yourself, of course, but it looks safe to me - there's only one buffer and fgets doesn't let it overflow, there's only one file opening, and while there is a potential race condition there, it's with /dev/console. If someone can exploit this rac…
Re: Beep security update
#50Earlier quoted context omitted.
To be clear: I wasn't suggesting that making everything context aware would be possible in either C or Posix. It would most likely require a complete rewrite of all APIs to begin with - including the C standard library. It would no longer resemble posix after that.
It's not something that can be solved on an API level. You can rewrite the C standard library all you want, you still won't be able to differentiate between this: void handle_signal(struct signal_handler_arg *arg) which does signal handling and this: void check_signal_info(struct signal_handler_arg *arg) which validates a struct signal_handler, is called outside a signal handler, and doesn't do any signal handling. S…
Let's use a pseudo OO syntax:
void foo(arg: argtype)
{
arg.do_thing(); // ok
frob(arg); // not possible - if frob might be forbidden anywhere then it's not callable like this
}
That frob is forbidden isn't because the compiler detected that foo is a signal handler, but because no forbidden functions exist. I'm not sure this would be practical in this context - but it's the only way I can imagine to have a compiler detect that you don't call a particular function from a particular context. Basically, very few global/static functoins would have to exist, and no/very little global state as well.