From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.3 required=5.0 tests=MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 14484 invoked from network); 17 Feb 2021 21:08:09 -0000 Received: from mother.openwall.net (195.42.179.200) by inbox.vuxu.org with ESMTPUTF8; 17 Feb 2021 21:08:09 -0000 Received: (qmail 7433 invoked by uid 550); 17 Feb 2021 21:08:07 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 7415 invoked from network); 17 Feb 2021 21:08:06 -0000 Date: Wed, 17 Feb 2021 16:07:54 -0500 From: Rich Felker To: Dominic Chen Cc: fweimer@redhat.com, musl@lists.openwall.com Message-ID: <20210217210748.GL11590@brightrain.aerifal.cx> References: <62be4b85-4a42-413e-a83f-866eab4d601a@gmail.com> <20210203192145.GW23432@brightrain.aerifal.cx> <20210203210149.GX23432@brightrain.aerifal.cx> <20210203225518.GY23432@brightrain.aerifal.cx> <20210215165622.GF11590@brightrain.aerifal.cx> <2e2e3693-b16a-d158-9617-99978a2b287f@gmail.com> <20210217201156.GK11590@brightrain.aerifal.cx> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="JYK4vJDZwFMowpUq" Content-Disposition: inline In-Reply-To: <20210217201156.GK11590@brightrain.aerifal.cx> User-Agent: Mutt/1.5.21 (2010-09-15) Subject: Re: [musl] Incorrect thread TID caching --JYK4vJDZwFMowpUq Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Wed, Feb 17, 2021 at 03:11:57PM -0500, Rich Felker wrote: > On Wed, Feb 17, 2021 at 02:49:45PM -0500, Dominic Chen wrote: > > On 2/15/2021 11:56 AM, Rich Felker wrote: > > >Following up on this now, the code in _Fork is something I really > > >don't want to duplicate for clone() for risk of forgetting there's a > > >copy in the latter and letting it bitrot there. I'd rather refactor > > >things so the same logic can be shared... > > > > Thanks for the update. Can you use something like > > __attribute__((always_inline)) to just write the logic once but > > force it to be inlined into both library functions? > > Whether it's inlined isn't really a big deal; this is not a hot path. > It's more just a matter of how it needs to be split up at the source > level, and it seems to be messy whichever way we choose. > > Trying to avoid calling __clone doesn't seem like such a good idea, > since the child has to run on a new stack -- if we did avoid it we'd > need a new way to switch stacks. The generic __unmapself has a hack > to do this already that we could reuse without needing new > arch-specific glue though. > > I'll keep trying things and see if I come up with something not too > unreasonable. Attached is a draft of how clone() *could* work without refactoring the pre/post logic from _Fork to use __clone. I don't particularly like it, and CRTJMP abuse like this (which __unmapself also does, as noted above) is not valid for FDPIC archs (it actually expects a code address not a function pointer). I'll try a version the other way and see how it looks. Rich --JYK4vJDZwFMowpUq Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="clone_forklike.diff" diff --git a/src/linux/clone.c b/src/linux/clone.c index 8c1af7d3..32d53a8f 100644 --- a/src/linux/clone.c +++ b/src/linux/clone.c @@ -4,6 +4,25 @@ #include #include "pthread_impl.h" #include "syscall.h" +#include "dynlink.h" + +extern int _Forklike(int (*)(void *), void *); + +struct clone_args { + int flags; + pid_t *ptid, *ctid; +}; + +static int do_clone(void *p) +{ + struct clone_args *args = p; + int mask = CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID; + int r = __syscall(SYS_clone, args->flags & ~mask, 0); + if (r>0 && (args->flags & CLONE_PARENT_SETTID)) *args->ptid = r; + if (!r && (args->flags & CLONE_CHILD_SETTID)) *args->ctid = __syscall(SYS_gettid); + if (!r && (args->flags & CLONE_CHILD_CLEARTID)) __syscall(SYS_set_tid_address, args->ctid); + return r; +} int clone(int (*func)(void *), void *stack, int flags, void *arg, ...) { @@ -17,5 +36,13 @@ int clone(int (*func)(void *), void *stack, int flags, void *arg, ...) ctid = va_arg(ap, pid_t *); va_end(ap); + if (!(flags & CLONE_VM)) { + struct clone_args args = { .flags = flags, .ptid = ptid, .ctid = ctid }; + if (flags & CLONE_THREAD) return __syscall_ret(-EINVAL); + int r = _Forklike(do_clone, &args); + if (r) return r; + CRTJMP(func, stack); + } + return __syscall_ret(__clone(func, stack, flags, arg, ptid, tls, ctid)); } --JYK4vJDZwFMowpUq--