v2-0001-Don-t-clobber-LD_-environment-variables.patch

application/octet-stream

Filename: v2-0001-Don-t-clobber-LD_-environment-variables.patch
Type: application/octet-stream
Part: 0
Message: Re: Regression tests fail with musl libc because libpq.so can't be loaded

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: format-patch
Series: patch v2-0001
Subject: Don't clobber LD_* environment variables.
File+
src/backend/utils/misc/ps_status.c 24 0
From a3a9a31bd2e95d93b3f2111e414fe0f3cda16423 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Tue, 19 Mar 2024 00:25:34 +1300
Subject: [PATCH v2] Don't clobber LD_* environment variables.

Our PS_USE_CLOBBER_ARGV code relocates the environment, which itself is
allowed, in order to steal the old space to make a bigger argv[0] for
ps/top to show, which is probably formally undefined behavior.

Unfortunately that corrupts musl's copy of LD_LIBRARY_PATH if set,
because it stashes a pointer to the initial value before main() begins.
It probably doesn't matter for installed servers but breaks the
regression tests.

Here we look out for variables named LD_* while computing how much space
to steal, so we can avoid clobbering them.  No change in behaviour if
not found, but otherwise you might potentially get ps status messages
truncated to a smaller size than before depending on the length of
preceding clobberable variables.  There doesn't seem to be a nice way to
distinguish musl from glibc, and the truncation size shouldn't be too
small or at least has an easy mitigation: define a dummy variable.

Reported-by: Wolfgang Walther <walther@technowledgy.de>
Discussion: https://postgr.es/m/fddd1cd6-dc16-40a2-9eb5-d7fef2101488%40technowledgy.de
---
 src/backend/utils/misc/ps_status.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/src/backend/utils/misc/ps_status.c b/src/backend/utils/misc/ps_status.c
index 5d829e6e48..e71f54623b 100644
--- a/src/backend/utils/misc/ps_status.c
+++ b/src/backend/utils/misc/ps_status.c
@@ -151,7 +151,31 @@ save_ps_display_args(int argc, char **argv)
 		for (i = 0; environ[i] != NULL; i++)
 		{
 			if (end_of_area + 1 == environ[i])
+			{
+
+#if defined(__linux__)
+				/*
+				 * If we see a variable named LD_XXX, give up here.  The musl
+				 * runtime linker is known to stash pointers to such values
+				 * before main() starts, so we don't want to corrupt them or
+				 * dlopen() might break.  Since they presumably need only the
+				 * value, it should be safe to steal the space right up to the
+				 * equal sign.
+				 */
+				if (strncmp(environ[i], "LD_", 3) == 0)
+				{
+					char	   *equals = strchr(environ[i], '=');
+
+					if (equals)
+						end_of_area = equals + 1;
+					else
+						end_of_area = environ[i] + strlen(environ[i]);
+					break;
+				}
+#endif
+
 				end_of_area = environ[i] + strlen(environ[i]);
+			}
 		}
 
 		ps_buffer = argv[0];
-- 
2.39.3 (Apple Git-146)