[libc-commits] [libc] [libc] No need to use recursion in fcntl (PR #99893)

Mikhail R. Gadelha via libc-commits libc-commits at lists.llvm.org
Mon Jul 22 09:27:22 PDT 2024


https://github.com/mikhailramalho created https://github.com/llvm/llvm-project/pull/99893

This patch removes the recursion in fcntl introduced by PR 99675 as it is not required and may be dangerous in some cases: there are toolchains that define F_GETLK == F_GETLK64, causing infinite recursion.

>From e9803476a9cd9589e84c9dbbc27f8b5527cee8ce Mon Sep 17 00:00:00 2001
From: "Mikhail R. Gadelha" <mikhail at igalia.com>
Date: Mon, 22 Jul 2024 13:23:13 -0300
Subject: [PATCH] [libc] No need to use recursion in fcntl

This patch removes the recursion in fcntl introduced by PR 99675 as it
is not required and may be dangerous in some cases: there are toolchains
that define F_GETLK == F_GETLK64, causing infinite recursion.
---
 libc/src/__support/OSUtil/linux/fcntl.cpp | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/libc/src/__support/OSUtil/linux/fcntl.cpp b/libc/src/__support/OSUtil/linux/fcntl.cpp
index 7731aa04a178d..4742b2a00220b 100644
--- a/libc/src/__support/OSUtil/linux/fcntl.cpp
+++ b/libc/src/__support/OSUtil/linux/fcntl.cpp
@@ -33,7 +33,8 @@ int fcntl(int fd, int cmd, void *arg) {
 #error "fcntl and fcntl64 syscalls not available."
 #endif
 
-  switch (cmd) {
+  int new_cmd = cmd;
+  switch (new_cmd) {
   case F_OFD_SETLKW: {
     struct flock *flk = reinterpret_cast<struct flock *>(arg);
     // convert the struct to a flock64
@@ -44,7 +45,8 @@ int fcntl(int fd, int cmd, void *arg) {
     flk64.l_len = flk->l_len;
     flk64.l_pid = flk->l_pid;
     // create a syscall
-    return LIBC_NAMESPACE::syscall_impl<int>(FCNTL_SYSCALL_ID, fd, cmd, &flk64);
+    return LIBC_NAMESPACE::syscall_impl<int>(FCNTL_SYSCALL_ID, fd, new_cmd,
+                                             &flk64);
   }
   case F_OFD_GETLK:
   case F_OFD_SETLK: {
@@ -57,8 +59,8 @@ int fcntl(int fd, int cmd, void *arg) {
     flk64.l_len = flk->l_len;
     flk64.l_pid = flk->l_pid;
     // create a syscall
-    int retVal =
-        LIBC_NAMESPACE::syscall_impl<int>(FCNTL_SYSCALL_ID, fd, cmd, &flk64);
+    int retVal = LIBC_NAMESPACE::syscall_impl<int>(FCNTL_SYSCALL_ID, fd,
+                                                   new_cmd, &flk64);
     // On failure, return
     if (retVal == -1)
       return -1;
@@ -89,22 +91,22 @@ int fcntl(int fd, int cmd, void *arg) {
 #ifdef SYS_fcntl64
   case F_GETLK: {
     if constexpr (FCNTL_SYSCALL_ID == SYS_fcntl64)
-      return fcntl(fd, F_GETLK64, arg);
+      new_cmd = F_GETLK64;
     break;
   }
   case F_SETLK: {
     if constexpr (FCNTL_SYSCALL_ID == SYS_fcntl64)
-      return fcntl(fd, F_SETLK64, arg);
+      new_cmd = F_SETLK64;
     break;
   }
   case F_SETLKW: {
     if constexpr (FCNTL_SYSCALL_ID == SYS_fcntl64)
-      return fcntl(fd, F_SETLKW64, arg);
+      new_cmd = F_SETLKW64;
     break;
   }
 #endif
   }
-  int retVal = LIBC_NAMESPACE::syscall_impl<int>(FCNTL_SYSCALL_ID, fd, cmd,
+  int retVal = LIBC_NAMESPACE::syscall_impl<int>(FCNTL_SYSCALL_ID, fd, new_cmd,
                                                  reinterpret_cast<void *>(arg));
   if (retVal >= 0) {
     return retVal;



More information about the libc-commits mailing list