summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Weißschuh <thomas.weissschuh@linutronix.de>2025-08-20 10:29:27 +0200
committerThomas Weißschuh <linux@weissschuh.net>2025-09-01 20:47:36 +0200
commitd1ff0e2d13d6ac3a15be7870e15216726b0a809a (patch)
tree18dd003a9026f70e4d3644f6ac7f5b48bc0f2e93
parent850047b19741490631855a475ccaa3ed29316039 (diff)
tools/nolibc: avoid error in dup2() if old fd equals new fd
dup2() allows both 'old' and 'new' to have the same value, which dup3() does not. If libc dup2() is implemented through the dup3() system call, then it would incorrectly fail in this case. Avoid the error by handling old == new explicitly. Fixes: 30ca20517ac1 ("tools headers: Move the nolibc header from rcutorture to tools/include/nolibc/") Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de> Acked-by: Willy Tarreau <w@1wt.eu> Link: https://lore.kernel.org/r/20250820-nolibc-dup2-einval-v2-1-807185a45c56@linutronix.de Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
-rw-r--r--tools/include/nolibc/sys.h13
1 files changed, 13 insertions, 0 deletions
diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index 295e71d34aba..90aadad31f6c 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -238,6 +238,19 @@ static __attribute__((unused))
int sys_dup2(int old, int new)
{
#if defined(__NR_dup3)
+ int ret, nr_fcntl;
+
+#ifdef __NR_fcntl64
+ nr_fcntl = __NR_fcntl64;
+#else
+ nr_fcntl = __NR_fcntl;
+#endif
+
+ if (old == new) {
+ ret = my_syscall2(nr_fcntl, old, F_GETFD);
+ return ret < 0 ? ret : old;
+ }
+
return my_syscall3(__NR_dup3, old, new, 0);
#elif defined(__NR_dup2)
return my_syscall2(__NR_dup2, old, new);