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.4 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,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 22386 invoked from network); 8 Apr 2021 17:41:02 -0000 Received: from mother.openwall.net (195.42.179.200) by inbox.vuxu.org with ESMTPUTF8; 8 Apr 2021 17:41:02 -0000 Received: (qmail 28102 invoked by uid 550); 8 Apr 2021 17:40:57 -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 28084 invoked from network); 8 Apr 2021 17:40:57 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=dereferenced.org; s=mailbun; t=1617903642; bh=CUhARRkCGNUnX8iCk9uXOkf9Z2wNpabVpllqZSOJ5Ww=; h=Date:From:To:Subject:In-Reply-To:References; b=Lxq15VSFdgYDrjURku3s01i+4H06F4o63NAyNZIgT79tyMMmUMV7MMANkigyLVO7+ 9P/pwlmTr1Baw9DJ4oGy+EqNRabUSgAmehNMaJnnYs9lVT/+msZggiEZN2L6iHBNDt DyX3fdDcy6YoN97vVRSZC9f23ofJevyKfetXbcWLLjv9Ldv8limP3WfyCWxmu7wabL 6IJa0ylmX2ybuGUnv4rhyGzdJ5ytc5WlhljwGB7BN/r9rRD18A+xMV+j7dPgfSLuVJ V+37ucGz0brF7N6gI1g3s0XqLqew+7GECNME+WChQmm+J9puxX6/EhoxGClqNZOGTC QsNZ7AOX+8nuA== Date: Thu, 8 Apr 2021 11:40:43 -0600 (MDT) From: Ariadne Conill To: musl@lists.openwall.com In-Reply-To: <00bc01d72c91$bdedb030$39c91090$@yandex-team.ru> Message-ID: References: <00bc01d72c91$bdedb030$39c91090$@yandex-team.ru> MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII; format=flowed Subject: Re: [musl] errno and swapcontext in a multithreaded setup Hello, On Thu, 8 Apr 2021, Andrey Bugaevskiy wrote: > Hi, > > I'm using makecontext/swapcontext to migrate contexts between threads > and this sometimes leads to getting incorrect errno values. This is not supported by libucontext. > Investigating further I've noticed that __errno_location > is marked __attribute__((const)). > This causes optimizers to assume that errno address never changes > in the scope of the function which is not the case in my scenario. > > Namely, this code: > > int test(ucontext_t* old_ctx, const ucontext_t* new_ctx) { > int err_before = errno; > swapcontext(old_ctx, new_ctx); > int err_after = errno; > return err_before | err_after; // do not optimize out > } > > translates with -O1 to something like this: > > 0000000000001109 : > 1109: endbr64 > 110d: push %r13 > 110f: push %r12 > 1111: push %rbp > 1112: push %rbx > 1113: sub $0x8,%rsp > 1117: mov %rdi,%r12 > 111a: mov %rsi,%r13 > 111d: callq 1030 <__errno_location@plt> > 1122: mov %rax,%rbx > 1125: mov (%rax),%ebp > 1127: mov %r13,%rsi > 112a: mov %r12,%rdi > 112d: callq 1020 > 1132: mov %ebp,%eax > 1134: or (%rbx),%eax > 1136: add $0x8,%rsp > 113a: pop %rbx > 113b: pop %rbp > 113c: pop %r12 > 113e: pop %r13 > 1140: retq > > errno location is being stored to a register and then reused. > However a call to __errno_location after swapcontext is expected to > return a different address if the context have been swapped back > into another thread. > There are a couple of similarly affected functions (pthread_self, > __h_errno_location). > > Removing __attribute__((const)) or changing it > to __attribute__((pure)) resolves the problem in newly compiled code. I believe these values use TLS (but not 100% sure, at least in uClibc they do). libucontext is not aware of TLS, and so clobbers the TLS register. You could modify libucontext to add awareness of the TLS register, but I don't think we would accept a patch for that. > Can this change be considered for the future versions of musl? No, musl is working as designed here. Ariadne