The author of beep needs to read the POSIX specification on async-signal-safety [1]. In particular, it is not safe to call exit, free, ioctl, putchar, or perror from a signal handler. [1] http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2...
> 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?
Beep security update
21–30 of 103 posts
Re: Beep security update
#22The author of beep needs to read the POSIX specification on async-signal-safety [1]. In particular, it is not safe to call exit, free, ioctl, putchar, or perror from a signal handler. [1] http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2...
> 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?
Re: Beep security update
#23Earlier 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.
Re: Beep security update
#24Can't one just sudo echo -e "\7” anyway? Or if you're trying to do something fancier there is snd-pcsp which lets use use the piezo as a normal ALSA device (quality may vary). Not that many modern machines even include such a useful device.
Nitpick: on my machine, that's: sudo echo -e "\07"
echo -e "\07"Re: Beep security update
#25Also see https://holeybeep.ninja/
I've got a couple of problems with that page: * curl | sudo bash for two lines of script * said script just checks if you have beep installed, not if you're vulnerable
"curl | bash" or "curl | sudo bash" is problematical no matter how large or small the script.
Yes, I know some people say that it is no worse than downloading to a file and then running the file without reading the script, which is what almost everyone does anyway.
These people are wrong. Downloading to a file and running it from there is always better because if you notice something wonky sometime after running the script, it is easier to prove the script caused it if you saved a copy before running it.
If you "curl | bash" it and then you notice something bad has happened and you want to look at the script, you have to curl it again. But then how do you know that second curl gives the same script as the one you just executed? If I were distributing a malicious script, I would set up my server to serve a non-malicious script most of the time and just occasionally substitute my malware script, and it would only distribute the malware once for each IP address.
Either do "curl > file; bash < file" of "curl | tee file | bash" rather than "curl | bash" if you aren't interesting in examining the script before running it.
Re: Beep security update
#26Earlier 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.
I'll bite. A helpful compiler would at an appropriate warning level tell you when you are setting a signal handler with a function you haven't (helpfully) annotated with some construct to say "this thing is a signal handler". Said helpful compiler would then also use this helpful annotation to forbid or loudly warn against a helpful subset of naught functions it is able to deduce are being called therein because huma…
(That's what I was saying, except the bit that programmers cannot reasonably be expected to understand what to do in a signal handler. That you should usually only set a (volatile) flag and return immediately, and should take extreme care if you really need to do more, is basically the first thing you learn when you read up on signal handlers. That's also completely obvious if you take a look at how they are implemented.)
Re: Beep security update
#27Earlier 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?
How would the compiler know that a function was a signal handler?
For example: the signal handler would be a function that accepts an argument of some kind, and the argument is the key to reaching all apis allowed from that point (e.g. the argument must be passed on to allowed apis, or the argument contains function pointers to all allowed functions, that is "OO-style").
I'm not saying this would be possible by any stretch of the imagination for POSIX.
Re: Beep security update
#28Earlier quoted context omitted.
I'll bite. A helpful compiler would at an appropriate warning level tell you when you are setting a signal handler with a function you haven't (helpfully) annotated with some construct to say "this thing is a signal handler". Said helpful compiler would then also use this helpful annotation to forbid or loudly warn against a helpful subset of naught functions it is able to deduce are being called therein because huma…
That's what I was saying. So why don't you step ahead and do it? I'm sure it will be not more than two weeks worth of work. And it will fatten up the compiler only a little bit. And it will annoy proficient programmers only a little bit. How would you deal with calling a function that is externally defined, so you can't easily check if it does something unsafe (or calls another function that does). I'd figure any att…
Re: Beep security update
#29Earlier quoted context omitted.
That's what I was saying. So why don't you step ahead and do it? I'm sure it will be not more than two weeks worth of work. And it will fatten up the compiler only a little bit. And it will annoy proficient programmers only a little bit. How would you deal with calling a function that is externally defined, so you can't easily check if it does something unsafe (or calls another function that does). I'd figure any att…
Oh, I think we agree. Implementing the feature sounds like a right creeping pain for very little payoff. I would differ wrt "basically the first thing you learn when you read up on signal handlers" -- these days, the crazy kids writing code just start using the language and libraries. Learning why is usually the last thing learnt, and only when something, like a beeping-beep service, sets fire to something.
But on the other hand, the signals API might be a problem. Signals aren't exactly praised as a marvel of engineering. There probably is a need for something as low-level as that in some cases. But in the common case an API that just asynchronously sets a volatile flag when a signal is received, should be sufficient. Calls to "slow" devices are interrupted and return EINTR anyway.
Re: Beep security update
#30Earlier quoted context omitted.
How would the compiler know that a function was a signal handler?
It wouldn't. But it might be possible to make it impossible to call forbidden_function() from anywhere where it shouldn't be possible. For example: the signal handler would be a function that accepts an argument of some kind, and the argument is the key to reaching all apis allowed from that point (e.g. the argument must be passed on to allowed apis, or the argument contains function pointers to all allowed functions…
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 very error-prone solutions. In C's case, in fact, I think C99 defines signal handlers as taking a single argument, an int. A compiler that doesn't let me call free from a function that takes a single integer argument wouldn't be too useful.
IRL, there are analysis tools that can help catch (a subset of) this sort of problem, but they are environment-specific and don't rely on just the function definition. They either look at the signal handler installation calls (but then they're restricted to information that's known at compile time!), or require some sort of annotation (e.g. via special comments a la Doxygen, or via macros etc.).
And even then, the sort of problems that they catch are specific to each environment. The restriction isn't that you shouldn't call under POSIX, the restriction is that you shouldn't call functions that are not async-signal-safe (i.e. they're not re-entrant or they're not atomic with respect to signals). There are a few POSIX functions that are safe to call from signals (see man 7 signal-safety on a Linux box), but that list obviously doesn't cover user-defined functions -- some of which may be OK to call, others not so much.
You can probably determine if a function is async-call-safe with some static analysis but at this point, it's the sort of stuff that really doesn't belong in a compiler anymore...