Validate the fd returned by cygheap_getfd operating on given mqd.

Reported-by: Christian Franke <christian.fra...@t-online.de>
Addresses: https://cygwin.com/pipermail/cygwin/2025-January/257090.html
Signed-off-by: Mark Geisert <m...@maxrnd.com>
Fixes: 46f3b0ce85a9 (Cygwin: POSIX msg queues: move all mq_* functionality into 
fhandler_mqueue)

---
 winsup/cygwin/posix_ipc.cc | 88 +++++++++++++++++++++++---------------
 1 file changed, 53 insertions(+), 35 deletions(-)

diff --git a/winsup/cygwin/posix_ipc.cc b/winsup/cygwin/posix_ipc.cc
index 34fd2ba34..3ce1ecda6 100644
--- a/winsup/cygwin/posix_ipc.cc
+++ b/winsup/cygwin/posix_ipc.cc
@@ -225,11 +225,14 @@ mq_getattr (mqd_t mqd, struct mq_attr *mqstat)
   int ret = -1;
 
   cygheap_fdget fd ((int) mqd, true);
-  fhandler_mqueue *fh = fd->is_mqueue ();
-  if (!fh)
-    set_errno (EBADF);
-  else
-    ret = fh->mq_getattr (mqstat);
+  if (fd >= 0)
+    {
+      fhandler_mqueue *fh = fd->is_mqueue ();
+      if (!fh)
+        set_errno (EBADF);
+      else
+        ret = fh->mq_getattr (mqstat);
+    }
   return ret;
 }
 
@@ -239,11 +242,14 @@ mq_setattr (mqd_t mqd, const struct mq_attr *mqstat, 
struct mq_attr *omqstat)
   int ret = -1;
 
   cygheap_fdget fd ((int) mqd, true);
-  fhandler_mqueue *fh = fd->is_mqueue ();
-  if (!fh)
-    set_errno (EBADF);
-  else
-    ret = fh->mq_setattr (mqstat, omqstat);
+  if (fd >= 0)
+    {
+      fhandler_mqueue *fh = fd->is_mqueue ();
+      if (!fh)
+        set_errno (EBADF);
+      else
+        ret = fh->mq_setattr (mqstat, omqstat);
+    }
   return ret;
 }
 
@@ -253,11 +259,14 @@ mq_notify (mqd_t mqd, const struct sigevent *notification)
   int ret = -1;
 
   cygheap_fdget fd ((int) mqd, true);
-  fhandler_mqueue *fh = fd->is_mqueue ();
-  if (!fh)
-    set_errno (EBADF);
-  else
-    ret = fh->mq_notify (notification);
+  if (fd >= 0)
+    {
+      fhandler_mqueue *fh = fd->is_mqueue ();
+      if (!fh)
+        set_errno (EBADF);
+      else
+        ret = fh->mq_notify (notification);
+    }
   return ret;
 }
 
@@ -268,11 +277,14 @@ mq_timedsend (mqd_t mqd, const char *ptr, size_t len, 
unsigned int prio,
   int ret = -1;
 
   cygheap_fdget fd ((int) mqd, true);
-  fhandler_mqueue *fh = fd->is_mqueue ();
-  if (!fh)
-    set_errno (EBADF);
-  else
-    ret = fh->mq_timedsend (ptr, len, prio, abstime);
+  if (fd >= 0)
+    {
+      fhandler_mqueue *fh = fd->is_mqueue ();
+      if (!fh)
+        set_errno (EBADF);
+      else
+        ret = fh->mq_timedsend (ptr, len, prio, abstime);
+    }
   return ret;
 }
 
@@ -289,11 +301,14 @@ mq_timedreceive (mqd_t mqd, char *ptr, size_t maxlen, 
unsigned int *priop,
   int ret = -1;
 
   cygheap_fdget fd ((int) mqd, true);
-  fhandler_mqueue *fh = fd->is_mqueue ();
-  if (!fh)
-    set_errno (EBADF);
-  else
-    ret = fh->mq_timedrecv (ptr, maxlen, priop, abstime);
+  if (fd >= 0)
+    {
+      fhandler_mqueue *fh = fd->is_mqueue ();
+      if (!fh)
+        set_errno (EBADF);
+      else
+        ret = fh->mq_timedrecv (ptr, maxlen, priop, abstime);
+    }
   return ret;
 }
 
@@ -309,18 +324,21 @@ mq_close (mqd_t mqd)
   __try
     {
       cygheap_fdget fd ((int) mqd, true);
-      if (!fd->is_mqueue ())
-       {
-         set_errno (EBADF);
-         __leave;
-       }
+      if (fd >= 0)
+        {
+          if (!fd->is_mqueue ())
+           {
+             set_errno (EBADF);
+             __leave;
+           }
 
-      if (mq_notify (mqd, NULL))       /* unregister calling process */
-       __leave;
+          if (mq_notify (mqd, NULL))   /* unregister calling process */
+           __leave;
 
-      fd->isclosed (true);
-      fd->close ();
-      fd.release ();
+          fd->isclosed (true);
+          fd->close ();
+          fd.release ();
+        }
       return 0;
     }
   __except (EBADF) {}
-- 
2.45.1

Reply via email to