Message ID | 88d3f1bb-f4e0-4c40-9304-3843513a1262@p183 |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp1163008vqo; Sat, 15 Apr 2023 10:39:50 -0700 (PDT) X-Google-Smtp-Source: AKy350a+dLQ9gzKipOtGqIqAg267JbqzEqd5MeVIa2hAV9uv1C9/JdjhKNHxJtbcbUFDT25KIg4q X-Received: by 2002:a17:90b:1e02:b0:246:aebf:21f5 with SMTP id pg2-20020a17090b1e0200b00246aebf21f5mr9863637pjb.41.1681580390523; Sat, 15 Apr 2023 10:39:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1681580390; cv=none; d=google.com; s=arc-20160816; b=LaNZJkhtNNcGpQLf18Yt8GFbWb6P68nSSAMaLKwmAPuwUU28RFGYZUCzXjz2ba+UmF rmejRrfCmZ7NeIz60jlMMKsWz84oPAzC6MsM4XVDw3jChATmQDlZ7RsOypCoUoQ+jh2L WZAucF/kTlI+LLyusKxGBIqdU7H6VtFCORe6l/JlVWxqzkj/NAem2KH+fQ4vUDRCcXm/ qNQSdU5R7V9OiPgD9rRAzhRZTyo4zWtX+P9RBTZA6nFxpzzOphLwjd4cz8LIQ+fi/57P 6Ge/z8FnJ9RuiQvW+qQdnHC2RUrNG9AA2Qrc0R2yTlS2kogOTYnb9/f8OMe4oOwMlEHu DLRg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:date:dkim-signature; bh=LjLF8YJVlIoAVrd1Wc6EQsJn6IlLs+osyJa+45a2H+4=; b=t38z4X+Sqw0KL/fDEmGuMYrIRvWWuHbXrCmNXyLlIaANBGNA/HZdjPgNf3nclrpXza B6r4TL2IWwC2gLKrcD+UB0Muy3mNIZhbWUpcArv7KB35p03eLUBGfZwxB4lpL4E3L6Wf DXOiJVT56iJL53JxTj4IKgaxk46wb0cirwSoOMq1WnDQnsutg7j9FeXfeEGjq8RB90oZ /WICBMHQW6LZWdivXFNiYVxr0Om9wa8G0DlzI+IBF7lw1Af++NDHpsjzAySrlkuupvFM OTFDgWdPbW8OOaPGLKLga6IHXc+43Ztctu8p2l5P3BAJLh9dI92l9P7Brw7t84uV5QY1 X0Yg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20221208 header.b=oUXO8xfk; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id l10-20020a17090a850a00b0024695095bb3si9980382pjn.189.2023.04.15.10.39.37; Sat, 15 Apr 2023 10:39:50 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20221208 header.b=oUXO8xfk; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230131AbjDORiV (ORCPT <rfc822;yuanzuo1009@gmail.com> + 99 others); Sat, 15 Apr 2023 13:38:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49350 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229720AbjDORiT (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Sat, 15 Apr 2023 13:38:19 -0400 Received: from mail-ej1-x62c.google.com (mail-ej1-x62c.google.com [IPv6:2a00:1450:4864:20::62c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 058E755B1; Sat, 15 Apr 2023 10:37:35 -0700 (PDT) Received: by mail-ej1-x62c.google.com with SMTP id xd13so19666674ejb.4; Sat, 15 Apr 2023 10:37:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1681580252; x=1684172252; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=LjLF8YJVlIoAVrd1Wc6EQsJn6IlLs+osyJa+45a2H+4=; b=oUXO8xfkcdjlTNarUAttjz4iKfRgUqUoQF8hZnkRSGRMulnqzN1ut6yrYdLXtnwixu mMa/b0DQ0aMcpVVtf+IFKipOSGtpHMU0fD2ZyarfAx1hL7bYGl5P3SmuHmjAoi45L2LF obhlm32zXABsQKFRaQgth1xFqG//E9loWeTS3oejfcLgUhCSN3DdPFtcKKM3YDlx4zZd +N3V5h7h4iPDWekAd4OGFdXHNLwJkxNt4oInz7qboX9vdhGSOKBILc/KhTmhQoyVdW1v sIOAnLsCb+Tv9pUyayQcXub6wWZk+kq+JYilPIIQ3Drp8xYNIaXy9HMTD8Ss+uLtskeO nw9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1681580252; x=1684172252; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=LjLF8YJVlIoAVrd1Wc6EQsJn6IlLs+osyJa+45a2H+4=; b=UYyqaeAqN8gKVyZ6KvleCiuFVG+Ef2K/J6NDJ6r8xOFdhGliKq3S+DrwK2QlCgJcmw IkPNvsL5MBRyr3xhrqBieN7BxYVv1c1F6m4rru0akOLOqtTa1WAoisgUWVKJhxrHcxmi Laum8ir1eosDAl1ngLoMfMF9aDDFtqUHCUsyOFZ5yf7dz4GvZor5sKzV4jg3zdtvgnos xrDEV10kkAbb+t+ZJIa4vpIJAEEypSGtrkkz3PNGYE0Pl8BgOpmkO/zvBwbq5X5/J/Iy 4D6H1ncrlaOBPw982Kjc7EBIew64BlPMCNpCzGE8/hw8E0n6j6aW/7+JwGgurmhnXfKO EESg== X-Gm-Message-State: AAQBX9dzR0vxSvArO4i6aIgycT0/GufHx4VdDDK8fYfD/a7pRxCFB+O4 3zg3QnR55KZugB4vcZSeMg== X-Received: by 2002:a17:906:5502:b0:94f:ca5:c437 with SMTP id r2-20020a170906550200b0094f0ca5c437mr2818304ejp.24.1681580251723; Sat, 15 Apr 2023 10:37:31 -0700 (PDT) Received: from p183 ([46.53.250.148]) by smtp.gmail.com with ESMTPSA id p25-20020a17090635d900b0094e75d3ba1bsm4054490ejb.131.2023.04.15.10.37.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 15 Apr 2023 10:37:31 -0700 (PDT) Date: Sat, 15 Apr 2023 20:37:29 +0300 From: Alexey Dobriyan <adobriyan@gmail.com> To: akpm@linux-foundation.org Cc: linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, Randy Dunlap <rdunlap@infradead.org>, Bagas Sanjaya <bagasdotme@gmail.com>, Jonathan Corbet <corbet@lwn.net> Subject: [PATCH v3] ELF: document some de-facto PT_* ABI quirks Message-ID: <88d3f1bb-f4e0-4c40-9304-3843513a1262@p183> References: <2acb586c-08a9-42d9-a41e-7986cc1383ea@p183> <e262ea00-a027-9073-812e-7e034d75e718@infradead.org> <c4233c97-306c-4db8-9667-34fc31ec4aed@p183> <87edp7jyu4.fsf@meer.lwn.net> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <87edp7jyu4.fsf@meer.lwn.net> X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1760365561083902985?= X-GMAIL-MSGID: =?utf-8?q?1763264839817911869?= |
Series |
[v3] ELF: document some de-facto PT_* ABI quirks
|
|
Commit Message
Alexey Dobriyan
April 15, 2023, 5:37 p.m. UTC
Turns out rules about PT_INTERP, PT_GNU_STACK and PT_GNU_PROPERTY
program headers are slightly different.
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
v3: move to Documentation/userspace-api/
v2: integrate into documentation build system
Documentation/userspace-api/ELF.rst | 34 ++++++++++++++++++++++++++++++++++
Documentation/userspace-api/index.rst | 1 +
2 files changed, 35 insertions(+)
new file mode 100644
Comments
Alexey Dobriyan <adobriyan@gmail.com> writes: > Turns out rules about PT_INTERP, PT_GNU_STACK and PT_GNU_PROPERTY > program headers are slightly different. > > Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> > --- > > v3: move to Documentation/userspace-api/ > v2: integrate into documentation build system > > Documentation/userspace-api/ELF.rst | 34 ++++++++++++++++++++++++++++++++++ > Documentation/userspace-api/index.rst | 1 + > 2 files changed, 35 insertions(+) Applied, thanks. jon
*thread necromancy* Question below... On Sat, Apr 15, 2023 at 08:37:29PM +0300, Alexey Dobriyan wrote: > Turns out rules about PT_INTERP, PT_GNU_STACK and PT_GNU_PROPERTY > program headers are slightly different. > > Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> > --- > > v3: move to Documentation/userspace-api/ > v2: integrate into documentation build system > > Documentation/userspace-api/ELF.rst | 34 ++++++++++++++++++++++++++++++++++ > Documentation/userspace-api/index.rst | 1 + > 2 files changed, 35 insertions(+) > > new file mode 100644 > --- /dev/null > +++ b/Documentation/userspace-api/ELF.rst > @@ -0,0 +1,34 @@ > +.. SPDX-License-Identifier: GPL-2.0 > + > +================================= > +Linux-specific ELF idiosyncrasies > +================================= > + > +Definitions > +=========== > + > +"First" program header is the one with the smallest offset in the file: > +e_phoff. > + > +"Last" program header is the one with the biggest offset in the file: > +e_phoff + (e_phnum - 1) * sizeof(Elf_Phdr). > + > +PT_INTERP > +========= > + > +First PT_INTERP program header is used to locate the filename of ELF > +interpreter. Other PT_INTERP headers are ignored (since Linux 2.4.11). > + > +PT_GNU_STACK > +============ > + > +Last PT_GNU_STACK program header defines userspace stack executability > +(since Linux 2.6.6). Other PT_GNU_STACK headers are ignored. > + > +PT_GNU_PROPERTY > +=============== > + > +ELF interpreter's last PT_GNU_PROPERTY program header is used (since > +Linux 5.8). If interpreter doesn't have one, then the last PT_GNU_PROPERTY > +program header of an executable is used. Other PT_GNU_PROPERTY headers > +are ignored. Should we perhaps solve some of these in some way? What would folks prefer the behaviors be? (I like to have things been "as expected", but it's not very obvious here for redundant headers...)
Kees Cook <keescook@chromium.org> writes: > *thread necromancy* Question below... > > On Sat, Apr 15, 2023 at 08:37:29PM +0300, Alexey Dobriyan wrote: >> Turns out rules about PT_INTERP, PT_GNU_STACK and PT_GNU_PROPERTY >> program headers are slightly different. >> >> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> >> --- >> >> v3: move to Documentation/userspace-api/ >> v2: integrate into documentation build system >> >> Documentation/userspace-api/ELF.rst | 34 ++++++++++++++++++++++++++++++++++ >> Documentation/userspace-api/index.rst | 1 + >> 2 files changed, 35 insertions(+) >> >> new file mode 100644 >> --- /dev/null >> +++ b/Documentation/userspace-api/ELF.rst >> @@ -0,0 +1,34 @@ >> +.. SPDX-License-Identifier: GPL-2.0 >> + >> +================================= >> +Linux-specific ELF idiosyncrasies >> +================================= >> + >> +Definitions >> +=========== >> + >> +"First" program header is the one with the smallest offset in the file: >> +e_phoff. Confusing e_phoff is the defined location of the array of program headers. Perhaps the "First" in that array with the lowest e_phnum? >> +"Last" program header is the one with the biggest offset in the file: >> +e_phoff + (e_phnum - 1) * sizeof(Elf_Phdr). Ditto the "Last" in the array with the largest array index. I nit pick this because it sounded at first like you were talking about p_offset. Which is a value contained in the program header entry. >> +PT_INTERP >> +========= >> + >> +First PT_INTERP program header is used to locate the filename of ELF >> +interpreter. Other PT_INTERP headers are ignored (since Linux 2.4.11). >> + >> +PT_GNU_STACK >> +============ >> + >> +Last PT_GNU_STACK program header defines userspace stack executability >> +(since Linux 2.6.6). Other PT_GNU_STACK headers are ignored. >> + >> +PT_GNU_PROPERTY >> +=============== >> + >> +ELF interpreter's last PT_GNU_PROPERTY program header is used (since >> +Linux 5.8). If interpreter doesn't have one, then the last PT_GNU_PROPERTY >> +program header of an executable is used. Other PT_GNU_PROPERTY headers >> +are ignored. A more interesting property to document is that PT_GNU_PROPERTY must precede PT_INTERP in the linux implementation, otherwise we ignore it. > Should we perhaps solve some of these in some way? What would folks > prefer the behaviors be? (I like to have things been "as expected", but > it's not very obvious here for redundant headers...) All of these are really headers that should appear only once. Quite frankly if we are going to do something with this my sense is that we should fail the execve with a clear error code as userspace should not be doing this, and accepting a malformed executable will hide errors, and perhaps hide someone causing problems. I really don't think having multiple copies of these headers with different values is something we should encourage. It looks like -ELIBBAD is the documented way to fail and report a bad file format. For PT_GNU_PROPTERTY perhaps we should accept it anywhere, instead of silently ignoring it depending upon it's location? I thinking change the code to talk one pass through the program headers to identify the interesting headers, and then with the interesting headers all identified we go do something with them. Anyway just my opinion, but that is what it feels like to me. Eric
On Thu, Dec 07, 2023 at 09:03:45AM -0600, Eric W. Biederman wrote: > Kees Cook <keescook@chromium.org> writes: > > > *thread necromancy* Question below... > > > > On Sat, Apr 15, 2023 at 08:37:29PM +0300, Alexey Dobriyan wrote: > >> Turns out rules about PT_INTERP, PT_GNU_STACK and PT_GNU_PROPERTY > >> program headers are slightly different. > >> > >> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> > >> --- > >> > >> v3: move to Documentation/userspace-api/ > >> v2: integrate into documentation build system > >> > >> Documentation/userspace-api/ELF.rst | 34 ++++++++++++++++++++++++++++++++++ > >> Documentation/userspace-api/index.rst | 1 + > >> 2 files changed, 35 insertions(+) > >> > >> new file mode 100644 > >> --- /dev/null > >> +++ b/Documentation/userspace-api/ELF.rst > >> @@ -0,0 +1,34 @@ > >> +.. SPDX-License-Identifier: GPL-2.0 > >> + > >> +================================= > >> +Linux-specific ELF idiosyncrasies > >> +================================= > >> + > >> +Definitions > >> +=========== > >> + > >> +"First" program header is the one with the smallest offset in the file: > >> +e_phoff. > > Confusing e_phoff is the defined location of the array of program > headers. > > Perhaps the "First" in that array with the lowest e_phnum? > > >> +"Last" program header is the one with the biggest offset in the file: > >> +e_phoff + (e_phnum - 1) * sizeof(Elf_Phdr). > > Ditto the "Last" in the array with the largest array index. > > I nit pick this because it sounded at first like you were talking about > p_offset. Which is a value contained in the program header entry. > > >> +PT_INTERP > >> +========= > >> + > >> +First PT_INTERP program header is used to locate the filename of ELF > >> +interpreter. Other PT_INTERP headers are ignored (since Linux 2.4.11). > >> + > >> +PT_GNU_STACK > >> +============ > >> + > >> +Last PT_GNU_STACK program header defines userspace stack executability > >> +(since Linux 2.6.6). Other PT_GNU_STACK headers are ignored. > >> + > >> +PT_GNU_PROPERTY > >> +=============== > >> + > >> +ELF interpreter's last PT_GNU_PROPERTY program header is used (since > >> +Linux 5.8). If interpreter doesn't have one, then the last PT_GNU_PROPERTY > >> +program header of an executable is used. Other PT_GNU_PROPERTY headers > >> +are ignored. > > A more interesting property to document is that PT_GNU_PROPERTY must > precede PT_INTERP in the linux implementation, otherwise we ignore it. > > > Should we perhaps solve some of these in some way? What would folks > > prefer the behaviors be? (I like to have things been "as expected", but > > it's not very obvious here for redundant headers...) > > All of these are really headers that should appear only once. Yes. > Quite frankly if we are going to do something with this my sense is that > we should fail the execve with a clear error code as userspace should > not be doing this, and accepting a malformed executable will hide > errors, and perhaps hide someone causing problems. Maybe do it for PT_GNU_PROPERTY which is relatively new. > I really don't think having multiple copies of these headers with > different values is something we should encourage. > > It looks like -ELIBBAD is the documented way to fail and report > a bad file format. It is obvious you don't know how much will break. > For PT_GNU_PROPTERTY perhaps we should accept it anywhere, instead of > silently ignoring it depending upon it's location? > > I thinking change the code to talk one pass through the program headers > to identify the interesting headers, and then with the interesting > headers all identified we go do something with them. > > Anyway just my opinion, but that is what it feels like to me. _Not_ checking for duplicates will result in the simplest and fastest exec. which is what current code does.
Alexey Dobriyan <adobriyan@gmail.com> writes: > On Thu, Dec 07, 2023 at 09:03:45AM -0600, Eric W. Biederman wrote: >> Kees Cook <keescook@chromium.org> writes: >> >> > *thread necromancy* Question below... >> > >> > On Sat, Apr 15, 2023 at 08:37:29PM +0300, Alexey Dobriyan wrote: >> >> Turns out rules about PT_INTERP, PT_GNU_STACK and PT_GNU_PROPERTY >> >> program headers are slightly different. >> >> >> >> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> >> >> --- >> >> >> >> v3: move to Documentation/userspace-api/ >> >> v2: integrate into documentation build system >> >> >> >> Documentation/userspace-api/ELF.rst | 34 ++++++++++++++++++++++++++++++++++ >> >> Documentation/userspace-api/index.rst | 1 + >> >> 2 files changed, 35 insertions(+) >> >> >> >> new file mode 100644 >> >> --- /dev/null >> >> +++ b/Documentation/userspace-api/ELF.rst >> >> @@ -0,0 +1,34 @@ >> >> +.. SPDX-License-Identifier: GPL-2.0 >> >> + >> >> +================================= >> >> +Linux-specific ELF idiosyncrasies >> >> +================================= >> >> + >> >> +Definitions >> >> +=========== >> >> + >> >> +"First" program header is the one with the smallest offset in the file: >> >> +e_phoff. >> >> Confusing e_phoff is the defined location of the array of program >> headers. >> >> Perhaps the "First" in that array with the lowest e_phnum? >> >> >> +"Last" program header is the one with the biggest offset in the file: >> >> +e_phoff + (e_phnum - 1) * sizeof(Elf_Phdr). >> >> Ditto the "Last" in the array with the largest array index. >> >> I nit pick this because it sounded at first like you were talking about >> p_offset. Which is a value contained in the program header entry. >> >> >> +PT_INTERP >> >> +========= >> >> + >> >> +First PT_INTERP program header is used to locate the filename of ELF >> >> +interpreter. Other PT_INTERP headers are ignored (since Linux 2.4.11). >> >> + >> >> +PT_GNU_STACK >> >> +============ >> >> + >> >> +Last PT_GNU_STACK program header defines userspace stack executability >> >> +(since Linux 2.6.6). Other PT_GNU_STACK headers are ignored. >> >> + >> >> +PT_GNU_PROPERTY >> >> +=============== >> >> + >> >> +ELF interpreter's last PT_GNU_PROPERTY program header is used (since >> >> +Linux 5.8). If interpreter doesn't have one, then the last PT_GNU_PROPERTY >> >> +program header of an executable is used. Other PT_GNU_PROPERTY headers >> >> +are ignored. >> >> A more interesting property to document is that PT_GNU_PROPERTY must >> precede PT_INTERP in the linux implementation, otherwise we ignore it. >> >> > Should we perhaps solve some of these in some way? What would folks >> > prefer the behaviors be? (I like to have things been "as expected", but >> > it's not very obvious here for redundant headers...) >> >> All of these are really headers that should appear only once. > > Yes. > >> Quite frankly if we are going to do something with this my sense is that >> we should fail the execve with a clear error code as userspace should >> not be doing this, and accepting a malformed executable will hide >> errors, and perhaps hide someone causing problems. > > Maybe do it for PT_GNU_PROPERTY which is relatively new. > >> I really don't think having multiple copies of these headers with >> different values is something we should encourage. >> >> It looks like -ELIBBAD is the documented way to fail and report >> a bad file format. > > It is obvious you don't know how much will break. My assumption is frankly that nothing will break. My quick examination of userspace binaries suggests that nothing is silly enough to duplicate such headers. Do you know of a binaries in userspace that duplicate these headers? Without a documented ordering arguably anything that results in these headers being duplicated is already buggy, and broken. I can think of no use for duplicating these headers other than as some kind of gadget in an exploit. I don't see how such a gadget would be useful currently. > >> For PT_GNU_PROPTERTY perhaps we should accept it anywhere, instead of >> silently ignoring it depending upon it's location? >> >> I thinking change the code to talk one pass through the program headers >> to identify the interesting headers, and then with the interesting >> headers all identified we go do something with them. >> >> Anyway just my opinion, but that is what it feels like to me. > > _Not_ checking for duplicates will result in the simplest and fastest exec. > which is what current code does. Given that I/O is involved taking a pre-pass through the headers is in the noise, and it might even make the code faster as it would prime the code for the other passes. The fastest of course would be to have the elf loader only look at the first of any of these headers. What got you wanting to document how we handle duplicates? Eric
On Sun, Dec 10, 2023 at 04:58:50PM -0600, Eric W. Biederman wrote: > Alexey Dobriyan <adobriyan@gmail.com> writes: > > > On Thu, Dec 07, 2023 at 09:03:45AM -0600, Eric W. Biederman wrote: > >> Quite frankly if we are going to do something with this my sense is that > >> we should fail the execve with a clear error code as userspace should > >> not be doing this, and accepting a malformed executable will hide > >> errors, and perhaps hide someone causing problems. > > > > Maybe do it for PT_GNU_PROPERTY which is relatively new. > > > >> I really don't think having multiple copies of these headers with > >> different values is something we should encourage. > >> > >> It looks like -ELIBBAD is the documented way to fail and report > >> a bad file format. > > > > It is obvious you don't know how much will break. > > My assumption is frankly that nothing will break. My quick examination > of userspace binaries suggests that nothing is silly enough to duplicate > such headers. Ha! Non-overlapping PT_LOAD segments is reasonable requirement (why would you have them?) but it was reverted. > Do you know of a binaries in userspace that duplicate these headers? > > Without a documented ordering arguably anything that results in > these headers being duplicated is already buggy, and broken. > > I can think of no use for duplicating these headers other than > as some kind of gadget in an exploit. I don't see how such > a gadget would be useful currently. > > > > >> For PT_GNU_PROPTERTY perhaps we should accept it anywhere, instead of > >> silently ignoring it depending upon it's location? > >> > >> I thinking change the code to talk one pass through the program headers > >> to identify the interesting headers, and then with the interesting > >> headers all identified we go do something with them. > >> > >> Anyway just my opinion, but that is what it feels like to me. > > > > _Not_ checking for duplicates will result in the simplest and fastest exec. > > which is what current code does. > > Given that I/O is involved taking a pre-pass through the headers is > in the noise, and it might even make the code faster as it would > prime the code for the other passes. Branches will evict other branches from branch predictor. And it is always more code. ELF is very rigid format. E.g segment headers can overlap everything else and it is not a problem. Overmapped PT_LOAD segments aren't a problem too (for the kernel). These things should have been rejected from the very beginning. I'd even argue kernel rejects too much: elf_entry = e_entry; if (BAD_ADDR(elf_entry)) { retval = -EINVAL; goto out_free_dentry; } Why even check? If e_entry is bad than process will segfault and that's it. elf_ppnt->p_filesz > elf_ppnt->p_memsz Again, why check, just map the minimum. > The fastest of course would be to have the elf loader only look > at the first of any of these headers. > > What got you wanting to document how we handle duplicates? I read ELF code too much and noticed that loops are slightly different, that's all.
--- /dev/null +++ b/Documentation/userspace-api/ELF.rst @@ -0,0 +1,34 @@ +.. SPDX-License-Identifier: GPL-2.0 + +================================= +Linux-specific ELF idiosyncrasies +================================= + +Definitions +=========== + +"First" program header is the one with the smallest offset in the file: +e_phoff. + +"Last" program header is the one with the biggest offset in the file: +e_phoff + (e_phnum - 1) * sizeof(Elf_Phdr). + +PT_INTERP +========= + +First PT_INTERP program header is used to locate the filename of ELF +interpreter. Other PT_INTERP headers are ignored (since Linux 2.4.11). + +PT_GNU_STACK +============ + +Last PT_GNU_STACK program header defines userspace stack executability +(since Linux 2.6.6). Other PT_GNU_STACK headers are ignored. + +PT_GNU_PROPERTY +=============== + +ELF interpreter's last PT_GNU_PROPERTY program header is used (since +Linux 5.8). If interpreter doesn't have one, then the last PT_GNU_PROPERTY +program header of an executable is used. Other PT_GNU_PROPERTY headers +are ignored. --- a/Documentation/userspace-api/index.rst +++ b/Documentation/userspace-api/index.rst @@ -23,6 +23,7 @@ place where this information is gathered. spec_ctrl accelerators/ocxl ebpf/index + ELF ioctl/index iommu iommufd