From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/593 Path: news.gmane.org!not-for-mail From: Rich Felker Newsgroups: gmane.linux.lib.musl.general Subject: Re: tough choice on thread pointer initialization issue Date: Sat, 25 Feb 2012 01:56:13 -0500 Message-ID: <20120225065613.GF184@brightrain.aerifal.cx> References: <20120210025824.GA25414@brightrain.aerifal.cx> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: dough.gmane.org 1330153050 27695 80.91.229.3 (25 Feb 2012 06:57:30 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sat, 25 Feb 2012 06:57:30 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-594-gllmg-musl=m.gmane.org@lists.openwall.com Sat Feb 25 07:57:30 2012 Return-path: Envelope-to: gllmg-musl@plane.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by plane.gmane.org with smtp (Exim 4.69) (envelope-from ) id 1S1BZP-0003SC-Sf for gllmg-musl@plane.gmane.org; Sat, 25 Feb 2012 07:57:27 +0100 Original-Received: (qmail 11360 invoked by uid 550); 25 Feb 2012 06:57:27 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Original-Received: (qmail 11351 invoked from network); 25 Feb 2012 06:57:26 -0000 Content-Disposition: inline In-Reply-To: <20120210025824.GA25414@brightrain.aerifal.cx> User-Agent: Mutt/1.5.21 (2010-09-15) Xref: news.gmane.org gmane.linux.lib.musl.general:593 Archived-At: On Thu, Feb 09, 2012 at 09:58:25PM -0500, Rich Felker wrote: > the bug i've found occurs when the thread pointer happens to get > initialized in code that runs from a signal handler. this is a rare > situation that will only happen if the program is avoiding > async-signal-unsafe functions in the main flow of execution so that > it's free to use them in a signal handler, but despite being rare, > it's perfectly legal, and right now musl crashes on such programs, for > example: > [...] > the issue is that when a signal handler returns, all registers, > including the thread-pointer registers (%gs or %fs on x86 or x86_64) > are reset to the values they had in the code the signal interrupted. > thus, musl thinks the thread pointer is valid at this point, but it's > actually null. > [...] > before i make a decision, i'd like to hear if anyone from the > community has strong opinions one way or the other. i've almost ruled > out approach #1 and i'm leaning towards #3, with the idea that > simplicity is worth more than a couple trivial syscalls. PING. Any more thoughts on this issue? I've looked into the "solution 4" that Solar proposed, which simply put is making __pthread_self() check for a clobbered thread register and restore it. While this sounds simple, there are a few issues I've run into whereby it starts to get ugly... 1. The proper value of the %gs register (for i386) or %fs register (for x86_64) needs to be saved somewhere global so that __pthread_self can restore it. This seems to be solvable but requires putting a global 16-bit var in __set_thread_area.s and getting the asm right to make it PIC-safe, and might call for some extra weak symbol hackery to avoid pulling in excess code. 2. On x86_64, it seems that 0 is a valid value for %fs, so we can't really tell if it's uninitialized! I don't have a machine to test with, but from reading the kernel sources, it looks like %fs is 0 and a hidden 64-bit offset is stored in a privileged register accessible only by the kernel (one which hopefully would not be clobbered by sigreturn, but I'm not sure...) when the thread pointer does not fit in 32 bits, and the old i386 method (LDT entry and non-zero %fs selector value) is used when the thread pointer fits in 32 bits. This might be a show-stopper, because if we can't tell if the thread pointer is valid, we can't restore it (and the value of %fs might actually need to differ per-thread if some threads are below the 4gb boundary and others are located above). 3. The code in __pthread_self() to test %gs and call out to external code when it needs to be restored is larger than I would like, especially since the inline asm block uses no clobbers, thus requiring all registers to be saved across a call from the asm. With these issues in mind, Solar's solution is seeming less appealing and maybe not even feasible. Any ideas for salvaging it, or should I fall back to one of the other options? (My original leaning was towards always setting up the thread pointer prior to program entry.) Rich