From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Florian Weimer Newsgroups: gmane.comp.lib.glibc.alpha Subject: Re: [PATCH 0/2] nptl: Update struct pthread_unwind_buf Date: Fri, 09 Feb 2018 11:48:30 +0100 Message-ID: <87d11emoap.fsf@mid.deneb.enyo.de> References: <20180201205757.51911-1-hjl.tools@gmail.com> <4abf9786-1879-f16c-5a01-3261cd718d63@redhat.com> <87inb7pug7.fsf@mid.deneb.enyo.de> <2a02aac9-6aa3-4dc6-b122-039ae85365e8@redhat.com> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: blaine.gmane.org 1518173239 1243 195.159.176.226 (9 Feb 2018 10:47:19 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 9 Feb 2018 10:47:19 +0000 (UTC) Cc: "H.J. Lu" , libc-alpha@sourceware.org To: Carlos O'Donell Original-X-From: libc-alpha-return-90173-glibc-alpha=m.gmane.org@sourceware.org Fri Feb 09 11:47:15 2018 Return-path: Envelope-to: glibc-alpha@blaine.gmane.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:references:date:in-reply-to :message-id:mime-version:content-type; q=dns; s=default; b=Uut8M 4mKZC2IQZWYMsgFWtYl+Xl/1EioPA70iEzgikpgBqf2CQd9exFaZ/hZm5ZrherZy 18yZeAK/PIjtQ9YlDiIxMClsmoMANYINTHveMv4lCuuIETEHdgkZOyGqULyhUkn4 krfvIJyMpVnKPHe4KSW8X9+jDzlq+8ARKDOrv0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:references:date:in-reply-to :message-id:mime-version:content-type; s=default; bh=51RdNfVBdvx 2BJuNRyum8MHWLDs=; b=Jb3zEJ96ALuP5O8QEuymO4CZtd7w39z2YkNCHgnP9AS kly9xOrYTPFnuHMRHR3t2UN/X++MYbIpCpKm4QjrdEqZAPs7nDFbjMexUorG4vB5 ag56SCAk6ogInVaoYXQmwSbUhZWgZamxi7JF4Nv8jrVZWNhlCKVEbLaTFgbLJVWM = Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Original-Sender: libc-alpha-owner@sourceware.org Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.1 required=5.0 tests=BAYES_00,KAM_LAZY_DOMAIN_SECURITY,RCVD_IN_DNSWL_NONE,TIME_LIMIT_EXCEEDED,T_RP_MATCHES_RCVD,UNSUBSCRIBE_BODY autolearn=unavailable version=3.3.2 spammy= X-HELO: albireo.enyo.de In-Reply-To: <2a02aac9-6aa3-4dc6-b122-039ae85365e8@redhat.com> (Carlos O'Donell's message of "Thu, 8 Feb 2018 22:29:32 -0800") Xref: news.gmane.org gmane.comp.lib.glibc.alpha:82521 Archived-At: Received: from server1.sourceware.org ([209.132.180.131] helo=sourceware.org) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ek6Cr-0007Zd-Sh for glibc-alpha@blaine.gmane.org; Fri, 09 Feb 2018 11:47:02 +0100 Received: (qmail 15277 invoked by alias); 9 Feb 2018 10:49:02 -0000 Received: (qmail 15115 invoked by uid 89); 9 Feb 2018 10:48:49 -0000 * Carlos O'Donell: > In the truncated sigjmp_buf used by pthread cancellation we have only > void * which is not large enough on x32, where you need a 64-bit > shadow stack pointer. It would work on every other machine though. > HJ has mentioned this problem already IIRC. > > Why would __pthread_register_cancel overwrite it? __pthread_unwind_buf_t is defined as: typedef struct { struct { __jmp_buf __cancel_jmp_buf; int __mask_was_saved; } __cancel_jmp_buf[1]; void *__pad[4]; } __pthread_unwind_buf_t __attribute__ ((__aligned__)); pthread_cleanup_push does this: # define pthread_cleanup_push(routine, arg) \ do { \ __pthread_unwind_buf_t __cancel_buf; \ void (*__cancel_routine) (void *) = (routine); \ void *__cancel_arg = (arg); \ int __not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *) \ __cancel_buf.__cancel_jmp_buf, 0); \ if (__glibc_unlikely (__not_first_call)) \ { \ __cancel_routine (__cancel_arg); \ __pthread_unwind_next (&__cancel_buf); \ /* NOTREACHED */ \ } \ \ __pthread_register_cancel (&__cancel_buf); \ do { __pthread_register_cancel overwrites __cancel_buf.__pad. If __sigsetjmp were to write to that memory area, it would not matter, as long as we skip restoring the shadow stack pointer during unwinding (which we do not need to do because we never return along the regular execution path recorded on the shadow stack). In short, the only thing need to ensure is that the over-write from __sigsetjmp stays within __cancel_buf. Then we are good, without changing the stack layout for cancellation. My proposal is still rather hackish, but so is the existing code (the truncated jump buffer), and HJ's approach of storing the shadow stack pointer in the signal save area of the non-truncated jump buffer. But I think we can make it work.