[PATCH v2 5/6] Cygwin: AF_UNIX: listen_pipe: check for STATUS_SUCCESS

2020-10-04 Thread Ken Brown via Cygwin-patches
A successful connection can be indicated by STATUS_SUCCESS or
STATUS_PIPE_CONNECTED.  Previously we were checking only for the
latter.
---
 winsup/cygwin/fhandler_socket_unix.cc | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/winsup/cygwin/fhandler_socket_unix.cc 
b/winsup/cygwin/fhandler_socket_unix.cc
index 0ae7fe125..1a9532fe5 100644
--- a/winsup/cygwin/fhandler_socket_unix.cc
+++ b/winsup/cygwin/fhandler_socket_unix.cc
@@ -1064,6 +1064,7 @@ fhandler_socket_unix::listen_pipe ()
   IO_STATUS_BLOCK io;
   HANDLE evt = NULL;
   DWORD waitret = WAIT_OBJECT_0;
+  int ret = -1;
 
   io.Status = STATUS_PENDING;
   if (!is_nonblocking () && !(evt = create_event ()))
@@ -1085,9 +1086,11 @@ fhandler_socket_unix::listen_pipe ()
 set_errno (EINTR);
   else if (status == STATUS_PIPE_LISTENING)
 set_errno (EAGAIN);
-  else if (status != STATUS_PIPE_CONNECTED)
+  else if (status == STATUS_SUCCESS || status == STATUS_PIPE_CONNECTED)
+ret = 0;
+  else
 __seterrno_from_nt_status (status);
-  return (status == STATUS_PIPE_CONNECTED) ? 0 : -1;
+  return ret;
 }
 
 ULONG
-- 
2.28.0



[PATCH v2 4/6] Cygwin: AF_UNIX: socket: set the O_RDWR flag

2020-10-04 Thread Ken Brown via Cygwin-patches
---
 winsup/cygwin/fhandler_socket_unix.cc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/winsup/cygwin/fhandler_socket_unix.cc 
b/winsup/cygwin/fhandler_socket_unix.cc
index 429aa8a90..0ae7fe125 100644
--- a/winsup/cygwin/fhandler_socket_unix.cc
+++ b/winsup/cygwin/fhandler_socket_unix.cc
@@ -1366,6 +1366,7 @@ fhandler_socket_unix::socket (int af, int type, int 
protocol, int flags)
   wmem (262144);
   set_addr_family (AF_UNIX);
   set_socket_type (type);
+  set_flags (O_RDWR | O_BINARY);
   if (flags & SOCK_NONBLOCK)
 set_nonblocking (true);
   if (flags & SOCK_CLOEXEC)
-- 
2.28.0



[PATCH v2 6/6] Cygwin: AF_UNIX: open_pipe: call recv_peer_info

2020-10-04 Thread Ken Brown via Cygwin-patches
If open_pipe is called with xchg_sock_info true, call recv_peer_info
in addition to send_sock_info.
---
 winsup/cygwin/fhandler_socket_unix.cc | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/winsup/cygwin/fhandler_socket_unix.cc 
b/winsup/cygwin/fhandler_socket_unix.cc
index 1a9532fe5..9f7f86c47 100644
--- a/winsup/cygwin/fhandler_socket_unix.cc
+++ b/winsup/cygwin/fhandler_socket_unix.cc
@@ -941,7 +941,11 @@ fhandler_socket_unix::open_pipe (PUNICODE_STRING 
pipe_name, bool xchg_sock_info)
 {
   set_handle (ph);
   if (xchg_sock_info)
-   send_sock_info (false);
+   {
+ /* FIXME: Should we check for errors? */
+ send_sock_info (false);
+ recv_peer_info ();
+   }
 }
   return status;
 }
-- 
2.28.0



[PATCH v2 0/6] Some AF_UNIX fixes

2020-10-04 Thread Ken Brown via Cygwin-patches
I'm about to push these.  Corinna, please check them when you return.
The only difference between v2 and v1 is that there are a few more
fixes.

I'm trying to help get the AF_UNIX development going again.  I'm
mostly working on the topic/af_unix branch.  But when I find bugs that
exist on master, I'll push those to master and then merge master to
topic/af_unix.

So far what I have on that branch locally (to be pushed shortly) is an
implementation of fhandler_socket_unix::read, which I've tested by
running the srver/client programs from Section 57.2 of Kerrisk's book,
"The Linux Programming Interface".

Ken Brown (6):
  Cygwin: AF_UNIX: use FILE_OPEN_REPARSE_POINT when needed
  Cygwin: fix handling of known reparse points that are not symlinks
  Cygwin: always recognize AF_UNIX sockets as reparse points
  Cygwin: AF_UNIX: socket: set the O_RDWR flag
  Cygwin: AF_UNIX: listen_pipe: check for STATUS_SUCCESS
  Cygwin: AF_UNIX: open_pipe: call recv_peer_info

 winsup/cygwin/fhandler.cc | 11 --
 winsup/cygwin/fhandler_socket_unix.cc | 31 +--
 winsup/cygwin/path.cc | 27 +++
 winsup/cygwin/security.cc |  8 +--
 4 files changed, 53 insertions(+), 24 deletions(-)

-- 
2.28.0



[PATCH v2 3/6] Cygwin: always recognize AF_UNIX sockets as reparse points

2020-10-04 Thread Ken Brown via Cygwin-patches
If __WITH_AF_UNIX is defined when Cygwin is built, then a named
AF_UNIX socket is represented by a reparse point with a
Cygwin-specific tag and GUID.  Make such files recognizable as reparse
points (but not as sockets) even if __WITH_AF_UNIX is not defined.
That way utilities such as 'ls' and 'rm' still behave reasonably.

This requires two changes:

- Define the GUID __cygwin_socket_guid unconditionally.

- Make check_reparse_point_target return PATH_REP on a reparse point
  of this type if __WITH_AF_UNIX is not defined.
---
 winsup/cygwin/fhandler_socket_unix.cc | 17 +
 winsup/cygwin/path.cc | 10 ++
 2 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/winsup/cygwin/fhandler_socket_unix.cc 
b/winsup/cygwin/fhandler_socket_unix.cc
index d7bb1090e..429aa8a90 100644
--- a/winsup/cygwin/fhandler_socket_unix.cc
+++ b/winsup/cygwin/fhandler_socket_unix.cc
@@ -8,9 +8,17 @@
Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
details. */
 
+#include "winsup.h"
+
+GUID __cygwin_socket_guid = {
+  .Data1 = 0xefc1714d,
+  .Data2 = 0x7b19,
+  .Data3 = 0x4407,
+  .Data4 = { 0xba, 0xb3, 0xc5, 0xb1, 0xf9, 0x2c, 0xb8, 0x8c }
+};
+
 #ifdef __WITH_AF_UNIX
 
-#include "winsup.h"
 #include 
 #include 
 #include 
@@ -124,13 +132,6 @@ class af_unix_pkt_hdr_t
   (void *)(((PBYTE)(_p)) + AF_UNIX_PKT_OFFSETOF_DATA (_p)); \
})
 
-GUID __cygwin_socket_guid = {
-  .Data1 = 0xefc1714d,
-  .Data2 = 0x7b19,
-  .Data3 = 0x4407,
-  .Data4 = { 0xba, 0xb3, 0xc5, 0xb1, 0xf9, 0x2c, 0xb8, 0x8c }
-};
-
 /* Some error conditions on pipes have multiple status codes, unfortunately. */
 #define STATUS_PIPE_NO_INSTANCE_AVAILABLE(status)  \
({ NTSTATUS _s = (status); \
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 2e3208d2d..4f5f03a76 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -2476,8 +2476,7 @@ check_reparse_point_string (PUNICODE_STRING subst)
 /* Return values:
 <0: Negative errno.
  0: Not a reparse point recognized by us.
->0: PATH_SYMLINK | PATH_REP for symlink or directory mount point,
-PATH_SOCKET | PATH_REP for AF_UNIX socket.
+>0: Path flags for a recognized reparse point, always including PATH_REP.
 */
 int
 check_reparse_point_target (HANDLE h, bool remote, PREPARSE_DATA_BUFFER rp,
@@ -2618,15 +2617,18 @@ check_reparse_point_target (HANDLE h, bool remote, 
PREPARSE_DATA_BUFFER rp,
}
   return -EIO;
 }
-#ifdef __WITH_AF_UNIX
   else if (rp->ReparseTag == IO_REPARSE_TAG_CYGUNIX)
 {
   PREPARSE_GUID_DATA_BUFFER rgp = (PREPARSE_GUID_DATA_BUFFER) rp;
 
   if (memcmp (CYGWIN_SOCKET_GUID, >ReparseGuid, sizeof (GUID)) == 0)
+#ifdef __WITH_AF_UNIX
return PATH_SOCKET | PATH_REP;
+#else
+/* Recognize this as a reparse point but not as a socket.  */
+return PATH_REP;
+#endif
 }
-#endif /* __WITH_AF_UNIX */
   return 0;
 }
 
-- 
2.28.0



[PATCH v2 2/6] Cygwin: fix handling of known reparse points that are not symlinks

2020-10-04 Thread Ken Brown via Cygwin-patches
Commit aa467e6e, "Cygwin: add AF_UNIX reparse points to path
handling", changed check_reparse_point_target so that it could return
a positive value on a known reparse point that is not a symlink.  But
some of the code in check_reparse_point that handles this positive
return value was executed unconditionally, when it should have been
executed only for symlinks.

As a result, posixify could be called on a buffer containing garbage,
and check_reparse_point could erroneously return a positive value on a
non-symlink.  This is now fixed so that posixify is only called if the
reparse point is a symlink, and check_reparse_point returns 0 if the
reparse point is not a symlink.

Also fix symlink_info::check to handle this last case, in which
check_reparse_point returns 0 on a known reparse point.
---
 winsup/cygwin/path.cc | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 638f1adce..2e3208d2d 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -2655,11 +2655,15 @@ symlink_info::check_reparse_point (HANDLE h, bool 
remote)
   /* ret is > 0, so it's a known reparse point, path in symbuf. */
   path_flags |= ret;
   if (ret & PATH_SYMLINK)
-sys_wcstombs (srcbuf, SYMLINK_MAX + 7, symbuf.Buffer,
- symbuf.Length / sizeof (WCHAR));
-  /* A symlink is never a directory. */
-  fileattr &= ~FILE_ATTRIBUTE_DIRECTORY;
-  return posixify (srcbuf);
+{
+  sys_wcstombs (srcbuf, SYMLINK_MAX + 7, symbuf.Buffer,
+   symbuf.Length / sizeof (WCHAR));
+  /* A symlink is never a directory. */
+  fileattr &= ~FILE_ATTRIBUTE_DIRECTORY;
+  return posixify (srcbuf);
+}
+  else
+return 0;
 }
 
 int
@@ -3274,6 +3278,9 @@ restart:
&= ~FILE_ATTRIBUTE_DIRECTORY;
  break;
}
+ else if (res == 0 && (path_flags & PATH_REP))
+   /* Known reparse point but not a symlink. */
+   goto file_not_symlink;
  else
{
  /* Volume moint point or unrecognized reparse point type.
-- 
2.28.0



[PATCH v2 1/6] Cygwin: AF_UNIX: use FILE_OPEN_REPARSE_POINT when needed

2020-10-04 Thread Ken Brown via Cygwin-patches
The following Windows system calls currently fail with
STATUS_IO_REPARSE_TAG_NOT_HANDLED when called on an AF_UNIX socket:

- NtOpenFile in get_file_sd

- NtOpenFile in set_file_sd

- NtCreateFile in fhandler_base::open

Fix this by adding the FILE_OPEN_REPARSE_POINT flag to those calls
when the file is a known reparse point.
---
 winsup/cygwin/fhandler.cc | 11 +--
 winsup/cygwin/security.cc |  8 ++--
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index 82b21aff4..5dbbd4068 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -620,13 +620,20 @@ fhandler_base::open (int flags, mode_t mode)
   else
 create_disposition = (flags & O_CREAT) ? FILE_OPEN_IF : FILE_OPEN;
 
-  if (get_device () == FH_FS)
+  if (get_device () == FH_FS
+#ifdef __WITH_AF_UNIX
+  || get_device () == FH_UNIX
+#endif
+  )
 {
-  /* Add the reparse point flag to known repares points, otherwise we
+  /* Add the reparse point flag to known reparse points, otherwise we
 open the target, not the reparse point.  This would break lstat. */
   if (pc.is_known_reparse_point ())
options |= FILE_OPEN_REPARSE_POINT;
+}
 
+  if (get_device () == FH_FS)
+{
   /* O_TMPFILE files are created with delete-on-close semantics, as well
 as with FILE_ATTRIBUTE_TEMPORARY.  The latter speeds up file access,
 because the OS tries to keep the file in memory as much as possible.
diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc
index 468b05164..d48526619 100644
--- a/winsup/cygwin/security.cc
+++ b/winsup/cygwin/security.cc
@@ -65,7 +65,9 @@ get_file_sd (HANDLE fh, path_conv , security_descriptor 
,
   fh ? pc.init_reopen_attr (attr, fh)
  : pc.get_object_attr (attr, sec_none_nih),
   , FILE_SHARE_VALID_FLAGS,
-  FILE_OPEN_FOR_BACKUP_INTENT);
+  FILE_OPEN_FOR_BACKUP_INTENT
+  | pc.is_known_reparse_point ()
+  ? FILE_OPEN_REPARSE_POINT : 0);
   if (!NT_SUCCESS (status))
{
  sd.free ();
@@ -232,7 +234,9 @@ set_file_sd (HANDLE fh, path_conv , security_descriptor 
, bool is_chown)
  : pc.get_object_attr (attr, sec_none_nih),
   ,
   FILE_SHARE_VALID_FLAGS,
-  FILE_OPEN_FOR_BACKUP_INTENT);
+  FILE_OPEN_FOR_BACKUP_INTENT
+  | pc.is_known_reparse_point ()
+  ? FILE_OPEN_REPARSE_POINT : 0);
  if (!NT_SUCCESS (status))
{
  fh = NULL;
-- 
2.28.0