On 01/29/2015 03:16 AM, Zbigniew Jędrzejewski-Szmek wrote:
2. SIGSEGV should be catched by a handler running on a separate
stack (SA_ONSTACK) - otherwise it can cause segfault itself, when
the first SIGSEGV which triggered the handler is caused by stack
overflow.
I'd take a patch for this, but in general: the crash handler is
nothing that is supposed to recover your system. All it does its close
all fds, fork, and coredump in the child while freezing in the
parent. That makes sure that all communication with PID 1 is severed
(so that clients talking to it don't hang), we get a clean coredump,
but the kernel doesn't oops immediately. That's really all there is to
it.

So far we never ran into stack overflow issues, hence nobody was ever
tempted to cover that case too, and set up a separate stack. In
particular since doing this without testing it is pointless...

--->
Actually, when the program is a critical part of the system, than ALL sig 
handlers should use separate stack (what in fact makes the life easier) - 
that's because it's completely unpredictable, whether there's enough stack 
space to execute the handler - i.e. each sig handler can cause segfault when 
it's executed at the bottom of the stack (where top/bootom is only a matter of 
naming convention)
IIUC, you are saying that we could trigger for example a FPE, and
then exhaust all the memory in the signal handler. Nah, we can ignore
this possibility.
No, I'm saying, that the handler can be invoked when there's not enough space left on the main stack, so it'll do nothing besides causing sagfault.

The only effect of SA_NODEFER is that sig mask is not automatically set for a 
signal which triggered the handler.
This means nesting of signals, as the handler can be interrupted and another 
instance is started for a new signal context.  (and sig handlers are not 
signal-safe with SA_NODEFER, what means that they have to be fully re-entrant)
This also means, that there's completely no warranty that the handler won't be 
interrupted with external signal -> mess.
Not really. systemd is single-threaded, so a signal could come only from two 
places:
the signal handler could cause a fault, or it could be delivered from another 
program.
The first is unlikely, stack handlers do a tiny amount of work, and the second 
is OK,
because killing PID 1 is only allowed for privileged processes, and if someone 
can
send arbitrary signals to PID 1, they can cause a failure in other ways.

Zbyszek
Yeah, it's unlikely, but it would be safer to at least check the source of the signal. But that's not really a problem, since the handler is not even re-entrant (f.e. due to dynamic memory allocation performed trough log_xxxx macros -> log_full_errno -> log_internal -> journal-send.c::_printf_() -> vasprintf() )

Whatever.

To summarise: there are no bugs in core/main.c:

1. Ignoring return value from sigaction is not a problem, because it's almost *unlikely* to fail. In any case, kernel will do the job, so it doesn't even matter whether the handlers are installed or not -> everything that can be done in the handler is to just quit anyway.

2. SIGSEGV handler (and others): it's *unlikely* to happen that the handler will be executed at the bottom of the main stack (with insufficient stack space or when the stack is already overflowed) - because stacks are huge, and in case of segfault see point 1.

3. SA_NODEFER is OK, cause it's *unlikely* that external signal gets delivered. Even if the crash() handler will crash (f.e. because it's not re-entrant), what (again) is *unlikely* to happen, see point 1.

I've learned a lot, sorry to waste Your time.

Regards.



_______________________________________________
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel

Reply via email to