bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Unix domain socket filename redirection (patch update)


From: Zartaj Majeed
Subject: Re: [PATCH] Unix domain socket filename redirection (patch update)
Date: Wed, 21 Jun 2017 08:53:39 -0400

This update to the patch adds the following:

1. Check socket file path length less than sizeof sun_path array in
struct sockaddr_un
2. Allow relative socket file paths starting with "./" or "../". This
means the pseudo filename
opened in bash is of the form "/dev/unixstream/./xyz.sock" or
"/dev/unixdgram/../xyz.sock"


diff --git a/Makefile.in b/Makefile.in
index c7b62bc0..542cede8 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -222,7 +222,7 @@ SHLIB_SOURCE = ${SH_LIBSRC}/clktck.c ${SH_LIBSRC}/getcwd.c \
  ${SH_LIBSRC}/input_avail.c ${SH_LIBSRC}/mbscasecmp.c \
  ${SH_LIBSRC}/fnxform.c ${SH_LIBSRC}/unicode.c \
  ${SH_LIBSRC}/wcswidth.c ${SH_LIBSRC}/wcsnwidth.c \
- ${SH_LIBSRC}/shmbchar.c
+ ${SH_LIBSRC}/shmbchar.c ${SH_LIBSRC}/usockopen.c

 SHLIB_LIB = -lsh
 SHLIB_LIBNAME = libsh.a
diff --git a/config.h.in b/config.h.in
index a5ad9e72..36e8f5dd 100644
--- a/config.h.in
+++ b/config.h.in
@@ -151,6 +151,10 @@
    socket connections when used in redirections */
 #undef NETWORK_REDIRECTIONS

+/* Define UNIXSOCK_REDIRECTIONS if you want
/dev/(unixstream|unixdgram)/path to open
+   socket connections when used in redirections */
+#undef UNIXSOCK_REDIRECTIONS
+
 /* Define PROGRAMMABLE_COMPLETION for the programmable completion features
    and the complete builtin. */
 #undef PROGRAMMABLE_COMPLETION
@@ -1042,6 +1046,9 @@
 /* Define if you have the <sys/socket.h> header file.  */
 #undef HAVE_SYS_SOCKET_H

+/* Define if you have the <sys/un.h> header file.  */
+#undef HAVE_SYS_UN_H
+
 /* Define if you have the <sys/stat.h> header file. */
 #undef HAVE_SYS_STAT_H

diff --git a/configure.ac b/configure.ac
index ce4e9b60..a8e9f43c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -168,6 +168,7 @@ opt_cond_regexp=yes
 opt_coproc=yes
 opt_arith_for_command=yes
 opt_net_redirs=yes
+opt_usock_redirs=yes
 opt_progcomp=yes
 opt_separate_help=no
 opt_multibyte=yes
@@ -196,7 +197,7 @@ if test $opt_minimal_config = yes; then
  opt_select=no opt_help=no opt_array_variables=no opt_dparen_arith=no
  opt_brace_expansion=no opt_disabled_builtins=no opt_command_timing=no
  opt_extended_glob=no opt_cond_command=no opt_arith_for_command=no
- opt_net_redirs=no opt_progcomp=no opt_separate_help=no
+ opt_net_redirs=no opt_usock_redirs=no opt_progcomp=no opt_separate_help=no
  opt_multibyte=yes opt_cond_regexp=no opt_coproc=no
  opt_casemod_attrs=no opt_casemod_expansions=no opt_extglob_default=no
  opt_globascii_default=no
@@ -227,6 +228,7 @@ AC_ARG_ENABLE(history,
AC_HELP_STRING([--enable-history], [turn on command histo
 AC_ARG_ENABLE(job-control, AC_HELP_STRING([--enable-job-control],
[enable job control features]), opt_job_control=$enableval)
 AC_ARG_ENABLE(multibyte, AC_HELP_STRING([--enable-multibyte], [enable
multibyte characters if OS supports them]), opt_multibyte=$enableval)
 AC_ARG_ENABLE(net-redirections,
AC_HELP_STRING([--enable-net-redirections], [enable /dev/tcp/host/port
redirection]), opt_net_redirs=$enableval)
+AC_ARG_ENABLE(usock-redirections,
AC_HELP_STRING([--enable-usock-redirections], [enable
/dev/unixstream/path redirection]), opt_usock_redirs=$enableval)
 AC_ARG_ENABLE(process-substitution,
AC_HELP_STRING([--enable-process-substitution], [enable process
substitution]), opt_process_subst=$enableval)
 AC_ARG_ENABLE(progcomp, AC_HELP_STRING([--enable-progcomp], [enable
programmable completion and the complete builtin]),
opt_progcomp=$enableval)
 AC_ARG_ENABLE(prompt-string-decoding,
AC_HELP_STRING([--enable-prompt-string-decoding], [turn on escape
character decoding in prompts]), opt_prompt_decoding=$enableval)
@@ -321,6 +323,9 @@ fi
 if test $opt_net_redirs = yes; then
 AC_DEFINE(NETWORK_REDIRECTIONS)
 fi
+if test $opt_usock_redirs = yes; then
+AC_DEFINE(UNIXSOCK_REDIRECTIONS)
+fi
 if test $opt_progcomp = yes; then
 AC_DEFINE(PROGRAMMABLE_COMPLETION)
 fi
@@ -702,7 +707,7 @@ AC_CHECK_HEADERS(unistd.h stdlib.h stdarg.h
varargs.h limits.h string.h \
  stdbool.h stddef.h stdint.h netdb.h pwd.h grp.h strings.h \
  regex.h syslog.h ulimit.h)
 AC_CHECK_HEADERS(sys/pte.h sys/stream.h sys/select.h sys/file.h sys/ioctl.h \
- sys/param.h sys/socket.h sys/stat.h \
+ sys/param.h sys/socket.h sys/un.h sys/stat.h \
  sys/time.h sys/times.h sys/types.h sys/wait.h)
 AC_CHECK_HEADERS(netinet/in.h arpa/inet.h)

diff --git a/externs.h b/externs.h
index fa0603d3..1315866c 100644
--- a/externs.h
+++ b/externs.h
@@ -270,6 +270,9 @@ extern int isnetconn __P((int));
 /* declarations for functions defined in lib/sh/netopen.c */
 extern int netopen __P((char *));

+/* declarations for functions defined in lib/sh/usockopen.c */
+extern int usockopen __P((char *));
+
 /* Declarations for  functions defined in lib/sh/oslib.c */

 #if !defined (HAVE_DUP2) || defined (DUP2_BROKEN)
diff --git a/lib/sh/Makefile.in b/lib/sh/Makefile.in
index 2ca921b3..3d357997 100644
--- a/lib/sh/Makefile.in
+++ b/lib/sh/Makefile.in
@@ -84,7 +84,7 @@ LIBRARY_NAME = libsh.a
 CSOURCES = clktck.c clock.c getcwd.c getenv.c oslib.c setlinebuf.c \
    strcasecmp.c strerror.c strtod.c strtol.c strtoul.c \
    vprint.c itos.c rename.c zread.c zwrite.c shtty.c \
-   inet_aton.c netconn.c netopen.c strpbrk.c timeval.c makepath.c \
+   inet_aton.c netconn.c netopen.c usockopen.c strpbrk.c timeval.c makepath.c \
    pathcanon.c pathphys.c tmpfile.c stringlist.c stringvec.c spell.c \
    shquote.c strtrans.c strcasestr.c snprintf.c mailstat.c \
    fmtulong.c fmtullong.c fmtumax.c shmatch.c strnlen.c \
@@ -101,7 +101,7 @@ HSOURCES =
 LIBOBJS = @LIBOBJS@
 OBJECTS = clktck.o clock.o getenv.o oslib.o setlinebuf.o strnlen.o \
   itos.o zread.o zwrite.o shtty.o shmatch.o eaccess.o \
-  netconn.o netopen.o timeval.o makepath.o pathcanon.o \
+  netconn.o netopen.o usockopen.o timeval.o makepath.o pathcanon.o \
   pathphys.o tmpfile.o stringlist.o stringvec.o spell.o shquote.o \
   strtrans.o snprintf.o mailstat.o fmtulong.o \
   fmtullong.o fmtumax.o zcatfd.o zmapfd.o winsize.o wcsdup.o \
@@ -166,6 +166,7 @@ memset.o: memset.c
 mktime.o: mktime.c
 netconn.o: netconn.c
 netopen.o: netopen.c
+usockopen.o: usockopen.c
 oslib.o: oslib.c
 pathcanon.o: pathcanon.c
 pathphys.o: pathphys.c
@@ -243,6 +244,7 @@ memset.o: ${BUILD_DIR}/config.h
 mktime.o: ${BUILD_DIR}/config.h
 netconn.o: ${BUILD_DIR}/config.h
 netopen.o: ${BUILD_DIR}/config.h
+usockopen.o: ${BUILD_DIR}/config.h
 oslib.o: ${BUILD_DIR}/config.h
 pathcanon.o: ${BUILD_DIR}/config.h
 pathphys.o: ${BUILD_DIR}/config.h
@@ -341,6 +343,8 @@ netopen.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h
 netopen.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
 #netopen.o: ${BUILD_DIR}/version.h

+usockopen.o: ${topdir}/bashansi.h ${topdir}/bashintl.h
+
 oslib.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h
 oslib.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h
${BASHINCDIR}/posixjmp.h
 oslib.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h
diff --git a/lib/sh/usockopen.c b/lib/sh/usockopen.c
new file mode 100644
index 00000000..56b164fb
--- /dev/null
+++ b/lib/sh/usockopen.c
@@ -0,0 +1,117 @@
+/*
+ * usockopen.c -- functions to make unix domain socket connections
+ *
+ * Zartaj T. Majeed
+ */
+
+/* Copyright (C) 1987-2017 Free Software Foundation, Inc.
+
+   This file is part of GNU Bash, the Bourne Again SHell.
+
+   Bash is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   Bash is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with Bash.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <config.h>
+
+#if defined (HAVE_UNISTD_H)
+#  include <unistd.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#if defined (HAVE_SYS_SOCKET_H)
+#  include <sys/socket.h>
+#endif
+
+#if defined (HAVE_SYS_UN_H)
+#  include <sys/un.h>
+#endif
+
+#include <bashansi.h>
+#include <bashintl.h>
+
+#include <errno.h>
+
+#ifndef errno
+extern int errno;
+#endif
+
+static int _usockopen __P((char *, int));
+
+/*
+ * Open Unix domain socket connection
+ * Returns the connected socket or -1 on error.
+ */
+static int
+_usockopen (path, typ)
+     char *path;
+     int typ;
+{
+  int s, e;
+  struct sockaddr_un addr;
+  int socktyp = typ == 's'? SOCK_STREAM: SOCK_DGRAM;
+  size_t len = strlen(path);
+
+  if (len >= sizeof addr.sun_path)
+    {
+      internal_error ("path too long \"%s\"", path);
+      errno = EINVAL;
+      return -1;
+    }
+
+  if ((s = socket (AF_UNIX, socktyp, 0)) < 0)
+    {
+      sys_error ("unix socket");
+      return -1;
+    }
+
+  memset (&addr, 0, sizeof addr);
+  addr.sun_family = AF_UNIX;
+  strncpy (addr.sun_path, path, sizeof(addr.sun_path) - 1);
+
+  if (connect (s, &addr, sizeof addr) < 0)
+    {
+      e = errno;
+      sys_error ("unix connect");
+      close (s);
+      errno = e;
+      return -1;
+    }
+  return s;
+}
+
+/*
+ * Open Unix domain socket connection to a path like
/dev/unixstream/tmp/xyz.sock or /dev/unixdgram/tmp/xyz.sock
+ * Returns the connected socket or -1 on error.
+ */
+int
+usockopen (path)
+     char *path;
+{
+  char *s;
+  int fd;
+
+  s = strchr (path+9, '/');
+  /* relative path starts with '"./" or "../" */
+  if (s[1] == '.' && s[2] == '/' ||
+      s[1] == '.' && s[2] == '.' && s[3] == '/')
+    {
+      ++s;
+    }
+  fd = _usockopen (s, path[9]);
+
+  return fd;
+}
+
diff --git a/redir.c b/redir.c
index 25488eaf..e026cc12 100644
--- a/redir.c
+++ b/redir.c
@@ -519,6 +519,8 @@ here_document_to_fd (redirectee, ri)
 #define RF_DEVSTDOUT 4
 #define RF_DEVTCP 5
 #define RF_DEVUDP 6
+#define RF_DEVUSTRM 7
+#define RF_DEVUDGRM 8

 /* A list of pattern/value pairs for filenames that the redirection
    code handles specially. */
@@ -535,6 +537,10 @@ static STRING_INT_ALIST _redir_special_filenames[] = {
   { "/dev/tcp/*/*", RF_DEVTCP },
   { "/dev/udp/*/*", RF_DEVUDP },
 #endif
+#if defined (UNIXSOCK_REDIRECTIONS)
+  { "/dev/unixstream/*", RF_DEVUSTRM },
+  { "/dev/unixdgram/*", RF_DEVUDGRM },
+#endif
   { (char *)NULL, -1 }
 };

@@ -588,6 +594,12 @@ redir_special_open (spec, filename, flags, mode, ri)
 #endif
       break;
 #endif /* NETWORK_REDIRECTIONS */
+
+#if defined (UNIXSOCK_REDIRECTIONS)
+    case RF_DEVUSTRM:
+    case RF_DEVUDGRM:
+      fd = usockopen (filename);
+#endif /* UNIXSOCK_REDIRECTIONS */
     }

   return fd;
diff --git a/tests/misc/devunix.tests b/tests/misc/devunix.tests
new file mode 100644
index 00000000..457a40f0
--- /dev/null
+++ b/tests/misc/devunix.tests
@@ -0,0 +1,18 @@
+sock=/tmp/devunixtest.sock
+out=/tmp/devunixtest.out
+s=abcd.$$
+
+nc -U -l $sock >$out&
+sleep 1
+exec 9>/dev/unixstream$sock
+
+echo "$s" >&9
+exec 9>&-
+
+read t <$out
+
+if [[ $s != $t ]]; then
+  echo "out \"$s\" in \"$t\""
+fi
+
+rm $sock $out



reply via email to

[Prev in Thread] Current Thread [Next in Thread]