top | item 40844257

(no title)

djmdjm | 1 year ago

Theo de Raadt made an, I think, cogent observation about this bug and how to prevent similar ones: no signal handler should call any function that isn't a signal-safe syscall. The rationale is that, over time, it's too way easy for any transitive call (where it's not always clear that it can be reached in signal context) to pick up some call that isn't async signal safe.

discuss

order

ralferoo|1 year ago

I'm kind of surprised advocating calling any syscall other than signal to add the handler back again. It's been a long time since I looked at example code, but back in the mid 90s, everything I saw (and so informed my habits) just set a flag, listened to the signal again if it was something like SIGUSR1 and then you'd pick up the flag on the next iteration of your main loop. Maybe that's also because I think of a signal like an interrupt, and something you want to get done as soon as possible to not cause any stalls to the main program.

I notice that nowadays signalfd() looks like a much better solution to the signal problem, but I've never tried using it. I think I'll give it a go in my next project.

qhwudbebd|1 year ago

In practice when I tried it, I wasn't sold on signalfd's benefits over the 90s style self-pipe, which is reliably portable too. Either way, being able to handle signals in a poll loop is much nicer than trying to do any real work in an async context.

formerly_proven|1 year ago

This isn't the case for OpenSSH but because a lot of environments (essentially all managed runtimes) actually do this transparently for you when you register a signal "handler" it might be that less people are aware that actual signal handlers require a ton of care. On the other hand "you can't even call strcmp in a signal handler or you'll randomly corrupt program state" used to be a favorite among practicing C lawyers.

fanf2|1 year ago

Exactly, yes :-) Signal handlers have so many hazards it's vital to keep them as simple as possible.

rwmj|1 year ago

A rule I try to follow: either set a global variable or write to a self pipe (using the write syscall), and handle the signal in the main loop.

lokar|1 year ago

You should read the sigsev handler at google, it’s great, doing all kinds of things. Of course it’s going to crash at some point anyway….

growse|1 year ago

I'm not overly familiar with the language and tooling ecosystem, but how trivial is this to detect on a static analysis?