Message ID | 20230607144227.8956-1-ansuelsmth@gmail.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp257222vqr; Wed, 7 Jun 2023 07:54:13 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6WcTUKDsbS//Mnkgq5LYEm1nCEWV6i0mEi4aWU5MinGlmu13dSjgxFw9jq0VXZz3ViYGeq X-Received: by 2002:a05:6a20:7d82:b0:10c:d5dd:c223 with SMTP id v2-20020a056a207d8200b0010cd5ddc223mr4103216pzj.15.1686149653357; Wed, 07 Jun 2023 07:54:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686149653; cv=none; d=google.com; s=arc-20160816; b=GstzEeTs63F0rlOFlA7cjaDgQzX+aqywbcfu0JR10MecpWoqHFlODdqfpAtG0QpKXx KuV+fQtulCGDC4xE7ayRzU7BX5o8psC+Nw5L2nfW0f37UlIerpu5mNour49vm8KGUvTz gj2gMpzSwhZkV1YBR9W/A5YwwPn2fxgBUURPC9Cqxn3ma+aWinlINGWDQ5Erj1dLAf8Q Sf94TWI4koyjyTSOpVZO4d/bXUsonyxyf/tF997caTgBOPIFltdMWSTU64jWTxIiAIHX z48lp+v+XTay++LiQHhz2f8RZcZwZhG28FTRRPQj42a+BnGfId3oP8zLMZqTNp3V2ex9 oBag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=bhU8rJcA/NcmdBFZbG66fI16dsKgmepn+1tYIFC8M3Y=; b=t4vdCek6R+UM2q3Y2TDODxMeDh9rMRy9imGOiwp8xu1i24Roam4YspswJO2tczFd33 /YJrgvGg8eyCekRHEw90AHiX5c0jkyoxneT+V6vcs3uWuEi/3Kqz8i9HSnnAaKrjXUnI vdIPhPq/J7p3tLfLf4UL/s1jWxxc5/iGoBxi3wC6UiJdAjnGspH81w598srpowghrb+3 aoYMx4VcLislLK1nuDalHZbKmcJpCzfXNBSl3+Po4A8tBD1/66caW71r1fxE8qalwJd+ XxhpCerQb2vJnBBd5ydUi6BUUYadzvTq0oAd0/DJIWYk74T3178eNOb0OBjrLj6WR3kr QhPA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20221208 header.b=bXFeImhQ; 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 130-20020a621888000000b0064d3a475274si8591394pfy.75.2023.06.07.07.54.00; Wed, 07 Jun 2023 07:54:13 -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=bXFeImhQ; 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 S241165AbjFGOmk (ORCPT <rfc822;xxoosimple@gmail.com> + 99 others); Wed, 7 Jun 2023 10:42:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35472 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241156AbjFGOmf (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 7 Jun 2023 10:42:35 -0400 Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 04CCA1BFB; Wed, 7 Jun 2023 07:42:33 -0700 (PDT) Received: by mail-wr1-x42b.google.com with SMTP id ffacd0b85a97d-30ae141785bso7298823f8f.3; Wed, 07 Jun 2023 07:42:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1686148951; x=1688740951; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=bhU8rJcA/NcmdBFZbG66fI16dsKgmepn+1tYIFC8M3Y=; b=bXFeImhQdmhi+fiXTrYziTug2rbzZLXJhrXLvGxWuoZ2j7UukUjIt8sAoeX/RF7xv1 UIJtUOm842Gd3oYnQ4uc1hb6B6+MA/hfg9r4H3Hd6U/vNOPgejThO0dav7DufAtYCl6M OXksAOKE/B4XZh3jUtATnWfvmYd1VDBw/RG6ydD8TjwOGxCr0qRJpccgdXxC4PzOkW82 C172foUptIBBIPMcXeHlpmSncRBj4r7KkYtmXktu4geGFPXgytJEs/WoCzv66A8gl82e cAzEr8z+geaUgs3Dh6Jpsl6ZP5g8P1kUAtcjHd9ee+vbQVvkFS3oh0pIi4d0mkaXUPkR tPgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686148951; x=1688740951; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=bhU8rJcA/NcmdBFZbG66fI16dsKgmepn+1tYIFC8M3Y=; b=crtewVQk8Z8j86s3wql2vppzG2uJfC5QkicP7TLrPlOFkeQgX9qCOGX47zn5R+pbrE M6r9XS76MUOpQ2GR5bLD8PsWbJXyIJ1NPuCQo54y+4BPinACkZzOZ/xZe3NcapolcvLx OL76W8b/4n+PDLJAPCgH3etDlUmqmBz5XLTVXYdY+mP6v0GLRDWY+3xD2K0IgtoidJAS weoy9V5Y+HXRwRNJF6MA4S3/V17IYvgZ81WD1JsftUSW0/0SH8c/tNJqIm6K5dXVGUib ujN7OKRjXQWjlY1xgyIdly1oCflS5VN/iPcMRyORCqI2eZQC8eAqP+rk50x3yqqHUh9B XmtQ== X-Gm-Message-State: AC+VfDxYHoPt/b5QbjZZjz41TOl42rfbuEaT/ZjV5rgJKaWPSNqMwGMK aM1Z5t8w05I9OhZtwaW2e5dTEpNg7Ls= X-Received: by 2002:a5d:408f:0:b0:309:4368:a8a0 with SMTP id o15-20020a5d408f000000b003094368a8a0mr4476903wrp.68.1686148950971; Wed, 07 Jun 2023 07:42:30 -0700 (PDT) Received: from localhost.localdomain (93-34-93-173.ip49.fastwebnet.it. [93.34.93.173]) by smtp.googlemail.com with ESMTPSA id z12-20020a5d4d0c000000b003068f5cca8csm15731342wrt.94.2023.06.07.07.42.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Jun 2023 07:42:30 -0700 (PDT) From: Christian Marangi <ansuelsmth@gmail.com> To: Alexander Viro <viro@zeniv.linux.org.uk>, Christian Brauner <brauner@kernel.org>, Eric Biederman <ebiederm@xmission.com>, Kees Cook <keescook@chromium.org>, Mark Brown <broonie@kernel.org>, Dave Martin <Dave.Martin@arm.com>, Catalin Marinas <catalin.marinas@arm.com>, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org Cc: Christian Marangi <ansuelsmth@gmail.com>, stable@vger.kernel.org Subject: [PATCH] binfmt_elf: dynamically allocate note.data in parse_elf_properties Date: Wed, 7 Jun 2023 16:42:27 +0200 Message-Id: <20230607144227.8956-1-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.39.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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,T_SCC_BODY_TEXT_LINE, URIBL_BLOCKED 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?1768056058776558159?= X-GMAIL-MSGID: =?utf-8?q?1768056058776558159?= |
Series |
binfmt_elf: dynamically allocate note.data in parse_elf_properties
|
|
Commit Message
Christian Marangi
June 7, 2023, 2:42 p.m. UTC
Dynamically allocate note.data in parse_elf_properties to fix
compilation warning on some arch.
On some arch note.data exceed the stack limit for a single function and
this cause the following compilation warning:
fs/binfmt_elf.c: In function 'parse_elf_properties.isra':
fs/binfmt_elf.c:821:1: error: the frame size of 1040 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
821 | }
| ^
cc1: all warnings being treated as errors
Fix this by dynamically allocating the array.
Update the sizeof of the union to the biggest element allocated.
Fixes: 00e19ceec80b ("ELF: Add ELF program property parsing support")
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Cc: stable@vger.kernel.org # v5.8+
---
fs/binfmt_elf.c | 36 +++++++++++++++++++++++++-----------
1 file changed, 25 insertions(+), 11 deletions(-)
Comments
On Wed, Jun 07, 2023 at 02:19:51PM -0700, Kees Cook wrote: > On Wed, Jun 07, 2023 at 04:42:27PM +0200, Christian Marangi wrote: > > Dynamically allocate note.data in parse_elf_properties to fix > > compilation warning on some arch. > > I'd rather avoid dynamic allocation as much as possible in the exec > path, but we can balance it against how much it may happen. > I guess there isn't a good way to handle this other than static global variables and kmalloc. But check the arch question for additional info on the case. > > On some arch note.data exceed the stack limit for a single function and > > this cause the following compilation warning: > > fs/binfmt_elf.c: In function 'parse_elf_properties.isra': > > fs/binfmt_elf.c:821:1: error: the frame size of 1040 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] > > 821 | } > > | ^ > > cc1: all warnings being treated as errors > > Which architectures see this warning? > This is funny. On OpenWRT we are enforcing WERROR and we had FRAME_WARN hardcoded to 1024. (the option is set to 2048 on 64bit arch) ARCH_USE_GNU_PROPERTY is set only on arm64 that have a FRAME_WARN set to 2048. So this was triggered by building arm64 with FRAME_WARN set to 1024. Now with the configuration of 2048 the stack warn is not triggered, but I wonder if it may happen to have a 32bit system with ARCH_USE_GNU_PROPERTY. That would effectively trigger the warning. So this is effectively a patch that fix a currently not possible configuration, since: !IS_ENABLED(CONFIG_ARCH_USE_GNU_PROPERTY) will result in node.data effectively never allocated by the compiler are the function will return 0 on everything that doesn't have CONFIG_ARCH_USE_GNU_PROPERTY. > > Fix this by dynamically allocating the array. > > Update the sizeof of the union to the biggest element allocated. > > How common are these notes? I assume they're very common; I see them > even in /bin/true: > > $ readelf -lW /bin/true | grep PROP > GNU_PROPERTY 0x000338 0x0000000000000338 0x0000000000000338 0x000030 0x000030 R 0x8 > > -- Is there a way to check if this kmalloc actually cause perf regression?
On Wed, Jun 07, 2023 at 04:42:27PM +0200, Christian Marangi wrote: > Dynamically allocate note.data in parse_elf_properties to fix > compilation warning on some arch. I'd rather avoid dynamic allocation as much as possible in the exec path, but we can balance it against how much it may happen. > On some arch note.data exceed the stack limit for a single function and > this cause the following compilation warning: > fs/binfmt_elf.c: In function 'parse_elf_properties.isra': > fs/binfmt_elf.c:821:1: error: the frame size of 1040 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] > 821 | } > | ^ > cc1: all warnings being treated as errors Which architectures see this warning? > Fix this by dynamically allocating the array. > Update the sizeof of the union to the biggest element allocated. How common are these notes? I assume they're very common; I see them even in /bin/true: $ readelf -lW /bin/true | grep PROP GNU_PROPERTY 0x000338 0x0000000000000338 0x0000000000000338 0x000030 0x000030 R 0x8
On Wed, Jun 07, 2023 at 08:31:58PM +0200, Christian Marangi wrote: > On Wed, Jun 07, 2023 at 02:19:51PM -0700, Kees Cook wrote: > > On Wed, Jun 07, 2023 at 04:42:27PM +0200, Christian Marangi wrote: > > > Dynamically allocate note.data in parse_elf_properties to fix > > > compilation warning on some arch. > > > > I'd rather avoid dynamic allocation as much as possible in the exec > > path, but we can balance it against how much it may happen. > > > > I guess there isn't a good way to handle this other than static global > variables and kmalloc. But check the arch question for additional info > on the case. > > > > On some arch note.data exceed the stack limit for a single function and > > > this cause the following compilation warning: > > > fs/binfmt_elf.c: In function 'parse_elf_properties.isra': > > > fs/binfmt_elf.c:821:1: error: the frame size of 1040 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] > > > 821 | } > > > | ^ > > > cc1: all warnings being treated as errors > > > > Which architectures see this warning? > > > > This is funny. On OpenWRT we are enforcing WERROR and we had FRAME_WARN > hardcoded to 1024. (the option is set to 2048 on 64bit arch) Ah-ha. Okay, I was wondering how you got that. :) > ARCH_USE_GNU_PROPERTY is set only on arm64 that have a FRAME_WARN set to > 2048. > > So this was triggered by building arm64 with FRAME_WARN set to 1024. > > Now with the configuration of 2048 the stack warn is not triggered, but > I wonder if it may happen to have a 32bit system with > ARCH_USE_GNU_PROPERTY. That would effectively trigger the warning. > > So this is effectively a patch that fix a currently not possible > configuration, since: > > !IS_ENABLED(CONFIG_ARCH_USE_GNU_PROPERTY) will result in node.data > effectively never allocated by the compiler are the function will return > 0 on everything that doesn't have CONFIG_ARCH_USE_GNU_PROPERTY. > > > > Fix this by dynamically allocating the array. > > > Update the sizeof of the union to the biggest element allocated. > > > > How common are these notes? I assume they're very common; I see them > > even in /bin/true: > > > > $ readelf -lW /bin/true | grep PROP > > GNU_PROPERTY 0x000338 0x0000000000000338 0x0000000000000338 0x000030 0x000030 R 0x8 > > > > -- > > Is there a way to check if this kmalloc actually cause perf regression? I don't have a good benchmark besides just an exec loop. But since this isn't reachable in a regular config, I'd rather keep things how there already are. -Kees
Christian Marangi <ansuelsmth@gmail.com> writes: > Dynamically allocate note.data in parse_elf_properties to fix > compilation warning on some arch. > > On some arch note.data exceed the stack limit for a single function and > this cause the following compilation warning: > fs/binfmt_elf.c: In function 'parse_elf_properties.isra': > fs/binfmt_elf.c:821:1: error: the frame size of 1040 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] > 821 | } > | ^ > cc1: all warnings being treated as errors > > Fix this by dynamically allocating the array. > Update the sizeof of the union to the biggest element allocated. > > Fixes: 00e19ceec80b ("ELF: Add ELF program property parsing support") > Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> > Cc: stable@vger.kernel.org # v5.8+ > --- > fs/binfmt_elf.c | 36 +++++++++++++++++++++++++----------- > 1 file changed, 25 insertions(+), 11 deletions(-) > > diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c > index 44b4c42ab8e8..90daa623ca13 100644 > --- a/fs/binfmt_elf.c > +++ b/fs/binfmt_elf.c > @@ -768,7 +768,7 @@ static int parse_elf_properties(struct file *f, const struct elf_phdr *phdr, > { > union { > struct elf_note nhdr; > - char data[NOTE_DATA_SZ]; > + char *data; > } note; If you are going to dynamically allocate this not that way please. Only dynamically allocating one member of a union is to put it politely completely broken. The entire union needs to be dynamically allocated. Given that the entire thing is 1024 bytes in size. I can understand the concern. Hmm. The entire union is a buffer for the entire note section. So 1K is understandable if it needs to hold all of the notes. Of course only a single note is a wrapper of a bunch of gnu_properties. Hopefully that single note comes first. The notehdr + name take 16 bytes. The only supported gnu_property takes 12 bytes. I think 16 in practice. Hmm. So we could do with a smaller buffer. Hmm. The code does not check that all phdr->p_filesz bytes are actually read. So I would suggest defining the union to be ELF_EXEC_PAGESIZE bytes, dynamically allocating it like we do all of the other buffers we read elf headers into, and then use elf_read to verify that we read all of phdr->p_filesz bytes. Just like we do for the elf program headers. I think having a second pattern for reading data is more likely to be a problem than a dynamic memory allocation. Especially since this code only runs on one architecture in practice. The changes will cost nothing except on arm64 and it will be as cheap as it can be, being simply a single page allocation. Either that or you can up your stack limit on 64bit architectures like everyone else. Eric
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 44b4c42ab8e8..90daa623ca13 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -768,7 +768,7 @@ static int parse_elf_properties(struct file *f, const struct elf_phdr *phdr, { union { struct elf_note nhdr; - char data[NOTE_DATA_SZ]; + char *data; } note; loff_t pos; ssize_t n; @@ -785,29 +785,41 @@ static int parse_elf_properties(struct file *f, const struct elf_phdr *phdr, return -ENOEXEC; /* If the properties are crazy large, that's too bad (for now): */ - if (phdr->p_filesz > sizeof(note)) + if (phdr->p_filesz > sizeof(*note.data) * NOTE_DATA_SZ) return -ENOEXEC; + note.data = kcalloc(NOTE_DATA_SZ, sizeof(*note.data), GFP_KERNEL); + if (!note.data) + return -ENOMEM; + pos = phdr->p_offset; n = kernel_read(f, ¬e, phdr->p_filesz, &pos); - BUILD_BUG_ON(sizeof(note) < sizeof(note.nhdr) + NOTE_NAME_SZ); - if (n < 0 || n < sizeof(note.nhdr) + NOTE_NAME_SZ) - return -EIO; + BUILD_BUG_ON(sizeof(*note.data) * NOTE_DATA_SZ < sizeof(note.nhdr) + NOTE_NAME_SZ); + if (n < 0 || n < sizeof(note.nhdr) + NOTE_NAME_SZ) { + ret = -EIO; + goto exit; + } if (note.nhdr.n_type != NT_GNU_PROPERTY_TYPE_0 || note.nhdr.n_namesz != NOTE_NAME_SZ || strncmp(note.data + sizeof(note.nhdr), - GNU_PROPERTY_TYPE_0_NAME, n - sizeof(note.nhdr))) - return -ENOEXEC; + GNU_PROPERTY_TYPE_0_NAME, n - sizeof(note.nhdr))) { + ret = -ENOEXEC; + goto exit; + } off = round_up(sizeof(note.nhdr) + NOTE_NAME_SZ, ELF_GNU_PROPERTY_ALIGN); - if (off > n) - return -ENOEXEC; + if (off > n) { + ret = -ENOEXEC; + goto exit; + } - if (note.nhdr.n_descsz > n - off) - return -ENOEXEC; + if (note.nhdr.n_descsz > n - off) { + ret = -ENOEXEC; + goto exit; + } datasz = off + note.nhdr.n_descsz; have_prev_type = false; @@ -817,6 +829,8 @@ static int parse_elf_properties(struct file *f, const struct elf_phdr *phdr, have_prev_type = true; } while (!ret); +exit: + kfree(note.data); return ret == -ENOENT ? 0 : ret; }