This is the mail archive of the cygwin-cvs@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[newlib-cygwin] Cygwin: improve storage and handling of AF_UNIX socket path


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

commit a27a7752ec68f32a826223db958effc0d98ef837
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Wed Feb 28 19:06:41 2018 +0100

    Cygwin: improve storage and handling of AF_UNIX socket path
    
    Define new struct sun_name_t and use throughout internally.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/fhandler.h              | 29 ++++++++++---
 winsup/cygwin/fhandler_socket_unix.cc | 77 ++++++++++++++++++++++++-----------
 2 files changed, 77 insertions(+), 29 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index d222494..1d4e681 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -12,6 +12,7 @@ details. */
 #include "tty.h"
 #include <cygwin/_socketflags.h>
 #include <cygwin/_ucred.h>
+#include <sys/un.h>
 
 /* fcntl flags used only internaly. */
 #define O_NOSYMLINK	0x080000
@@ -816,15 +817,31 @@ class fhandler_socket_local: public fhandler_socket_wsock
   }
 };
 
+struct sun_name_t
+{
+  __socklen_t un_len;
+  union
+    {
+      struct sockaddr_un un;
+      /* Allows 108 bytes sun_path plus trailing NUL */
+      char _nul[sizeof (struct sockaddr_un) + 1];
+    };
+};
+
 class fhandler_socket_unix : public fhandler_socket
 {
  protected:
-  char *sun_path;
-  char *peer_sun_path;
-  void set_sun_path (const char *path);
-  char *get_sun_path () {return sun_path;}
-  void set_peer_sun_path (const char *path);
-  char *get_peer_sun_path () {return peer_sun_path;}
+  sun_name_t *sun_path;
+  sun_name_t *peer_sun_path;
+  sun_name_t *get_sun_path () {return sun_path;}
+  sun_name_t *get_peer_sun_path () {return peer_sun_path;}
+  void set_sun_path (struct sockaddr_un *un, __socklen_t unlen);
+  void set_sun_path (sun_name_t *snt)
+    { snt ? set_sun_path (&snt->un, snt->un_len) : set_sun_path (NULL, 0); }
+  void set_peer_sun_path (struct sockaddr_un *un, __socklen_t unlen);
+  void set_peer_sun_path (sun_name_t *snt)
+    { snt ? set_peer_sun_path (&snt->un, snt->un_len)
+	  : set_peer_sun_path (NULL, 0); }
 
  protected:
   struct ucred peer_cred;
diff --git a/winsup/cygwin/fhandler_socket_unix.cc b/winsup/cygwin/fhandler_socket_unix.cc
index d912759..1d8c4c4 100644
--- a/winsup/cygwin/fhandler_socket_unix.cc
+++ b/winsup/cygwin/fhandler_socket_unix.cc
@@ -164,15 +164,28 @@ fhandler_socket_unix::~fhandler_socket_unix ()
 }
 
 void
-fhandler_socket_unix::set_sun_path (const char *path)
+fhandler_socket_unix::set_sun_path (struct sockaddr_un *un, socklen_t unlen)
 {
-  sun_path = path ? cstrdup (path) : NULL;
+  if (!un)
+    sun_path = NULL;
+  sun_path = (struct sun_name_t *) cmalloc_abort (HEAP_FHANDLER,
+						  sizeof *sun_path);
+  sun_path->un_len = unlen;
+  memcpy (&sun_path->un, un, sizeof (*un));
+  sun_path->_nul[sizeof (struct sockaddr_un)] = '\0';
 }
 
 void
-fhandler_socket_unix::set_peer_sun_path (const char *path)
+fhandler_socket_unix::set_peer_sun_path (struct sockaddr_un *un,
+					 socklen_t unlen)
 {
-  peer_sun_path = path ? cstrdup (path) : NULL;
+  if (!un)
+    peer_sun_path = NULL;
+  peer_sun_path = (struct sun_name_t *) cmalloc_abort (HEAP_FHANDLER,
+						       sizeof *peer_sun_path);
+  peer_sun_path->un_len = unlen;
+  memcpy (&peer_sun_path->un, un, sizeof (*un));
+  peer_sun_path->_nul[sizeof (struct sockaddr_un)] = '\0';
 }
 
 void
@@ -258,28 +271,34 @@ fhandler_socket_unix::connect (const struct sockaddr *name, int namelen)
 int
 fhandler_socket_unix::getsockname (struct sockaddr *name, int *namelen)
 {
-  struct sockaddr_un sun;
+  sun_name_t sun;
 
-  sun.sun_family = AF_UNIX;
-  sun.sun_path[0] = '\0';
   if (get_sun_path ())
-    strncat (sun.sun_path, get_sun_path (), UNIX_PATH_MAX - 1);
-  memcpy (name, &sun, MIN (*namelen, (int) SUN_LEN (&sun) + 1));
-  *namelen = (int) SUN_LEN (&sun) + (get_sun_path () ? 1 : 0);
+    memcpy (&sun, &get_sun_path ()->un, get_sun_path ()->un_len);
+  else
+    {
+      sun.un_len = sizeof (sa_family_t);
+      sun.un.sun_family = AF_UNIX;
+      sun.un.sun_path[0] = '\0';
+    }
+  memcpy (name, &sun, MIN (*namelen, sun.un_len));
   return 0;
 }
 
 int
 fhandler_socket_unix::getpeername (struct sockaddr *name, int *namelen)
 {
-  struct sockaddr_un sun;
-  memset (&sun, 0, sizeof sun);
-  sun.sun_family = AF_UNIX;
-  sun.sun_path[0] = '\0';
+  sun_name_t sun;
+
   if (get_peer_sun_path ())
-    strncat (sun.sun_path, get_peer_sun_path (), UNIX_PATH_MAX - 1);
-  memcpy (name, &sun, MIN (*namelen, (int) SUN_LEN (&sun) + 1));
-  *namelen = (int) SUN_LEN (&sun) + (get_peer_sun_path () ? 1 : 0);
+    memcpy (&sun, &get_peer_sun_path ()->un, get_peer_sun_path ()->un_len);
+  else
+    {
+      sun.un_len = sizeof (sa_family_t);
+      sun.un.sun_family = AF_UNIX;
+      sun.un.sun_path[0] = '\0';
+    }
+  memcpy (name, &sun, MIN (*namelen, sun.un_len));
   return 0;
 }
 
@@ -598,7 +617,9 @@ fhandler_socket_unix::fstat (struct stat *buf)
 {
   int ret = 0;
 
-  if (!get_sun_path () || get_sun_path ()[0] == '\0')
+  if (!get_sun_path ()
+      || get_sun_path ()->un_len <= (socklen_t) sizeof (sa_family_t)
+      || get_sun_path ()->un.sun_path[0] == '\0')
     return fhandler_socket::fstat (buf);
   ret = fhandler_base::fstat_fs (buf);
   if (!ret)
@@ -612,7 +633,9 @@ fhandler_socket_unix::fstat (struct stat *buf)
 int __reg2
 fhandler_socket_unix::fstatvfs (struct statvfs *sfs)
 {
-  if (!get_sun_path () || get_sun_path ()[0] == '\0')
+  if (!get_sun_path ()
+      || get_sun_path ()->un_len <= (socklen_t) sizeof (sa_family_t)
+      || get_sun_path ()->un.sun_path[0] == '\0')
     return fhandler_socket::fstatvfs (sfs);
   fhandler_disk_file fh (pc);
   fh.get_device () = FH_FS;
@@ -622,7 +645,9 @@ fhandler_socket_unix::fstatvfs (struct statvfs *sfs)
 int
 fhandler_socket_unix::fchmod (mode_t newmode)
 {
-  if (!get_sun_path () || get_sun_path ()[0] == '\0')
+  if (!get_sun_path ()
+      || get_sun_path ()->un_len <= (socklen_t) sizeof (sa_family_t)
+      || get_sun_path ()->un.sun_path[0] == '\0')
     return fhandler_socket::fchmod (newmode);
   fhandler_disk_file fh (pc);
   fh.get_device () = FH_FS;
@@ -639,7 +664,9 @@ fhandler_socket_unix::fchmod (mode_t newmode)
 int
 fhandler_socket_unix::fchown (uid_t uid, gid_t gid)
 {
-  if (!get_sun_path () || get_sun_path ()[0] == '\0')
+  if (!get_sun_path ()
+      || get_sun_path ()->un_len <= (socklen_t) sizeof (sa_family_t)
+      || get_sun_path ()->un.sun_path[0] == '\0')
     return fhandler_socket::fchown (uid, gid);
   fhandler_disk_file fh (pc);
   return fh.fchown (uid, gid);
@@ -648,7 +675,9 @@ fhandler_socket_unix::fchown (uid_t uid, gid_t gid)
 int
 fhandler_socket_unix::facl (int cmd, int nentries, aclent_t *aclbufp)
 {
-  if (!get_sun_path () || get_sun_path ()[0] == '\0')
+  if (!get_sun_path ()
+      || get_sun_path ()->un_len <= (socklen_t) sizeof (sa_family_t)
+      || get_sun_path ()->un.sun_path[0] == '\0')
     return fhandler_socket::facl (cmd, nentries, aclbufp);
   fhandler_disk_file fh (pc);
   return fh.facl (cmd, nentries, aclbufp);
@@ -657,7 +686,9 @@ fhandler_socket_unix::facl (int cmd, int nentries, aclent_t *aclbufp)
 int
 fhandler_socket_unix::link (const char *newpath)
 {
-  if (!get_sun_path () || get_sun_path ()[0] == '\0')
+  if (!get_sun_path ()
+      || get_sun_path ()->un_len <= (socklen_t) sizeof (sa_family_t)
+      || get_sun_path ()->un.sun_path[0] == '\0')
     return fhandler_socket::link (newpath);
   fhandler_disk_file fh (pc);
   return fh.link (newpath);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]