Received: by 2002:a05:7412:b101:b0:e2:908c:2ebd with SMTP id az1csp3430034rdb; Thu, 16 Nov 2023 09:13:25 -0800 (PST) X-Google-Smtp-Source: AGHT+IEcVp5fwbR3J8Vino3ceOJcIKZ0TJuQpWNoKif6TSV4gG2JvlhvmbKU1y1VLDxgszxdp4q2 X-Received: by 2002:a17:902:ec92:b0:1ca:7439:f74f with SMTP id x18-20020a170902ec9200b001ca7439f74fmr10034160plg.60.1700154805339; Thu, 16 Nov 2023 09:13:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1700154805; cv=none; d=google.com; s=arc-20160816; b=OlznlvnQrLbzHPcy5FnAksRRFUYovj5bz/9L/BJFZ+7p12v6gBeQPcww4T17viibpH yvBmNlAob9iXibMXn7tOy8wWEl6aLj5CKEy4i/fUuXqcpcgQyiK+XTB1XtG8IZqw73Fb uwWaFVB+65IZD9JrY1/rwBc/LFO0sTJo5MitF1dY4SC+Rl/rtao8VUF22Gmv3dWoWk5z hFG2VmP0ez0YAvOARls1gHiSMSAzehm53w67F70rVuVAWBo/6ccGLw/M38kq8PTy6E5S gzpP0j23AnVpwuGUU2KigCeCC6DehH8TTShAOE8bfBt1lyzLglZXcadVCeGJLUGLcfI7 kwHg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:content-disposition :mime-version:references:message-id:subject:cc:to:from:date :dkim-signature; bh=rriOKmH8E9hkmOxPeS6KUmox+mrthGZOdjRWS2B5ZXY=; fh=Q5kxJ4WOsbfqYOcRhl2omzsWhVklCAuO2/j2BRYW/Yo=; b=yHFr45LTjvJvX/myTRnMeKtnw376DgZR2SIaUIF0FTalCi1k95+RoGlcsWUdwSJ6L+ afAuQtKqF8qc3/2N7cY8vgWc3QW1QuSoAFQ1hUIihQ1/6NFozDk51Vdqnj6FbYMrR6/Z Mc92qpnw8mY1pKOIWv0wePxLisCKs+xJ05VsQWwcnsay6LXNv0n2iY2UgH9cETbbupW4 DSGmHr7gH2innbtTBegVgO1jzMrWBpTuSE/L2K3mwqxHyTjXkh/5NUfYK6VMHtjBVSzc AJ/a6vu54fIpuHWScTem4C7FKD2s1GHgMnvjKbexvcr9dprtggVYJPBSGYYw2iYustXF H6ng== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@infradead.org header.s=bombadil.20210309 header.b="Z/tOBzhB"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from snail.vger.email (snail.vger.email. [2620:137:e000::3:7]) by mx.google.com with ESMTPS id l2-20020a170902d34200b001c9d9050b37si12223492plk.260.2023.11.16.09.13.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Nov 2023 09:13:25 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) client-ip=2620:137:e000::3:7; Authentication-Results: mx.google.com; dkim=pass header.i=@infradead.org header.s=bombadil.20210309 header.b="Z/tOBzhB"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 71831813EABC; Thu, 16 Nov 2023 09:13:14 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231322AbjKPRNO (ORCPT + 99 others); Thu, 16 Nov 2023 12:13:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49512 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229464AbjKPRNM (ORCPT ); Thu, 16 Nov 2023 12:13:12 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 428A5D52; Thu, 16 Nov 2023 09:13:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Sender:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=rriOKmH8E9hkmOxPeS6KUmox+mrthGZOdjRWS2B5ZXY=; b=Z/tOBzhB1GcjJdQQrjjAvtFcxh rH5gAWfhwbAulmEQCuJeXwASCnUMMkcQGn2clVN0jCHFPyFMgCteVKp6h/xdR4OKfRks6R0uTX8NB pXSG4/NO9YbGtVWl96kio1ldRqxkvEalEi+SZ7NuQsmvxmpV4jsBZmHycEqUyk8OB8GgTBPEKpfCZ Of47G6t9hYLxm9+Xh00HpkoA27ECUMTkyJPvbqYKKfNYzmUhikbSqOK/I0tOlVPSbCMHC8E7lcYaa STgBqBHkmZD5PelziCmsq7/HymQvUcAJFXdMyR3yYfN6T2msb0pYvlGpPshZvSk8eFDLZksL/5rpU BqirE7dA==; Received: from mcgrof by bombadil.infradead.org with local (Exim 4.96 #2 (Red Hat Linux)) id 1r3fux-0045Gx-2T; Thu, 16 Nov 2023 17:12:39 +0000 Date: Thu, 16 Nov 2023 09:12:39 -0800 From: Luis Chamberlain To: Matthew Maurer Cc: gary@garyguo.net, masahiroy@kernel.org, Michael Ellerman , Miguel Ojeda , Alex Gaynor , Wedson Almeida Filho , Nicholas Piggin , Josh Poimboeuf , Song Liu , Petr Mladek , Naveen N Rao , Andrew Morton , "Masami Hiramatsu (Google)" , "Paul E. McKenney" , Nick Desaulniers , Randy Dunlap , Mathieu Desnoyers , Nhat Pham , Greg Kroah-Hartman , Marc =?iso-8859-1?Q?Aur=E8le?= La France , Christophe Leroy , Nathan Chancellor , Nicolas Schier , Boqun Feng , =?iso-8859-1?Q?Bj=F6rn?= Roy Baron , Benno Lossin , Andreas Hindborg , Alice Ryhl , Vlastimil Babka , Ard Biesheuvel , linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, linux-kbuild@vger.kernel.org, rust-for-linux@vger.kernel.org Subject: Re: [PATCH 2/3] modpost: Extended modversion support Message-ID: References: <20231115185858.2110875-1-mmaurer@google.com> <20231115185858.2110875-3-mmaurer@google.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20231115185858.2110875-3-mmaurer@google.com> Sender: Luis Chamberlain X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_EF,HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE, URIBL_BLOCKED autolearn=no 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: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Thu, 16 Nov 2023 09:13:14 -0800 (PST) On Wed, Nov 15, 2023 at 06:50:10PM +0000, Matthew Maurer wrote: > Adds a new format for modversions which stores each field in a separate > elf section. The "why" is critical and not mentioned. And I'd like to also see documented this with foresight, if Rust needed could this be used in the future for other things? Also please include folks CC'd in *one* patch to *all* patches as otherwise we have no context. > This initially adds support for variable length names, but > could later be used to add additional fields to modversions in a > backwards compatible way if needed. > > Adding support for variable length names makes it possible to enable > MODVERSIONS and RUST at the same time. > > Signed-off-by: Matthew Maurer > --- > arch/powerpc/kernel/module_64.c | 24 +++++++++- Why was only powerpc modified? If the commit log explained this it would make it easier for review. > diff --git a/kernel/module/internal.h b/kernel/module/internal.h > index c8b7b4dcf782..0c188c96a045 100644 > --- a/kernel/module/internal.h > +++ b/kernel/module/internal.h > @@ -80,7 +80,7 @@ struct load_info { > unsigned int used_pages; > #endif > struct { > - unsigned int sym, str, mod, vers, info, pcpu; > + unsigned int sym, str, mod, vers, info, pcpu, vers_ext_crc, vers_ext_name; We might as well modify this in a preliminary patch to add each new unsinged int in a new line, so that it is easier to blame when each new entry gets added. It should not grow the size of the struct at all but it would make futur extensions easier to review what is new and git blame easier to spot when something was added. Although we don't use this extensively today this can easily grow for convenience and making code easier to read. > diff --git a/kernel/module/version.c b/kernel/module/version.c > index 53f43ac5a73e..93d97dad8c77 100644 > --- a/kernel/module/version.c > +++ b/kernel/module/version.c > @@ -19,11 +19,28 @@ int check_version(const struct load_info *info, > unsigned int versindex = info->index.vers; > unsigned int i, num_versions; > struct modversion_info *versions; > + struct modversion_info_ext version_ext; > > /* Exporting module didn't supply crcs? OK, we're already tainted. */ > if (!crc) > return 1; > > + /* If we have extended version info, rely on it */ > + if (modversion_ext_start(info, &version_ext) >= 0) { There are two things we need to do to make processing modules easier: 1) ELF validation 2) Once checked then process the information We used to have this split up but also had a few places which did both 1) and 2) together. This was wrong and so I want to keep things tidy and ensure we do things which validate the ELF separate. To that end please put the checks to validate the ELF first so that we report to users with a proper error/debug check in case the ELF is wrong, this enables futher debug checks for that to be done instead of confusing users who end up scratching their heads why something failed. So please split up the ELF validation check and put that into elf_validity_cache_copy() which runs *earlier* than this. Then *if* if has this, you just process it. Please take care to be very pedantic in the elf_validity_cache_copy() and extend the checks you have for validation in modversion_ext_start() and bring them to elf_validity_cache_copy() with perhaps *more* stuff which does any insane checks to verify it is 100% correct. > + do { > + if (strncmp(version_ext.name.value, symname, > + version_ext.name.end - version_ext.name.value) != 0) > + continue; > + > + if (*version_ext.crc.value == *crc) > + return 1; > + pr_debug("Found checksum %X vs module %X\n", > + *crc, *version_ext.crc.value); > + goto bad_version; > + } while (modversion_ext_advance(&version_ext) == 0); Can you do a for_each_foo()) type loop here instead after validation? Because the validation would ensure your loop is bounded then. Look at for_each_mod_mem_type() for inspiration. > + goto broken_toolchain; The broken toolchain thing would then be an issue reported in the ELF validation. > @@ -87,6 +105,65 @@ int same_magic(const char *amagic, const char *bmagic, > return strcmp(amagic, bmagic) == 0; > } > > +#define MODVERSION_FIELD_START(sec, field) \ > + field.value = (typeof(field.value))sec.sh_addr; \ > + field.end = field.value + sec.sh_size > + > +ssize_t modversion_ext_start(const struct load_info *info, > + struct modversion_info_ext *start) > +{ > + unsigned int crc_idx = info->index.vers_ext_crc; > + unsigned int name_idx = info->index.vers_ext_name; > + Elf_Shdr *sechdrs = info->sechdrs; > + > + // Both of these fields are needed for this to be useful > + // Any future fields should be initialized to NULL if absent. Curious, what gave you the impression // type style comments are welcomed, please replace that with either a one line /* foo comment */ Or a multi-line: /* * stuff and go into great deatils * more elaaborate explanation */ Of even better, since you are moving this to ELF Validation please add undertand what elf_validity_cache_copy() does, and add kdoc style comments for it and then extend it with why Rust needs these magical things. > + if ((crc_idx == 0) || (name_idx == 0)) > + return -EINVAL; > + > + MODVERSION_FIELD_START(sechdrs[crc_idx], start->crc); > + MODVERSION_FIELD_START(sechdrs[name_idx], start->name); > + > + return (start->crc.end - start->crc.value) / sizeof(*start->crc.value); > +} > + > +static int modversion_ext_s32_advance(struct modversion_info_ext_s32 *field) > +{ > + if (!field->value) > + return 0; > + if (field->value >= field->end) > + return -EINVAL; > + field->value++; > + return 0; > +} > + > +static int modversion_ext_string_advance(struct modversion_info_ext_string *s) > +{ > + if (!s->value) > + return 0; > + if (s->value >= s->end) > + return -EINVAL; > + s->value += strnlen(s->value, s->end - s->value - 1) + 1; > + if (s->value >= s->end) > + return -EINVAL; > + return 0; > +} > + > +int modversion_ext_advance(struct modversion_info_ext *start) > +{ > + int ret; > + > + ret = modversion_ext_s32_advance(&start->crc); > + if (ret < 0) > + return ret; > + > + ret = modversion_ext_string_advance(&start->name); > + if (ret < 0) > + return ret; > + > + return 0; > +} Please add all the validation as part of the ELF validation sanity checks and make sure you rant so toolchains get easily debugged and fixed. That would make the processing of data a secodnary step and it is easier to read and simpler code. The validation then becomes the part which kicks issues out early. > /* > * Generate the signature for all relevant module structures here. > * If these change, we don't want to try to parse the module. > diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c > index 973b5e5ae2dd..884860c2e833 100644 > --- a/scripts/mod/modpost.c > +++ b/scripts/mod/modpost.c > @@ -1910,15 +1910,42 @@ static void add_versions(struct buffer *b, struct module *mod) > continue; > } > if (strlen(s->name) >= MODULE_NAME_LEN) { > - error("too long symbol \"%s\" [%s.ko]\n", > - s->name, mod->name); > - break; > + /* this symbol will only be in the extended info */ > + continue; I cannot grok why this is being done, but hopefully in the next patch series this will be easier to understand. Luis