[PATCH v2] locale: memory leak in newlocale (BZ #25770)
Dmitry Kovalenko
d.kovalenko@postgrespro.ru
Tue May 20 18:18:34 GMT 2025
From efa5f4140f96c84446da085c99f472bb0f2dbb1a Mon Sep 17 00:00:00 2001
From: "d.kovalenko" <d.kovalenko@postgrespro.ru>
Date: Tue, 20 May 2025 20:59:23 +0300
Subject: [PATCH v2] locale: memory leak in newlocale (BZ #25770)
To: libc-alpha@sourceware.org
It is a fix for memory leak in the function 'newlocale' (the real name is __newlocale).
There is not released a memory for the local buffer 'locale_path'.
https://sourceware.org/bugzilla/show_bug.cgi?id=25770
---
Patch was tested on Ubuntu 24.04.
My 'LOCPATH' environment variable is "/snap/code/193/usr/lib/locale".
With an original (system) libc I have the following problem:
#0 0x7d5c3aafc778 in realloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:85
#1 0x7d5c394b05f2 in __argz_add_sep string/argz-addsep.c:34
#2 0x7d5c39439bdb in __newlocale locale/newlocale.c:111
#3 0x7d5c370e58fc (/lib/x86_64-linux-gnu/libp11-kit.so.0+0x1098fc) (BuildId: 1cbcd6ac7e0ff0259eb3acc14d556d2c1ec00cdc)
#4 0x7d5c3b14571e in call_init elf/dl-init.c:74
#5 0x7d5c3b145823 in call_init elf/dl-init.c:120
#6 0x7d5c3b145823 in _dl_init elf/dl-init.c:121
#7 0x7d5c3b15f59f (/lib64/ld-linux-x86-64.so.2+0x1f59f) (BuildId: 1c8db5f83bba514f8fd5f1fb6d7be975be1bb855)
SUMMARY: AddressSanitizer: 46 byte(s) leaked in 1 allocation(s).
When I run with my corrected libc, through runtest.sh <my-application>, all is OK.
Signed-off-by: Dmitry Kovalenko <d.kovalenko@postgrespro.ru>
Co-authored-by: Florian Weimer <fweimer@redhat.com>
---
locale/newlocale.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/locale/newlocale.c b/locale/newlocale.c
index d25a6038d3..c95b2132f6 100644
--- a/locale/newlocale.c
+++ b/locale/newlocale.c
@@ -39,7 +39,7 @@ __libc_rwlock_define (extern , __libc_setlocale_lock attribute_hidden)
locale_t
-__newlocale (int category_mask, const char *locale, locale_t base)
+__newlocale_1 (int category_mask, const char *locale, locale_t base, char **tmp_buffer)
{
/* Intermediate memory for result. */
const char *newnames[__LC_LAST];
@@ -51,6 +51,8 @@ __newlocale (int category_mask, const char *locale, locale_t base)
int cnt;
size_t names_len;
+ (*tmp_buffer) = NULL;
+
/* We treat LC_ALL in the same way as if all bits were set. */
if (category_mask == 1 << LC_ALL)
category_mask = (1 << __LC_LAST) - 1 - (1 << LC_ALL);
@@ -111,6 +113,8 @@ __newlocale (int category_mask, const char *locale, locale_t base)
if (__argz_add_sep (&locale_path, &locale_path_len,
_nl_default_locale_path, ':') != 0)
return NULL;
+
+ (*tmp_buffer) = locale_path;
}
/* Get the names for the locales we are interested in. We either
@@ -275,4 +279,21 @@ __newlocale (int category_mask, const char *locale, locale_t base)
return result_ptr;
}
+
+locale_t
+__newlocale (int category_mask, const char *locale, locale_t base)
+{
+ char* tmp_buffer = NULL;
+
+ const locale_t result = __newlocale_1(
+ category_mask,
+ locale,
+ base,
+ &tmp_buffer);
+
+ free(tmp_buffer);
+
+ return result;
+}
+
weak_alias (__newlocale, newlocale)
--
2.43.0
More information about the Libc-alpha
mailing list