From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-oa1-x29.google.com (mail-oa1-x29.google.com [IPv6:2001:4860:4864:20::29]) by sourceware.org (Postfix) with ESMTPS id 37E3D3858D33 for ; Fri, 31 Mar 2023 12:52:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 37E3D3858D33 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org Received: by mail-oa1-x29.google.com with SMTP id 586e51a60fabf-177ca271cb8so23054766fac.2 for ; Fri, 31 Mar 2023 05:52:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1680267177; h=content-transfer-encoding:in-reply-to:organization:from:references :to:content-language:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=HHsHK2pIcXH50DFZEsPjkL8H+7uKM9lSokPIr1XB3i4=; b=WiMGsHHJe9BlHoVrvmvRPuhH7d2NwHfhV/jOrdsZSeGG1VlByYLf8SqORf9pRl3dwG RZKEJ7alJJ6IKAOIU+SLiA8JgYp94DzgLUr/8H/LzmBmW6xP7uLznewD4qnfsRID+hDo 5lqRQAs2tXUyzIzwtUzhbOH6vQqDYuFuq6YpdNzW5oD9r8LQFM/1j37KCIGmNWVlSFUW M4vs+QSLpUO2E/XHiG0udIb/6gXtSp7Hn2gYlFFJ4WvpICdH+hg0X3rIHPE+9KMtVTJ8 1qOUO+pAFb46xeP8Rh94vSMdw0AgRwYMdTcyQdOwdGVXYthzeiKv/JU+1ItaEiYWTke2 IT6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680267177; h=content-transfer-encoding:in-reply-to:organization:from:references :to:content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=HHsHK2pIcXH50DFZEsPjkL8H+7uKM9lSokPIr1XB3i4=; b=pzIHkHcpfT5a1lOEAsFGBapUCKVfmB65X9Sajvw9juRqnLi4EBy9gSzs6gmS/rCEWy bKb49FHhdV/aEb+fHXB1KPPeJnV1J7huOWnCswZo+b8VdQlnrqbFO+SgjUU13qeHy4s3 kOrDQv/Gri0IazIK9qmxPN/L9z7TQZTv9fnmxMuK3FZLJmJX/bmMyNbDt70uq1K7SWpf k//wE9ARP/wV/w9wuSFVMkjXleE57i+QOaMjH4h6t4lV9abLFn2SZsayHHVu+X2pfWK4 XKe9PF0f4ug8uHtA3VdgMspGyGonNyM4B4yr2jzA8JutqOsNiwaYYiaFtZbLh0nwvxfe K6XQ== X-Gm-Message-State: AO0yUKUkmbC4SWhW2ihxOFqWENVCmid7Am6pXXli5bw9lrx2TzWWsx3H Gz/t2a2M1zcknNbGtlq0w0pogQ== X-Google-Smtp-Source: AKy350a1GMHrJO/mi8TkVSTVf1W0SYDRabFgelgoXEErn4870sdUXbq9shjNWRbgrUBNdbCqqXeu7w== X-Received: by 2002:a05:6870:e40d:b0:177:a5e2:442e with SMTP id n13-20020a056870e40d00b00177a5e2442emr18488530oag.43.1680267177264; Fri, 31 Mar 2023 05:52:57 -0700 (PDT) Received: from ?IPV6:2804:1b3:a7c1:60f9:4ca7:df5c:ca4c:27b4? ([2804:1b3:a7c1:60f9:4ca7:df5c:ca4c:27b4]) by smtp.gmail.com with ESMTPSA id c5-20020a056830000500b0068bd922a244sm1072636otp.20.2023.03.31.05.52.55 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 31 Mar 2023 05:52:56 -0700 (PDT) Message-ID: <067bc0d9-6329-7c85-0bba-8615b5b99154@linaro.org> Date: Fri, 31 Mar 2023 09:52:53 -0300 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Thunderbird/102.9.0 Subject: Re: clone() and Glibc Content-Language: en-US To: Frederico Silva Correa , libc-alpha@sourceware.org References: <9b0e446e29a20f2ad1903e5cf681bffa@inf.ufrgs.br> From: Adhemerval Zanella Netto Organization: Linaro In-Reply-To: <9b0e446e29a20f2ad1903e5cf681bffa@inf.ufrgs.br> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-6.0 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,NICE_REPLY_A,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 30/03/23 20:35, Frederico Silva Correa via Libc-alpha wrote: > Dear developers of the GNU libc: > > At the quality of a novice, recently graduated in CS (despite familiarized with both C and C++), I found myself puzzled by a little issue. > > Glibc provides a wrapper for the clone() system call, which receives parameters in the following order: > > - a pointer to the function "func" to be run by the child thread; > - a base address for the child stack (we'll be back here), since I'm passing CLONE_VM, therefore sharing memory thus unable to reuse the parent thread's stack addresses; > - 0x100 or the flag CLONE_VM; > - a pointer to the arguments to be passed to "func" and run with the child thread. > > Automatic storage local variables are usually placed into the stack, which remains more or less a fixed value, decided when the application is run, is that correct? > Very well. What, then, would be a stack frame whose "base address" I myself malloc'd (at the HEAP) then arbitrarily decided that space --- again, a priori in the heap --- to be treated like a stack frame pertaining to the child thread. > > How am I supposed to interpret all of this? The space allocated at the heap need to be freed in the first place? Is this so-called "stack" on the heap? Or is it a regular stack frame? What about the potential threatens related to e.g. ret2plt and format string attacks? > > I'd be very pleased to have these questions clarified, both as a language enthusiast and as an user with security worries. > > Thanks in advance. > You can check clone usage within glibc on the posix_spawn implementation [1] and on pthread_create [2]. It seems that your described user case seems to something alike pthread_crate, and it either explicit allocate the thread stack or get it from pthread_attr_t attribute. The code is somewhat complex [2] because it tries to maintain a cache of allocated stack, but you check the 'allocate_stack' function where is the main logic. And both posix_spawn and pthread_crate, the code creates a fixed size stack (posix_spawn takes in consideration the passed args plus some slack while the pthread_create is configurable). The stack is marked as non-executable as per ABI (if PT_GNU_STACK is set), and a guard page is added to catch overflow (assuming -fstack-clash-protection). And for posix_create, an user allocated stack can be freed after the thread terminates (either by calling pthread_exit, ended after the function exist, or with pthread_cancel), and it is up to caller to deallocate the thread stack. This get murky with detached threads, where is UB to call pthread_join to check if the is still active (glibc returns EINVAL in this case and with an user allocated stack it means that it won't be reused). I am using the pthread code as example to show that clone with CLONE_VM is *really* tricky and not really meant to be used in generic code that aims to work with along with C runtime. You actually use stack with clone you will need a way to synchronize the thread end of execution: on pthread_create we use CLONE_CHILD_CLEARTID, while for posix_spawn is simpler because it used CLONE_VFORK (the caller thread will stop execution until the callee thread executes). [1] https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/spawni.c;h=bc321d4c5879fba178ae4fb3f6e18eeb10ad0a72;hb=HEAD#l339 [2] https://sourceware.org/git/?p=glibc.git;a=blob;f=nptl/pthread_create.c;h=a3619da1e216190bb4679936e105d418f683222a;hb=HEAD#l297 [3] https://sourceware.org/git/?p=glibc.git;a=blob;f=nptl/allocatestack.c;h=c7adbccd6fc9ae99e6777034443c53a0224c6b1c;hb=HEAD