https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=230f4802edfba76da303e57a11ea04d67bc31b0d

commit 230f4802edfba76da303e57a11ea04d67bc31b0d
Author:     Corinna Vinschen <cori...@vinschen.de>
AuthorDate: Tue Feb 25 11:05:32 2025 +0100
Commit:     Corinna Vinschen <cori...@vinschen.de>
CommitDate: Wed Feb 26 09:45:04 2025 +0100

    Cygwin: pipes: fix error handling when creating a pipe
    
    The nt_create() function returns a Windows error code, but
    it only calls NT functions.  In one case, it returns the
    Windows error code without converting the NT status code
    to a Windows error code first.
    
    To fix this mess, change nt_create() to a function returning
    the NT status code directly. Let the (only) caller handle
    the conversion from NT status code to errno value.
    
    Reported-by: "knut st. osmundsen" <bird-cyg...@anduin.net>
    Fixes: f56206cd86b9 ("Cygwin: fhandler_pipe: fix permission problem")
    Signed-off-by: Corinna Vinschen <cori...@vinschen.de>

Diff:
---
 winsup/cygwin/fhandler/pipe.cc | 40 +++++++++++++++++-----------------------
 1 file changed, 17 insertions(+), 23 deletions(-)

diff --git a/winsup/cygwin/fhandler/pipe.cc b/winsup/cygwin/fhandler/pipe.cc
index 074cb50cafaa..e24252deee42 100644
--- a/winsup/cygwin/fhandler/pipe.cc
+++ b/winsup/cygwin/fhandler/pipe.cc
@@ -945,8 +945,8 @@ is_running_as_service (void)
    simplicity, nt_create will omit the 'open_mode' and 'name'
    parameters, which aren't needed for our purposes.  */
 
-static int nt_create (LPSECURITY_ATTRIBUTES, HANDLE &, HANDLE &, DWORD,
-                     int64_t *);
+static NTSTATUS nt_create (LPSECURITY_ATTRIBUTES, HANDLE &, HANDLE &, DWORD,
+                          int64_t *);
 
 int
 fhandler_pipe::create (fhandler_pipe *fhs[2], unsigned psize, int mode)
@@ -956,10 +956,10 @@ fhandler_pipe::create (fhandler_pipe *fhs[2], unsigned 
psize, int mode)
   int res = -1;
   int64_t unique_id = 0; /* Compiler complains if not initialized... */
 
-  int ret = nt_create (sa, r, w, psize, &unique_id);
-  if (ret)
+  NTSTATUS status = nt_create (sa, r, w, psize, &unique_id);
+  if (!NT_SUCCESS (status))
     {
-      __seterrno_from_win_error (ret);
+      __seterrno_from_nt_status (status);
       goto out;
     }
   if ((fhs[0] = (fhandler_pipe *) build_fh_dev (*piper_dev)) == NULL)
@@ -1010,9 +1010,9 @@ out:
   return res;
 }
 
-static int
-nt_create (LPSECURITY_ATTRIBUTES sa_ptr, HANDLE &r, HANDLE &w,
-               DWORD psize, int64_t *unique_id)
+static NTSTATUS
+nt_create (LPSECURITY_ATTRIBUTES sa_ptr, HANDLE &r, HANDLE &w, DWORD psize,
+          int64_t *unique_id)
 {
   NTSTATUS status;
   HANDLE npfsh;
@@ -1027,10 +1027,7 @@ nt_create (LPSECURITY_ATTRIBUTES sa_ptr, HANDLE &r, 
HANDLE &w,
 
   status = fhandler_base::npfs_handle (npfsh);
   if (!NT_SUCCESS (status))
-    {
-      __seterrno_from_nt_status (status);
-      return GetLastError ();
-    }
+    return status;
 
   /* Ensure that there is enough pipe buffer space for atomic writes.  */
   if (!psize)
@@ -1045,12 +1042,12 @@ nt_create (LPSECURITY_ATTRIBUTES sa_ptr, HANDLE &r, 
HANDLE &w,
   access = GENERIC_READ | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE;
 
   ULONG pipe_type = pipe_byte ? FILE_PIPE_BYTE_STREAM_TYPE
-    : FILE_PIPE_MESSAGE_TYPE;
+                             : FILE_PIPE_MESSAGE_TYPE;
 
   /* Retry NtCreateNamedPipeFile as long as the pipe name is in use.
      Retrying will probably never be necessary, but we want
      to be as robust as possible.  */
-  DWORD err = 0;
+  NTSTATUS err = STATUS_SUCCESS;
   while (!r)
     {
       static volatile ULONG pipe_unique_id;
@@ -1082,7 +1079,7 @@ nt_create (LPSECURITY_ATTRIBUTES sa_ptr, HANDLE &r, 
HANDLE &w,
       if (NT_SUCCESS (status))
        {
          debug_printf ("pipe read handle %p", r);
-         err = 0;
+         err = STATUS_SUCCESS;
          break;
        }
 
@@ -1104,9 +1101,8 @@ nt_create (LPSECURITY_ATTRIBUTES sa_ptr, HANDLE &r, 
HANDLE &w,
          break;
        default:
          {
-           __seterrno_from_nt_status (status);
-           err = GetLastError ();
-           debug_printf ("failed, %E");
+           err = status;
+           debug_printf ("NtCreateNamedPipeFile failed: %y", err);
            r = NULL;
          }
        }
@@ -1124,16 +1120,14 @@ nt_create (LPSECURITY_ATTRIBUTES sa_ptr, HANDLE &r, 
HANDLE &w,
   status = NtOpenFile (&w, access, &attr, &io, 0, 0);
   if (!NT_SUCCESS (status))
     {
-      DWORD err = GetLastError ();
-      debug_printf ("NtOpenFile failed, r %p, %E", r);
+      debug_printf ("NtOpenFile failed, r %p: %y", r, status);
       if (r)
        NtClose (r);
       w = NULL;
-      return err;
+      return status;
     }
 
-  /* Success. */
-  return 0;
+  return STATUS_SUCCESS;
 }
 
 /* Called by dtable::init_std_file_from_handle for stdio handles

Reply via email to