* [musl] Is errno signal-safe?
@ 2022-02-16 19:40 Markus Wichmann
2022-02-16 19:56 ` Carlos O'Donell
0 siblings, 1 reply; 4+ messages in thread
From: Markus Wichmann @ 2022-02-16 19:40 UTC (permalink / raw)
To: musl
Hi all,
today I had a flash of inspiration while staring at some code: errno is
a global variable, right? OK, it is thread-local, but still a global
variable in the context of one thread. And looking at a global variable
while it may (or may not) be modified in a signal handler is not safe to
do.
So now I have to wonder. There are a bunch of functions that set errno,
that are on the ostensibly async-signal-safe list, like for example
write(). And to my knowledge, changes to errno are not turned back by
sigreturn(). So, are changes to errno made in a signal handler
propagated to the main program? If so, how do I inspect errno correctly
in the main program? I could block signals, but for one thing, doing so
every time errno might be relevant is going to be overkill, and for two,
if the system call I want the errno from is also blocking and I want to
allow signals while the call is blocking, there is no way to do that
without race condition.
But then again, now that I thought of it, this is so obvious that surely
someone else must have stumbled across it before, right? A solution must
exist, right?
Ciao,
Markus
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [musl] Is errno signal-safe?
2022-02-16 19:40 [musl] Is errno signal-safe? Markus Wichmann
@ 2022-02-16 19:56 ` Carlos O'Donell
2022-02-16 21:01 ` Florian Weimer
0 siblings, 1 reply; 4+ messages in thread
From: Carlos O'Donell @ 2022-02-16 19:56 UTC (permalink / raw)
To: musl, Markus Wichmann
On 2/16/22 14:40, Markus Wichmann wrote:
> Hi all,
>
> today I had a flash of inspiration while staring at some code: errno is
> a global variable, right? OK, it is thread-local, but still a global
> variable in the context of one thread. And looking at a global variable
> while it may (or may not) be modified in a signal handler is not safe to
> do.
It is required that errno, if changed, must be restored by the signal handler before exit
(though note that for glibc the underlying lazy TLS allocation implementation makes errno
AS-unsafe for first use in a signal handler because calloc is used to allocate the storage).
> So now I have to wonder. There are a bunch of functions that set errno,
> that are on the ostensibly async-signal-safe list, like for example
> write(). And to my knowledge, changes to errno are not turned back by
> sigreturn(). So, are changes to errno made in a signal handler
> propagated to the main program? If so, how do I inspect errno correctly
> in the main program? I could block signals, but for one thing, doing so
> every time errno might be relevant is going to be overkill, and for two,
> if the system call I want the errno from is also blocking and I want to
> allow signals while the call is blocking, there is no way to do that
> without race condition.
You don't need to do any of that. A correctly written signal handler must save and
restore errno or not modify it all.
It has been discussed before by both glibc and musl developers that it might be a good
idea all around to wrap signal handlers and save and restore errno in the wrapper
to avoid this entire class of problems (but this is easier said than done).
> But then again, now that I thought of it, this is so obvious that surely
> someone else must have stumbled across it before, right? A solution must
> exist, right?
It's not entirely obvious (like [1] is not always obvious), but it has been discussed and
considered, and the solution is emergent given the standards requirements :}
--
Cheers,
Carlos.
[1] https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/commit/?id=dbb01cbbdb60c34a16d9d48cb58ed3680a5dd36d
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [musl] Is errno signal-safe?
2022-02-16 19:56 ` Carlos O'Donell
@ 2022-02-16 21:01 ` Florian Weimer
2022-02-16 21:02 ` Carlos O'Donell
0 siblings, 1 reply; 4+ messages in thread
From: Florian Weimer @ 2022-02-16 21:01 UTC (permalink / raw)
To: Carlos O'Donell; +Cc: musl, Markus Wichmann
* Carlos O'Donell:
> On 2/16/22 14:40, Markus Wichmann wrote:
>> Hi all,
>>
>> today I had a flash of inspiration while staring at some code: errno is
>> a global variable, right? OK, it is thread-local, but still a global
>> variable in the context of one thread. And looking at a global variable
>> while it may (or may not) be modified in a signal handler is not safe to
>> do.
>
> It is required that errno, if changed, must be restored by the signal
> handler before exit (though note that for glibc the underlying lazy
> TLS allocation implementation makes errno AS-unsafe for first use in a
> signal handler because calloc is used to allocate the storage).
glibc uses initial-exec TLS under the hood for storing the int variable,
so the variable access itself async-signal-safe (whether it goes
directly to errno@GLIBC_PRIVATE or via __errno_location, it doesn't
matter).
Thanks,
Florian
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [musl] Is errno signal-safe?
2022-02-16 21:01 ` Florian Weimer
@ 2022-02-16 21:02 ` Carlos O'Donell
0 siblings, 0 replies; 4+ messages in thread
From: Carlos O'Donell @ 2022-02-16 21:02 UTC (permalink / raw)
To: Florian Weimer; +Cc: musl, Markus Wichmann
On 2/16/22 16:01, Florian Weimer wrote:
> * Carlos O'Donell:
>
>> On 2/16/22 14:40, Markus Wichmann wrote:
>>> Hi all,
>>>
>>> today I had a flash of inspiration while staring at some code: errno is
>>> a global variable, right? OK, it is thread-local, but still a global
>>> variable in the context of one thread. And looking at a global variable
>>> while it may (or may not) be modified in a signal handler is not safe to
>>> do.
>>
>> It is required that errno, if changed, must be restored by the signal
>> handler before exit (though note that for glibc the underlying lazy
>> TLS allocation implementation makes errno AS-unsafe for first use in a
>> signal handler because calloc is used to allocate the storage).
>
> glibc uses initial-exec TLS under the hood for storing the int variable,
> so the variable access itself async-signal-safe (whether it goes
> directly to errno@GLIBC_PRIVATE or via __errno_location, it doesn't
> matter).
Thanks. I'd forgotten about that quirk. Every *other* use of non-initial-exec TLS is
still AS-unsafe.
--
Cheers,
Carlos.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-02-16 21:03 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-16 19:40 [musl] Is errno signal-safe? Markus Wichmann
2022-02-16 19:56 ` Carlos O'Donell
2022-02-16 21:01 ` Florian Weimer
2022-02-16 21:02 ` Carlos O'Donell
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/musl/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).