If a shared library (so) is loaded using dlopen and utilizes thread-local storage (TLS), the memory will not be freed upon thread exit, resulting in a memory leak.
This issue has been resolved in glibc-2.14. However, it remains unresolved in uClibc.
The following patch is based on the patch made in glibc and has been validated as effective on the x86-64 architecture.
diff --git a/libpthread/nptl/allocatestack.c b/libpthread/nptl/allocatestack.c
index 7ef884543..941ef22f0 100644
--- a/libpthread/nptl/allocatestack.c
+++ b/libpthread/nptl/allocatestack.c
@@ -24,6 +24,7 @@
#include <unistd.h>
#include <sys/mman.h>
#include <sys/param.h>
+#include <dl-tls.h>
#include <tls.h>
#include <lowlevellock.h>
#include <link.h>
@@ -241,6 +242,10 @@ get_cached_stack (size_t *sizep, void **memp)
/* Clear the DTV. */
dtv_t *dtv = GET_DTV (TLS_TPADJ (result));
+ for (size_t cnt = 0; cnt < dtv[-1].counter; ++cnt)
+ if (! dtv[1 + cnt].pointer.is_static
+ && dtv[1 + cnt].pointer.val != TLS_DTV_UNALLOCATED)
+ free (dtv[1 + cnt].pointer.val);
memset (dtv, '\0', (dtv[-1].counter + 1) * sizeof (dtv_t));
/* Re-initialize the TLS. */
diff --git a/libpthread/nptl/sysdeps/generic/dl-tls.c b/libpthread/nptl/sysdeps/generic/dl-tls.c
index 7d25e4706..7b7991be8 100644
--- a/libpthread/nptl/sysdeps/generic/dl-tls.c
+++ b/libpthread/nptl/sysdeps/generic/dl-tls.c
@@ -45,8 +45,6 @@
to allow dynamic loading of modules defining IE-model TLS data. */
# define TLS_STATIC_SURPLUS 64 + DL_NNS * 100
-/* Value used for dtv entries for which the allocation is delayed. */
-# define TLS_DTV_UNALLOCATED ((void *) -1l)
#ifndef SHARED
extern dtv_t static_dtv;
diff --git a/libpthread/nptl/sysdeps/x86_64/dl-tls.h b/libpthread/nptl/sysdeps/x86_64/dl-tls.h
index d6c338cda..5cac55f33 100644
--- a/libpthread/nptl/sysdeps/x86_64/dl-tls.h
+++ b/libpthread/nptl/sysdeps/x86_64/dl-tls.h
@@ -26,3 +26,6 @@ typedef struct
extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
Ref:
https://sourceware.org/bugzilla/show_bug.cgi?id=12650
How to reproduce:
-------------------------------------------------------------------------------------------------------------------------------------
本邮件及其附件含有新华三集团的保密信息,仅限于发送给上面地址中列出
的个人或群组。禁止任何其他人以任何形式使用(包括但不限于全部或部分地泄露、复制、
或散发)本邮件中的信息。如果您错收了本邮件,请您立即电话或邮件通知发件人并删除本
邮件!
This e-mail and its attachments contain confidential information from New H3C, which is
intended only for the person or entity whose address is listed above. Any use of the
information contained herein in any way (including, but not limited to, total or partial
disclosure, reproduction, or dissemination) by persons other than the intended
recipient(s) is prohibited. If you receive this e-mail in error, please notify the sender
by phone or email immediately and delete it!
With time64 enabled we have to use statx() instead of stat() or fstat()
If the _dl_fstat implementation isn't selected correctly
we can have multiple errors inside dynamic linker
during startup of the system and of the almost every process
Add sparc exclusion like in other places inside this header
Signed-off-by: Dmitry Chestnykh <dm.chestnykh(a)gmail.com>
---
ldso/include/dl-syscall.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ldso/include/dl-syscall.h b/ldso/include/dl-syscall.h
index 180d03012..c143b8d45 100644
--- a/ldso/include/dl-syscall.h
+++ b/ldso/include/dl-syscall.h
@@ -168,7 +168,7 @@ static __always_inline int _dl_stat(const char *file_name,
#if defined __NR_fstat64 && !defined __NR_fstat && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__))
# define __NR__dl_fstat __NR_fstat64
static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf)
-#elif defined __NR_fstat
+#elif defined __NR_fstat && !defined __UCLIBC_USE_TIME64__ || defined(__sparc__)
# define __NR__dl_fstat __NR_fstat
static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf)
#elif defined __NR_statx && defined __UCLIBC_HAVE_STATX__
--
2.46.0
With time64 enabled we have to use statx() instead of stat() or fstat()
If the _dl_fstat implementation isn't selected correctly
we can have multiple errors inside dynamic linker
during startup of the system and of the almost every process
Signed-off-by: Dmitry Chestnykh <dm.chestnykh(a)gmail.com>
---
ldso/include/dl-syscall.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ldso/include/dl-syscall.h b/ldso/include/dl-syscall.h
index 180d03012..4b0d0f395 100644
--- a/ldso/include/dl-syscall.h
+++ b/ldso/include/dl-syscall.h
@@ -168,7 +168,7 @@ static __always_inline int _dl_stat(const char *file_name,
#if defined __NR_fstat64 && !defined __NR_fstat && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__))
# define __NR__dl_fstat __NR_fstat64
static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf)
-#elif defined __NR_fstat
+#elif defined __NR_fstat && !defined __UCLIBC_USE_TIME64__
# define __NR__dl_fstat __NR_fstat
static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf)
#elif defined __NR_statx && defined __UCLIBC_HAVE_STATX__
--
2.46.0
Hi uClibc-ng hackers,
I released 1.0.50 today.
See his git shortlog for changes:
Dmitry Chestnykh (2):
Fix compilation with 4.x kernel headers
Group conditions after `&&`
Frank Mehnert (6):
libdl: properly cast parameters for %p format string specifier
iconv: explicit cast to `unsigned char*`
iconv: explicitly state operator precedence
ldso.c: use 'unsigned int' as loop variable type
iconv: fix parameter type of utf8seq_is_{overlong,surrogate,illegal}
iconv: prevent compiler warning during initialization with jis0208
J. Neuschäfer (1):
bits/stat.h: Declare st_mtim if defined(__USE_XOPEN2K8), everywhere
Marcus Haehnel (5):
ldso/dl-vdso: avoid compiler warning if configured without vdso
uclibc: Fix double promotion warning
libm: Fix float conversion compiler warning
features.h: add clang prerequisite macro
buildsys: allow building with gcc-14
Sven Linker (1):
c++: Remove deprecated dynamic exception specification
Valentin Gehrke (1):
arm: Replace deprecated asm instructions for ARMv8 AArch32
Waldemar Brodkorb (9):
Clang support for gnu_inline attribute
allow to use <sys/ucontext.h>
add SEEK_DATA/SEEK_HOLE
lseek: allow SEEK_DATA/SEEK_HOLE to be used
bits/stat.h: Declare st_mtim if defined(__USE_XOPEN2K8), add missing
riscv: remove incomplete context implementation, use libucontext
add memfd_create syscall wrapper
getrandom: remove __USE_GNU / add GRND_INSECURE
bump version for 1.0.50 release
Yann Le Du (1):
stdlib: increase number of static atexit handlers to 32
Happy Updating!
Sunshine,
Waldemar Brodkorb
If the conditions are not grouped we can reach
this block even if `__NR_stat` is not defined.
`defined __NR_stat && ((!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__))`
gives us false but `LINUX_VERSION_CODE <= KERNEL_VERSION(5,1,0))`
may give us true. So if linux headers version is below 5.1.0 and
__NR_stat is not defined we can have compilation error
Signed-off-by: Dmitry Chestnykh <dm.chestnykh(a)gmail.com>
---
ldso/include/dl-syscall.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ldso/include/dl-syscall.h b/ldso/include/dl-syscall.h
index 9ec0eac60..180d03012 100644
--- a/ldso/include/dl-syscall.h
+++ b/ldso/include/dl-syscall.h
@@ -141,7 +141,7 @@ static __always_inline int _dl_stat(const char *file_name,
{
return _dl_newfstatat(AT_FDCWD, file_name, buf, 0);
}
-#elif defined __NR_stat && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__)) || (LINUX_VERSION_CODE <= KERNEL_VERSION(5,1,0))
+#elif defined __NR_stat && (!defined(__UCLIBC_USE_TIME64__) || defined(__sparc__) || (LINUX_VERSION_CODE <= KERNEL_VERSION(5,1,0)))
# define __NR__dl_stat __NR_stat
static __always_inline _syscall2(int, _dl_stat, const char *, file_name,
struct stat *, buf)
--
2.45.2
While building software that sets _POSIX_C_SOURCE=200809L and uses
stat.st_mtim for ARM, it was noticed that st_mtim was not defined.
This seems to be because common/bits/stat.h was picked up, which does
not take __USE_XOPEN2K8 as a reason to enable st_mtim and related
fields. This appears to be an oversight, and porting the check from
common-generic/bits/stat.h to other architectures does indeed fix the
build issue.
This patch is based on commit 50bd6d06e ("Fix memory corruption due to
struct stat field").
Signed-off-by: J. Neuschäfer <j.neuschaefer(a)gmx.net>
---
libc/sysdeps/linux/alpha/bits/stat.h | 2 +-
libc/sysdeps/linux/common/bits/stat.h | 4 ++--
libc/sysdeps/linux/frv/bits/stat.h | 4 ++--
libc/sysdeps/linux/ia64/bits/stat.h | 4 ++--
libc/sysdeps/linux/m68k/bits/stat.h | 4 ++--
libc/sysdeps/linux/mips/bits/stat.h | 4 ++--
libc/sysdeps/linux/nds32/bits/stat.h | 4 ++--
libc/sysdeps/linux/powerpc/bits/stat.h | 4 ++--
8 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/libc/sysdeps/linux/alpha/bits/stat.h b/libc/sysdeps/linux/alpha/bits/stat.h
index 88bc6617d..f2dca250d 100644
--- a/libc/sysdeps/linux/alpha/bits/stat.h
+++ b/libc/sysdeps/linux/alpha/bits/stat.h
@@ -40,7 +40,7 @@
Use neat tidy anonymous unions and structures when possible. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
# if __GNUC_PREREQ(3,3)
# define __ST_TIME(X) \
__extension__ union { \
diff --git a/libc/sysdeps/linux/common/bits/stat.h b/libc/sysdeps/linux/common/bits/stat.h
index 07c09f50a..fc76cc3e7 100644
--- a/libc/sysdeps/linux/common/bits/stat.h
+++ b/libc/sysdeps/linux/common/bits/stat.h
@@ -61,7 +61,7 @@ struct stat
#else
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
#endif
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -107,7 +107,7 @@ struct stat64
__blksize_t st_blksize; /* Optimal block size for I/O. */
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
diff --git a/libc/sysdeps/linux/frv/bits/stat.h b/libc/sysdeps/linux/frv/bits/stat.h
index 381d207f2..18321c080 100644
--- a/libc/sysdeps/linux/frv/bits/stat.h
+++ b/libc/sysdeps/linux/frv/bits/stat.h
@@ -70,7 +70,7 @@ struct stat
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
#endif
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -117,7 +117,7 @@ struct stat64
__blksize_t st_blksize; /* Optimal block size for I/O. */
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
diff --git a/libc/sysdeps/linux/ia64/bits/stat.h b/libc/sysdeps/linux/ia64/bits/stat.h
index 6723166e7..2b70b8cf8 100644
--- a/libc/sysdeps/linux/ia64/bits/stat.h
+++ b/libc/sysdeps/linux/ia64/bits/stat.h
@@ -38,7 +38,7 @@ struct stat
int pad0;
__dev_t st_rdev; /* Device number, if device. */
__off_t st_size; /* Size of file, in bytes. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -77,7 +77,7 @@ struct stat64
int pad0;
__dev_t st_rdev; /* Device number, if device. */
__off_t st_size; /* Size of file, in bytes. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
diff --git a/libc/sysdeps/linux/m68k/bits/stat.h b/libc/sysdeps/linux/m68k/bits/stat.h
index 7b9c3d144..70da1b384 100644
--- a/libc/sysdeps/linux/m68k/bits/stat.h
+++ b/libc/sysdeps/linux/m68k/bits/stat.h
@@ -60,7 +60,7 @@ struct stat
#else
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
#endif
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -106,7 +106,7 @@ struct stat64
__blksize_t st_blksize; /* Optimal block size for I/O. */
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
diff --git a/libc/sysdeps/linux/mips/bits/stat.h b/libc/sysdeps/linux/mips/bits/stat.h
index 539fa33d2..bad2a0244 100644
--- a/libc/sysdeps/linux/mips/bits/stat.h
+++ b/libc/sysdeps/linux/mips/bits/stat.h
@@ -60,7 +60,7 @@ struct stat
long int st_pad2[2];
__off64_t st_size; /* Size of file, in bytes. */
#endif
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -103,7 +103,7 @@ struct stat {
unsigned int st_rdev; /* Device number, if device. */
int st_pad2[3];
__off_t st_size; /* Size of file, in bytes. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
diff --git a/libc/sysdeps/linux/nds32/bits/stat.h b/libc/sysdeps/linux/nds32/bits/stat.h
index c4e09e0f2..5272751f4 100644
--- a/libc/sysdeps/linux/nds32/bits/stat.h
+++ b/libc/sysdeps/linux/nds32/bits/stat.h
@@ -64,7 +64,7 @@ struct stat
#else
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
#endif
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -110,7 +110,7 @@ struct stat64
__blksize_t st_blksize; /* Optimal block size for I/O. */
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
diff --git a/libc/sysdeps/linux/powerpc/bits/stat.h b/libc/sysdeps/linux/powerpc/bits/stat.h
index 7494586b5..ce2ebf896 100644
--- a/libc/sysdeps/linux/powerpc/bits/stat.h
+++ b/libc/sysdeps/linux/powerpc/bits/stat.h
@@ -59,7 +59,7 @@ struct stat
# else
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
# endif
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -99,7 +99,7 @@ struct stat64
__off64_t st_size; /* Size of file, in bytes. */
__blksize_t st_blksize; /* Optimal block size for I/O. */
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
-#ifdef __USE_MISC
+#if defined(__USE_MISC) || defined(__USE_XOPEN2K8)
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
---
base-commit: 05b11809bd11450aff3d20e43f18415ce58601e7
change-id: 20240727-stat-3fad5c0d2dfb
Best regards,
--
J. Neuschäfer <j.neuschaefer(a)gmx.net>
From: Frank Mehnert <frank.mehnert(a)kernkonzept.com>
Use `unsigned char *s` rather than `char *s`. First, this fixes compiler
warnings when these functions are called from utf8dec_wchar() passing
the `in` pointer of type `unsigned char *`.
Second, these functions are always called with characters >= 0x80 so the
sign bit is set. Shifting right a negative signed value will insert `1`
from the left side, so `foo >> 1` where foo is negative will always have
the sign bit set. So at least "case 2" would never return true.
There is a similar problem with tests like
(*(s+1) >= 0xA0) && (*(s+1) <= 0xBF)
This condition is always false with `char *s`.
Signed-off-by: Marcus Haehnel <marcus.haehnel(a)kernkonzept.com>
---
libiconv/iconv.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/libiconv/iconv.c b/libiconv/iconv.c
index 6876ab5f7..095932fd6 100644
--- a/libiconv/iconv.c
+++ b/libiconv/iconv.c
@@ -242,7 +242,7 @@ static inline int utf8enc_wchar(char *outb, wchar_t c)
}
}
-static inline int utf8seq_is_overlong(char *s, int n)
+static inline int utf8seq_is_overlong(unsigned char *s, int n)
{
switch (n)
{
@@ -268,12 +268,12 @@ static inline int utf8seq_is_overlong(char *s, int n)
return 0;
}
-static inline int utf8seq_is_surrogate(char *s, int n)
+static inline int utf8seq_is_surrogate(unsigned char *s, int n)
{
return ((n == 3) && (*s == 0xED) && (*(s+1) >= 0xA0) && (*(s+1) <= 0xBF));
}
-static inline int utf8seq_is_illegal(char *s, int n)
+static inline int utf8seq_is_illegal(unsigned char *s, int n)
{
return ((n == 3) && (*s == 0xEF) && (*(s+1) == 0xBF) &&
(*(s+2) >= 0xBE) && (*(s+2) <= 0xBF));
--
2.45.2