lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <BN0P110MB2020D78705BB39062BF8D107FD1FA@BN0P110MB2020.NAMP110.PROD.OUTLOOK.COM>
Date: Thu, 25 Sep 2025 17:00:35 +0000
From: "Hill, Steven " <steven.hill@...lins.com>
To: "linux-hardening@...r.kernel.org" <linux-hardening@...r.kernel.org>
CC: Kees Cook <kees@...nel.org>, Masahiro Yamada <masahiroy@...nel.org>
Subject: [RFC] gcc-plugins patch for compiler versioning.

Hello.

Would like to have comments on the attached patch. There could be another
option for checking both gcc and glibc versions. Just wanted comments before
doing anything further. I am not on the mailing list, so please CC: on any
replies. Thank you.

-Steve


>From b1ac0805d70aaa2e1500a071f63c88bcaa76754e Mon Sep 17 00:00:00 2001
From: "Steven J. Hill" <steven.hill@...lins.com>
Date: Tue, 23 Sep 2025 18:21:09 -0500
Subject: [PATCH] gcc-plugins: Relax constraints on plugin compatibility.

The compatibility check for gcc plugins is too inflexible,
and a lot of times wrong. Add ability to let the user choose
how stringent compatibility is.

Signed-off-by: Steven J. Hill <steven.hill@...lins.com>
---
 scripts/gcc-plugins/Kconfig                   | 36 +++++++++++++++++++
 scripts/gcc-plugins/Makefile                  | 15 +++++++-
 scripts/gcc-plugins/compare-libc-versions.sh  | 28 +++++++++++++++
 scripts/gcc-plugins/gcc-common.h              | 18 ++++++++++
 scripts/gcc-plugins/latent_entropy_plugin.c   |  2 +-
 scripts/gcc-plugins/randomize_layout_plugin.c |  2 +-
 scripts/gcc-plugins/sancov_plugin.c           |  2 +-
 scripts/gcc-plugins/stackleak_plugin.c        |  2 +-
 scripts/gcc-plugins/structleak_plugin.c       |  2 +-
 9 files changed, 101 insertions(+), 6 deletions(-)
 create mode 100755 scripts/gcc-plugins/compare-libc-versions.sh

diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig
index 929997fb5e45..626a9200f2a1 100644
--- a/scripts/gcc-plugins/Kconfig
+++ b/scripts/gcc-plugins/Kconfig
@@ -19,6 +19,42 @@ menuconfig GCC_PLUGINS

 if GCC_PLUGINS

+choice
+       prompt "Version checking"
+       help
+         Each plugin is required to call plugin_default_version_check() in
+         its init function. This check can at times be too stringent or
+         just plain wrong, especially when cross-compiling. See source file
+         gcc/plugin.cc in the gcc repository for more details. This option
+         allows for the user to choose how stringent the check should be.
+
+       config GCC_PLUGIN_VERSION_CHECK_DEFAULT
+               bool "Default behavior"
+               help
+                 Just calls plugin_default_version_check() like before.
+
+       config GCC_PLUGIN_VERSION_CHECK_NONE
+               bool "Disable checking"
+               help
+                 Plugins will be built without any incompatibilities
+                 being reported to the user.
+
+       config GCC_PLUGIN_VERSION_CHECK_GCC
+               bool "Check only GCC versions"
+               help
+                 Compare only the GCC version strings of the host and
+                 target compilers.
+
+       config GCC_PLUGIN_VERSION_CHECK_LIBC
+               bool "Check C library versions"
+               help
+                 Compares only C library versions. Checks the
+                 version strings and the highest library API versions
+                 supported in each toolchain. Only glibc-based tools
+                 are currently supported.
+
+endchoice
+
 config GCC_PLUGIN_SANCOV
        bool
        # Plugin can be removed once the kernel only supports GCC 6+
diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile
index 320afd3cf8e8..48d50a3fe362 100644
--- a/scripts/gcc-plugins/Makefile
+++ b/scripts/gcc-plugins/Makefile
@@ -24,6 +24,19 @@ targets += randomize_layout_seed.h

 always-y += $(GCC_PLUGIN)

+ifdef CONFIG_GCC_PLUGIN_VERSION_CHECK_DEFAULT
+GCC_PLUGINS_CHECK_VERSION = -DGCC_PLUGIN_VERSION_DEFAULT
+endif
+ifdef CONFIG_GCC_PLUGIN_VERSION_CHECK_NONE
+GCC_PLUGINS_CHECK_VERSION = -DGCC_PLUGIN_VERSION_NONE
+endif
+ifdef CONFIG_GCC_PLUGIN_VERSION_CHECK_GCC
+GCC_PLUGINS_CHECK_VERSION = -DGCC_PLUGIN_VERSION_GCC
+endif
+ifdef CONFIG_GCC_PLUGIN_VERSION_CHECK_LIBC
+GCC_PLUGINS_CHECK_VERSION = $(shell $(srctree)/scripts/gcc-plugins/compare-libc-versions.sh "$(HOSTCXX)" "$(CC)")
+endif
+
 GCC_PLUGINS_DIR = $(shell $(CC) -print-file-name=plugin)

 plugin_cxxflags        = -Wp,-MMD,$(depfile) $(KBUILD_HOSTCXXFLAGS) -fPIC \
@@ -32,7 +45,7 @@ plugin_cxxflags       = -Wp,-MMD,$(depfile) $(KBUILD_HOSTCXXFLAGS) -fPIC \
                  -I $(GCC_PLUGINS_DIR)/include -I $(obj) \
                  -fno-rtti -fno-exceptions -fasynchronous-unwind-tables \
                  -ggdb -Wno-narrowing -Wno-unused-variable \
-                 -Wno-format-diag
+                 $(GCC_PLUGINS_CHECK_VERSION) -Wno-format-diag

 plugin_ldflags = -shared

diff --git a/scripts/gcc-plugins/compare-libc-versions.sh b/scripts/gcc-plugins/compare-libc-versions.sh
new file mode 100755
index 000000000000..592e501575f2
--- /dev/null
+++ b/scripts/gcc-plugins/compare-libc-versions.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# glibc version comparison script
+
+if test $# -ne 2; then
+       echo "Usage: $0 <hostcxx> <targetcxx>"
+       exit 1
+fi
+
+#
+# Get paths of base C libraries.
+#
+HOSTLIBPATH=$("$1" -print-file-name=libc.so.6)
+TARGLIBPATH=$("$2" -print-file-name=libc.so.6)
+
+#
+# Find the highest library version supported in each.
+#
+HOSTVER=$(readelf -V "$HOSTLIBPATH" | grep "Parent 1: GLIBC_2" | \
+         sed -e's/.*Parent 1: GLIBC_2\.//g' | sort -rn | head -1)
+TARGVER=$(readelf -V "$TARGLIBPATH" | grep "Parent 1: GLIBC_2" | \
+         sed -e's/.*Parent 1: GLIBC_2\.//g' | sort -rn | head -1)
+
+#
+# If we get a match, emit the pre-processor flag.
+#
+[ "${HOSTVER}" = "${TARGVER}" ] && echo "-DGCC_PLUGIN_VERSION_LIBC"
diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h
index 3222c1070444..5a747895d8e6 100644
--- a/scripts/gcc-plugins/gcc-common.h
+++ b/scripts/gcc-plugins/gcc-common.h
@@ -439,4 +439,22 @@ static inline void debug_gimple_stmt(const_gimple s)
 #define last_stmt(x)                   last_nondebug_stmt(x)
 #endif

+static inline int plugin_version_check(struct plugin_gcc_version *plugin_ver,
+                                      struct plugin_gcc_version *gcc_ver)
+{
+#ifdef GCC_PLUGIN_VERSION_DEFAULT
+       return plugin_default_version_check(plugin_ver, gcc_ver);
+#endif
+#ifdef GCC_PLUGIN_VERSION_NONE
+       return 1;
+#endif
+#ifdef GCC_PLUGIN_VERSION_GCC
+       return (strcmp(plugin_ver->basever, gcc_ver->basever) == 0);
+#endif
+#ifdef GCC_PLUGIN_VERSION_LIBC
+       return 1;
+#endif
+       return 0;
+}
+
 #endif
diff --git a/scripts/gcc-plugins/latent_entropy_plugin.c b/scripts/gcc-plugins/latent_entropy_plugin.c
index ff0b192be91f..e1899f16bf22 100644
--- a/scripts/gcc-plugins/latent_entropy_plugin.c
+++ b/scripts/gcc-plugins/latent_entropy_plugin.c
@@ -596,7 +596,7 @@ __visible int plugin_init(struct plugin_name_args *plugin_info,

        PASS_INFO(latent_entropy, "optimized", 1, PASS_POS_INSERT_BEFORE);

-       if (!plugin_default_version_check(version, &gcc_version)) {
+       if (!plugin_version_check(version, &gcc_version)) {
                error(G_("incompatible gcc/plugin versions"));
                return 1;
        }
diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c
index 5694df3da2e9..fd8220c6daeb 100644
--- a/scripts/gcc-plugins/randomize_layout_plugin.c
+++ b/scripts/gcc-plugins/randomize_layout_plugin.c
@@ -851,7 +851,7 @@ __visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gc
        find_bad_casts_pass_info.ref_pass_instance_number       = 1;
        find_bad_casts_pass_info.pos_op                 = PASS_POS_INSERT_AFTER;

-       if (!plugin_default_version_check(version, &gcc_version)) {
+       if (!plugin_version_check(version, &gcc_version)) {
                error(G_("incompatible gcc/plugin versions"));
                return 1;
        }
diff --git a/scripts/gcc-plugins/sancov_plugin.c b/scripts/gcc-plugins/sancov_plugin.c
index b76cb9c42cec..78e1e38d3922 100644
--- a/scripts/gcc-plugins/sancov_plugin.c
+++ b/scripts/gcc-plugins/sancov_plugin.c
@@ -106,7 +106,7 @@ __visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gc
        /* BBs can be split afterwards?? */
        PASS_INFO(sancov, "asan", 0, PASS_POS_INSERT_BEFORE);

-       if (!plugin_default_version_check(version, &gcc_version)) {
+       if (!plugin_version_check(version, &gcc_version)) {
                error(G_("incompatible gcc/plugin versions"));
                return 1;
        }
diff --git a/scripts/gcc-plugins/stackleak_plugin.c b/scripts/gcc-plugins/stackleak_plugin.c
index d20c47d21ad8..2d3129ad2507 100644
--- a/scripts/gcc-plugins/stackleak_plugin.c
+++ b/scripts/gcc-plugins/stackleak_plugin.c
@@ -560,7 +560,7 @@ __visible int plugin_init(struct plugin_name_args *plugin_info,
         */
        PASS_INFO(stackleak_cleanup, "*free_cfg", 1, PASS_POS_INSERT_BEFORE);

-       if (!plugin_default_version_check(version, &gcc_version)) {
+       if (!plugin_version_check(version, &gcc_version)) {
                error(G_("incompatible gcc/plugin versions"));
                return 1;
        }
diff --git a/scripts/gcc-plugins/structleak_plugin.c b/scripts/gcc-plugins/structleak_plugin.c
index d8c744233832..7128889979f5 100644
--- a/scripts/gcc-plugins/structleak_plugin.c
+++ b/scripts/gcc-plugins/structleak_plugin.c
@@ -216,7 +216,7 @@ __visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gc

        PASS_INFO(structleak, "early_optimizations", 1, PASS_POS_INSERT_BEFORE);

-       if (!plugin_default_version_check(version, &gcc_version)) {
+       if (!plugin_version_check(version, &gcc_version)) {
                error(G_("incompatible gcc/plugin versions"));
                return 1;
        }
--
2.29.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ