* Differences between man-pages and libc manual safety markings
@ 2014-10-17 13:26 Michael Kerrisk (man-pages)
[not found] ` <544118FA.3070003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
0 siblings, 1 reply; 35+ messages in thread
From: Michael Kerrisk (man-pages) @ 2014-10-17 13:26 UTC (permalink / raw)
To: Peng Haitao
Cc: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w, Alexandre Oliva,
Carlos O'Donell,
linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Hello Haitao,
I was comparing some of the MT-Safety markings in man-pages versus the glibc
manual (https://www.gnu.org/software/libc/manual/html_mono/libc.html)
I found four cases that seem to contradict. Are there errors in either
the man pages or in the glibc manual?
==
ctermid.3 MT-Unsafe race:ctermid/!s
glibc: MT-Safe
man-pages and glibc manual disagree (man-pages seems to be more
precise than glibc).
==
getcwd.3 MT-Safe env
glibc: MT-Safe
man-pages and glibc manual disagree on "env" (man-pages seems
to be more precise than glibc).
==
getlogin.3 MT-Unsafe race:cuserid/!string locale
glibc: MT-Unsafe race:getlogin race:utent sig:ALRM timer locale
man-pages and glibc manual disagree on "race:cuserid/!string" versus
"race:getlogin"
==
regex.3 MT-Safe env
glibc: MT-Safe locale
man-pages and glibc manual disagree on "env" versus "locale"
==
Cheers,
Michael
--
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 35+ messages in thread[parent not found: <544118FA.3070003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <544118FA.3070003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> @ 2014-10-20 15:47 ` Carlos O'Donell [not found] ` <CAE2sS1jbGRT4uvBBVAPJkX2Mi4gHG=ii_G713MHhQzyGxO4yyw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 2014-10-21 8:31 ` Peng Haitao ` (2 subsequent siblings) 3 siblings, 1 reply; 35+ messages in thread From: Carlos O'Donell @ 2014-10-20 15:47 UTC (permalink / raw) To: Michael Kerrisk (man-pages) Cc: Peng Haitao, Alexandre Oliva, linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Torvald Riegel On Fri, Oct 17, 2014 at 9:26 AM, Michael Kerrisk (man-pages) <mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > I was comparing some of the MT-Safety markings in man-pages versus the glibc > manual (https://www.gnu.org/software/libc/manual/html_mono/libc.html) > I found four cases that seem to contradict. Are there errors in either > the man pages or in the glibc manual? What's missing here is detailed analysis notes. In glibc we added the detailed notes into the comments, and Alex did a great job maintaining those. Peng, if you have detailed notes, please provide them so we can compare to glibc's notes. > == > ctermid.3 MT-Unsafe race:ctermid/!s > glibc: MT-Safe > > man-pages and glibc manual disagree (man-pages seems to be more > precise than glibc). IMO, Alex's original marking is correct. The code in question is a POSIX stub: === char * ctermid (s) char *s; { static char name[L_ctermid]; if (s == NULL) s = name; return strcpy (s, "/dev/tty"); } === Threads could race to set `s` to point to `name` and it would be fine. Similarly threads could race to write to characters in `s` and it would also be fine. They all copy the same thing into the destination buffer. It is only unsafe if you can prove the intermediate results of a pointer copy or strcpy change bytes in the destination string in ways that make it invalid during the copying. Lastly, note that because `s` is not an opaque type, and the user controls it, and we never mark a function unsafe if it's a user controlled buffer. We expect the user to manage that buffer, otherwise tons of functions become unsafe. > == > getcwd.3 MT-Safe env > glibc: MT-Safe > > man-pages and glibc manual disagree on "env" (man-pages seems > to be more precise than glibc). In this particular case I again think glibc's notation is correct. I don't see why `env` is involved in getcwd. Please provide more detailed rationale. > == > getlogin.3 MT-Unsafe race:cuserid/!string locale > glibc: MT-Unsafe race:getlogin race:utent sig:ALRM timer locale > > man-pages and glibc manual disagree on "race:cuserid/!string" versus > "race:getlogin" Peng or others needs to provide more detailed rationale for why they arrived at this result. > == > regex.3 MT-Safe env > glibc: MT-Safe locale > > man-pages and glibc manual disagree on "env" versus "locale" All of the functions in regex touch locales, and therefore we mark this function `MT-Safe locale` because the `locale` annotations are defined as being useful to note that MT-Safety is at risk if locale is modified. Again, functions that modify locales are marked MT-Unsafe const:locale to indicate that using them would break these functions. Why is this marked `env`? Is it because the initialization of the localization information might depend on the environment settings for the locale? If you can prove that then it might be `MT-Safe env locale`, but I the initialization is done via setlocale() and therefore that function has the appropriate markings (not this one). Cheers, Carlos. -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <CAE2sS1jbGRT4uvBBVAPJkX2Mi4gHG=ii_G713MHhQzyGxO4yyw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <CAE2sS1jbGRT4uvBBVAPJkX2Mi4gHG=ii_G713MHhQzyGxO4yyw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> @ 2014-10-21 8:53 ` Peng Haitao [not found] ` <54461F16.2080705-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Peng Haitao @ 2014-10-21 8:53 UTC (permalink / raw) To: Carlos O'Donell, Michael Kerrisk (man-pages) Cc: Alexandre Oliva, linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Torvald Riegel On 10/20/2014 11:47 PM, Carlos O'Donell wrote: > On Fri, Oct 17, 2014 at 9:26 AM, Michael Kerrisk (man-pages) > <mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: >> I was comparing some of the MT-Safety markings in man-pages versus the glibc >> manual (https://www.gnu.org/software/libc/manual/html_mono/libc.html) >> I found four cases that seem to contradict. Are there errors in either >> the man pages or in the glibc manual? > > What's missing here is detailed analysis notes. > > In glibc we added the detailed notes into the comments, and Alex did a > great job maintaining those. > > Peng, if you have detailed notes, please provide them so we can > compare to glibc's notes. > >> == >> ctermid.3 MT-Unsafe race:ctermid/!s >> glibc: MT-Safe >> >> man-pages and glibc manual disagree (man-pages seems to be more >> precise than glibc). > > IMO, Alex's original marking is correct. > POSIX said: The ctermid() function need not be thread-safe if called with a NULL parameter. The tmpnam() function need not be thread-safe if called with a NULL parameter. In glibc manual, tmpnam() is "MT-Unsafe race:tmpnam/!result" ctermid() is "MT-Safe" The code of tmpnam() is: === static char tmpnam_buffer[L_tmpnam]; char *tmpnam (char *s) { char tmpbufmem[L_tmpnam]; char *tmpbuf = s ?: tmpbufmem; if (__builtin_expect (__path_search (tmpbuf, L_tmpnam, NULL, NULL, 0), 0)) return NULL; if (__glibc_unlikely (__gen_tempname (tmpbuf, 0, 0, __GT_NOCREATE))) return NULL; if (s == NULL) return (char *) memcpy (tmpnam_buffer, tmpbuf, L_tmpnam); return s; } === The codes of ctermid() and cuserid() are similar to tmpnam(), so I think ctermid() should be "MT-Unsafe race:ctermid/!s". cuserid() should be "MT-Unsafe race:cuserid/!string locale". Thanks. -- Best Regards, Peng > The code in question is a POSIX stub: > === > char * > ctermid (s) > char *s; > { > static char name[L_ctermid]; > > if (s == NULL) > s = name; > > return strcpy (s, "/dev/tty"); > } > === > > Threads could race to set `s` to point to `name` and it would be fine. > > Similarly threads could race to write to characters in `s` and it > would also be fine. > > They all copy the same thing into the destination buffer. > > It is only unsafe if you can prove the intermediate results of a > pointer copy or strcpy change bytes in the destination string in ways > that make it invalid during the copying. > > Lastly, note that because `s` is not an opaque type, and the user > controls it, and we never mark a function unsafe if it's a user > controlled buffer. We expect the user to manage that buffer, otherwise > tons of functions become unsafe. > >> == >> getcwd.3 MT-Safe env >> glibc: MT-Safe >> >> man-pages and glibc manual disagree on "env" (man-pages seems >> to be more precise than glibc). > > In this particular case I again think glibc's notation is correct. I > don't see why `env` is involved in getcwd. Please provide more > detailed rationale. > >> == >> getlogin.3 MT-Unsafe race:cuserid/!string locale >> glibc: MT-Unsafe race:getlogin race:utent sig:ALRM timer locale >> >> man-pages and glibc manual disagree on "race:cuserid/!string" versus >> "race:getlogin" > > Peng or others needs to provide more detailed rationale for why they > arrived at this result. > >> == >> regex.3 MT-Safe env >> glibc: MT-Safe locale >> >> man-pages and glibc manual disagree on "env" versus "locale" > > All of the functions in regex touch locales, and therefore we mark > this function `MT-Safe locale` because the `locale` annotations are > defined as being useful to note that MT-Safety is at risk if locale is > modified. Again, functions that modify locales are marked MT-Unsafe > const:locale to indicate that using them would break these functions. > > Why is this marked `env`? Is it because the initialization of the > localization information might depend on the environment settings for > the locale? If you can prove that then it might be `MT-Safe env > locale`, but I the initialization is done via setlocale() and > therefore that function has the appropriate markings (not this one). > > Cheers, > Carlos. > -- > To unsubscribe from this list: send the line "unsubscribe linux-man" in > the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > . > -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <54461F16.2080705-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <54461F16.2080705-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org> @ 2014-10-23 6:16 ` Alexandre Oliva [not found] ` <oroat3wbsl.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Alexandre Oliva @ 2014-10-23 6:16 UTC (permalink / raw) To: Peng Haitao Cc: Carlos O'Donell, Michael Kerrisk (man-pages), linux-man@vger.kernel.org, Torvald Riegel On Oct 21, 2014, Peng Haitao <penght-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org> wrote: > The codes of ctermid() and cuserid() are similar to tmpnam(), Not quite. ctermid copies a constant string to the static buffer, so any thread calls it with a NULL string will cause the copy to be done, and when it is complete, nothing different will ever be stored in that buffer, so the thread that completed the call can safely read from the static buffer, and expect to get the constant string. tmpnam does not copy a constant string to the static buffer, so each call may store a different string in it, so race protection is necessary. cuserid is somewhere in between: as long as euid doesn't change, and the same login name is found for that euid, the string will remain the same. I'm concerned I may have missed the static buffer in the analysis, though, because I didn't mention it in the comments, and I don't remember having taking it into account (but then, I don't remember the analysis of this particular function in any other way ;-). I'm inclined to decide the glibc manual entry is missing a MT-Unsafe race:cuserid/!string annotation for cuserid. As for ctermid, I admit that, strictly speaking, there's a potential race as defined by POSIX: one thread may be reading from the static buffer while another is overwriting it with the same bytes, without any intervening synchronization operation. I decided that this is a harmless race. However, should a machine be unable to perform char-sized writes, and instead resorted to larger-sized read-modify-write cycles, then a strcpy implementation that modified one byte at a time with such cycles could race with itself, even writing the same sequence of bytes in the same order. However, if we had such a machine, and we didn't optimize strcpy to coalesce writes to bytes in the same word into a single read-modify-write cycle, we'd be failing at a far more fundamental level. So I crossed my fingers and hoped we'd always have such optimizations, so that the potential race would never become a real problem in this case. -- Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <oroat3wbsl.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <oroat3wbsl.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> @ 2014-10-23 9:29 ` Torvald Riegel [not found] ` <1414056576.8483.79.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Torvald Riegel @ 2014-10-23 9:29 UTC (permalink / raw) To: Alexandre Oliva Cc: Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org On Thu, 2014-10-23 at 04:16 -0200, Alexandre Oliva wrote: > On Oct 21, 2014, Peng Haitao <penght-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org> wrote: > > > The codes of ctermid() and cuserid() are similar to tmpnam(), > > Not quite. > > ctermid copies a constant string to the static buffer, so any thread > calls it with a NULL string will cause the copy to be done, and when it > is complete, nothing different will ever be stored in that buffer, so > the thread that completed the call can safely read from the static > buffer, and expect to get the constant string. > > tmpnam does not copy a constant string to the static buffer, so each > call may store a different string in it, so race protection is > necessary. > > > cuserid is somewhere in between: as long as euid doesn't change, and the > same login name is found for that euid, the string will remain the same. > I'm concerned I may have missed the static buffer in the analysis, > though, because I didn't mention it in the comments, and I don't > remember having taking it into account (but then, I don't remember the > analysis of this particular function in any other way ;-). > > I'm inclined to decide the glibc manual entry is missing a MT-Unsafe > race:cuserid/!string annotation for cuserid. > > As for ctermid, I admit that, strictly speaking, there's a potential > race as defined by POSIX: one thread may be reading from the static > buffer while another is overwriting it with the same bytes, without any > intervening synchronization operation. I decided that this is a > harmless race. I don't think it's easy to classify something as a harmless race. If you violate the data-race-freedom assumption of an implementation, or of the compiler, you're really making assumptions about those implementations. In this case, you must make assumptions about strcpy's implementation to prove that this race condition won't trigger an error in any execution. > However, should a machine be unable to perform > char-sized writes, and instead resorted to larger-sized > read-modify-write cycles, then a strcpy implementation that modified one > byte at a time with such cycles could race with itself, even writing the > same sequence of bytes in the same order. However, if we had such a > machine, and we didn't optimize strcpy to coalesce writes to bytes in > the same word into a single read-modify-write cycle, we'd be failing at > a far more fundamental level. A strcpy implementation can assume that no other thread is observing the data during the execution of the function. Thus, it would be allowed to write intermediate results. For example, it could be allowed to write the whole string, but garbage for the terminating zero, and then fix up the zero afterwards. It could also use funny SIMD instructions or such that don't work like normal memory accesses in a concurrent setting. And so on. So, to make ctermid safe we would have to put these constraints on the implementation, compiler, etc. While I would also guess that none of the above seems likely on current systems, I don't think we can actually track and maintain such requirements -- because they're hacks. This would also be detected by data race detectors, so they would complain about a MT-Safe function. I think there's also hardware being designed on which synchronizing loads/stores differ from nonsynchronizing ones. glibc doesn't run on such hardware today, but if we want to do at some point, this would be an issue. > So I crossed my fingers and hoped we'd > always have such optimizations, so that the potential race would never > become a real problem in this case. I think we should be much more conservative here. Having to cross fingers is not something I want to have to rely on :) -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <1414056576.8483.79.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <1414056576.8483.79.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> @ 2014-10-24 11:48 ` Alexandre Oliva [not found] ` <or38adofh9.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Alexandre Oliva @ 2014-10-24 11:48 UTC (permalink / raw) To: Torvald Riegel Cc: Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man@vger.kernel.org On Oct 23, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: > I don't think it's easy to classify something as a harmless race. In general, I'd agree with you. But writing the same data onto the same memory range with code under our entire control that completes execution on any thread before returning control to any potental reader can access it is such a case IMHO. > In this case, you must make assumptions about strcpy's implementation I did, and I'm quite comfortable with them. Do you have any evidence that they don't hold, or that they might not hold, or are you just making wild speculations about compliant but entirely nonsensical implementations of strcpy that we'd likely never bring into glibc? > It could also use funny SIMD instructions or such that don't work like > normal memory accesses in a concurrent setting. As long as they don't write outside the memory area of the static char[] where we're to store the constant string forever, they should still be safe, because callers can only get to the data after their own thread finishes writing to the string. And if the caller wishes to pass the string on to another thread, then it must ensure the transfer is properly synchronized. So the only potentially dangerous case really is that of strcpy writing intermediate nonsense, or the case I discussed in my previous email, of larger-than-byte read-modify-write cycles that pick up uninitialized fragments and then, after another thread initializes those fragments, overwrite parts of the same word with the uninitialized fragments they read before. > I think there's also hardware being designed on which synchronizing > loads/stores differ from nonsynchronizing ones. It *still* wouldn't be a problem. A reader only gets a chance to read after its own writer completed (over?)writing the memory area with the bits that shall remain there forever. Given this more detailed explanation of the conditions that apply and that IMHO make it perfectly safe, do you still see any concrete error situation here? -- Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <or38adofh9.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <or38adofh9.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> @ 2014-10-24 12:12 ` Torvald Riegel [not found] ` <1414152747.18538.26.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> 2014-10-24 12:14 ` Torvald Riegel 1 sibling, 1 reply; 35+ messages in thread From: Torvald Riegel @ 2014-10-24 12:12 UTC (permalink / raw) To: Alexandre Oliva Cc: Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org On Fri, 2014-10-24 at 09:48 -0200, Alexandre Oliva wrote: > On Oct 23, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: > > > I don't think it's easy to classify something as a harmless race. > > In general, I'd agree with you. > > But writing the same data onto the same memory range with code under our > entire control that completes execution on any thread before returning > control to any potental reader can access it is such a case IMHO. The contract for a normal sequential function is that there must be a certain state or output *after* it has completed execution. There is no guarantee whatsoever about what happens during its execution -- you only get this for concurrent specifications, to some extent. > > In this case, you must make assumptions about strcpy's implementation > > I did, and I'm quite comfortable with them. But did you at the very least document those assumptions on all the strcpy implementations? If not, nothing warns anyone working on those implementations. > Do you have any evidence that they don't hold, or that they might not > hold, or are you just making wild speculations about compliant but > entirely nonsensical implementations of strcpy that we'd likely never > bring into glibc? Why do you think that they are nonsensical? strcpy is a sequential function, so as long as it doesn't touch memory outside of what it is supposed to access, and as long as the state/output matches it's contract when it returns, then the implementation is free to do what it thinks works best. > > It could also use funny SIMD instructions or such that don't work like > > normal memory accesses in a concurrent setting. > > As long as they don't write outside the memory area of the static char[] > where we're to store the constant string forever, they should still be > safe, because callers can only get to the data after their own thread > finishes writing to the string. I agree that they will not see state before the execution of any of the concurrent strcpys, and I never said that. The point is that they can see intermediate writes of other threads, which are allowed to be anything. To put it abstractly: Just because the sequential composition of two strcpy's copying the same string to the same location is as if the two strcpy's were idempotent wrt. each other, it doesn't mean that concurrent execution provides the same guarantees. > And if the caller wishes to pass the > string on to another thread, then it must ensure the transfer is > properly synchronized. That's not the point. > So the only potentially dangerous case really is that of strcpy writing > intermediate nonsense, or the case I discussed in my previous email, of > larger-than-byte read-modify-write cycles that pick up uninitialized > fragments and then, after another thread initializes those fragments, > overwrite parts of the same word with the uninitialized fragments they > read before. > > > > I think there's also hardware being designed on which synchronizing > > loads/stores differ from nonsynchronizing ones. > > It *still* wouldn't be a problem. A reader only gets a chance to read > after its own writer completed (over?)writing the memory area with the > bits that shall remain there forever. The hardware requires synchronizing accesses, and just the mere presence of a data race may lead to undefined behavior of the program. We typically don't have this on current CPUs, where individual loads/stores are basically atomic, or at least are a combination of the individual bytes stored concurrently. But if you bring in a GPU whose firmware, or the driver, is actually a compiler that may do whole-program optimization, things look differently. > > Given this more detailed explanation of the conditions that apply and > that IMHO make it perfectly safe, do you still see any concrete error > situation here? Yes. We can make the trade-off that it's safe *if* in turn, we put the required assumptions (and check them) on all strcpy implementations. But if we don't do the latter, then we're introducing a fault, and even if it may not lead to errors in the present, it's still a fault we're adding. I don't see any point in digging our own bug grave, even if this one here is just a part of it. So, in my opinion, this should either be unsafe (which would be easy -- is there a real benefit to have it be safe?), or we make it safe and document the trade-off, and document the constraints on all strcpy implementations so that future implementers are aware of it. -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <1414152747.18538.26.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <1414152747.18538.26.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> @ 2014-10-24 16:31 ` Alexandre Oliva [not found] ` <orioj9bfaa.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Alexandre Oliva @ 2014-10-24 16:31 UTC (permalink / raw) To: Torvald Riegel Cc: Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man@vger.kernel.org On Oct 24, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: > On Fri, 2014-10-24 at 09:48 -0200, Alexandre Oliva wrote: >> On Oct 23, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: >> >> > I don't think it's easy to classify something as a harmless race. >> >> In general, I'd agree with you. >> >> But writing the same data onto the same memory range with code under our >> entire control that completes execution on any thread before returning >> control to any potental reader can access it is such a case IMHO. > The contract for a normal sequential function is that there must be a > certain state or output *after* it has completed execution. We're not talking about the strcpy contract in the abstract. We're talking about implementations we control, and that ought to be as efficient as possible because it's such a frequently used function. Writing intermediate states is not something such a function would want to do. > There is no > guarantee whatsoever about what happens during its execution There are plenty of guarantees in the existing implementations. Admittedly, I didn't look at all of them, but logic tells me they won't add writes to memory just because they can just so as to feed your FUD. > But did you at the very least document those assumptions on all the > strcpy implementations? No. I rather derived my reasoning from a perfectly reasonable requirement we already place on any strcpy implementation we use: that it shouldn't do more work than what is expected of it. > Why do you think that they are nonsensical? strcpy is a sequential > function, so as long as it doesn't touch memory outside of what it is > supposed to access, and as long as the state/output matches it's > contract when it returns, then the implementation is free to do what it > thinks works best. Sorry, no, we're not living in a purely theoretical world. We're living in a world of real and efficient implementations of strcpy. They don't waste cycles doing useless work such as writing garbage before writing what is expected of them. > The point is that they can see intermediate writes of other threads Which, except for the case I mentioned, are writes of the same data that was already there. What's the problem with that, again? > To put it abstractly: Just because the sequential composition of two > strcpy's copying the same string to the same location is as if the two > strcpy's were idempotent wrt. each other, it doesn't mean that > concurrent execution provides the same guarantees. Will you please come down to Earth and have a look at actual strcpy implementations we ship? >> > I think there's also hardware being designed on which synchronizing >> > loads/stores differ from nonsynchronizing ones. >> >> It *still* wouldn't be a problem. A reader only gets a chance to read >> after its own writer completed (over?)writing the memory area with the >> bits that shall remain there forever. > The hardware requires synchronizing accesses, and just the mere presence > of a data race may lead to undefined behavior of the program. We > typically don't have this on current CPUs, where individual loads/stores > are basically atomic, or at least are a combination of the individual > bytes stored concurrently. But if you bring in a GPU whose firmware, or > the driver, is actually a compiler that may do whole-program > optimization, things look differently. If we get there, we can change this function to use a pre-initialized static buffer and skip the strcpy altogether if the user doesn't supply a buffer. > Yes. We can make the trade-off that it's safe *if* in turn, we put the > required assumptions (and check them) on all strcpy implementations. If you think that necessary, would you please submit a patch to all implementations of such performance-critical micro functions indicating they must not do needless work such as writing garbage before writing what they're told to write at a certain portion of memory? That would be totally redundant IMHO, and it should probably be in pretty much every glibc source file, but if it makes you happy, I wouldn't oppose that. -- Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <orioj9bfaa.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <orioj9bfaa.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> @ 2014-10-24 19:15 ` Torvald Riegel [not found] ` <1414178101.18538.53.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> 2014-10-27 20:46 ` Mark Thompson 1 sibling, 1 reply; 35+ messages in thread From: Torvald Riegel @ 2014-10-24 19:15 UTC (permalink / raw) To: Alexandre Oliva Cc: Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org On Fri, 2014-10-24 at 14:31 -0200, Alexandre Oliva wrote: > On Oct 24, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: > > > On Fri, 2014-10-24 at 09:48 -0200, Alexandre Oliva wrote: > >> On Oct 23, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: > >> > >> > I don't think it's easy to classify something as a harmless race. > >> > >> In general, I'd agree with you. > >> > >> But writing the same data onto the same memory range with code under our > >> entire control that completes execution on any thread before returning > >> control to any potental reader can access it is such a case IMHO. > > > The contract for a normal sequential function is that there must be a > > certain state or output *after* it has completed execution. > > We're not talking about the strcpy contract in the abstract. When somebody works on a strcpy implementation, the strcpy contract is the law. > We're > talking about implementations we control, and that ought to be as > efficient as possible because it's such a frequently used function. > Writing intermediate states is not something such a function would want > to do. Please. We're talking corner cases here. Just because there's obviously bogus stuff that shares a property with a corner case doesn't mean that no corner cases would ever arise in practice. > > There is no > > guarantee whatsoever about what happens during its execution > > There are plenty of guarantees in the existing implementations. > Admittedly, I didn't look at all of them, So you looked at some. Did you look at future ones? Is your future self guaranteed to tell other future implementers about the assumptions you make? > but logic tells me they won't > add writes to memory just because they can just so as to feed your FUD. Please try to understand the difference between being conservative, defensive, or just mindful of future people working on glibc -- and FUD. Trying to not create a potential future problem is not FUD. > > But did you at the very least document those assumptions on all the > > strcpy implementations? > > No. So how should people implementing strcpy differently, in the future, have any idea about your reasoning? > I rather derived my reasoning from a perfectly reasonable > requirement we already place on any strcpy implementation we use: that > it shouldn't do more work than what is expected of it. And that's not what needs to happen. Doing extra, intermediate writes could be one reason. But preventing that doesn't prevent the problem in general. See my remarks about GPUs etc. > > Why do you think that they are nonsensical? strcpy is a sequential > > function, so as long as it doesn't touch memory outside of what it is > > supposed to access, and as long as the state/output matches it's > > contract when it returns, then the implementation is free to do what it > > thinks works best. > > Sorry, no, we're not living in a purely theoretical world. We're living > in a world of real and efficient implementations of strcpy. They don't > waste cycles doing useless work such as writing garbage before writing > what is expected of them. Likewise. Please, just try to be a bit more conservative in the assumptions you make about future HW and potential implementations. > > The point is that they can see intermediate writes of other threads > > Which, except for the case I mentioned, are writes of the same data that > was already there. What's the problem with that, again? > > > To put it abstractly: Just because the sequential composition of two > > strcpy's copying the same string to the same location is as if the two > > strcpy's were idempotent wrt. each other, it doesn't mean that > > concurrent execution provides the same guarantees. > > Will you please come down to Earth and have a look at actual strcpy > implementations we ship? This is not the point! I already said that I would also guess that it works in practice on current systems. Also, if someone should have looked at them, then this would be you. > >> > I think there's also hardware being designed on which synchronizing > >> > loads/stores differ from nonsynchronizing ones. > >> > >> It *still* wouldn't be a problem. A reader only gets a chance to read > >> after its own writer completed (over?)writing the memory area with the > >> bits that shall remain there forever. > > > The hardware requires synchronizing accesses, and just the mere presence > > of a data race may lead to undefined behavior of the program. We > > typically don't have this on current CPUs, where individual loads/stores > > are basically atomic, or at least are a combination of the individual > > bytes stored concurrently. But if you bring in a GPU whose firmware, or > > the driver, is actually a compiler that may do whole-program > > optimization, things look differently. > > If we get there, we can change this function to use a pre-initialized > static buffer and skip the strcpy altogether if the user doesn't supply > a buffer. But we won't know! Because nobody (except you maybe, unless you forgot) will remember that there is this relationship -- you haven't documented the constraint anywhere. And when somebody else implements strcpy, then she'll think about just strcpy, not the additional requirement you added without documenting it. > > Yes. We can make the trade-off that it's safe *if* in turn, we put the > > required assumptions (and check them) on all strcpy implementations. > > If you think that necessary, would you please submit a patch to all > implementations of such performance-critical micro functions indicating > they must not do needless work such as writing garbage before writing > what they're told to write at a certain portion of memory? 1.) That is not what we'd have to document. 2.) You should have done that when deciding to rely on this for making the function MT-Safe. > That would be totally redundant IMHO, and it should probably be in > pretty much every glibc source file, but if it makes you happy, I > wouldn't oppose that. That's not the point. Let me try to make another, similar example, to perhaps make it clearer. nptl has very little documentation of the precise contracts / semantics of many of the synchronization mechanisms etc. So when the people actively working on it change, all the silent assumptions get lost. Which leaves us in a state like now where for a lot of things, we don't really know why they work, under which additional assumptions, etc. And it's so much harder to maintain as a result. Another good example, and one that I've been looking at recently, are the atomic operations. If you look closely, you'll see that on the different archs, some of them vary in terms of the included barriers. And it's not even an obvious bug, because if you look at just all the atomics and not all uses of them in glibc, then making those choices is understandable. It looks reasonable from an arch maintainer perspective. But it's either too few or more barriers than necessary. And what happens with some of the powerpc or x86 atomic ops is that if you use them in a way that seems to match what they promise, it won't work. Yes, it works in (most of) the current code, but it's error-prone. How do we expect to keep this consistent and keep on top of all this if we're not programming defensively and document properly? Do you see the similarities? What did you say about me spreading FUD again? -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <1414178101.18538.53.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <1414178101.18538.53.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> @ 2014-10-30 18:24 ` Alexandre Oliva [not found] ` <orbnottnzb.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Alexandre Oliva @ 2014-10-30 18:24 UTC (permalink / raw) To: Torvald Riegel Cc: Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man@vger.kernel.org On Oct 24, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: >> There are plenty of guarantees in the existing implementations. >> Admittedly, I didn't look at all of them, > So you looked at some. Did you look at future ones? I see that's a rhetorical question. How could anyone? How are they relevant to *current* properties, that I've been asked to document in glibc? Do you remember that that very manual states they are not promises of future behavior of future releases of glibc? >> > But did you at the very least document those assumptions on all the >> > strcpy implementations? >> No. > So how should people implementing strcpy differently, in the future, > have any idea about your reasoning? How could documentation next to current implementations possibly affect people implementing strcpy from scratch in new architectures? How am I supposed to divine what the important features of such future architectures are so that I can document them? How would you? > I already said that I would also guess that it works in practice on > current systems. Good. Then we're in agreement that the current documentation is accurate, in spite of the potential race that future implementations of strcpy might introduce. >> > The hardware requires synchronizing accesses, and just the mere presence >> > of a data race may lead to undefined behavior of the program. Sorry, but “undefined behavior” is standardese for “don't do that”. Real hardware doesn't behave in undefined ways. Since we're talking about existing code running on actual hardware, it is always possible to enumerate what kinds of behaviors may be observed as a consequence of a running certain instruction sequences, with or without interference of other processors/threads/whatever. In some cases, like this one, it can be proven that none of the potential behaviors deviates from that which is desired. >> > But if you bring in a GPU whose firmware, or >> > the driver, is actually a compiler that may do whole-program >> > optimization, things look differently. Yeah, it can just optimize away the strcpy and use the original string, since it's not modified by the caller and its address is not compared wtih anything else. Way to go! And still safe. > But we won't know! Enters your hypothetical race detector for the hypothetical future architecture to report the hypothetical race introduced by the hypothetical strcpy. > How do we expect to keep this consistent and keep on top of all this > if we're not programming defensively and document properly? I agree it might be useful to have some part of the manual, or some other piece of internal documentation, where we document assumptions guiding implementation decisions. We'll have a maintenance challenge in keeping them accurate over time, but I guess they might be better than nothing. Rather than documenting properties of one specific (per-arch, per-ABI, whatever) implementation in its own file, it would be a reference point for anyone starting a new arch from scratch. Maybe you can use whatever pearls you find while going through my notes in the manual to start such a section with information you might find useful. I say you, singular, because, well, you pose as having a much better understanding of the issues than I do, so you couldn't possibly disagree that you're far better suited to do this job than I am. > Do you see the similarities? Not much, really. IIUC, you described cases in which low-level implementations didn't offer standard-imposed guarantees that users expected and relied on, whereas what we are speaking of here is implementations going beyond standard-imposed guarantees, and other implementation internals relying on these (observable but undocumented) guarantees to offer safety properties that, per the standard, need not even be offered in the first place. I wish I could say this reliance led to better performance too, but in this case, it doesn't. -- Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <orbnottnzb.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <orbnottnzb.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> @ 2014-10-30 19:01 ` Torvald Riegel [not found] ` <1414695671.10085.180.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Torvald Riegel @ 2014-10-30 19:01 UTC (permalink / raw) To: Alexandre Oliva Cc: Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org On Thu, 2014-10-30 at 16:24 -0200, Alexandre Oliva wrote: > On Oct 24, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: > > >> There are plenty of guarantees in the existing implementations. > >> Admittedly, I didn't look at all of them, > > > So you looked at some. Did you look at future ones? > > I see that's a rhetorical question. How could anyone? Yep it's a trick question, to some extent. The point I'm trying to make is that future implementations are constrained by the contract of the function, including the MT-Safety guarantees you give. At the very least it's a big heads-up to any future implementation, right? > How are they > relevant to *current* properties, that I've been asked to document in > glibc? Do you remember that that very manual states they are not > promises of future behavior of future releases of glibc? I would have hoped that another goal had been to also come up with documentation that can be easily maintained and adapted when implementations change. I agree that the annotations are no promise of future behavior. But that does not mean that they should bit-rot quickly because it's unclear whether they still hold when anything was changed, like a strcpy implementation that still perfectly fits the strcpy contract and MT-Safety annotations and comments. > >> > But did you at the very least document those assumptions on all the > >> > strcpy implementations? > > >> No. > > > So how should people implementing strcpy differently, in the future, > > have any idea about your reasoning? > > How could documentation next to current implementations possibly affect > people implementing strcpy from scratch in new architectures? Well, they look at other code, you put the constraint in the manual as comments, or anywhere else where it makes future contributors notice it. YOu can't put the comment on a nonexisting future implementation, but there's certainly other ways to do it. > How am I > supposed to divine what the important features of such future > architectures are so that I can document them? How would you? You stick to the contract of a function. In the strcpy example, you say that the string data is required to not be subject to concurrent accesses. > > I already said that I would also guess that it works in practice on > > current systems. > > Good. Then we're in agreement that the current documentation is > accurate, in spite of the potential race that future implementations of > strcpy might introduce. > > > >> > The hardware requires synchronizing accesses, and just the mere presence > >> > of a data race may lead to undefined behavior of the program. > > Sorry, but “undefined behavior” is standardese for “don't do that”. It's don't do that for a reason, not just don't do that and you'll be fine. > Real hardware doesn't behave in undefined ways. Since we're talking > about existing code running on actual hardware, it is always possible to > enumerate what kinds of behaviors may be observed as a consequence of a > running certain instruction sequences, with or without interference of > other processors/threads/whatever. In some cases, like this one, it can > be proven that none of the potential behaviors deviates from that which > is desired. > > >> > But if you bring in a GPU whose firmware, or > >> > the driver, is actually a compiler that may do whole-program > >> > optimization, things look differently. > > Yeah, it can just optimize away the strcpy and use the original string, > since it's not modified by the caller and its address is not compared > wtih anything else. Way to go! And still safe. Do you see that this is just what you would be hoping for, but not all that the compiler would be allowed to do? > > But we won't know! > > Enters your hypothetical race detector for the hypothetical future > architecture to report the hypothetical race introduced by the > hypothetical strcpy. Please try to understand the issue. Maybe you can't imagine someone building glibc with ThreadSanitizer or such, but that doesn't mean it won't happen. > > How do we expect to keep this consistent and keep on top of all this > > if we're not programming defensively and document properly? > > I agree it might be useful to have some part of the manual, or some > other piece of internal documentation, where we document assumptions > guiding implementation decisions. We'll have a maintenance challenge in > keeping them accurate over time, but I guess they might be better than > nothing. Rather than documenting properties of one specific (per-arch, > per-ABI, whatever) implementation in its own file, it would be a > reference point for anyone starting a new arch from scratch. > > Maybe you can use whatever pearls you find while going through my notes > in the manual to start such a section with information you might find > useful. > > I say you, singular, because, well, you pose as having a much better > understanding of the issues than I do, so you couldn't possibly disagree > that you're far better suited to do this job than I am. How is that supposed to work if you haven't documented all the assumptions you made (i.e., if ctermid is not just an outlier)? Should I review all the code again? I offered help in working on a way to define the MT-Safety annotations thoroughly and in a hopefully more future-proof way before you started to work -- but you didn't seem interested back then. You said elsewhere in the thread that you have no other information than what's in the manual. If you have anything else, in general, that might hint at what assumptions you made beyond the contracts of functions (e.g., assumptions about reasonable implementations) but didn't make explicit in the manual, please share this. -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <1414695671.10085.180.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <1414695671.10085.180.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> @ 2014-11-01 8:48 ` Alexandre Oliva [not found] ` <ora94b8fxl.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Alexandre Oliva @ 2014-11-01 8:48 UTC (permalink / raw) To: Torvald Riegel Cc: Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man@vger.kernel.org On Oct 30, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: > On Thu, 2014-10-30 at 16:24 -0200, Alexandre Oliva wrote: >> >> > The hardware requires synchronizing accesses, and just the mere presence >> >> > of a data race may lead to undefined behavior of the program. >> >> Sorry, but “undefined behavior” is standardese for “don't do that”. > It's don't do that for a reason, not just don't do that and you'll be > fine. Yup. But remember, it's users of the standard we implement that are not supposed to do that. We can and often do get away with such stuff as part of the implementation of the standard. There's a long history of doing so: remember when we implemented mutexes without standard atomics? Nowadays, you might look at them and find those implementations disgusting, and think “how the heck nobody thought of documenting the reliance of this code on certain memory model properties that no longer hold?” The obvious answer is that, back then, such properties were perfectly normal and they had no idea something else might take over in the distant future. The point I'm trying to make is that there's only so much future-proofness you can put into this sort of documentation. The most difficult bits to document are not those that are surprising as of the writing of the docs, but those that are blatantly obvious to pretty much anyone at that time, but that over time become surprising. Historians run into lots of walls related with this sort of implicit knowledge of a time. > Please try to understand the issue. I do. It's very clear to me. You wanted and hoped me to do a lot of work that I was not supposed to do, and I didn't do it, in part because I have little hope of seeing the future as well as you claim to be able to. > How is that supposed to work if you haven't documented all the > assumptions you made (i.e., if ctermid is not just an outlier)? It is, but if I were to document all the assumptions I made, I'd have to write several books of assumptions, encoding all the knowledge I've accumulated about how past and present hardware architectures work, any one of which might change in future architectures. > Should I review all the code again? Sure! Clearly you're not happy with the annotations and comments I made, so I don't see another way to go about it. > you didn't seem interested back then. There's a huge difference between being interested and being pragmatic about fulfilling one's assignment from up the management chain, rather than doing somebody else's work while slowing down one's own. > You said elsewhere in the thread that you have no other information than > what's in the manual ... and what we covered in earlier discussions. > what assumptions you made beyond the contracts of functions Heh. It's almost funny that you talk about the contracts of functions, when you yourself claimed their definitions were not clear enough to figure out what the precise requirements were. Please make up your mind about that point before wasting more my time, will you? -- Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <ora94b8fxl.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <ora94b8fxl.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> @ 2014-11-01 10:47 ` Torvald Riegel [not found] ` <1414838867.10085.431.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Torvald Riegel @ 2014-11-01 10:47 UTC (permalink / raw) To: Alexandre Oliva Cc: Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org On Sat, 2014-11-01 at 06:48 -0200, Alexandre Oliva wrote: > On Oct 30, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: > > > On Thu, 2014-10-30 at 16:24 -0200, Alexandre Oliva wrote: > >> >> > The hardware requires synchronizing accesses, and just the mere presence > >> >> > of a data race may lead to undefined behavior of the program. > >> > >> Sorry, but “undefined behavior” is standardese for “don't do that”. > > > It's don't do that for a reason, not just don't do that and you'll be > > fine. > > Yup. But remember, it's users of the standard we implement that are not > supposed to do that. We can and often do get away with such stuff as > part of the implementation of the standard. There's a long history of > doing so: remember when we implemented mutexes without standard atomics? > Nowadays, you might look at them and find those implementations > disgusting, and think “how the heck nobody thought of documenting the > reliance of this code on certain memory model properties that no longer > hold?” The obvious answer is that, back then, such properties were > perfectly normal and they had no idea something else might take over in > the distant future. The point I'm trying to make is that there's only > so much future-proofness you can put into this sort of documentation. I don't disagree with this in general. But in the concrete case we're talking about, it's really not that hard. Does strcpy need to consider that there are concurrent accesses and that it has to do achieve something under concurrent execution, or does it not? It's not surprising that this matters today (ie, when you made the choices), and it's not like we've been aware of this since just yesterday. > The most difficult bits to document are not those that are surprising as > of the writing of the docs, but those that are blatantly obvious to > pretty much anyone at that time, but that over time become surprising. > Historians run into lots of walls related with this sort of implicit > knowledge of a time. That's why I'm arguing for being conservative: Be a little cautious with what you consider obvious. I definitely agree that one can't be perfect with that but, for example, it's a clear difference whether you implement on an additional implementation property or can just rely on the sequential contract of the function. > > Please try to understand the issue. > > I do. It's very clear to me. You wanted and hoped me to do a lot of > work that I was not supposed to do, and I didn't do it, in part because > I have little hope of seeing the future as well as you claim to be able > to. I don't asked you to know about everything that happens in the future. Because that will be hard, as you say. But the result of this is that it helps to be cautious when making assumptions about things that may easily change in the future and that you can't predict. IOW, when you can't easily predict future implementations, be conservative when making assumptions about them. Or at least document that. > > How is that supposed to work if you haven't documented all the > > assumptions you made (i.e., if ctermid is not just an outlier)? > > It is, but if I were to document all the assumptions I made, I'd have to > write several books of assumptions, encoding all the knowledge I've > accumulated about how past and present hardware architectures work, any > one of which might change in future architectures. I don't think it's that hard. Coming back to the "being conservative" point, if you feel like you have to write a book about the assumptions you make that your code (or your documentation, annotations, ...) rely on, then maybe it's better to take a step back and do not make those assumptions in the first place. In our case here, if you feel like what you require from the strcpy implementation is very complex, perhaps just not make the requirement and tag ctermid as unsafe? Or, don't go for specifying assumptions about strcpy in the ctermid docs, but rather try to solve it at the other end by documenting that strcpy has to work well under concurrent execution, in particular under concurrent but "idempotent" copies to a memory range. > > what assumptions you made beyond the contracts of functions > > Heh. It's almost funny that you talk about the contracts of functions, > when you yourself claimed their definitions were not clear enough to > figure out what the precise requirements were. Please make up your mind > about that point before wasting more my time, will you? I never said that the sequential contract of strcpy would be incomplete or wrong in some way. I said that the MT-Safety definition needs improvement. When you make the assumption that it has to work even under concurrent accesses to the destination string, you go beyond the sequential contract of the function. You specified it as MT-Safe, but in your specification that means that the caller-provided data is supposed to be protected from concurrent accesses by the caller. So, your assumption still conflicts with the contract when taking MT-Safe docs into account. Thus, what I said was not inconsistent. -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <1414838867.10085.431.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <1414838867.10085.431.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> @ 2014-11-01 18:32 ` Alexandre Oliva [not found] ` <orwq7e22n2.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Alexandre Oliva @ 2014-11-01 18:32 UTC (permalink / raw) To: Torvald Riegel Cc: Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man@vger.kernel.org On Nov 1, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: > It's not surprising that this matters today (ie, when you made the > choices), and it's not like we've been aware of this since just > yesterday. > That's why I'm arguing for being conservative That goes both ways. While strcpy coded for current standards might wish to make such optimizations, old code written for earlier standards that did not make allowances for the proposed strcpy optimization would break. So we have to be conservative in strcpy to avoid breaking valid old programs (per the standards they were written for), and this implies not making the proposed optimization, which brings us back to the conclusion that the ctermid(NULL) implementation is MT-Safe. And AS-Safe, too. > it helps to be cautious when making assumptions about things that may > easily change in the future and that you can't predict. Per the above, this one property of strcpy is not one that can *easily* change. Quite the opposite. It takes a lot of wording contortionism to make writing garbage fit into the strcpy contract even under current standards. > In our case here, if you feel like what you require from the strcpy > implementation is very complex I don't. The requirements are the common requirements that apply to all historical standards that have specified strcpy. Nothing beyond that. Now that's not much of a strong or surprising assumption, is it? > Or, don't go for specifying assumptions about strcpy in the ctermid > docs, but rather try to solve it at the other end by documenting that > strcpy has to work well under concurrent execution, in particular under > concurrent but "idempotent" copies to a memory range. My take is that requirement is already coded in early C standards.c -- Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <orwq7e22n2.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <orwq7e22n2.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> @ 2014-11-01 18:58 ` Torvald Riegel [not found] ` <1414868298.10085.488.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Torvald Riegel @ 2014-11-01 18:58 UTC (permalink / raw) To: Alexandre Oliva Cc: Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org On Sat, 2014-11-01 at 16:32 -0200, Alexandre Oliva wrote: > On Nov 1, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: > > > It's not surprising that this matters today (ie, when you made the > > choices), and it's not like we've been aware of this since just > > yesterday. > > > That's why I'm arguing for being conservative > > That goes both ways. While strcpy coded for current standards might > wish to make such optimizations, old code written for earlier standards > that did not make allowances for the proposed strcpy optimization would > break. Which earlier standard are you referring to? Did any old standard have strcpy as something else than a sequentially-specified function? > So we have to be conservative in strcpy to avoid breaking valid > old programs (per the standards they were written for), and this implies > not making the proposed optimization, which brings us back to the > conclusion that the ctermid(NULL) implementation is MT-Safe. And > AS-Safe, too. > > > it helps to be cautious when making assumptions about things that may > > easily change in the future and that you can't predict. > > Per the above, this one property of strcpy is not one that can *easily* > change. Quite the opposite. It takes a lot of wording contortionism to > make writing garbage fit into the strcpy contract even under current > standards. No it does not. Sequential specifications for functions are before invocation / after invocation rules -- how the function does it is not restricted, especially if all it does is write to the destination string, in some way. It is not specified as operating on volatile-qualified data, so C as-if rule applies. Same for compilers. If, for a piece of sequential code, the compiler can prove that a location will be written to, then sure it is allowed to write a speculative value early, for example. There's a reason we have the volatile qualifier and it's not the default. > > In our case here, if you feel like what you require from the strcpy > > implementation is very complex > > I don't. The requirements are the common requirements that apply to all > historical standards that have specified strcpy. Nothing beyond that. > Now that's not much of a strong or surprising assumption, is it? > > > Or, don't go for specifying assumptions about strcpy in the ctermid > > docs, but rather try to solve it at the other end by documenting that > > strcpy has to work well under concurrent execution, in particular under > > concurrent but "idempotent" copies to a memory range. > > My take is that requirement is already coded in early C standards.c > They didn't specify rules for multi-threaded execution, did they? There's volatile, and the as-if rule, but the latter really allows stuff like speculative writes. -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <1414868298.10085.488.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <1414868298.10085.488.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> @ 2014-11-03 5:13 ` Alexandre Oliva [not found] ` <or4mug27f7.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Alexandre Oliva @ 2014-11-03 5:13 UTC (permalink / raw) To: Torvald Riegel Cc: Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man@vger.kernel.org On Nov 1, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: > On Sat, 2014-11-01 at 16:32 -0200, Alexandre Oliva wrote: >> That goes both ways. While strcpy coded for current standards might >> wish to make such optimizations, old code written for earlier standards >> that did not make allowances for the proposed strcpy optimization would >> break. > Which earlier standard are you referring to? I think going back to C90 would do. > Did any old standard have strcpy as something else than a > sequentially-specified function? Your question needs to be rephrased to take out the “sequentially-” noise that distorts your reasoning into some kind of tunnel vision. There's nothing specifically sequential about it, nor is it only before/after invocation: the standard states what the function does, and if it does something else that conflicts with the specification and is observable, it diverges from the specification. Right? > especially if all it does is write to the destination > string, in some way. The way is not specified, but it does not state that it is to write something else there before, and doing so is NOT allowed by the as-if rule. Consider a function that goes: for (;;) { extern char buffer[]; strcpy (buffer, "foo"); signal (SIGUSR1, testme); strcpy (buffer, "fool"); signal (SIGUSR1, SIG_IGN); } Now, if the signal handler testme were to inspect buffer[1] (knowing the only window in which it may be activated is the above, in a single-threaded program), what values could it possibly find there? Please justify with quotes from combinations of C and POSIX standards of the same vintage you can find. How about buffer[0], and buffer[3]? > It is not specified as operating on volatile-qualified data volatile doesn't mean what you appear to suggest it does. volatile means operations are not to be reordered, combined or otherwise optimized. It does not mean writing garbage to a global variable is allowed just because it's not volatile, any more than it means the as-if rule allows a function to release a lock on entry and take it again before returning. What if printf were to do that on the lock that controls stdout? Surely that would be observable, as much as the contents of the buffer within the signal handler. > They didn't specify rules for multi-threaded execution, did they? Exactly! I don't think you can push the as-if rule as far as you suggest when it comes to global symbols, or other symbols whose pointers have escaped. POSIX memory synchronization requirements might make speculative writes defensible for asynchronicity arising from threads, but from async signals? I don't see allowances for that, do you? -- Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <or4mug27f7.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <or4mug27f7.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> @ 2014-11-03 16:10 ` Torvald Riegel [not found] ` <1415031006.4531.44.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Torvald Riegel @ 2014-11-03 16:10 UTC (permalink / raw) To: Alexandre Oliva Cc: Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org On Mon, 2014-11-03 at 03:13 -0200, Alexandre Oliva wrote: > On Nov 1, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: > > > On Sat, 2014-11-01 at 16:32 -0200, Alexandre Oliva wrote: > >> That goes both ways. While strcpy coded for current standards might > >> wish to make such optimizations, old code written for earlier standards > >> that did not make allowances for the proposed strcpy optimization would > >> break. > > > Which earlier standard are you referring to? > > I think going back to C90 would do. > > > Did any old standard have strcpy as something else than a > > sequentially-specified function? > > Your question needs to be rephrased to take out the “sequentially-” > noise that distorts your reasoning into some kind of tunnel vision. Ignoring perhaps signal handlers for a second, is there anything in C90 that is not a sequential program? > There's nothing specifically sequential about it, nor is it only > before/after invocation: the standard states what the function does, Yes. And how do function definitions work? You specify before and after. Because you couldn't reasonably specify how it's implemented, nor would you want to. So it has a precondition, and it has a postcondition. Just think about the sorting function analogy I mentioned, will you? > and > if it does something else that conflicts with the specification and is > observable, it diverges from the specification. Right? Sure, but we still don't agree what is specified, so this sentence here doesn't add anything. > > > especially if all it does is write to the destination > > string, in some way. > > The way is not specified, Exactly. Period. Can it set bit by bit? Sure it can, why not? But you would end up with the same kind of "garbage" as you call it. Or you could write by adding 1's until it reaches the final value. > but it does not state that it is to write > something else there before, and doing so is NOT allowed by the as-if > rule. Consider a function that goes: > > for (;;) { > extern char buffer[]; > strcpy (buffer, "foo"); > signal (SIGUSR1, testme); > strcpy (buffer, "fool"); > signal (SIGUSR1, SIG_IGN); > } > > > Now, if the signal handler testme were to inspect buffer[1] (knowing the > only window in which it may be activated is the above, in a > single-threaded program), what values could it possibly find there? > Please justify with quotes from combinations of C and POSIX standards of > the same vintage you can find. How about buffer[0], and buffer[3]? I find it very telling that you completely ignored the sorting function analogy I mentioned. Here is the paragraph again, from my previous email: Would you make any assumptions about the stores performed by a sorting function that is specified to take an array, and return with the array's elements being sorted? Would you require it to only write finally sorted data out, or would you allow it to use the array as scratch space too? I guess the latter. And the same applies to strcpy, you don't want to restrict whether it copies forwards or backwards, for example. And you don't have to for sequential code. Unless you reply to that, I won't spend further time discussing with you. > > > It is not specified as operating on volatile-qualified data > > volatile doesn't mean what you appear to suggest it does. > > volatile means operations are not to be reordered, combined or otherwise > optimized. Precisely, it means that volatile accesses have to executed as-if by the abstract machine. So, if we have volatile for that, do you see that something of this won't hold for nonvolatile? > It does not mean writing garbage to a global variable is > allowed just because it's not volatile, any more than it means the as-if > rule allows a function to release a lock on entry and take it again > before returning. What if printf were to do that on the lock that > controls stdout? Surely that would be observable, as much as the > contents of the buffer within the signal handler. Those examples don't apply here, and I said before why, and you didn't dispute that, so I'm not writing that again. > > They didn't specify rules for multi-threaded execution, did they? > > Exactly! Good. Because then effects of multi-threaded execution are not specified. So there's no constraints. -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <1415031006.4531.44.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <1415031006.4531.44.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> @ 2014-11-04 0:18 ` Alexandre Oliva 0 siblings, 0 replies; 35+ messages in thread From: Alexandre Oliva @ 2014-11-04 0:18 UTC (permalink / raw) To: Torvald Riegel Cc: Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man@vger.kernel.org On Nov 3, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: > Unless you reply to that, I won't spend further time discussing with > you. You promise to stop harrassing me? You got yourself a deal! Thank you thank you thank you! -- Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Differences between man-pages and libc manual safety markings [not found] ` <orioj9bfaa.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> 2014-10-24 19:15 ` Torvald Riegel @ 2014-10-27 20:46 ` Mark Thompson [not found] ` <544EAF20.8050509-W77v16wj1OVeoWH0uzbU5w@public.gmane.org> 1 sibling, 1 reply; 35+ messages in thread From: Mark Thompson @ 2014-10-27 20:46 UTC (permalink / raw) To: Alexandre Oliva, Torvald Riegel Cc: Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org On 24/10/14 17:31, Alexandre Oliva wrote: > > We're not talking about the strcpy contract in the abstract. We're > talking about implementations we control, and that ought to be as > efficient as possible because it's such a frequently used function. > Writing intermediate states is not something such a function would want > to do. > I don't think this assumption is reasonable. While it is not (to my knowledge) violated anywhere in glibc yet, it is not a stretch that a correct and useful implementation of strcpy would be written in the near future on a currently-existing machine which does violate it. To offer a concrete example, consider an instruction which allocates a cache line without reading it from memory, such as wh64 on alpha, tilepro or tilegx. The point of the instruction is to avoid loading part of a cache line if you are going to overwrite all of it, so the explicit semantics from the point of view of the user are that the contents of the cache line addressed are replaced with unspecified data. Removing the redundant load reduces the memory bandwidth used in large copy operations by one third, so this is certainly worth looking at for long strcpy. Now suppose we have such an implementation. Consider two distinct threads copying the same thing which is longer than a cache line into a cache-line-aligned buffer, on a uniprocessor machine: Thread 1: Allocate cache line. Overwrite whole cache line. Return from call. Get preempted. Enough other things happen to flush the whole cache back to memory, including the written line. Thread 2: Allocate cache line (the line is not already present in the cache, so fill with unspecified data to avoid loading an old value from memory). Overwrite the first byte or word, but not the whole line (so it is now dirty, and must therefore overwrite the copy in memory if flushed). Get preempted. Thread 1: User code reads the result, it's wrong. This does have very strong alignment constraints so I don't know whether anyone would actually bother to write an optimised strcpy like this, but it certainly isn't a purely theoretical failing. Note also that if the strcpy here were replaced with strlen+memcpy, it would already be wrong on alpha, tilepro and tilegx with currently released glibc, as all have an optimised memcpy implementation using this feature. Regards, - Mark P.S. Even the "no point in writing redundant data" straw man is made of surprisingly resilient straw. Since strcpy will always write at least one byte, can you really argue that adding "*dest = 0;" to the beginning of a strcpy function is always a bad thing? It seems to me that it actually helps in at least some cases if neither source nor destination is already present in cache, because we can then start loading the first destination line from memory in parallel with the load of the first source line without needing to wait for the data dependency on the source. -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <544EAF20.8050509-W77v16wj1OVeoWH0uzbU5w@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <544EAF20.8050509-W77v16wj1OVeoWH0uzbU5w@public.gmane.org> @ 2014-10-29 8:55 ` Alexandre Oliva [not found] ` <ork33jqmqe.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Alexandre Oliva @ 2014-10-29 8:55 UTC (permalink / raw) To: Mark Thompson Cc: Torvald Riegel, Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man@vger.kernel.org On Oct 27, 2014, Mark Thompson <mrt-W77v16wj1OVeoWH0uzbU5w@public.gmane.org> wrote: > Now suppose we have such an implementation. Consider two distinct > threads copying the same thing which is longer than a cache line "/dev/tty" (the constant string copied in the case at hand) is not longer than a cache line (right? :-), so while your case is compelling, it doesn't apply. > Since strcpy will always write at least one byte, can you really argue > that adding "*dest = 0;" to the beginning of a strcpy function is > always a bad thing? Now, this one is compelling *and* fitting IMHO. Of course we could rule this out in glibc, but should we? Maybe not. So I guess we're better off fixing the implementation of ctermid(NULL) to return a pointer to a constant string that (per POSIX) must not be modified by the caller, rather than needlessly copying it to another buffer. Then, if/when such a strcpy implementation comes up, we'll be ready for it ;-) Thanks, -- Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <ork33jqmqe.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <ork33jqmqe.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> @ 2014-10-29 9:12 ` Torvald Riegel [not found] ` <1414573935.18538.74.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Torvald Riegel @ 2014-10-29 9:12 UTC (permalink / raw) To: Alexandre Oliva Cc: Mark Thompson, Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org On Wed, 2014-10-29 at 06:55 -0200, Alexandre Oliva wrote: > On Oct 27, 2014, Mark Thompson <mrt-W77v16wj1OVeoWH0uzbU5w@public.gmane.org> wrote: > > > Now suppose we have such an implementation. Consider two distinct > > threads copying the same thing which is longer than a cache line > > "/dev/tty" (the constant string copied in the case at hand) is not > longer than a cache line (right? :-), so while your case is compelling, > it doesn't apply. That depends on the alignment of the strings. It's 9 bytes including trailing zero... > > Since strcpy will always write at least one byte, can you really argue > > that adding "*dest = 0;" to the beginning of a strcpy function is > > always a bad thing? > > Now, this one is compelling *and* fitting IMHO. > > Of course we could rule this out in glibc, but should we? Maybe not. > > So I guess we're better off fixing the implementation of ctermid(NULL) > to return a pointer to a constant string that (per POSIX) must not be > modified by the caller, rather than needlessly copying it to another > buffer. Then, if/when such a strcpy implementation comes up, we'll be > ready for it ;-) Yes, we either need to change the implementation, or make it MT-Unsafe for now. We should also review all other cases of "benign" race conditions. As this example shows, they can be not "benign" without this being easy to spot. So, IMO, we should really avoid them unless we have a strong reason not to. This will also give less false positives when using race detectors. Alex, when you did the MT Safety review, which other cases of "benign" race conditions did you see? It would be useful to revisit those, I think. -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <1414573935.18538.74.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <1414573935.18538.74.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> @ 2014-10-30 18:00 ` Alexandre Oliva [not found] ` <orfve5tp3e.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Alexandre Oliva @ 2014-10-30 18:00 UTC (permalink / raw) To: Torvald Riegel Cc: Mark Thompson, Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man@vger.kernel.org On Oct 29, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: > On Wed, 2014-10-29 at 06:55 -0200, Alexandre Oliva wrote: >> On Oct 27, 2014, Mark Thompson <mrt-W77v16wj1OVeoWH0uzbU5w@public.gmane.org> wrote: >> >> > Now suppose we have such an implementation. Consider two distinct >> > threads copying the same thing which is longer than a cache line >> >> "/dev/tty" (the constant string copied in the case at hand) is not >> longer than a cache line (right? :-), so while your case is compelling, >> it doesn't apply. > That depends on the alignment of the strings. No, sorry. The alignment of a string that is smaller than a cache can't possibly make the string itself bigger than a cache line, and any padding introduced by alignment, before or after the string, won't make strcpy copy more bytes than the size of the string. Maybe you were thinking of straddling over more than one a cache line? That still wouldn't apply: the case mark described was one in which an *entire* cache line would be overwritten, so it didn't have to be fetched from memory. If a smaller-than-cache-line string is placed entirely in a single cache line, it will require that line to be fetched; if it straddles over two cache lines, it requires *both* to be fetched; if it didn't, or if it straddled over more than two cache lines, it wouldn't be smaller than the cache line. >> > Since strcpy will always write at least one byte, can you really argue >> > that adding "*dest = 0;" to the beginning of a strcpy function is >> > always a bad thing? >> >> Now, this one is compelling *and* fitting IMHO. >> >> Of course we could rule this out in glibc, but should we? Maybe not. >> >> So I guess we're better off fixing the implementation of ctermid(NULL) >> to return a pointer to a constant string that (per POSIX) must not be >> modified by the caller, rather than needlessly copying it to another >> buffer. Then, if/when such a strcpy implementation comes up, we'll be >> ready for it ;-) > Yes, we either need to change the implementation, or make it MT-Unsafe > for now. We only have to make it MT-Unsafe for now if the scenario above, of strcpy *always* writing a zero byte to the beginning of the destination string, were present in any implementation of strcpy in glibc. Do you see any implementations of strcpy in glibc doing that? > As this example shows, they can be not "benign" without this being > easy to spot. As much as you might want it to be so, it doesn't show an such thing. The example just shows that changing part of the implementation can make other parts that rely on it racy, so changes that might affect safety properties have to be made with a lot of care. Now that's not much of a surprise, is it? > Alex, when you did the MT Safety review, which other cases of "benign" > race conditions did you see? We've already discussed them in the list where we should have been discussing this in the first place. You have access to my notes in the comments added next to the safety annotations in the manual. That's all I got. -- Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <orfve5tp3e.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <orfve5tp3e.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> @ 2014-10-30 18:41 ` Torvald Riegel [not found] ` <1414694486.10085.165.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Torvald Riegel @ 2014-10-30 18:41 UTC (permalink / raw) To: Alexandre Oliva Cc: Mark Thompson, Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org On Thu, 2014-10-30 at 16:00 -0200, Alexandre Oliva wrote: > On Oct 29, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: > > > On Wed, 2014-10-29 at 06:55 -0200, Alexandre Oliva wrote: > >> On Oct 27, 2014, Mark Thompson <mrt-W77v16wj1OVeoWH0uzbU5w@public.gmane.org> wrote: > >> > >> > Now suppose we have such an implementation. Consider two distinct > >> > threads copying the same thing which is longer than a cache line > >> > >> "/dev/tty" (the constant string copied in the case at hand) is not > >> longer than a cache line (right? :-), so while your case is compelling, > >> it doesn't apply. > > > That depends on the alignment of the strings. > > No, sorry. The alignment of a string that is smaller than a cache can't > possibly make the string itself bigger than a cache line, and any > padding introduced by alignment, before or after the string, won't make > strcpy copy more bytes than the size of the string. > > Maybe you were thinking of straddling over more than one a cache line? Yep, and agreed that this wasn't what Mark described. > >> > Since strcpy will always write at least one byte, can you really argue > >> > that adding "*dest = 0;" to the beginning of a strcpy function is > >> > always a bad thing? > >> > >> Now, this one is compelling *and* fitting IMHO. > >> > >> Of course we could rule this out in glibc, but should we? Maybe not. > >> > >> So I guess we're better off fixing the implementation of ctermid(NULL) > >> to return a pointer to a constant string that (per POSIX) must not be > >> modified by the caller, rather than needlessly copying it to another > >> buffer. Then, if/when such a strcpy implementation comes up, we'll be > >> ready for it ;-) > > > Yes, we either need to change the implementation, or make it MT-Unsafe > > for now. > > We only have to make it MT-Unsafe for now if the scenario above, of > strcpy *always* writing a zero byte to the beginning of the destination > string, were present in any implementation of strcpy in glibc. > > Do you see any implementations of strcpy in glibc doing that? Can we please fix faults even if they are not triggering a error right now? Please? Why should we jump through all those hoops, make all those assumptions, just to stick to this unusual reasoning? We want to build stuff that's easy to maintain, not a maze. > > > As this example shows, they can be not "benign" without this being > > easy to spot. > > As much as you might want it to be so, it doesn't show an such thing. No, it definitely does. You made an assumption about a "perfectly reasonable requirement we already place on any strcpy implementation we use". Mark showed that there are reasonable, and existing, strcpy implementations (or similar for memcpy) that conflict with your assumption. So, it seems your "perfectly reasonable requirement" is (1) not so obviously clear at all and (2) would be easy to break by perfectly reasonable implementations. > The example just shows that changing part of the implementation can make > other parts that rely on it racy, so changes that might affect safety > properties have to be made with a lot of care. That's the wrong way around. The situation you describe exists in practice, yes, but it's what we need to avoid, not the goal. We have contracts for functions, and documentation, to actually decrease complexity. This means that we need to be able to change implementations of functions if they still satisfy the contract. It's simply a matter of trying to keep things modular -- divide an conquer. In this example, strcpy is sequential code, period. (Of course, as far as the string data is concerned.) That's the existing contract. You made an assumption in your MT-Safe reasoning that *extends* this contract with an additional rule (for which we needed several emails to define it, so no, it's not a trivial addition) -- that certain race conditions must be benign. Thus, either you are breaking the contract, or you need to document that this is the new contract. > Now that's not much of a surprise, is it? > > > Alex, when you did the MT Safety review, which other cases of "benign" > > race conditions did you see? > > We've already discussed them in the list where we should have been > discussing this in the first place. > > You have access to my notes in the comments added next to the safety > annotations in the manual. That's all I got. In the notes for ctermid, I can't see anything that would hint at an assumed benign race condition. Does that mean that you didn't make notes for benign race conditions in general? -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <1414694486.10085.165.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <1414694486.10085.165.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> @ 2014-11-01 8:24 ` Alexandre Oliva [not found] ` <oregtn8h23.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Alexandre Oliva @ 2014-11-01 8:24 UTC (permalink / raw) To: Torvald Riegel Cc: Mark Thompson, Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man@vger.kernel.org On Oct 30, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: > On Thu, 2014-10-30 at 16:00 -0200, Alexandre Oliva wrote: >> Do you see any implementations of strcpy in glibc doing that? > Can we please fix faults even if they are not triggering a error right > now? Sure! But the way to fix that is *not* modifying a piece of documentation that is supposed to document current state, and that does, into something that doesn't, is it? strcpy as it is implemented today makes ctermid MT-Safe. That's what the current documentation states, and AFAICT that is correct. Do you disagree? If so, please point out in current code where it deviates. > No, it definitely does. You made an assumption about a "perfectly > reasonable requirement we already place on any strcpy implementation we > use". ... and that current implementations of strcpy in glibc abide by, so the above is tautologically correct. Introducing different behavior, such as unconditionally writing something else on the string, is indeed a change in the current contract. > So, it seems your "perfectly reasonable requirement" is (1) > not so obviously clear at all I guess it will be once you observe the existing implementations. Have you? > and (2) would be easy to break by perfectly reasonable > implementations. That much is true. Which is why ctermid safety notes have comments in the manual indicating what's going on in there, and why it's safe in spite of the potential race. > This means that we need to be able to change > implementations of functions if they still satisfy the contract. So you agree that it would be perfectly legitimate to address the current problem by documentng that glibc's implementatios of strcpy must not write to the destination any data other than what they were asked to write? Or even that concurrent runs of strcpy writing the same string to the same destination must not introduce windows in which data other than what is being written or what was in there before is visible? These are all derivable from current implementations in glibc, so it wouldn't be changing any contracts, just imposing further requirements on future implementations so as to keep the current ctermid safe. > In the notes for ctermid, I can't see anything that would hint at an > assumed benign race condition. Are you sure you're looking at the right place? @deftypefun {char *} ctermid (char *@var{string}) @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} @c This function is a stub by default; the actual implementation, for @c posix systems, returns an internal buffer if passed a NULL string, @c but the internal buffer is always set to /dev/tty. > Does that mean that you didn't make notes for benign race conditions > in general? If you saw the above and didn't see that, we can agree they're not in a form you expect. But no, I don't think I have made notes with blinking red letters whenever I made an assumption you'd disagree with. We've covered some of them already in past discussions that led nowhere, so I won't repeat myself to avoid wasting both of us even more time. I will just say that, after we had that conversation and I agreed to take additional notes of potential races involving bit operations in IOstream functions, I didn't find any more of those, and ctermid is certainly an outlier; I don't recall other situations that involved that sort of reasoning. Other pervasive cases I'm not sure I mentioned then have to do with unguarded access to constant locale data, that have only been annotated when the pointer to the current locale object is accessed more than once. That's really all I can think of that you might find objectionable, but I'm sure there'd be plenty of other cases you'd have objected to if you had done the review. Now here's something that might make your head spin: here's the object code generated for ctermid, non-PIC (but PIC is different only in how it initializes %rdx with the address of the buffer): 0000000000000000 <ctermid>: 0: 48 89 f8 mov %rdi,%rax 3: 48 85 ff test %rdi,%rdi 6: ba 00 00 00 00 mov $0x0,%edx 7: R_X86_64_32 .bss b: 48 0f 44 c2 cmove %rdx,%rax f: 48 b9 2f 64 65 76 2f movabs $0x7974742f7665642f,%rcx 16: 74 74 79 19: 48 89 08 mov %rcx,(%rax) 1c: c6 40 08 00 movb $0x0,0x8(%rax) 20: c3 retq Do you see any strcpy call in there? Yeah, the compiler turns strcpy of a constant into memcpy, and that in turn gets inlined into a word-and-byte store. This in turn invalidates Mark Thompson's reasoning: now there's no longer any point in storing a NUL upfront to cache the dest line in *while* we load the beginning of src, because src is part of the instruction stream. Writing a byte upfront would just waste cycles that could have been spent writing the actual data, so no sane optimizing compiler would do that. -- Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <oregtn8h23.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <oregtn8h23.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> @ 2014-11-01 12:40 ` Torvald Riegel [not found] ` <1414845631.10085.474.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Torvald Riegel @ 2014-11-01 12:40 UTC (permalink / raw) To: Alexandre Oliva Cc: Mark Thompson, Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org On Sat, 2014-11-01 at 06:24 -0200, Alexandre Oliva wrote: > On Oct 30, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: > > > On Thu, 2014-10-30 at 16:00 -0200, Alexandre Oliva wrote: > >> Do you see any implementations of strcpy in glibc doing that? > > > Can we please fix faults even if they are not triggering a error right > > now? > > Sure! But the way to fix that is *not* modifying a piece of > documentation that is supposed to document current state, and that does, > into something that doesn't, is it? > > strcpy as it is implemented today makes ctermid MT-Safe. That's what > the current documentation states, and AFAICT that is correct. Do you > disagree? If so, please point out in current code where it deviates. The fault is in the difference between what strcpy is specified to do (ie, it's sequential contract plus your MT-Safe annotation that, however, requires callers to protect caller-supplied data from data races) -- and what you rely on. You didn't document that difference, or your assumption, anywhere. Even if our current implementation doesn't trigger an issue, there's still a fault in your documentation. That's what I'm talking about. > > No, it definitely does. You made an assumption about a "perfectly > > reasonable requirement we already place on any strcpy implementation we > > use". > > ... and that current implementations of strcpy in glibc abide by, so the > above is tautologically correct. Ahem, no. Because we do not place this requirement on any strcpy implementation, or is it documented or obvious anywhere? The fact that current implementations happen to abide by such a requirement does not mean that we make this requirement. If so, you could point me at it. And no, referring to all other implementations and saying "do exactly what they do" is not an implicit requirement. > Introducing different behavior, such > as unconditionally writing something else on the string, is indeed a > change in the current contract. No, it's not. It deviates from what current implementations might do. But the sequential contract of strcpy says that the accesses should only go to what the abstract machine would do (ie, don't write to other strings), and that *when strcpy* returns, it must have copied. That's the contract. > > So, it seems your "perfectly reasonable requirement" is (1) > > not so obviously clear at all > > I guess it will be once you observe the existing implementations. > Have you? See Mark's comments. Are you saying that the implementation possibility he mentions is obviously wrong? If it's not, then you don't have an obvious requirement to not do it. > > and (2) would be easy to break by perfectly reasonable > > implementations. > > That much is true. Which is why ctermid safety notes have comments in > the manual indicating what's going on in there, and why it's safe in > spite of the potential race. No. All that I see is this (which you're aware of, see below): @c This function is a stub by default; the actual implementation, for @c posix systems, returns an internal buffer if passed a NULL string, @c but the internal buffer is always set to /dev/tty. Where does it talk about a potential data race? It says that's there a shared buffer, but it does not mention that there's something special about how the buffer is initialized. Nor that this affects strcpy implementations in any way. And how do you expect strcpy implementers to be aware of this, in practice, with high probability? Should they review all the callers and look for undocumented assumptions? Do you think that this scales well and keeps complexity down? > > This means that we need to be able to change > > implementations of functions if they still satisfy the contract. > > So you agree that it would be perfectly legitimate to address the > current problem by documentng that glibc's implementatios of strcpy must > not write to the destination any data other than what they were asked to > write? Or even that concurrent runs of strcpy writing the same string > to the same destination must not introduce windows in which data other > than what is being written or what was in there before is visible? The latter is better. > These are all derivable from current implementations in glibc, so it > wouldn't be changing any contracts, just imposing further requirements > on future implementations so as to keep the current ctermid safe. No. Implementations do not define the contract. Implementations satisfy the contract. The point of reasoning in terms of contracts is that those provide an abstraction, and state the requirements on implementations. This allows decoupling, which is critical for keeping complexity at a maintainable level. You can ignore all that and assume that the only contract of a function is the union of its implementations. But that's BAD when we have a function like strcpy that already has a contract. It's not so bad when we do this in tightly coupled functions, and it would be overkill to specify a contract for, say, a static function that just has two call sites in the function right next to it in the same file. But why should strcpy and ctermid be tightly coupled? > > In the notes for ctermid, I can't see anything that would hint at an > > assumed benign race condition. > > Are you sure you're looking at the right place? > > @deftypefun {char *} ctermid (char *@var{string}) > @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} > @c This function is a stub by default; the actual implementation, for > @c posix systems, returns an internal buffer if passed a NULL string, > @c but the internal buffer is always set to /dev/tty. Yes that. See above... > > Does that mean that you didn't make notes for benign race conditions > > in general? > > If you saw the above and didn't see that, we can agree they're not in a > form you expect. But no, I don't think I have made notes with blinking > red letters whenever I made an assumption you'd disagree with. We've > covered some of them already in past discussions that led nowhere, so I > won't repeat myself to avoid wasting both of us even more time. I will > just say that, after we had that conversation and I agreed to take > additional notes of potential races involving bit operations in IOstream > functions, I didn't find any more of those, and ctermid is certainly an > outlier; I don't recall other situations that involved that sort of > reasoning. Good. That information helps, thanks. > Other pervasive cases I'm not sure I mentioned then have to > do with unguarded access to constant locale data, that have only been > annotated when the pointer to the current locale object is accessed more > than once. I can't quite follow that. Do the accesses constitute data races? Can you give me some more pointers or background info? > That's really all I can think of that you might find > objectionable, but I'm sure there'd be plenty of other cases you'd have > objected to if you had done the review. Or maybe not. What makes you think that way? I'm asking to get a feel for what else you might have assumed to be okay that I wouldn't. > Now here's something that might make your head spin: Sorry, but why? If, then because this example doesn't actually support your arguments. I'm arguing that bringing in additional dependencies on implementation details doesn't help keeping complexity down nor makes things less fragile -- and you give an example that adds even more dependencies (ie, assumptions about a specific compiler)? Oh, and BTW, I already mentioned that one has to consider the compiler too when dealing with "benign" race conditions, didn't I? > here's the object > code generated for ctermid, non-PIC (but PIC is different only in how it > initializes %rdx with the address of the buffer): > > 0000000000000000 <ctermid>: > 0: 48 89 f8 mov %rdi,%rax > 3: 48 85 ff test %rdi,%rdi > 6: ba 00 00 00 00 mov $0x0,%edx > 7: R_X86_64_32 .bss > b: 48 0f 44 c2 cmove %rdx,%rax > f: 48 b9 2f 64 65 76 2f movabs $0x7974742f7665642f,%rcx > 16: 74 74 79 > 19: 48 89 08 mov %rcx,(%rax) > 1c: c6 40 08 00 movb $0x0,0x8(%rax) > 20: c3 retq > > Do you see any strcpy call in there? Yeah, the compiler turns strcpy of > a constant into memcpy, So now you depend on the compiler's memcpy implementation. Great. We can consider the optimized memcpy Mark mentions. (strcpy on constant string is strlen (known a priori) + memcpy.) > and that in turn gets inlined into a > word-and-byte store. This in turn invalidates Mark Thompson's > reasoning: now there's no longer any point in storing a NUL upfront to > cache the dest line in *while* we load the beginning of src, because src > is part of the instruction stream. Writing a byte upfront would just > waste cycles that could have been spent writing the actual data, so no > sane optimizing compiler would do that. Please look again at the case he described. The src doesn't matter, it's the destination. The only thing that saves you here is that cachelines will be likely longer than "/dev/tty" plus trailing zero. So if we would change the string and make it longer, you'd hit exactly the issue you described if the compiler's memcpy makes the optimization. -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <1414845631.10085.474.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <1414845631.10085.474.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> @ 2014-11-01 18:22 ` Alexandre Oliva [not found] ` <or1tpm3hn5.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Alexandre Oliva @ 2014-11-01 18:22 UTC (permalink / raw) To: Torvald Riegel Cc: Mark Thompson, Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man@vger.kernel.org On Nov 1, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: > On Sat, 2014-11-01 at 06:24 -0200, Alexandre Oliva wrote: >> strcpy as it is implemented today makes ctermid MT-Safe. That's what >> the current documentation states, and AFAICT that is correct. Do you >> disagree? If so, please point out in current code where it deviates. > The fault is in the difference between what strcpy is specified to do Please point out the part of strcpy's contract that states it can write garbage to the destination before writing what it ought to, and then you (and Mark) might have a point. Don't even bother arguing a function might do things not explicitly written out in their specs, or I'll suggest functions might release locks and take them back at will, just to put things in a familiar context in which you'd see how bad that would be. You may then resort to the as-if rule combined with the requirement for synchronization points between reads and writes by different threads, and that would be correct for *current* standards. Not so for much older standards, that had no such requirements, and that existing programs still target, so we should ideally provide an implementation suitable for them. So, who changed the contract and put in additional requirements, again? > See Mark's comments. Are you saying that the implementation possibility > he mentions is obviously wrong? It depends on the targeted standard. For recent standards, it's a legitimate optimization. For older standards, it would not be. For future ones, I seem to have misplaced my crystal ball . > @c This function is a stub by default; the actual implementation, for > @c posix systems, returns an internal buffer if passed a NULL string, > @c but the internal buffer is always set to /dev/tty. > Where does it talk about a potential data race? It says that's there a > shared buffer, but it does not mention that there's something special > about how the buffer is initialized. Nor that this affects strcpy > implementations in any way. See?, that's what I said about the notes not being in a form you wanted. The information is all there: there's a static shared buffer (as required by ctermid(NULL), and that's usually not thread-safe, but that's tacit knowledge of our time not explicitly duplicated there), and it's always set to /dev/tty (and the fact that it uses strcpy is just an implementation detail that, after optimization, is not even true any more). > And how do you expect strcpy implementers to be aware of this, in > practice, with high probability? I don't. You wish they would, and I understand why, but that's all. You wish I had solved a documentation problem, but I was under no obligation to do so and I had enough on my plate already so I did not jump through additional hoops just to satisfy your wishes. > Should they review all the callers and look for undocumented > assumptions? I'm afraid that's how things have usually been done. > Do you think that this scales well and keeps complexity down? No. I don't disagree such documentation is desirable. >> Other pervasive cases I'm not sure I mentioned then have to >> do with unguarded access to constant locale data, that have only been >> annotated when the pointer to the current locale object is accessed more >> than once. > I can't quite follow that. Do the accesses constitute data races? Can > you give me some more pointers or background info? Look at the implementation of the ctype family of macros/functions, for one. Technically, there are data races in there: the global pointer to the current locale object can be modified by other threads and they don't take anything like a read lock to ensure they have the current pointer and that it's not being modified concurrently. However, because of the way locale is implemented, the pointer is modified atomically (while holding a write lock, and written as a single word to a properly aligned location), so readers in other threads may get either the old pointer or the new one. The old locale data remains valid forever (till the end of the program), so it is safe to keep on using it until some synchronization point or whatever else updates the local view of the global pointer. Numerous functions access ctype data once; given the above, those are never a problem, in spite of the race in the global locale pointer. Some functions access ctype data multiple times; given the above, and because the locale structures are accessed in a way that enable the compiler to load the global locale pointer only once, and the compiler performs this optimization (or, in some cases, the load is factored out explicitly in the source code), these are not a problem, in spite of the same race. Some functions call multiple functions that each access ctype data, each one loading the global locale pointer independently. These are prone to inconsistent behavior, since parts of their execution may use one locale while another part may use another locale. These were consistently marked with the “locale” keyword. >> That's really all I can think of that you might find >> objectionable, but I'm sure there'd be plenty of other cases you'd have >> objected to if you had done the review. > Or maybe not. What makes you think that way? That you've surprised me again and again with objections to issues I hadn't regarded as objectionable. > I'm asking to get a feel for what else you might have assumed to be > okay that I wouldn't. How could I do that without knowing what *your* criteria could be? >> Now here's something that might make your head spin: > Sorry, but why? Because we've been talking about strcpy, because my recollection incorrectly told me ctermid used the internal, non-preemptible name for strcpy, but strcpy happens to be actually irrelevant because it is optimized away. > So now you depend on the compiler's memcpy implementation. Great. We > can consider the optimized memcpy Mark mentions. (strcpy on constant > string is strlen (known a priori) + memcpy.) Well, no, it's more efficient than that, because it doesn't have to load the src: it is a known constant. It's more like an open-coded array initialization. > Please look again at the case he described. Likewise. No, seriously, I mean, look at the *other* case he described, the one that actually matters. Not the one about invalidating a entire cache line, that I've already demonstrated as not applicable to this short string, but you get back to with a hypothetical larger string that might indeed invalidate the underlying assumptions. I'm sorry to disappoint you, but my code review abilities do not cover hypothetical and nonsensical changes you might want to suggest just to break observations derived from the code on which the documented properties were based. I was talking about the one that starts out by writing garbage to the first byte to trigger the prefetching of that cache line. The one that would break the strcpy contract of old standards, but that is valid under current standards' contracts that include the as-if rule and the no-data-races mandate. -- Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <or1tpm3hn5.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <or1tpm3hn5.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> @ 2014-11-01 19:54 ` Torvald Riegel [not found] ` <1414871691.10085.529.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Torvald Riegel @ 2014-11-01 19:54 UTC (permalink / raw) To: Alexandre Oliva Cc: Mark Thompson, Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org On Sat, 2014-11-01 at 16:22 -0200, Alexandre Oliva wrote: > On Nov 1, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: > > > On Sat, 2014-11-01 at 06:24 -0200, Alexandre Oliva wrote: > >> strcpy as it is implemented today makes ctermid MT-Safe. That's what > >> the current documentation states, and AFAICT that is correct. Do you > >> disagree? If so, please point out in current code where it deviates. > > > The fault is in the difference between what strcpy is specified to do > > Please point out the part of strcpy's contract that states it can write > garbage to the destination before writing what it ought to, and then you > (and Mark) might have a point. It's a sequential specification, so before/after, the intermediate steps are unspecified, so it is allowed to do what it wants there. Within the rules of C -- so as-if applies here. And that doesn't disallow strcpy to prevent writing intermediate states (whether you consider them garbage or not). Would you make any assumptions about the stores performed by a sorting function that is specified to take an array, and return with the array's elements being sorted? Would you require it to only write finally sorted data out, or would you allow it to use the array as scratch space too? I guess the latter. And the same applies to strcpy, you don't want to restrict whether it copies forwards or backwards, for example. And you don't have to for sequential code. > Don't even bother arguing a function might do things not explicitly > written out in their specs, or I'll suggest functions might release > locks and take them back at will, just to put things in a familiar > context in which you'd see how bad that would be. First, now you're talking about concurrent code, not sequential code. If we assume we have concurrent code, then you could even release and acquire locks at will if you can prove that this is still okay under as-if. But that's besides the point we're discussing here because... .. strcpy is not specified as a concurrent function, is it? And it doesn't operate on volatile data. So, yes, it can write other stuff to the strings it will overwrite eventually with the final results. Same as a sorting function might do. The requirement is about the state after the function has completed, not while it does something. That's why these things are called post-conditions. > > You may then resort to the as-if rule combined with the requirement for > synchronization points between reads and writes by different threads, > and that would be correct for *current* standards. Not so for much > older standards, that had no such requirements, If you're referring to pre-C11 C standards, then they had a single-threaded abstract machine, didn't they? > and that existing > programs still target, so we should ideally provide an implementation > suitable for them. > > > So, who changed the contract and put in additional requirements, again? > > > See Mark's comments. Are you saying that the implementation possibility > > he mentions is obviously wrong? > > It depends on the targeted standard. For recent standards, it's a > legitimate optimization. For older standards, it would not be. Unless you say which "older standards" you actually refer to, I can't interpret your statement. Because older standards for single-threaded abstract machines do allow this. > For > future ones, I seem to have misplaced my crystal ball . > > > @c This function is a stub by default; the actual implementation, for > > @c posix systems, returns an internal buffer if passed a NULL string, > > @c but the internal buffer is always set to /dev/tty. > > > Where does it talk about a potential data race? It says that's there a > > shared buffer, but it does not mention that there's something special > > about how the buffer is initialized. Nor that this affects strcpy > > implementations in any way. > > See?, that's what I said about the notes not being in a form you wanted. > The information is all there: there's a static shared buffer (as > required by ctermid(NULL), and that's usually not thread-safe, but > that's tacit knowledge of our time not explicitly duplicated there), Wow, really? It supposed to be "tacit knowledge of our time" to not have thread-safe initialization of a static buffer? Or have a pre-initialized static buffer? "but the internal buffer is always set to /dev/tty" makes it obvious that there's a data race? Really? Maybe we should make a poll on libc-alpha to see which percentage of people actually understands this comment as implying that there is a data race. > and > it's always set to /dev/tty (and the fact that it uses strcpy is just an > implementation detail that, after optimization, is not even true any > more). The validity of this comment relies on the "implementation detail" and on other implementation details such as what the compiler does. So that doesn't look like "just an implementation detail" to me... > > And how do you expect strcpy implementers to be aware of this, in > > practice, with high probability? > > I don't. You wish they would, and I understand why, but that's all. > You wish I had solved a documentation problem, but I was under no > obligation to do so and I had enough on my plate already so I did not > jump through additional hoops just to satisfy your wishes. I'm not really sure what to say after reading that. Also note that "your wishes" isn't what this is about -- it is about maintainable documentation. This affects glibc in general. > > Should they review all the callers and look for undocumented > > assumptions? > > I'm afraid that's how things have usually been done. > > > Do you think that this scales well and keeps complexity down? > > No. I don't disagree such documentation is desirable. > > >> Other pervasive cases I'm not sure I mentioned then have to > >> do with unguarded access to constant locale data, that have only been > >> annotated when the pointer to the current locale object is accessed more > >> than once. > > > I can't quite follow that. Do the accesses constitute data races? Can > > you give me some more pointers or background info? > > Look at the implementation of the ctype family of macros/functions, for > one. Technically, there are data races in there: the global pointer to > the current locale object can be modified by other threads and they > don't take anything like a read lock to ensure they have the current > pointer and that it's not being modified concurrently. > > However, because of the way locale is implemented, the pointer is > modified atomically (while holding a write lock, and written as a single > word to a properly aligned location), so readers in other threads may > get either the old pointer or the new one. > > The old locale data remains valid forever (till the end of the program), > so it is safe to keep on using it until some synchronization point or > whatever else updates the local view of the global pointer. > > Numerous functions access ctype data once; given the above, those are > never a problem, in spite of the race in the global locale pointer. I have to look at this in detail, but I'm concerned about two issues there: 1) Do the loads use an acquire fence (ie, atomic_read_barrier)? If not, is any new locale data they can read from initialized before those reads (e.g., at program startup, so happening before any spawned threads)? 2) If the compiler sees such a load (e.g., because it's a macro, or with LTO and inlining), and it's not marked as an atomic access, it can be free to reload it. Which could lead to partially reading from the old and new locale. > Some functions access ctype data multiple times; given the above, and > because the locale structures are accessed in a way that enable the > compiler to load the global locale pointer only once, and the compiler > performs this optimization So correctness applies in some cases on certain, optional compiler optimizations to be performed? That wouldn't be good. > (or, in some cases, the load is factored out > explicitly in the source code), these are not a problem, in spite of the > same race. > > Some functions call multiple functions that each access ctype data, each > one loading the global locale pointer independently. These are prone to > inconsistent behavior, since parts of their execution may use one locale > while another part may use another locale. These were consistently > marked with the “locale” keyword. Thanks for the additional information. It's helpful. > > >> That's really all I can think of that you might find > >> objectionable, but I'm sure there'd be plenty of other cases you'd have > >> objected to if you had done the review. > > > Or maybe not. What makes you think that way? > > That you've surprised me again and again with objections to issues I > hadn't regarded as objectionable. > > > I'm asking to get a feel for what else you might have assumed to be > > okay that I wouldn't. > > How could I do that without knowing what *your* criteria could be? You can't a priori. But we can keep talking, and you can explain more of your reasoning, and we can further discuss it to see whether there are differences. The above is a good start, so I appreciate that. > >> Now here's something that might make your head spin: > > > Sorry, but why? > > Because we've been talking about strcpy, because my recollection > incorrectly told me ctermid used the internal, non-preemptible name for > strcpy, but strcpy happens to be actually irrelevant because it is > optimized away. > > > So now you depend on the compiler's memcpy implementation. Great. We > > can consider the optimized memcpy Mark mentions. (strcpy on constant > > string is strlen (known a priori) + memcpy.) > > Well, no, it's more efficient than that, because it doesn't have to load > the src: it is a known constant. It's more like an open-coded array > initialization. As I said in my previous email, how to write to the destination matters. > > Please look again at the case he described. > > Likewise. No, seriously, I mean, look at the *other* case he described, > the one that actually matters. Not the one about invalidating a entire > cache line, that I've already demonstrated as not applicable to this > short string, but you get back to with a hypothetical larger string that > might indeed invalidate the underlying assumptions. Oh great, > I'm sorry to > disappoint you, but my code review abilities do not cover hypothetical > and nonsensical changes you might want to suggest just to break > observations derived from the code on which the documented properties > were based. > > I was talking about the one that starts out by writing garbage to the > first byte to trigger the prefetching of that cache line. The one that > would break the strcpy contract of old standards, but that is valid > under current standards' contracts that include the as-if rule Then please refer me to the concrete old standard (and we should support it, actually) and the wording in there that *requires* strcpy to issue a certain set of stores instead of just, for example, requiring that when the function returns, the string has been copied. Second, when you've done that, could you please explain to me how a compiler is supposed to optimize code without something like an as-if rule? > and the > no-data-races mandate. For there to be data races, the standard must actually acknowledge that things are supposed to work in a multi-threaded setting. Could you refer me to the respective wording too, please? -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <1414871691.10085.529.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <1414871691.10085.529.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org> @ 2014-11-03 5:43 ` Alexandre Oliva [not found] ` <orzjc8zvn6.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> 0 siblings, 1 reply; 35+ messages in thread From: Alexandre Oliva @ 2014-11-03 5:43 UTC (permalink / raw) To: Torvald Riegel Cc: Mark Thompson, Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man@vger.kernel.org On Nov 1, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: >> The information is all there: there's a static shared buffer (as >> required by ctermid(NULL), and that's usually not thread-safe, but >> that's tacit knowledge of our time not explicitly duplicated there), > Wow, really? It supposed to be "tacit knowledge of our time" to not > have thread-safe initialization of a static buffer? You seem to have misread what I wrote. It's the fact that ctermid(NULL) is not required to be thread-safe that is tacit knowledge of our time. > "but the internal buffer is always set > to /dev/tty" makes it obvious that there's a data race? The reasoning indicates there's something non-obvious going on there. When there isn't, there's no reason for any such note. > Maybe we should make a poll on libc-alpha to see which percentage of > people actually understands this comment as implying that there is a > data race. Will you please stop putting words I didn't say in my mouth? Where did I say the comment meant to imply that there was a data race in there? All it was meant to do was justify why I regarded the function as MT-Safe and AS-Safe, in spite of the possibility of concurrent initializations of the buffer. > Also note that "your wishes" isn't what this is about -- it is about > maintainable documentation. This affects glibc in general. That's still your wishes for additional documentation that nobody has stepped up to do. Others (myself included) may share such a wish for better documentation on various fronts, but none of this would entitle you to demand me to do so, or to complain that I didn't, when I never agreed to do it. > 1) Do the loads use an acquire fence (ie, atomic_read_barrier)? No. > If not, is any new locale data they can read from initialized before > those reads (e.g., at program startup, so happening before any spawned > threads)? No > 2) If the compiler sees such a load (e.g., because it's a macro, or with > LTO and inlining), and it's not marked as an atomic access, it can be > free to reload it. Which could lead to partially reading from the old > and new locale. Yes, but only if there's more than one use (thus marked locale). If there's only one use, the compiler could, but would not do something that stupid. >> Some functions access ctype data multiple times; given the above, and >> because the locale structures are accessed in a way that enable the >> compiler to load the global locale pointer only once, and the compiler >> performs this optimization > So correctness applies in some cases on certain, optional compiler > optimizations to be performed? That is glibc's locale design, yes. Sane compilers help keep glibc sane and safe. We are indeed relying on compiler sanity. > Then please refer me to the concrete old standard (and we should support > it, actually) and the wording in there that *requires* strcpy to issue a > certain set of stores instead of just, for example, requiring that when > the function returns, the string has been copied. These are equivalent requirements IMHO, because neither makes other allowances for using the user-visible storage as scratch space, and both, because of asynchronous signals, rule this possibility out for storage that the signal handler could observe. Anyway, let's leave this point for the other sub-thread, to avoid duplication, shall we? > Second, when you've done that, could you please explain to me how a > compiler is supposed to optimize code without something like an as-if > rule? The key is external observability, and ordering requirements. strcpy's sequential specification does not mandate chars to be copied in any predetermined order, so strcpy is free to reorder and regroup loads and stores as it sees fit. None of this steps out of its explicit specification. Writing garbage, however, would step out, but it might still be allowed under the as-if rule if this couldn't be legitimately observed, e.g. if any attempt to observe it would invoke undefined behavior. >> and the >> no-data-races mandate. > For there to be data races, the standard must actually acknowledge that > things are supposed to work in a multi-threaded setting. Could you > refer me to the respective wording too, please? Why are you doing this? You know where this requirement is in POSIX! For a long time we have had threads as a POSIX add-on to C standards that said nothing about threads. POSIX imports (defers to) standard C without conflicting with it. It logically follows from these two statements that all requirements from standard C on strcpy implementations still apply under POSIX. If you agree that a signal handlers' ability to observe deviations from standard-mandated behavior indicate deviation from the standard, rather than something that could be tolerated under the as-if rule, then this strcpy requirement carries over to the multi-thread extensions to C specified in POSIX. -- Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <orzjc8zvn6.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <orzjc8zvn6.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> @ 2014-11-03 13:07 ` Mark Thompson [not found] ` <54577E17.7000109-W77v16wj1OVeoWH0uzbU5w@public.gmane.org> 2014-11-03 15:55 ` Torvald Riegel 1 sibling, 1 reply; 35+ messages in thread From: Mark Thompson @ 2014-11-03 13:07 UTC (permalink / raw) To: Alexandre Oliva, Torvald Riegel Cc: linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org On 03/11/14 05:43, Alexandre Oliva wrote: > > The key is external observability, and ordering requirements. > > strcpy's sequential specification does not mandate chars to be copied in > any predetermined order, so strcpy is free to reorder and regroup loads > and stores as it sees fit. None of this steps out of its explicit > specification. Writing garbage, however, would step out, but it might > still be allowed under the as-if rule if this couldn't be legitimately > observed, e.g. if any attempt to observe it would invoke undefined > behavior. On 03/11/14 05:13, Alexandre Oliva wrote: > > The way is not specified, but it does not state that it is to write > something else there before, and doing so is NOT allowed by the as-if > rule. Consider a function that goes: > > for (;;) { > extern char buffer[]; > strcpy (buffer, "foo"); > signal (SIGUSR1, testme); > strcpy (buffer, "fool"); > signal (SIGUSR1, SIG_IGN); > } > > > Now, if the signal handler testme were to inspect buffer[1] (knowing the > only window in which it may be activated is the above, in a > single-threaded program), what values could it possibly find there? > Please justify with quotes from combinations of C and POSIX standards of > the same vintage you can find. How about buffer[0], and buffer[3]? > I disagree with this reasoning, though I am not sufficiently familiar with the standards involved to argue with it effectively. However, I do see a more concerning point here: does this argument also apply to memcpy()? I can't find any language in the standard which places additional requirements on strcpy() (and which would disallow implementation as strlen+memcpy, for example). Given that, does it not follow that the current, released, implementation of memcpy() in glibc for architectures using a wh64 instruction (alpha, tilepro and tilegx) is entirely wrong? - Mark -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <54577E17.7000109-W77v16wj1OVeoWH0uzbU5w@public.gmane.org>]
* Re: Differences between man-pages and libc manual safety markings [not found] ` <54577E17.7000109-W77v16wj1OVeoWH0uzbU5w@public.gmane.org> @ 2014-11-19 0:26 ` Alexandre Oliva 0 siblings, 0 replies; 35+ messages in thread From: Alexandre Oliva @ 2014-11-19 0:26 UTC (permalink / raw) To: Mark Thompson; +Cc: Torvald Riegel, linux-man@vger.kernel.org On Nov 3, 2014, Mark Thompson <mrt-W77v16wj1OVeoWH0uzbU5w@public.gmane.org> wrote: > I disagree with this reasoning, though I am not sufficiently familiar > with the standards involved to argue with it effectively. > However, I do see a more concerning point here: does this argument > also apply to memcpy()? If the argument is correct, then I don't see why it wouldn't. The discussion has been ongoing in glibc-alpha, but it's not clear that any argument any of us might bring up at this point would amount to global consensus on what the standards actually meant, so I take it they're more like exploring what is already defined and what isn't, to perhaps later seek clarification from the standard bodies. > Given that, does it not follow that the current, released, > implementation of memcpy() in glibc for architectures using a wh64 > instruction (alpha, tilepro and tilegx) is entirely wrong? If the argument, as stated, is correct, yes. There's an alternative argument that wouldn't rule it out, though, that amounts to requiring the implementation to stick to the stated specification of *copying* data from source to destination (as opposed to writing random bits in dest until it compares equal to source), but with enough leeway to make copying behavior that performs cache-line invalidation when there is certainty that the entire cache line is going to be overwritten. It is hard to specify that formally, but the intuitive notion could be that, if the implementation does what the spec says it should (namely, reading from source and storing in target), besides ensuring the postconditions are met if the preconditions were met to begin with, without modifying memory that shouldn't have been modified, it could be ok. That's not my reading, but it's a possibility the standard bodies might consider if the intent is to rule out garbage writing but not cache invalidation. -- Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Differences between man-pages and libc manual safety markings [not found] ` <orzjc8zvn6.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> 2014-11-03 13:07 ` Mark Thompson @ 2014-11-03 15:55 ` Torvald Riegel 1 sibling, 0 replies; 35+ messages in thread From: Torvald Riegel @ 2014-11-03 15:55 UTC (permalink / raw) To: Alexandre Oliva Cc: Mark Thompson, Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org On Mon, 2014-11-03 at 03:43 -0200, Alexandre Oliva wrote: > On Nov 1, 2014, Torvald Riegel <triegel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote: > > >> The information is all there: there's a static shared buffer (as > >> required by ctermid(NULL), and that's usually not thread-safe, but > >> that's tacit knowledge of our time not explicitly duplicated there), > > > Wow, really? It supposed to be "tacit knowledge of our time" to not > > have thread-safe initialization of a static buffer? > > You seem to have misread what I wrote. It's the fact that ctermid(NULL) > is not required to be thread-safe that is tacit knowledge of our time. I don't find that interpretation any less surprising. So, again, why is that "tacit knowledge of our time"? > > "but the internal buffer is always set > > to /dev/tty" makes it obvious that there's a data race? > > The reasoning indicates there's something non-obvious going on there. > When there isn't, there's no reason for any such note. So, the note says that an internal buffer is used if NULL is returned, but this buffer is always set to /dev/tty. Why does that indicate that there's a race, or that ctermid(NULL) is not MT-Safe, different from the actual annotation you added? > > Maybe we should make a poll on libc-alpha to see which percentage of > > people actually understands this comment as implying that there is a > > data race. > > Will you please stop putting words I didn't say in my mouth? That's the way I understood your comment but ... > Where did I say the comment meant to imply that there was a data race in > there? > > All it was meant to do was justify why I regarded the function as > MT-Safe and AS-Safe, in spite of the possibility of concurrent > initializations of the buffer. ... we can as well make a poll about this reasoning of yours above. > > Also note that "your wishes" isn't what this is about -- it is about > > maintainable documentation. This affects glibc in general. > > That's still your wishes for additional documentation that nobody has > stepped up to do. Others (myself included) may share such a wish for > better documentation on various fronts, but none of this would entitle > you to demand me to do so, or to complain that I didn't, when I never > agreed to do it. Yeah, you never promised me to create maintainable documentation. So I can't demand it. I just thought that this would be common sense, and as here, it's actually not a lot of work. You'd have had to just write another sentence, or say @ data race on initialization of static buffer or @ buffer initialized by running strcpy potentially concurrently or really something like that. Sorry if I've asked for something outrageous here... > > 1) Do the loads use an acquire fence (ie, atomic_read_barrier)? > > No. > > > If not, is any new locale data they can read from initialized before > > those reads (e.g., at program startup, so happening before any spawned > > threads)? > > No Then this sounds like a bug that could trigger an error on archs with weak HW memory models. And to be clear, I'd never asked you to fix it, but I would have appreciated if you gave me (or other glibc folks) a heads-up that something might be fishy here, so *somebody* (not you, don't worry) can revisit it later on. I guess nobody specifically asked you to report potential bugs you've found during the review for MT-Safety. It would have just been better if you did note them... > > 2) If the compiler sees such a load (e.g., because it's a macro, or with > > LTO and inlining), and it's not marked as an atomic access, it can be > > free to reload it. Which could lead to partially reading from the old > > and new locale. > > Yes, but only if there's more than one use (thus marked locale). If > there's only one use, the compiler could, but would not do something > that stupid. Register pressure? Whenever you say "something that stupid", it should have a very simple reason. So if you can't give a one-sentence reply why reload would be "that stupid", then maybe you're wrong, huh? > >> Some functions access ctype data multiple times; given the above, and > >> because the locale structures are accessed in a way that enable the > >> compiler to load the global locale pointer only once, and the compiler > >> performs this optimization > > > So correctness applies in some cases on certain, optional compiler > > optimizations to be performed? > > That is glibc's locale design, yes. Sane compilers help keep glibc sane > and safe. We are indeed relying on compiler sanity. Sanity is not defined by adhering to the hacks you have in mind but by adhering to the standards and following the conventions that all the involved projects have agreed on. Should we make a poll with the gcc folks to see how many would agree reloading a nonatomic / non-shared mem location would be insane? > > Then please refer me to the concrete old standard (and we should support > > it, actually) and the wording in there that *requires* strcpy to issue a > > certain set of stores instead of just, for example, requiring that when > > the function returns, the string has been copied. > > These are equivalent requirements IMHO, because neither makes other > allowances for using the user-visible storage as scratch space, and > both, because of asynchronous signals, rule this possibility out for > storage that the signal handler could observe. Anyway, let's leave this > point for the other sub-thread, to avoid duplication, shall we? Fine, let's continue there... > > Second, when you've done that, could you please explain to me how a > > compiler is supposed to optimize code without something like an as-if > > rule? > > The key is external observability, and ordering requirements. > > strcpy's sequential specification does not mandate chars to be copied in > any predetermined order, But it's not explicitly allowed either. This contradicts with what you said above. Please make a consistent argument. Otherwise, I'll reply: strcpy's sequential specification does not mandata chars to be copied atomically, so we can copy by adding 1 to each char until it reaches the final value. > so strcpy is free to reorder and regroup loads > and stores as it sees fit. None of this steps out of its explicit > specification. Writing garbage, however, would step out, but it might > still be allowed under the as-if rule if this couldn't be legitimately > observed, e.g. if any attempt to observe it would invoke undefined > behavior. If that is how you interpret the language standard, then please tell me why we need volatile. Seriously. > >> and the > >> no-data-races mandate. > > > For there to be data races, the standard must actually acknowledge that > > things are supposed to work in a multi-threaded setting. Could you > > refer me to the respective wording too, please? > > Why are you doing this? You know where this requirement is in POSIX! > > For a long time we have had threads as a POSIX add-on to C standards > that said nothing about threads. POSIX imports (defers to) standard C > without conflicting with it. It logically follows from these two > statements that all requirements from standard C on strcpy > implementations still apply under POSIX. If you agree that a signal > handlers' ability to observe deviations from standard-mandated behavior The question is still what standard-mandated behavior is. Which you don't constrain by bringing in POSIX. > indicate deviation from the standard, rather than something that could > be tolerated under the as-if rule, then this strcpy requirement carries > over to the multi-thread extensions to C specified in POSIX. Also, think about the compiler example with strcpy being replaced by the compiler, that *you* brought up. Do you think the compiler agrees with, or is at least aware of your opinion, that it has to make strcpy volatile because POSIX uses C and you interpret it to mean that every handler can peek into intermediate state and find something that you think makes sense? A side note: We can keep discussing this, but I can't imagine any further additional reasons you could bring up why either the ctermid MT-Safety annotation is incomplete or the glibc implementation of ctermid is wrong. In this discussion, you and I disagree, and Mark seems to disagree with your reasoning as well. Maybe you should get other opinions, or just agree that maybe your reasoning might not be as fault-free as it may seem. A second side note: When us three here are discussing this for ages, then obviously, your MT-Safety note on ctermid is NOT easy to understand. There should be absolutely no discussion that something needs to change. If any of our documentation leads to at least some disagreement between glibc contributors, it's not clear enough. Period. -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Differences between man-pages and libc manual safety markings [not found] ` <or38adofh9.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org> 2014-10-24 12:12 ` Torvald Riegel @ 2014-10-24 12:14 ` Torvald Riegel 1 sibling, 0 replies; 35+ messages in thread From: Torvald Riegel @ 2014-10-24 12:14 UTC (permalink / raw) To: Alexandre Oliva Cc: Peng Haitao, Carlos O'Donell, Michael Kerrisk (man-pages), linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org On Fri, 2014-10-24 at 09:48 -0200, Alexandre Oliva wrote: > Given this more detailed explanation of the conditions that apply and > that IMHO make it perfectly safe, do you still see any concrete error > situation here? Oh, and I forgot to highlight the race detection issue again. Unnecessarily introducing false positives with race detectors doesn't sound useful to me... -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Differences between man-pages and libc manual safety markings [not found] ` <544118FA.3070003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2014-10-20 15:47 ` Carlos O'Donell @ 2014-10-21 8:31 ` Peng Haitao 2015-01-07 6:12 ` Michael Kerrisk (man-pages) 2015-01-07 6:16 ` Michael Kerrisk (man-pages) 3 siblings, 0 replies; 35+ messages in thread From: Peng Haitao @ 2014-10-21 8:31 UTC (permalink / raw) To: Michael Kerrisk (man-pages), Carlos O'Donell Cc: Alexandre Oliva, linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org On 10/17/2014 09:26 PM, Michael Kerrisk (man-pages) wrote: > Hello Haitao, > > I was comparing some of the MT-Safety markings in man-pages versus the glibc > manual (https://www.gnu.org/software/libc/manual/html_mono/libc.html) > I found four cases that seem to contradict. Are there errors in either > the man pages or in the glibc manual? > > == > ctermid.3 MT-Unsafe race:ctermid/!s > glibc: MT-Safe > > man-pages and glibc manual disagree (man-pages seems to be more > precise than glibc). > > == > getcwd.3 MT-Safe env > glibc: MT-Safe > > man-pages and glibc manual disagree on "env" (man-pages seems > to be more precise than glibc). > In getcwd.3 man-page: getcwd() and getwd() are "MT-Safe" get_current_dir_name() is "MT-Safe env" URL: http://thread.gmane.org/gmane.linux.man/6580 The annotations are equal to glibc manual:) > == > getlogin.3 MT-Unsafe race:cuserid/!string locale > glibc: MT-Unsafe race:getlogin race:utent sig:ALRM timer locale > > man-pages and glibc manual disagree on "race:cuserid/!string" versus > "race:getlogin" > In getlogin.3 man-page: getlogin() is "MT-Unsafe locale" getlogin_r() is "MT-Safe locale" cuserid() is "MT-Unsafe race:cuserid/!string locale" In glibc manual: getlogin() is "MT-Unsafe race:getlogin race:utent sig:ALRM timer locale" getlogin_r() is nonexistent cuserid() is "MT-Safe locale" glibc manual is more precise than man-page of getlogin(). The difference of cuserid() is similar to ctermid(). > == > regex.3 MT-Safe env > glibc: MT-Safe locale > In regex.3 man-page: regcomp() and regexec() are "MT-Safe locale" regerror() is "MT-Safe env" regfree() is "MT-Safe" URL: http://thread.gmane.org/gmane.linux.man/6609 The annotations are equal to glibc manual:) -- Best Regards, Peng > man-pages and glibc manual disagree on "env" versus "locale" > > == > > Cheers, > > Michael > > -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Differences between man-pages and libc manual safety markings [not found] ` <544118FA.3070003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2014-10-20 15:47 ` Carlos O'Donell 2014-10-21 8:31 ` Peng Haitao @ 2015-01-07 6:12 ` Michael Kerrisk (man-pages) 2015-01-07 6:16 ` Michael Kerrisk (man-pages) 3 siblings, 0 replies; 35+ messages in thread From: Michael Kerrisk (man-pages) @ 2015-01-07 6:12 UTC (permalink / raw) To: Ma Shimiao Cc: Peng Haitao, mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w, Alexandre Oliva, Carlos O'Donell, linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Qian Lei [CC += Ma Shimiao] Hello Ma Shimiao, As the person taking over the ATTRIBUTES patch series for man-pages, are you aware of the earlier mail thread below? I will CC you into one or two of the other notable mails in this thread as well. Thanks, Michael On 10/17/2014 03:26 PM, Michael Kerrisk (man-pages) wrote: > Hello Haitao, > > I was comparing some of the MT-Safety markings in man-pages versus the glibc > manual (https://www.gnu.org/software/libc/manual/html_mono/libc.html) > I found four cases that seem to contradict. Are there errors in either > the man pages or in the glibc manual? > > == > ctermid.3 MT-Unsafe race:ctermid/!s > glibc: MT-Safe > > man-pages and glibc manual disagree (man-pages seems to be more > precise than glibc). > > == > getcwd.3 MT-Safe env > glibc: MT-Safe > > man-pages and glibc manual disagree on "env" (man-pages seems > to be more precise than glibc). > > == > getlogin.3 MT-Unsafe race:cuserid/!string locale > glibc: MT-Unsafe race:getlogin race:utent sig:ALRM timer locale > > man-pages and glibc manual disagree on "race:cuserid/!string" versus > "race:getlogin" > > == > regex.3 MT-Safe env > glibc: MT-Safe locale > > man-pages and glibc manual disagree on "env" versus "locale" > > == > > Cheers, > > Michael > > -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/ -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: Differences between man-pages and libc manual safety markings [not found] ` <544118FA.3070003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> ` (2 preceding siblings ...) 2015-01-07 6:12 ` Michael Kerrisk (man-pages) @ 2015-01-07 6:16 ` Michael Kerrisk (man-pages) 3 siblings, 0 replies; 35+ messages in thread From: Michael Kerrisk (man-pages) @ 2015-01-07 6:16 UTC (permalink / raw) To: Peng Haitao, Ma Shimiao Cc: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w, Alexandre Oliva, Carlos O'Donell, linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Hi Ma Shimiao, You can see the whole discussion thread here: http://thread.gmane.org/gmane.linux.man/7223 Thanks, Michael On 10/17/2014 03:26 PM, Michael Kerrisk (man-pages) wrote: > Hello Haitao, > > I was comparing some of the MT-Safety markings in man-pages versus the glibc > manual (https://www.gnu.org/software/libc/manual/html_mono/libc.html) > I found four cases that seem to contradict. Are there errors in either > the man pages or in the glibc manual? > > == > ctermid.3 MT-Unsafe race:ctermid/!s > glibc: MT-Safe > > man-pages and glibc manual disagree (man-pages seems to be more > precise than glibc). > > == > getcwd.3 MT-Safe env > glibc: MT-Safe > > man-pages and glibc manual disagree on "env" (man-pages seems > to be more precise than glibc). > > == > getlogin.3 MT-Unsafe race:cuserid/!string locale > glibc: MT-Unsafe race:getlogin race:utent sig:ALRM timer locale > > man-pages and glibc manual disagree on "race:cuserid/!string" versus > "race:getlogin" > > == > regex.3 MT-Safe env > glibc: MT-Safe locale > > man-pages and glibc manual disagree on "env" versus "locale" > > == > > Cheers, > > Michael > > -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/ -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 35+ messages in thread
end of thread, other threads:[~2015-01-07 6:16 UTC | newest]
Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-10-17 13:26 Differences between man-pages and libc manual safety markings Michael Kerrisk (man-pages)
[not found] ` <544118FA.3070003-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2014-10-20 15:47 ` Carlos O'Donell
[not found] ` <CAE2sS1jbGRT4uvBBVAPJkX2Mi4gHG=ii_G713MHhQzyGxO4yyw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-10-21 8:53 ` Peng Haitao
[not found] ` <54461F16.2080705-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
2014-10-23 6:16 ` Alexandre Oliva
[not found] ` <oroat3wbsl.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>
2014-10-23 9:29 ` Torvald Riegel
[not found] ` <1414056576.8483.79.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>
2014-10-24 11:48 ` Alexandre Oliva
[not found] ` <or38adofh9.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>
2014-10-24 12:12 ` Torvald Riegel
[not found] ` <1414152747.18538.26.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>
2014-10-24 16:31 ` Alexandre Oliva
[not found] ` <orioj9bfaa.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>
2014-10-24 19:15 ` Torvald Riegel
[not found] ` <1414178101.18538.53.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>
2014-10-30 18:24 ` Alexandre Oliva
[not found] ` <orbnottnzb.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>
2014-10-30 19:01 ` Torvald Riegel
[not found] ` <1414695671.10085.180.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>
2014-11-01 8:48 ` Alexandre Oliva
[not found] ` <ora94b8fxl.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>
2014-11-01 10:47 ` Torvald Riegel
[not found] ` <1414838867.10085.431.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>
2014-11-01 18:32 ` Alexandre Oliva
[not found] ` <orwq7e22n2.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>
2014-11-01 18:58 ` Torvald Riegel
[not found] ` <1414868298.10085.488.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>
2014-11-03 5:13 ` Alexandre Oliva
[not found] ` <or4mug27f7.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>
2014-11-03 16:10 ` Torvald Riegel
[not found] ` <1415031006.4531.44.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>
2014-11-04 0:18 ` Alexandre Oliva
2014-10-27 20:46 ` Mark Thompson
[not found] ` <544EAF20.8050509-W77v16wj1OVeoWH0uzbU5w@public.gmane.org>
2014-10-29 8:55 ` Alexandre Oliva
[not found] ` <ork33jqmqe.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>
2014-10-29 9:12 ` Torvald Riegel
[not found] ` <1414573935.18538.74.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>
2014-10-30 18:00 ` Alexandre Oliva
[not found] ` <orfve5tp3e.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>
2014-10-30 18:41 ` Torvald Riegel
[not found] ` <1414694486.10085.165.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>
2014-11-01 8:24 ` Alexandre Oliva
[not found] ` <oregtn8h23.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>
2014-11-01 12:40 ` Torvald Riegel
[not found] ` <1414845631.10085.474.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>
2014-11-01 18:22 ` Alexandre Oliva
[not found] ` <or1tpm3hn5.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>
2014-11-01 19:54 ` Torvald Riegel
[not found] ` <1414871691.10085.529.camel-I2ZjUw8blINjztcc/or7kQ@public.gmane.org>
2014-11-03 5:43 ` Alexandre Oliva
[not found] ` <orzjc8zvn6.fsf-pcXFJVXz+5uzQB+pC5nmwQ@public.gmane.org>
2014-11-03 13:07 ` Mark Thompson
[not found] ` <54577E17.7000109-W77v16wj1OVeoWH0uzbU5w@public.gmane.org>
2014-11-19 0:26 ` Alexandre Oliva
2014-11-03 15:55 ` Torvald Riegel
2014-10-24 12:14 ` Torvald Riegel
2014-10-21 8:31 ` Peng Haitao
2015-01-07 6:12 ` Michael Kerrisk (man-pages)
2015-01-07 6:16 ` Michael Kerrisk (man-pages)
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).