parent
85febc7ff7
commit
8e15cc337d
@ -0,0 +1,266 @@
|
|||||||
|
From 8412c867a501e3a68e55fef6215e86d3ac9f617b Mon Sep 17 00:00:00 2001
|
||||||
|
Message-Id: <8412c867a501e3a68e55fef6215e86d3ac9f617b.1398703637.git.luto@amacapital.net>
|
||||||
|
In-Reply-To: <3c5d5b344ee945b99e4bb16a44af6f293601813d.1398703637.git.luto@amacapital.net>
|
||||||
|
References: <3c5d5b344ee945b99e4bb16a44af6f293601813d.1398703637.git.luto@amacapital.net>
|
||||||
|
From: David Adam <zanchey@ucc.gu.uwa.edu.au>
|
||||||
|
Date: Sun, 20 Apr 2014 17:51:27 +0800
|
||||||
|
Subject: [PATCH 3/4] Check effective credentials of socket peers
|
||||||
|
|
||||||
|
Fix for CVE-2014-2905.
|
||||||
|
|
||||||
|
Code for getpeereid() on non-BSD systems imported from the PostgreSQL
|
||||||
|
project under a BSD-style license.
|
||||||
|
---
|
||||||
|
configure.ac | 4 +--
|
||||||
|
doc_src/license.hdr | 30 +++++++++++++++++++-
|
||||||
|
env_universal.cpp | 9 ++++++
|
||||||
|
fallback.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
fallback.h | 4 +++
|
||||||
|
fishd.cpp | 9 +++++-
|
||||||
|
osx/config.h | 6 ++++
|
||||||
|
7 files changed, 137 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index ea7c592..bdfa5f0 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -557,7 +557,7 @@ LIBS=$LIBS_COMMON
|
||||||
|
# Check presense of various header files
|
||||||
|
#
|
||||||
|
|
||||||
|
-AC_CHECK_HEADERS([getopt.h termios.h sys/resource.h term.h ncurses/term.h ncurses.h curses.h stropts.h siginfo.h sys/select.h sys/ioctl.h execinfo.h spawn.h sys/sysctl.h])
|
||||||
|
+AC_CHECK_HEADERS([getopt.h termios.h sys/resource.h term.h ncurses/term.h ncurses.h curses.h stropts.h siginfo.h sys/select.h sys/ioctl.h execinfo.h spawn.h sys/sysctl.h sys/un.h sys/ucred.h ucred.h ])
|
||||||
|
|
||||||
|
if test x$local_gettext != xno; then
|
||||||
|
AC_CHECK_HEADERS([libintl.h])
|
||||||
|
@@ -698,7 +698,7 @@ fi
|
||||||
|
AC_CHECK_FUNCS( wcsdup wcsndup wcslen wcscasecmp wcsncasecmp fwprintf )
|
||||||
|
AC_CHECK_FUNCS( futimes wcwidth wcswidth wcstok fputwc fgetwc )
|
||||||
|
AC_CHECK_FUNCS( wcstol wcslcat wcslcpy lrand48_r killpg )
|
||||||
|
-AC_CHECK_FUNCS( backtrace backtrace_symbols sysconf getifaddrs )
|
||||||
|
+AC_CHECK_FUNCS( backtrace backtrace_symbols sysconf getifaddrs getpeerucred getpeereid )
|
||||||
|
|
||||||
|
if test x$local_gettext != xno; then
|
||||||
|
AC_CHECK_FUNCS( gettext dcgettext )
|
||||||
|
diff --git a/doc_src/license.hdr b/doc_src/license.hdr
|
||||||
|
index 64bab10..f292722 100644
|
||||||
|
--- a/doc_src/license.hdr
|
||||||
|
+++ b/doc_src/license.hdr
|
||||||
|
@@ -1400,6 +1400,34 @@ POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
|
||||||
|
-*/
|
||||||
|
+<hr>
|
||||||
|
+
|
||||||
|
+<h2>License for getpeereid</h2>
|
||||||
|
+
|
||||||
|
+\c fish contains code imported from the PostgreSQL project under
|
||||||
|
+license, namely the getpeereid fallback function. This code is copyrighted
|
||||||
|
+by:
|
||||||
|
+
|
||||||
|
+Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
|
||||||
|
+
|
||||||
|
+Portions Copyright (c) 1994, The Regents of the University of California
|
||||||
|
+
|
||||||
|
+Permission to use, copy, modify, and distribute this software and its
|
||||||
|
+documentation for any purpose, without fee, and without a written agreement
|
||||||
|
+is hereby granted, provided that the above copyright notice and this
|
||||||
|
+paragraph and the following two paragraphs appear in all copies.
|
||||||
|
+
|
||||||
|
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
|
||||||
|
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
|
||||||
|
+LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
|
||||||
|
+DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
|
||||||
|
+POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
+
|
||||||
|
+THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
|
||||||
|
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
+AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||||
|
+ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
|
||||||
|
+PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
|
|
||||||
|
\htmlonly </div> \endhtmlonly
|
||||||
|
+*/
|
||||||
|
diff --git a/env_universal.cpp b/env_universal.cpp
|
||||||
|
index c7d060a..987f88b 100644
|
||||||
|
--- a/env_universal.cpp
|
||||||
|
+++ b/env_universal.cpp
|
||||||
|
@@ -88,6 +88,8 @@ static int try_get_socket_once(void)
|
||||||
|
|
||||||
|
wdir = path;
|
||||||
|
wuname = user;
|
||||||
|
+ uid_t seuid;
|
||||||
|
+ gid_t segid;
|
||||||
|
|
||||||
|
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
||||||
|
{
|
||||||
|
@@ -135,6 +137,13 @@ static int try_get_socket_once(void)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if ((getpeereid(s, &seuid, &segid) != 0) || seuid != geteuid())
|
||||||
|
+ {
|
||||||
|
+ debug(1, L"Wrong credentials for socket %s at fd %d", name.c_str(), s);
|
||||||
|
+ close(s);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if ((make_fd_nonblocking(s) != 0) || (fcntl(s, F_SETFD, FD_CLOEXEC) != 0))
|
||||||
|
{
|
||||||
|
wperror(L"fcntl");
|
||||||
|
diff --git a/fallback.cpp b/fallback.cpp
|
||||||
|
index 5e4b3e1..34db397 100644
|
||||||
|
--- a/fallback.cpp
|
||||||
|
+++ b/fallback.cpp
|
||||||
|
@@ -15,8 +15,9 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
+#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
-#include <unistd.h>
|
||||||
|
+#include <sys/param.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
@@ -1521,3 +1522,80 @@ static int mk_wcswidth(const wchar_t *pwcs, size_t n)
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HAVE_BROKEN_WCWIDTH
|
||||||
|
+
|
||||||
|
+#ifndef HAVE_GETPEEREID
|
||||||
|
+
|
||||||
|
+/*-------------------------------------------------------------------------
|
||||||
|
+ *
|
||||||
|
+ * getpeereid.c
|
||||||
|
+ * get peer userid for UNIX-domain socket connection
|
||||||
|
+ *
|
||||||
|
+ * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
|
||||||
|
+ *
|
||||||
|
+ *
|
||||||
|
+ * IDENTIFICATION
|
||||||
|
+ * src/port/getpeereid.c
|
||||||
|
+ *
|
||||||
|
+ *-------------------------------------------------------------------------
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifdef HAVE_SYS_UN_H
|
||||||
|
+#include <sys/un.h>
|
||||||
|
+#endif
|
||||||
|
+#ifdef HAVE_UCRED_H
|
||||||
|
+#include <ucred.h>
|
||||||
|
+#endif
|
||||||
|
+#ifdef HAVE_SYS_UCRED_H
|
||||||
|
+#include <sys/ucred.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * BSD-style getpeereid() for platforms that lack it.
|
||||||
|
+ */
|
||||||
|
+int getpeereid(int sock, uid_t *uid, gid_t *gid)
|
||||||
|
+{
|
||||||
|
+#if defined(SO_PEERCRED)
|
||||||
|
+ /* Linux: use getsockopt(SO_PEERCRED) */
|
||||||
|
+ struct ucred peercred;
|
||||||
|
+ socklen_t so_len = sizeof(peercred);
|
||||||
|
+
|
||||||
|
+ if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) != 0 ||
|
||||||
|
+ so_len != sizeof(peercred))
|
||||||
|
+ return -1;
|
||||||
|
+ *uid = peercred.uid;
|
||||||
|
+ *gid = peercred.gid;
|
||||||
|
+ return 0;
|
||||||
|
+#elif defined(LOCAL_PEERCRED)
|
||||||
|
+ /* Debian with FreeBSD kernel: use getsockopt(LOCAL_PEERCRED) */
|
||||||
|
+ struct xucred peercred;
|
||||||
|
+ socklen_t * so_len = sizeof(peercred);
|
||||||
|
+
|
||||||
|
+ if (getsockopt(sock, 0, LOCAL_PEERCRED, &peercred, &so_len) != 0 ||
|
||||||
|
+ so_len != sizeof(peercred) ||
|
||||||
|
+ peercred.cr_version != XUCRED_VERSION)
|
||||||
|
+ return -1;
|
||||||
|
+ *uid = peercred.cr_uid;
|
||||||
|
+ *gid = peercred.cr_gid;
|
||||||
|
+ return 0;
|
||||||
|
+#elif defined(HAVE_GETPEERUCRED)
|
||||||
|
+ /* Solaris: use getpeerucred() */
|
||||||
|
+ ucred_t *ucred;
|
||||||
|
+
|
||||||
|
+ ucred = NULL; /* must be initialized to NULL */
|
||||||
|
+ if (getpeerucred(sock, &ucred) == -1)
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ *uid = ucred_geteuid(ucred);
|
||||||
|
+ *gid = ucred_getegid(ucred);
|
||||||
|
+ ucred_free(ucred);
|
||||||
|
+
|
||||||
|
+ if (*uid == (uid_t) (-1) || *gid == (gid_t) (-1))
|
||||||
|
+ return -1;
|
||||||
|
+ return 0;
|
||||||
|
+#else
|
||||||
|
+ /* No implementation available on this platform */
|
||||||
|
+ errno = ENOSYS;
|
||||||
|
+ return -1;
|
||||||
|
+#endif
|
||||||
|
+}
|
||||||
|
+#endif // HAVE_GETPEEREID
|
||||||
|
diff --git a/fallback.h b/fallback.h
|
||||||
|
index eba91be..6898ea5 100644
|
||||||
|
--- a/fallback.h
|
||||||
|
+++ b/fallback.h
|
||||||
|
@@ -482,3 +482,7 @@ double nan(char *tagp);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
+
|
||||||
|
+#ifndef HAVE_GETPEEREID
|
||||||
|
+int getpeereid(int sock, uid_t *uid, gid_t *gid);
|
||||||
|
+#endif
|
||||||
|
diff --git a/fishd.cpp b/fishd.cpp
|
||||||
|
index edb79c2..1e09524 100644
|
||||||
|
--- a/fishd.cpp
|
||||||
|
+++ b/fishd.cpp
|
||||||
|
@@ -880,6 +880,8 @@ int main(int argc, char ** argv)
|
||||||
|
int child_socket;
|
||||||
|
struct sockaddr_un remote;
|
||||||
|
socklen_t t;
|
||||||
|
+ uid_t sock_euid;
|
||||||
|
+ gid_t sock_egid;
|
||||||
|
int max_fd;
|
||||||
|
int update_count=0;
|
||||||
|
|
||||||
|
@@ -1000,7 +1002,12 @@ int main(int argc, char ** argv)
|
||||||
|
{
|
||||||
|
debug(4, L"Connected with new child on fd %d", child_socket);
|
||||||
|
|
||||||
|
- if (make_fd_nonblocking(child_socket) != 0)
|
||||||
|
+ if (((getpeereid(child_socket, &sock_euid, &sock_egid) != 0) || sock_euid != geteuid()))
|
||||||
|
+ {
|
||||||
|
+ debug(1, L"Wrong credentials for child on fd %d", child_socket);
|
||||||
|
+ close(child_socket);
|
||||||
|
+ }
|
||||||
|
+ else if (make_fd_nonblocking(child_socket) != 0)
|
||||||
|
{
|
||||||
|
wperror(L"fcntl");
|
||||||
|
close(child_socket);
|
||||||
|
diff --git a/osx/config.h b/osx/config.h
|
||||||
|
index 4968a78..bc058ae 100644
|
||||||
|
--- a/osx/config.h
|
||||||
|
+++ b/osx/config.h
|
||||||
|
@@ -40,6 +40,12 @@
|
||||||
|
/* Define to 1 if you have the <getopt.h> header file. */
|
||||||
|
#define HAVE_GETOPT_H 1
|
||||||
|
|
||||||
|
+/* Define to 1 if you have the `getpeereid' function. */
|
||||||
|
+#define HAVE_GETPEEREID 1
|
||||||
|
+
|
||||||
|
+/* Define to 1 if you have the `getpeerucred' function. */
|
||||||
|
+/* #undef HAVE_GETPEERUCRED */
|
||||||
|
+
|
||||||
|
/* Define to 1 if you have the `gettext' function. */
|
||||||
|
/* #undef HAVE_GETTEXT */
|
||||||
|
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
@ -0,0 +1,70 @@
|
|||||||
|
From c0989dce2d882c94eb3183e7b94402ba53534abb Mon Sep 17 00:00:00 2001
|
||||||
|
Message-Id: <c0989dce2d882c94eb3183e7b94402ba53534abb.1398703637.git.luto@amacapital.net>
|
||||||
|
In-Reply-To: <3c5d5b344ee945b99e4bb16a44af6f293601813d.1398703637.git.luto@amacapital.net>
|
||||||
|
References: <3c5d5b344ee945b99e4bb16a44af6f293601813d.1398703637.git.luto@amacapital.net>
|
||||||
|
From: David Adam <zanchey@ucc.gu.uwa.edu.au>
|
||||||
|
Date: Sun, 20 Apr 2014 23:51:20 +0800
|
||||||
|
Subject: [PATCH 4/4] use mktemp(1) to generate temporary file names
|
||||||
|
|
||||||
|
Fix for CVE-2014-2906.
|
||||||
|
|
||||||
|
Closes a race condition in funced which would allow execution of
|
||||||
|
arbitrary code; closes a race condition in psub which would allow
|
||||||
|
alternation of the data stream.
|
||||||
|
|
||||||
|
Note that `psub -f` does not work (#1040); a fix should be committed
|
||||||
|
separately for ease of maintenance.
|
||||||
|
---
|
||||||
|
share/functions/funced.fish | 6 +-----
|
||||||
|
share/functions/psub.fish | 11 +++--------
|
||||||
|
2 files changed, 4 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/share/functions/funced.fish b/share/functions/funced.fish
|
||||||
|
index 3c2de06..ca2e277 100644
|
||||||
|
--- a/share/functions/funced.fish
|
||||||
|
+++ b/share/functions/funced.fish
|
||||||
|
@@ -81,11 +81,7 @@ function funced --description 'Edit function definition'
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
- set -q TMPDIR; or set -l TMPDIR /tmp
|
||||||
|
- set -l tmpname (printf "$TMPDIR/fish_funced_%d_%d.fish" %self (random))
|
||||||
|
- while test -f $tmpname
|
||||||
|
- set tmpname (printf "$TMPDIR/fish_funced_%d_%d.fish" %self (random))
|
||||||
|
- end
|
||||||
|
+ set tmpname (mktemp -t fish_funced.XXXXXXXXXX)
|
||||||
|
|
||||||
|
if functions -q -- $funcname
|
||||||
|
functions -- $funcname > $tmpname
|
||||||
|
diff --git a/share/functions/psub.fish b/share/functions/psub.fish
|
||||||
|
index 42e34c7..7877aa4 100644
|
||||||
|
--- a/share/functions/psub.fish
|
||||||
|
+++ b/share/functions/psub.fish
|
||||||
|
@@ -45,21 +45,16 @@ function psub --description "Read from stdin into a file and output the filename
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
- # Find unique file name for writing output to
|
||||||
|
- while true
|
||||||
|
- set filename /tmp/.psub.(echo %self).(random);
|
||||||
|
- if not test -e $filename
|
||||||
|
- break;
|
||||||
|
- end
|
||||||
|
- end
|
||||||
|
-
|
||||||
|
if test use_fifo = 1
|
||||||
|
# Write output to pipe. This needs to be done in the background so
|
||||||
|
# that the command substitution exits without needing to wait for
|
||||||
|
# all the commands to exit
|
||||||
|
+ set dir (mktemp -d /tmp/.psub.XXXXXXXXXX); or return
|
||||||
|
+ set filename $dir/psub.fifo
|
||||||
|
mkfifo $filename
|
||||||
|
cat >$filename &
|
||||||
|
else
|
||||||
|
+ set filename (mktemp /tmp/.psub.XXXXXXXXXX)
|
||||||
|
cat >$filename
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
1.9.0
|
||||||
|
|
Loading…
Reference in new issue