This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: ctermid: return string literal, document MT-Safety pitfall


On Fri, 2014-11-14 at 21:58 -0200, Alexandre Oliva wrote:
> On Nov 14, 2014, Florian Weimer <fweimer@redhat.com> wrote:
> 
> > On 11/14/2014 05:45 PM, Alexandre Oliva wrote:
> >> Say, given:
> >> 
> >> char foo[5] = "12";
> >> 
> >> int main() {
> >> signal (SIGUSR1, checkme)
> >> strcpy (&foo[1], "23");
> >> }
> >> 
> >> what standard-compliant values can checkme legitimately expect to find
> >> in foo[0], foo[1], foo[2], foo[3], and foo[4]?
> 
> > foo is not an atomic object, so this is undefined.
> 
> Yeah, I goofed in the testcase, and I failed to mention the reasoning
> was supposed to apply to earlier C standards, that we still intend to
> comply with, so our implementation of strcpy shouldn't gratuitously
> break.
> 
> In order to avoid the undefinedness under e.g. C90, the actual string
> couldn't be in static storage.  Getting ahold of a pointer to the string
> storage could be messy, though; maybe C90 and C99 were written so as to
> imply it couldn't be done at all, even if POSIX introduced means that
> would make it possible, such as writing the pointer to a pipe, or to a
> file using POSIX functions not defined in standard C.  If their intent
> was to make access impossible, then my argument would indeed fall apart.
> 
> > As a tried to explain, things turn out rather messy if you add the
> > _Atomic qualifier.  I still think the values are unspecified (despite
> > the standard saying they are not) because the accesses from strcpy and
> > the signal handler are not sequenced.
> 
> Once we make C11 the focus, getting the pointer to the signal handler is
> easier, through an _Atomic intptr_t with static or per-thread storage,
> but the string storage would have to be _Atomic as well, and then, as
> you say, what might happen within strcpy, memcpy et al is not entirely
> clear.  However, making it unspecified might be pushing it too far.

For example, strcpy doesn't take atomic types as arguments, so it won't
access the memory atomically, so you get data races and undefined
behavior unless you make sure that the signal handler happens after or
before the strcpy (via happens-before).

Please have a look at C11 (N1570) 5.1.2.3p10, which gives an example of
an allowed implementation that just guarantees equality of non-volatiles
to the abstract machine at function boundaries.

> The standard could specify, for example, that it is unspecified, within
> an interrupting signal handler, whether observed values would be those
> originally held in the atomic storage, or those that should be put in
> there by the copy, without permitting any other values.

If the signal handler's atomic accesses are concurrent with other atomic
accesses, then there is no data race because atomics don't create data
races.  But strcpy doesn't write with atomics.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]