99989d3b91
The bump to 2.4.48 introduced a bug that, according to the author, only happen in certain cases on glibc. But under uclibc-ng, it happens every time. The bug essentially cause any program calling any libattr.so function to enter an infinite recursion, because of a symbol conflict between uclibc-ng and libattr wrappers, that causes the libattr wrappers to call themselves. This infinite recursion does not consume the stack, so programs basically behave like they enter an infinite loop. It is easy to reproduce with qemu_arm_versatile_defconfig + BR2_PACKAGE_ATTR: "getfattr ." never returns and takes 100% CPU. Upstream fixed it, but the patch is not part of a release yet, so take the patch. Signed-off-by: Nicolas Cavallari <nicolas.cavallari@green-communications.fr> Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
127 lines
3.9 KiB
Diff
127 lines
3.9 KiB
Diff
From 14adc898a36948267bfe5c63b399996879e94c98 Mon Sep 17 00:00:00 2001
|
|
From: Andreas Gruenbacher <agruenba@redhat.com>
|
|
Date: Fri, 17 Aug 2018 14:07:31 +0200
|
|
Subject: Switch back to syscall()
|
|
|
|
Switch back to syscall() for the *xattr system calls. The current
|
|
mechanism of forwarding those calls to glibc breaks libraries like
|
|
libfakeroot (fakeroot) and libasan (the gcc address sanitizer; gcc
|
|
-fsanitize=address).
|
|
|
|
Those libraries provide wrappers for functions defined in other shared
|
|
libraries, usually glibc, do their own processing, and forward calls to
|
|
the original symbols looke dup via dlsym(RTLD_NEXT, "symbol_name"). In
|
|
our case, dlsym returns the libattr_*xattr wrappers. However, when our
|
|
wrappers try calling glibc, they end up calling the libfakeroot /
|
|
libasan wrappers instead because those override the original symbols =>
|
|
recursion.
|
|
|
|
The libattr_*xattr wrappers will only be used when symbols are looked up
|
|
at runtime (dlopen / dlsym). Programs linking against libattr will
|
|
directly use the glibc provided symbols. Therefore, the slightly worse
|
|
performance of syscall() won't affect any of the "normal" users of
|
|
libattr.
|
|
|
|
[nicolas.cavallari: with uclibc-ng, the recursion always happen]
|
|
Signed-off-by: Nicolas Cavallari <nicolas.cavallari@green-communications.fr>
|
|
---
|
|
libattr/syscalls.c | 26 ++++++++++++++------------
|
|
1 file changed, 14 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/libattr/syscalls.c b/libattr/syscalls.c
|
|
index 3013aa0..721ad7f 100644
|
|
--- a/libattr/syscalls.c
|
|
+++ b/libattr/syscalls.c
|
|
@@ -22,6 +22,8 @@
|
|
|
|
#include "config.h"
|
|
|
|
+#include <unistd.h>
|
|
+#include <sys/syscall.h>
|
|
#include <sys/xattr.h>
|
|
|
|
#ifdef HAVE_VISIBILITY_ATTRIBUTE
|
|
@@ -31,67 +33,67 @@
|
|
int libattr_setxattr(const char *path, const char *name,
|
|
void *value, size_t size, int flags)
|
|
{
|
|
- return setxattr(path, name, value, size, flags);
|
|
+ return syscall(__NR_setxattr, path, name, value, size, flags);
|
|
}
|
|
|
|
int libattr_lsetxattr(const char *path, const char *name,
|
|
void *value, size_t size, int flags)
|
|
{
|
|
- return lsetxattr(path, name, value, size, flags);
|
|
+ return syscall(__NR_lsetxattr, path, name, value, size, flags);
|
|
}
|
|
|
|
int libattr_fsetxattr(int filedes, const char *name,
|
|
void *value, size_t size, int flags)
|
|
{
|
|
- return fsetxattr(filedes, name, value, size, flags);
|
|
+ return syscall(__NR_fsetxattr, filedes, name, value, size, flags);
|
|
}
|
|
|
|
ssize_t libattr_getxattr(const char *path, const char *name,
|
|
void *value, size_t size)
|
|
{
|
|
- return getxattr(path, name, value, size);
|
|
+ return syscall(__NR_getxattr, path, name, value, size);
|
|
}
|
|
|
|
ssize_t libattr_lgetxattr(const char *path, const char *name,
|
|
void *value, size_t size)
|
|
{
|
|
- return lgetxattr(path, name, value, size);
|
|
+ return syscall(__NR_lgetxattr, path, name, value, size);
|
|
}
|
|
|
|
ssize_t libattr_fgetxattr(int filedes, const char *name,
|
|
void *value, size_t size)
|
|
{
|
|
- return fgetxattr(filedes, name, value, size);
|
|
+ return syscall(__NR_fgetxattr, filedes, name, value, size);
|
|
}
|
|
|
|
ssize_t libattr_listxattr(const char *path, char *list, size_t size)
|
|
{
|
|
- return listxattr(path, list, size);
|
|
+ return syscall(__NR_listxattr, path, list, size);
|
|
}
|
|
|
|
ssize_t libattr_llistxattr(const char *path, char *list, size_t size)
|
|
{
|
|
- return llistxattr(path, list, size);
|
|
+ return syscall(__NR_llistxattr, path, list, size);
|
|
}
|
|
|
|
ssize_t libattr_flistxattr(int filedes, char *list, size_t size)
|
|
{
|
|
- return flistxattr(filedes, list, size);
|
|
+ return syscall(__NR_flistxattr, filedes, list, size);
|
|
}
|
|
|
|
int libattr_removexattr(const char *path, const char *name)
|
|
{
|
|
- return removexattr(path, name);
|
|
+ return syscall(__NR_removexattr, path, name);
|
|
}
|
|
|
|
int libattr_lremovexattr(const char *path, const char *name)
|
|
{
|
|
- return lremovexattr(path, name);
|
|
+ return syscall(__NR_lremovexattr, path, name);
|
|
}
|
|
|
|
int libattr_fremovexattr(int filedes, const char *name)
|
|
{
|
|
- return fremovexattr(filedes, name);
|
|
+ return syscall(__NR_fremovexattr, filedes, name);
|
|
}
|
|
|
|
#ifdef HAVE_VISIBILITY_ATTRIBUTE
|
|
--
|
|
cgit v1.0-41-gc330
|
|
|