1a69b38
From 40fbf74b02b8ad6625e3aa49d2cdef2b52e47a04 Mon Sep 17 00:00:00 2001
1a69b38
From: Daiki Ueno <ueno@gnu.org>
1a69b38
Date: Mon, 25 Jan 2021 18:24:01 +0100
1a69b38
Subject: [PATCH] compat: Pacify ASan complaints on intentionally leaked buffer
1a69b38
1a69b38
Reported by Viktor Ashirov in:
1a69b38
https://bugzilla.redhat.com/show_bug.cgi?id=1905581
1a69b38
---
1a69b38
 common/compat.c  | 25 +++++++++++++++++++------
1a69b38
 common/library.c |  9 +++++++++
1a69b38
 2 files changed, 28 insertions(+), 6 deletions(-)
1a69b38
1a69b38
diff --git a/common/compat.c b/common/compat.c
1a69b38
index 4390cef..d6c5af6 100644
1a69b38
--- a/common/compat.c
1a69b38
+++ b/common/compat.c
1a69b38
@@ -100,6 +100,19 @@ extern char *program_invocation_short_name;
1a69b38
 extern char *__progname;
1a69b38
 #endif
1a69b38
 
1a69b38
+#ifdef __linux__
1a69b38
+/* This symbol is also defined in library.c so as to be freed by the library
1a69b38
+ * destructor.  If weak symbols are not supported nor library.c is not linked we
1a69b38
+ * simply leak the memory allocated with realpath().  */
1a69b38
+#ifdef __GNUC__
1a69b38
+extern char *p11_program_realpath;
1a69b38
+
1a69b38
+char *p11_program_realpath __attribute__((weak));
1a69b38
+#else
1a69b38
+static char *p11_program_realpath;
1a69b38
+#endif
1a69b38
+#endif
1a69b38
+
1a69b38
 const char *
1a69b38
 getprogname (void)
1a69b38
 {
1a69b38
@@ -124,14 +137,14 @@ getprogname (void)
1a69b38
 		 * Logic borrowed from:
1a69b38
 		 * <https://github.com/mesa3d/mesa/commit/759b94038987bb983398cd4b1d2cb1c8f79817a9>.
1a69b38
 		 */
1a69b38
-		static char *buf;
1a69b38
-
1a69b38
-		if (!buf)
1a69b38
-			buf = realpath ("/proc/self/exe", NULL);
1a69b38
+		if (!p11_program_realpath)
1a69b38
+			p11_program_realpath = realpath ("/proc/self/exe", NULL);
1a69b38
 
1a69b38
-		if (buf && strncmp (buf, name, strlen (buf)) == 0)
1a69b38
+		if (p11_program_realpath &&
1a69b38
+		    strncmp (p11_program_realpath, name,
1a69b38
+			     strlen (p11_program_realpath)) == 0)
1a69b38
 			/* Use the executable path if the prefix matches. */
1a69b38
-			name = strrchr (buf, '/') + 1;
1a69b38
+			name = strrchr (p11_program_realpath, '/') + 1;
1a69b38
 		else
1a69b38
 			/* Otherwise fall back to
1a69b38
 			 * program_invocation_short_name. */
1a69b38
diff --git a/common/library.c b/common/library.c
1a69b38
index 891344a..1581702 100644
1a69b38
--- a/common/library.c
1a69b38
+++ b/common/library.c
1a69b38
@@ -82,6 +82,11 @@ unsigned int p11_forkid = 1;
1a69b38
 extern locale_t p11_message_locale;
1a69b38
 #endif
1a69b38
 
1a69b38
+#ifdef __linux__
1a69b38
+/* used only under __linux__ in the getprogname() emulation in compat.c. */
1a69b38
+char *p11_program_realpath;
1a69b38
+#endif
1a69b38
+
1a69b38
 static char *
1a69b38
 thread_local_message (void)
1a69b38
 {
1a69b38
@@ -190,6 +195,10 @@ p11_library_uninit (void)
1a69b38
 #endif
1a69b38
 	p11_mutex_uninit (&p11_virtual_mutex);
1a69b38
 	p11_mutex_uninit (&p11_library_mutex);
1a69b38
+
1a69b38
+#ifdef __linux__
1a69b38
+	free (p11_program_realpath);
1a69b38
+#endif
1a69b38
 }
1a69b38
 
1a69b38
 #endif /* OS_UNIX */
1a69b38
-- 
1a69b38
2.29.2
1a69b38