From nobody Mon Nov 25 01:32:29 2024 Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E615F1DFE1D for ; Wed, 30 Oct 2024 23:05:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730329511; cv=none; b=IVgT67DX6MiAdCMvEX6/uPN+Zspks+2FKNZovEgJsOkThHFHVGo2ocXt9sdlBMczg0ZsRVr6GDmlYqxY1dL08K4F+MqyAi/xTCqQ0Jpx3g43XqUFbd6G0PcIUhmislAuXNEuabPHLhHTYnYMiI9Q+X0e3ykjTHvFGzGN3OTmxjg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730329511; c=relaxed/simple; bh=Q6PChDL+oyVIftKwE+bBAXZjV7BwBjURcBa1udfZz4U=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=hrV7ihYTtosAeDPYZwqFpQgb5S4FluAeS8OQLgLgxAmVZfvYeRKi8JICu94kvBpCs9Wj+H05QFxGUKqHa2JeXCRFJVPbFfcrGqdLdhSMuwd4grK8BWlI1AMkQaqMKmRjclpWI5PzQzQpMPQeSGSl5FDfLr5+c7gd4Bjm4INSvkM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--mmaurer.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=0jF8bFwX; arc=none smtp.client-ip=209.85.128.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--mmaurer.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="0jF8bFwX" Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-6e32b43e053so5068097b3.1 for ; Wed, 30 Oct 2024 16:05:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1730329508; x=1730934308; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=M9nQk6Vo8fRWDZnjgBzQeNQ0t1uhkA+WPna5Ivbnx+E=; b=0jF8bFwXYLiS2HJwZbzFaNEs1QJ9spGh3Cmn5jTsRDKSVf07GTmf3wQlaXNlMyMI2K dkBKkiDFQJxadbKWk+zv8I4q7N1kAgJLWxb92SYki35tcVXmqIzG4fsvJwvFNGaVq1N9 uzqlDXwr/GEvhu4xOYZutrZkOOyKLisCCsKQNVxayvV0TxdwAvTANR8UDI6Z/iue2I3k U1dxz0SqVSM0nr2iXg9WVmMRA+2wCCOhDzQb4U7cYoiUJXzLUqNjDhD09/XxvE7hjNz4 s5U4AzPlAUMCM4XBlWS1pH7bO+jhdZuJhpf/opKZqk33ZJbpLoDHR1aW3ZQ9nRR7ClSw rC1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730329508; x=1730934308; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=M9nQk6Vo8fRWDZnjgBzQeNQ0t1uhkA+WPna5Ivbnx+E=; b=VOV2Wk/JzVk9NB52pO17XlH+gAOTiR3AdCnkXMNEG00d2B9VwPzrl0K4sKGZ4Md/mP tlzDHBPXIm4nYl66nJSsMgg0FRt1+1+KxDGL7/Uar7g7p34dwF10c6fODPdmZdfZQTTe t2T2JFfe2RanI3J1RZulPgKvhMCoocteVBqi8X5nc2x+mFKBhH73LXQ59k4RQlvHgX6N NBJ00RzecQIbBJQoeloS5TBkMskhj8UDaE9APB9sSZ673Mvg9rCjv9szAiMSvEm07hoQ 9a7/9ZYxQA+gEIWgOMCiJo7dieSOMaRPc9Xuouz+TOb20JrwqqBk2Tkt9HGu2nhgeB51 vsKA== X-Forwarded-Encrypted: i=1; AJvYcCUvJINEYnXui+JgM3pEGmfZO1tOkWxg3YcXVwOWFPyJQQoX0PYBQzmEaby8EaPh40/SlrwqscBiTsFG01k=@vger.kernel.org X-Gm-Message-State: AOJu0YxDL+yX0k3KYMb7nt8Ot+haCf4Zv+MPT+rMUBke8TWzscYzh9MY px3SzMS9QsW/KRZsBxiEjRbJChZ4cX8DvIrnVHH/JnkhMRDeU4pW4XyRj0hNV1D1UHPS39+gG9v F5dsb7w== X-Google-Smtp-Source: AGHT+IFvZLz7CVdvhJjJoh+yqpQ35aVD3PCtqu26YbxX8dAJAbgIAzOeOK4f9sJtySMAH38zABThUZljaU2M X-Received: from anyblade.c.googlers.com ([fda3:e722:ac3:cc00:20:ed76:c0a8:1791]) (user=mmaurer job=sendgmr) by 2002:a25:838d:0:b0:e27:3e6a:345 with SMTP id 3f1490d57ef6-e3087c22e77mr11084276.10.1730329507922; Wed, 30 Oct 2024 16:05:07 -0700 (PDT) Date: Wed, 30 Oct 2024 23:05:02 +0000 In-Reply-To: <20241030-extended-modversions-v8-0-93acdef62ce8@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20241030-extended-modversions-v8-0-93acdef62ce8@google.com> X-Mailer: b4 0.15-dev Message-ID: <20241030-extended-modversions-v8-1-93acdef62ce8@google.com> Subject: [PATCH v8 1/3] modules: Support extended MODVERSIONS info From: Matthew Maurer To: Michael Ellerman , Nicholas Piggin , Christophe Leroy , Naveen N Rao , Madhavan Srinivasan , Luis Chamberlain , Petr Pavlu , Sami Tolvanen , Daniel Gomez , Masahiro Yamada , Nathan Chancellor , Nicolas Schier , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , "=?utf-8?q?Bj=C3=B6rn_Roy_Baron?=" , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross Cc: 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, Matthew Maurer Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Adds a new format for MODVERSIONS which stores each field in a separate ELF section. 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. Any new fields will be ignored by old user tooling, unlike the current format where user tooling cannot tolerate adjustments to the format (for example making the name field longer). Since PPC munges its version records to strip leading dots, we reproduce the munging for the new format. Other architectures do not appear to have architecture-specific usage of this information. Reviewed-by: Sami Tolvanen Signed-off-by: Matthew Maurer Acked-by: Michael Ellerman (powerpc) --- arch/powerpc/kernel/module_64.c | 24 ++++++++++- kernel/module/internal.h | 11 +++++ kernel/module/main.c | 92 +++++++++++++++++++++++++++++++++++++= ---- kernel/module/version.c | 45 ++++++++++++++++++++ 4 files changed, 162 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_6= 4.c index e9bab599d0c2745e4d2b5cae04f2c56395c24654..02ada0b057cef6b2f29fa7519a5= d52acac740ee5 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c @@ -355,6 +355,24 @@ static void dedotify_versions(struct modversion_info *= vers, } } =20 +/* Same as normal versions, remove a leading dot if present. */ +static void dedotify_ext_version_names(char *str_seq, unsigned long size) +{ + unsigned long out =3D 0; + unsigned long in; + char last =3D '\0'; + + for (in =3D 0; in < size; in++) { + /* Skip one leading dot */ + if (last =3D=3D '\0' && str_seq[in] =3D=3D '.') + in++; + last =3D str_seq[in]; + str_seq[out++] =3D last; + } + /* Zero the trailing portion of the names table for robustness */ + memset(&str_seq[out], 0, size - out); +} + /* * Undefined symbols which refer to .funcname, hack to funcname. Make .TOC. * seem to be defined (value set later). @@ -424,10 +442,12 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr, me->arch.toc_section =3D i; if (sechdrs[i].sh_addralign < 8) sechdrs[i].sh_addralign =3D 8; - } - else if (strcmp(secstrings+sechdrs[i].sh_name,"__versions")=3D=3D0) + } else if (strcmp(secstrings + sechdrs[i].sh_name, "__versions") =3D=3D = 0) dedotify_versions((void *)hdr + sechdrs[i].sh_offset, sechdrs[i].sh_size); + else if (strcmp(secstrings + sechdrs[i].sh_name, "__version_ext_names") = =3D=3D 0) + dedotify_ext_version_names((void *)hdr + sechdrs[i].sh_offset, + sechdrs[i].sh_size); =20 if (sechdrs[i].sh_type =3D=3D SHT_SYMTAB) dedotify((void *)hdr + sechdrs[i].sh_offset, diff --git a/kernel/module/internal.h b/kernel/module/internal.h index daef2be8390222c22220e2f168baa8d35ad531b9..59959c21b205bf91c0073260885= 743098c4022cf 100644 --- a/kernel/module/internal.h +++ b/kernel/module/internal.h @@ -86,6 +86,8 @@ struct load_info { unsigned int vers; unsigned int info; unsigned int pcpu; + unsigned int vers_ext_crc; + unsigned int vers_ext_name; } index; }; =20 @@ -389,6 +391,15 @@ void module_layout(struct module *mod, struct modversi= on_info *ver, struct kerne struct kernel_symbol *ks, struct tracepoint * const *tp); int check_modstruct_version(const struct load_info *info, struct module *m= od); int same_magic(const char *amagic, const char *bmagic, bool has_crcs); +struct modversion_info_ext { + size_t remaining; + const s32 *crc; + const char *name; +}; +void modversion_ext_start(const struct load_info *info, struct modversion_= info_ext *ver); +void modversion_ext_advance(struct modversion_info_ext *ver); +#define for_each_modversion_info_ext(ver, info) \ + for (modversion_ext_start(info, &ver); ver.remaining > 0; modversion_ext_= advance(&ver)) #else /* !CONFIG_MODVERSIONS */ static inline int check_version(const struct load_info *info, const char *symname, diff --git a/kernel/module/main.c b/kernel/module/main.c index b40b632f00a65e66ed73c4b386ef1f323a5b790c..9a9feca344f8bb06408d350e13f= 759bb909962cd 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -2039,6 +2039,82 @@ static int elf_validity_cache_index_str(struct load_= info *info) return 0; } =20 +/** + * elf_validity_cache_index_versions() - Validate and cache version indices + * @info: Load info to cache version indices in. + * Must have &load_info->sechdrs and &load_info->secstrings popula= ted. + * @flags: Load flags, relevant to suppress version loading, see + * uapi/linux/module.h + * + * If we're ignoring modversions based on @flags, zero all version indices + * and return validity. Othewrise check: + * + * * If "__version_ext_crcs" is present, "__version_ext_names" is present + * * There is a name present for every crc + * + * Then populate: + * + * * &load_info->index.vers + * * &load_info->index.vers_ext_crc + * * &load_info->index.vers_ext_names + * + * if present. + * + * Return: %0 if valid, %-ENOEXEC on failure. + */ +static int elf_validity_cache_index_versions(struct load_info *info, int f= lags) +{ + unsigned int vers_ext_crc; + unsigned int vers_ext_name; + size_t crc_count; + size_t remaining_len; + size_t name_size; + char *name; + + /* If modversions were suppressed, pretend we didn't find any */ + if (flags & MODULE_INIT_IGNORE_MODVERSIONS) { + info->index.vers =3D 0; + info->index.vers_ext_crc =3D 0; + info->index.vers_ext_name =3D 0; + return 0; + } + + vers_ext_crc =3D find_sec(info, "__version_ext_crcs"); + vers_ext_name =3D find_sec(info, "__version_ext_names"); + + /* If we have one field, we must have the other */ + if (!!vers_ext_crc !=3D !!vers_ext_name) { + pr_err("extended version crc+name presence does not match"); + return -ENOEXEC; + } + + /* + * If we have extended version information, we should have the same + * number of entries in every section. + */ + if (vers_ext_crc) { + crc_count =3D info->sechdrs[vers_ext_crc].sh_size / sizeof(s32); + name =3D (void *)info->hdr + + info->sechdrs[vers_ext_name].sh_offset; + remaining_len =3D info->sechdrs[vers_ext_name].sh_size; + + while (crc_count--) { + name_size =3D strnlen(name, remaining_len) + 1; + if (name_size > remaining_len) { + pr_err("more extended version crcs than names"); + return -ENOEXEC; + } + remaining_len -=3D name_size; + name +=3D name_size; + } + } + + info->index.vers =3D find_sec(info, "__versions"); + info->index.vers_ext_crc =3D vers_ext_crc; + info->index.vers_ext_name =3D vers_ext_name; + return 0; +} + /** * elf_validity_cache_index() - Resolve, validate, cache section indices * @info: Load info to read from and update. @@ -2053,9 +2129,7 @@ static int elf_validity_cache_index_str(struct load_i= nfo *info) * * elf_validity_cache_index_mod() * * elf_validity_cache_index_sym() * * elf_validity_cache_index_str() - * - * If versioning is not suppressed via flags, load the version index from - * a section called "__versions" with no validation. + * * elf_validity_cache_index_versions() * * If CONFIG_SMP is enabled, load the percpu section by name with no * validation. @@ -2078,11 +2152,9 @@ static int elf_validity_cache_index(struct load_info= *info, int flags) err =3D elf_validity_cache_index_str(info); if (err < 0) return err; - - if (flags & MODULE_INIT_IGNORE_MODVERSIONS) - info->index.vers =3D 0; /* Pretend no __versions section! */ - else - info->index.vers =3D find_sec(info, "__versions"); + err =3D elf_validity_cache_index_versions(info, flags); + if (err < 0) + return err; =20 info->index.pcpu =3D find_pcpusec(info); =20 @@ -2293,6 +2365,10 @@ static int rewrite_section_headers(struct load_info = *info, int flags) =20 /* Track but don't keep modinfo and version sections. */ info->sechdrs[info->index.vers].sh_flags &=3D ~(unsigned long)SHF_ALLOC; + info->sechdrs[info->index.vers_ext_crc].sh_flags &=3D + ~(unsigned long)SHF_ALLOC; + info->sechdrs[info->index.vers_ext_name].sh_flags &=3D + ~(unsigned long)SHF_ALLOC; info->sechdrs[info->index.info].sh_flags &=3D ~(unsigned long)SHF_ALLOC; =20 return 0; diff --git a/kernel/module/version.c b/kernel/module/version.c index 53f43ac5a73e9d537a9e95ff97728a51fad0e797..c246d40879706d4f413fa7ea9bb= e2264ea1b2aa8 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 =3D info->index.vers; unsigned int i, num_versions; struct modversion_info *versions; + struct modversion_info_ext version_ext; =20 /* Exporting module didn't supply crcs? OK, we're already tainted. */ if (!crc) return 1; =20 + /* If we have extended version info, rely on it */ + if (info->index.vers_ext_crc) { + for_each_modversion_info_ext(version_ext, info) { + if (strcmp(version_ext.name, symname) !=3D 0) + continue; + if (*version_ext.crc =3D=3D *crc) + return 1; + pr_debug("Found checksum %X vs module %X\n", + *crc, *version_ext.crc); + goto bad_version; + } + pr_warn_once("%s: no extended symbol version for %s\n", + info->name, symname); + return 1; + } + /* No versions at all? modprobe --force does this. */ if (versindex =3D=3D 0) return try_to_force_load(mod, symname) =3D=3D 0; @@ -87,6 +104,34 @@ int same_magic(const char *amagic, const char *bmagic, return strcmp(amagic, bmagic) =3D=3D 0; } =20 +void modversion_ext_start(const struct load_info *info, + struct modversion_info_ext *start) +{ + unsigned int crc_idx =3D info->index.vers_ext_crc; + unsigned int name_idx =3D info->index.vers_ext_name; + Elf_Shdr *sechdrs =3D info->sechdrs; + + /* + * Both of these fields are needed for this to be useful + * Any future fields should be initialized to NULL if absent. + */ + if (crc_idx =3D=3D 0 || name_idx =3D=3D 0) { + start->remaining =3D 0; + return; + } + + start->crc =3D (const s32 *)sechdrs[crc_idx].sh_addr; + start->name =3D (const char *)sechdrs[name_idx].sh_addr; + start->remaining =3D sechdrs[crc_idx].sh_size / sizeof(*start->crc); +} + +void modversion_ext_advance(struct modversion_info_ext *vers) +{ + vers->remaining--; + vers->crc++; + vers->name +=3D strlen(vers->name) + 1; +} + /* * Generate the signature for all relevant module structures here. * If these change, we don't want to try to parse the module. --=20 2.47.0.163.g1226f6d8fa-goog From nobody Mon Nov 25 01:32:29 2024 Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 75E51215034 for ; Wed, 30 Oct 2024 23:05:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730329514; cv=none; b=AiF4L0ALwS9jFIfs0mD7gt+vDoQu5lEUWH787QcIXgKU/5d3DgQz79OJZcYHJPS7705deQIU2wy8CqzyApU0pyxtOsU8dBQR8ixFD6wDhrlevPFb2tHAPWFOv/DMVb9W2Ggsn7QtgV7p9u1ol75cjbupy9DJ4zCQfquWt+z4AMk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730329514; c=relaxed/simple; bh=NtLMxTWzg8A6ddRuBfeXKLMlTjPwJlOC6sG3G44LhJc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=fQQzC0yij75/1gjtOrClp10Ql8xwIlpt7FXJlNvOS4whorhqAr12ZrfmK+5D/lIQ4R7vsgdaJXHayGK6C1yY9hIdPTYyZ0nKawabx3gVp03/t13R23jTO0lGY/TyRxOsbVwpO9Lts8fuzwv7RPfMQ7vI960DbEfikDAXP5bOYmI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--mmaurer.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=PfwDeRod; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--mmaurer.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="PfwDeRod" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-e02fff66a83so574771276.0 for ; Wed, 30 Oct 2024 16:05:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1730329509; x=1730934309; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Lf2RaH8Zu4NEwKY7+VQ2i/VDOOS80VSf3H4AZvHUtmw=; b=PfwDeRodWfXI9sGttu3yEFZT77TTc29o0c44EfS4kVIexC/pJ9ahmubLFL51izuLzX 7RtzLesu10fVONcYRoxVEdErIm5nSdLFyYs6C8Ri3wMIEE5vH+gq9i1lFLBxML3QNNi2 upx2w0b1RmXiw706a88pJ5GVSXL3i45BRph07wRwhNvdcIgPqK73wLncjtyqWMu3wVtD XHeJK2xcb/n/spY1ZL8VcH1ypOLYGMqwvEd51sEE8xBsyyxtZkNyJo/KUXJdBp+RthJv 0JK5GhF2v0INiGw1FkZ8dePBRcE0f5W6wXQITjC7CdOdPytcUnk711+0F9+A3sME27Ru h9ZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730329509; x=1730934309; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Lf2RaH8Zu4NEwKY7+VQ2i/VDOOS80VSf3H4AZvHUtmw=; b=EkH5SBcMKT1Nn/jRQeiE7ShTFYwaR90naL2zOGKohq391KURG2/NNU3ro8gl33XXHf G/+Z1rRiO7cKtf1nmTOrC3rPyHEw1+Uhlyb87FWnUOnzWxIcX84FANsLb4sokz9Xl5s+ wyhecIaIRt67v+06VrUqpg2FfMQnkGfMHSBlrz16ppRbMwRVv4fqKZaIxnixJGMPUlWi 4m0xvl30FGV8KL2+pS/aknMsa1yUrYy7WjrT0OMMEhoe/sqSy745nBpI/mIT0UpVJL9k +EXqhSjVyPWY5eC3UMeOmVaftEhcZBqncC1U05PDKPV8vIewesjTj5ASSwGu6eOlNnpt IkLA== X-Forwarded-Encrypted: i=1; AJvYcCWpW9mldCipAs7t1DwbqgtuvCclDA3OXw86nA3YOmKVox//zDygK+X793R1YStjfazgc0QCY6LXyiYmA7s=@vger.kernel.org X-Gm-Message-State: AOJu0YwlCZM4WAHpy7Wc1fNt5WNBYe/tLOxvxhGUBWS2VIMD4fXsC2Bt n2ozfUTyCtN++k0J0KNGqVJepzpUL2+yFjV4f2LkDPiDJjO3t4pX/6dqj1XOkN/Qfo3YzEzZhz4 juhjrDQ== X-Google-Smtp-Source: AGHT+IFDzETx1IxdRbLAIqaAPyxx98KHviaDO/FFlJlj8jY3I21JzThgEVbqar+FfXYCF0IIpT6jB+iiISBC X-Received: from anyblade.c.googlers.com ([fda3:e722:ac3:cc00:20:ed76:c0a8:1791]) (user=mmaurer job=sendgmr) by 2002:a25:a3e6:0:b0:e30:be64:f7e6 with SMTP id 3f1490d57ef6-e30e5a3cb05mr632276.3.1730329509506; Wed, 30 Oct 2024 16:05:09 -0700 (PDT) Date: Wed, 30 Oct 2024 23:05:03 +0000 In-Reply-To: <20241030-extended-modversions-v8-0-93acdef62ce8@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20241030-extended-modversions-v8-0-93acdef62ce8@google.com> X-Mailer: b4 0.15-dev Message-ID: <20241030-extended-modversions-v8-2-93acdef62ce8@google.com> Subject: [PATCH v8 2/3] modpost: Produce extended MODVERSIONS information From: Matthew Maurer To: Michael Ellerman , Nicholas Piggin , Christophe Leroy , Naveen N Rao , Madhavan Srinivasan , Luis Chamberlain , Petr Pavlu , Sami Tolvanen , Daniel Gomez , Masahiro Yamada , Nathan Chancellor , Nicolas Schier , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , "=?utf-8?q?Bj=C3=B6rn_Roy_Baron?=" , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross Cc: 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, Matthew Maurer Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Generate both the existing modversions format and the new extended one when running modpost. Presence of this metadata in the final .ko is guarded by CONFIG_EXTENDED_MODVERSIONS. We no longer generate an error on long symbols in modpost if CONFIG_EXTENDED_MODVERSIONS is set, as they can now be appropriately encoded in the extended section. These symbols will be skipped in the previous encoding. An error will still be generated if CONFIG_EXTENDED_MODVERSIONS is not set. Reviewed-by: Sami Tolvanen Signed-off-by: Matthew Maurer --- kernel/module/Kconfig | 10 ++++++++ scripts/Makefile.modpost | 1 + scripts/mod/modpost.c | 65 ++++++++++++++++++++++++++++++++++++++++++++= +--- 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/kernel/module/Kconfig b/kernel/module/Kconfig index e6b2427e5c190aacf7b9c5c1bb57fca39d311564..a31c617cd67d3d66b24d2fba34c= bd5cc9c53ab78 100644 --- a/kernel/module/Kconfig +++ b/kernel/module/Kconfig @@ -208,6 +208,16 @@ config ASM_MODVERSIONS assembly. This can be enabled only when the target architecture supports it. =20 +config EXTENDED_MODVERSIONS + bool "Extended Module Versioning Support" + depends on MODVERSIONS + help + This enables extended MODVERSIONs support, allowing long symbol + names to be versioned. + + The most likely reason you would enable this is to enable Rust + support. If unsure, say N. + config MODULE_SRCVERSION_ALL bool "Source checksum for all modules" help diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 44936ebad161e914cbcc40ac74a2d651596d7b07..765da63d592be56fe93c0f4a35f= 1bfbcb924541a 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -43,6 +43,7 @@ MODPOST =3D scripts/mod/modpost modpost-args =3D \ $(if $(CONFIG_MODULES),-M) \ $(if $(CONFIG_MODVERSIONS),-m) \ + $(if $(CONFIG_EXTENDED_MODVERSIONS),-x) \ $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \ $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \ $(if $(KBUILD_MODPOST_WARN),-w) \ diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 107393a8c48a5993dbe456702fec0652a967ee86..bd38f33fd41fbd98bce34f8924b= 2fb0ac04297ee 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -32,6 +32,8 @@ static bool module_enabled; static bool modversions; /* Is CONFIG_MODULE_SRCVERSION_ALL set? */ static bool all_versions; +/* Is CONFIG_EXTENDED_MODVERSIONS set? */ +static bool extended_modversions; /* If we are modposting external module set to 1 */ static bool external_module; /* Only warn about unresolved symbols */ @@ -1817,6 +1819,52 @@ static void add_exported_symbols(struct buffer *buf,= struct module *mod) } } =20 +/** + * Record CRCs for unresolved symbols, supporting long names + */ +static void add_extended_versions(struct buffer *b, struct module *mod) +{ + struct symbol *s; + + if (!extended_modversions) + return; + + buf_printf(b, "\n"); + buf_printf(b, "static const s32 ____version_ext_crcs[]\n"); + buf_printf(b, "__used __section(\"__version_ext_crcs\") =3D {\n"); + list_for_each_entry(s, &mod->unresolved_symbols, list) { + if (!s->module) + continue; + if (!s->crc_valid) { + /* + * We already warned on this when producing the legacy + * modversions table. + */ + continue; + } + buf_printf(b, "\t%#8x,\n", s->crc); + } + buf_printf(b, "};\n"); + + buf_printf(b, "static const char ____version_ext_names[]\n"); + buf_printf(b, "__used __section(\"__version_ext_names\") =3D\n"); + list_for_each_entry(s, &mod->unresolved_symbols, list) { + if (!s->module) + continue; + if (!s->crc_valid) { + /* + * We already warned on this when producing the legacy + * modversions table. + * We need to skip its name too, as the indexes in + * both tables need to align. + */ + continue; + } + buf_printf(b, "\t\"%s\\0\"\n", s->name); + } + buf_printf(b, ";\n"); +} + /** * Record CRCs for unresolved symbols **/ @@ -1840,9 +1888,14 @@ static void add_versions(struct buffer *b, struct mo= dule *mod) continue; } if (strlen(s->name) >=3D MODULE_NAME_LEN) { - error("too long symbol \"%s\" [%s.ko]\n", - s->name, mod->name); - break; + if (extended_modversions) + /* this symbol will only be in the extended info */ + continue; + else { + error("too long symbol \"%s\" [%s.ko]\n", + s->name, mod->name); + break; + } } buf_printf(b, "\t{ %#8x, \"%s\" },\n", s->crc, s->name); @@ -1972,6 +2025,7 @@ static void write_mod_c_file(struct module *mod) add_header(&buf, mod); add_exported_symbols(&buf, mod); add_versions(&buf, mod); + add_extended_versions(&buf, mod); add_depends(&buf, mod); add_moddevtable(&buf, mod); add_srcversion(&buf, mod); @@ -2130,7 +2184,7 @@ int main(int argc, char **argv) LIST_HEAD(dump_lists); struct dump_list *dl, *dl2; =20 - while ((opt =3D getopt(argc, argv, "ei:MmnT:to:au:WwENd:")) !=3D -1) { + while ((opt =3D getopt(argc, argv, "ei:MmnT:to:au:WwENd:x")) !=3D -1) { switch (opt) { case 'e': external_module =3D true; @@ -2179,6 +2233,9 @@ int main(int argc, char **argv) case 'd': missing_namespace_deps =3D optarg; break; + case 'x': + extended_modversions =3D true; + break; default: exit(1); } --=20 2.47.0.163.g1226f6d8fa-goog From nobody Mon Nov 25 01:32:29 2024 Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 38016217656 for ; Wed, 30 Oct 2024 23:05:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730329514; cv=none; b=li6gx78TszsLx1beG5msKwJq7aIj9rG1MOdK+88iHr8RnxcK/5Mwk0cQPnDiXwI76Ucl8a2gPUDpPaHfRafSWGtKOyKmfuz0eMOYqejavV/LNP8+U/7+50VzTrndaN34E5RXBJjPE3LsjUtjFmnTBfCr2W7eiYI27bNoQeZGhAg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730329514; c=relaxed/simple; bh=wPil2ZePOaGBCbeMdHPmjyhJDTULE3Tr9nw/1oyU7eE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=ZLHLhRWFDcEDQIE0l5MupsrfyKVMzSEbZYfMmUalYVmNrQUI6qny9uUTmYjhOlb5ldXV3uNrDvmpqmmGqnF9bWBFXxB0Zf+WwmuIVK2hGRQo4xH2/5KwFttD/j2ldxkRCwimSWk/iQm6xTgeC3+nRSe5DAX/aaPeZPVHBc3e0dc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--mmaurer.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=ZlRl9g0J; arc=none smtp.client-ip=209.85.128.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--mmaurer.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="ZlRl9g0J" Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-6e315a5b199so5824847b3.2 for ; Wed, 30 Oct 2024 16:05:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1730329511; x=1730934311; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=t+3KnK+Z0gtSs2Co5ku0tpPq/BkCZXZuUXUNlsOrMro=; b=ZlRl9g0JflIDAYJCrbZbY3cXotfqjnsL/rv1hF/KgnZQ2IWG6anFfnDMAXvKltGN8K /pjFf7CLsuYJU8WuGulJzLF3PRQRIjKiCQwHLfhu2cL+khjDmap9lwJuyzPTPEELTRGg WHz0HdORvestpNHGdiUSv1FHrLDeIXD3sCnr1dWqsGXWr/gb7f0oh2wud336iCiaqzUt eSKFWX6BUZma3YgdAiJ38ncGpm4i6lKH9yjBvI4GmrVQv0rrGPkaKxa62pcm7PcgkI9a XxZxAQwzH1lpuDmGCQ1oD852B3FWSQTmzWcH6FPINNW2R+SsY7KzHrPf3vCvnT0/NCW3 N+PA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730329511; x=1730934311; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=t+3KnK+Z0gtSs2Co5ku0tpPq/BkCZXZuUXUNlsOrMro=; b=kQLqNBN/Qab4LPHTk8tne9OLdLoxZaCb4GnNZMh+PPa3fL1BzXej/KVtXImFhVQKOA FU88HFKhl+qgCT0GnBP7HWqaRV+b+JrgfuTCbPxYTqC0QORJxHgfvPetzWWqxz/GEVF1 jpEF4DvQplwev+Wg/W+qF/qeCxKLWF2sNKiGbUdOVvg0V4MR3WAQE13ZFlTnr/w8Dn2m zH4rDn1lqieBUJ7OD11DNCRxfv6E2qvs9DSqM+HFWDJYKKa8YGHNUoIJ/UZR53h23jDl ir7gt0sgPaoxz64HM5D0qgpaM2DFiN9lseb3kcQBHv9Sngm4Wb8HahzYl4Laa3U4GwZR B2FA== X-Forwarded-Encrypted: i=1; AJvYcCW+70CZc9h7i8tA9MVKx55QHNe8JlfM/lgpcxK1VZ70xkfF3bt4DtDw7WfPfvM6fwqrhjeu3EEGA0TuQik=@vger.kernel.org X-Gm-Message-State: AOJu0YxAFbkpO9QZb/lfREXY9k3u5zfRV3ZqAE9HFOavfCXysORz3qio SdF9I8zAOS+T1BcgV8jUg5HHpZCI+w69Kan/4Q+iJh9envSd/g8aELf+eB1EFUTlOPa5koBgCyA RdR4EYA== X-Google-Smtp-Source: AGHT+IFXDvQAF6rmmyjqCuHXp7247+2WzHwGzszYhdJsIGiPI6HKKDpKzPTAlySRxwxd3AE241ZoGZd587t3 X-Received: from anyblade.c.googlers.com ([fda3:e722:ac3:cc00:20:ed76:c0a8:1791]) (user=mmaurer job=sendgmr) by 2002:a81:d806:0:b0:663:ddc1:eab8 with SMTP id 00721157ae682-6e9d8b0412emr4041757b3.4.1730329511025; Wed, 30 Oct 2024 16:05:11 -0700 (PDT) Date: Wed, 30 Oct 2024 23:05:04 +0000 In-Reply-To: <20241030-extended-modversions-v8-0-93acdef62ce8@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20241030-extended-modversions-v8-0-93acdef62ce8@google.com> X-Mailer: b4 0.15-dev Message-ID: <20241030-extended-modversions-v8-3-93acdef62ce8@google.com> Subject: [PATCH v8 3/3] rust: Use gendwarfksyms + extended modversions for CONFIG_MODVERSIONS From: Matthew Maurer To: Michael Ellerman , Nicholas Piggin , Christophe Leroy , Naveen N Rao , Madhavan Srinivasan , Luis Chamberlain , Petr Pavlu , Sami Tolvanen , Daniel Gomez , Masahiro Yamada , Nathan Chancellor , Nicolas Schier , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , "=?utf-8?q?Bj=C3=B6rn_Roy_Baron?=" , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross Cc: 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, Matthew Maurer Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Sami Tolvanen Previously, two things stopped Rust from using MODVERSIONS: 1. Rust symbols are occasionally too long to be represented in the original versions table 2. Rust types cannot be properly hashed by the existing genksyms approach because: * Looking up type definitions in Rust is more complex than C * Type layout is potentially dependent on the compiler in Rust, not just the source type declaration. CONFIG_EXTENDED_MODVERSIONS addresses the first point, and CONFIG_GENDWARFKSYMS the second. If Rust wants to use MODVERSIONS, allow it to do so by selecting both features. Signed-off-by: Sami Tolvanen Co-developed-by: Matthew Maurer Signed-off-by: Matthew Maurer --- init/Kconfig | 3 ++- rust/Makefile | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/init/Kconfig b/init/Kconfig index c521e1421ad4abd80080bce8cf1c68389cb65c69..5e6d9868705ece2b2f6b90d7ce1= 97a4d66240b6b 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1946,7 +1946,8 @@ config RUST bool "Rust support" depends on HAVE_RUST depends on RUST_IS_AVAILABLE - depends on !MODVERSIONS + select EXTENDED_MODVERSIONS if MODVERSIONS + depends on !MODVERSIONS || GENDWARFKSYMS depends on !GCC_PLUGIN_RANDSTRUCT depends on !RANDSTRUCT depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE diff --git a/rust/Makefile b/rust/Makefile index b5e0a73b78f3e58fc8fb8c9fab8fb5792406c6d8..0e98590082a1ac88e6ee29c28ce= 1b1d19982ac10 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -303,10 +303,11 @@ $(obj)/bindings/bindings_helpers_generated.rs: privat= e bindgen_target_extra =3D ; $(obj)/bindings/bindings_helpers_generated.rs: $(src)/helpers/helpers.c FO= RCE $(call if_changed_dep,bindgen) =20 +rust_exports =3D $(NM) -p --defined-only $(1) | awk '$$2~/(T|R|D|B)/ && $$= 3!~/__cfi/ { printf $(2),$(3) }' + quiet_cmd_exports =3D EXPORTS $@ cmd_exports =3D \ - $(NM) -p --defined-only $< \ - | awk '$$2~/(T|R|D|B)/ && $$3!~/__cfi/ {printf "EXPORT_SYMBOL_RUST_GPL(%= s);\n",$$3}' > $@ + $(call rust_exports,$<,"EXPORT_SYMBOL_RUST_GPL(%s);\n",$$3) > $@ =20 $(obj)/exports_core_generated.h: $(obj)/core.o FORCE $(call if_changed,exports) @@ -378,11 +379,36 @@ ifneq ($(or $(CONFIG_ARM64),$(and $(CONFIG_RISCV),$(C= ONFIG_64BIT))),) __ashlti3 __lshrti3 endif =20 +ifdef CONFIG_MODVERSIONS +cmd_gendwarfksyms =3D $(if $(skip_gendwarfksyms),, \ + $(call rust_exports,$@,"%s\n",$$3) | \ + scripts/gendwarfksyms/gendwarfksyms \ + $(if $(KBUILD_GENDWARFKSYMS_STABLE), --stable) \ + $(if $(KBUILD_SYMTYPES), --symtypes $(@:.o=3D.symtypes),) \ + $@ >> $(dot-target).cmd) +endif + define rule_rustc_library $(call cmd_and_fixdep,rustc_library) $(call cmd,gen_objtooldep) + $(call cmd,gendwarfksyms) endef =20 +define rule_rust_cc_library + $(call if_changed_rule,cc_o_c) + $(call cmd,force_checksrc) + $(call cmd,gendwarfksyms) +endef + +# helpers.o uses the same export mechanism as Rust libraries, so ensure sy= mbol +# versions are calculated for the helpers too. +$(obj)/helpers/helpers.o: $(src)/helpers/helpers.c $(recordmcount_source) = FORCE + +$(call if_changed_rule,rust_cc_library) + +# Disable symbol versioning for exports.o to avoid conflicts with the actu= al +# symbol versions generated from Rust objects. +$(obj)/exports.o: private skip_gendwarfksyms =3D 1 + $(obj)/core.o: private skip_clippy =3D 1 $(obj)/core.o: private skip_flags =3D -Wunreachable_pub $(obj)/core.o: private rustc_objcopy =3D $(foreach sym,$(redirect-intrinsi= cs),--redefine-sym $(sym)=3D__rust$(sym)) @@ -394,6 +420,7 @@ ifneq ($(or $(CONFIG_X86_64),$(CONFIG_X86_32)),) $(obj)/core.o: scripts/target.json endif =20 +$(obj)/compiler_builtins.o: private skip_gendwarfksyms =3D 1 $(obj)/compiler_builtins.o: private rustc_objcopy =3D -w -W '__*' $(obj)/compiler_builtins.o: $(src)/compiler_builtins.rs $(obj)/core.o FORCE +$(call if_changed_rule,rustc_library) @@ -404,6 +431,7 @@ $(obj)/alloc.o: private rustc_target_flags =3D $(alloc-= cfgs) $(obj)/alloc.o: $(RUST_LIB_SRC)/alloc/src/lib.rs $(obj)/compiler_builtins.= o FORCE +$(call if_changed_rule,rustc_library) =20 +$(obj)/build_error.o: private skip_gendwarfksyms =3D 1 $(obj)/build_error.o: $(src)/build_error.rs $(obj)/compiler_builtins.o FOR= CE +$(call if_changed_rule,rustc_library) =20 @@ -413,6 +441,7 @@ $(obj)/bindings.o: $(src)/bindings/lib.rs \ $(obj)/bindings/bindings_helpers_generated.rs FORCE +$(call if_changed_rule,rustc_library) =20 +$(obj)/uapi.o: private skip_gendwarfksyms =3D 1 $(obj)/uapi.o: $(src)/uapi/lib.rs \ $(obj)/compiler_builtins.o \ $(obj)/uapi/uapi_generated.rs FORCE --=20 2.47.0.163.g1226f6d8fa-goog