This is the mail archive of the
cygwin-cvs@cygwin.com
mailing list for the Cygwin project.
[newlib-cygwin] Cygwin: improve storage and handling of AF_UNIX socket path
- From: Corinna Vinschen <corinna at sourceware dot org>
- To: cygwin-cvs at sourceware dot org
- Date: 1 Mar 2018 17:31:13 -0000
- Subject: [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);