From d760ebeab2fa146bd3a6ea581efc0834a1920a50 Mon Sep 17 00:00:00 2001 From: Robbie Harwood Date: Wed, 17 Oct 2018 15:27:45 -0400 Subject: [PATCH] Use port-sockets.h macros in cc_kcm, sendto_kdc Resolves: #1631998 --- ...IPE-from-socket-writes-on-UNIX-likes.patch | 86 +++++++++++ ...ockets.h-macros-in-cc_kcm-sendto_kdc.patch | 138 ++++++++++++++++++ krb5.spec | 8 +- 3 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 Prevent-SIGPIPE-from-socket-writes-on-UNIX-likes.patch create mode 100644 Use-port-sockets.h-macros-in-cc_kcm-sendto_kdc.patch diff --git a/Prevent-SIGPIPE-from-socket-writes-on-UNIX-likes.patch b/Prevent-SIGPIPE-from-socket-writes-on-UNIX-likes.patch new file mode 100644 index 0000000..d8238ba --- /dev/null +++ b/Prevent-SIGPIPE-from-socket-writes-on-UNIX-likes.patch @@ -0,0 +1,86 @@ +From 23e01e9a966ee0aa08668a75f5753a55e1ea4547 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 12 Oct 2018 16:57:05 -0400 +Subject: [PATCH] Prevent SIGPIPE from socket writes on UNIX-likes + +When writing to a disconnected socket, try to only get EPIPE rather +than taking down the process with SIGPIPE. + +On recent Linux and other systems which have it, switch from writev to +sendmsg and pass MSG_NOSIGNAL. + +On BSD-likes, set SO_NOSIGPIPE at connect time. + +ticket: 8753 (new) +(cherry picked from commit 98bf22027bd6e746f456a671ca5e257ca4bd371e) +--- + src/include/port-sockets.h | 43 +++++++++++++++++++++++++++++++++++--- + 1 file changed, 40 insertions(+), 3 deletions(-) + +diff --git a/src/include/port-sockets.h b/src/include/port-sockets.h +index b3ab9c906..3b05e022d 100644 +--- a/src/include/port-sockets.h ++++ b/src/include/port-sockets.h +@@ -158,6 +158,7 @@ typedef int socklen_t; + #include /* For struct sockaddr_in and in_addr */ + #include /* For inet_ntoa */ + #include ++#include /* For memset */ + + #ifndef HAVE_NETDB_H_H_ERRNO + extern int h_errno; /* In case it's missing, e.g., HP-UX 10.20. */ +@@ -218,15 +219,51 @@ typedef struct iovec sg_buf; + #define SOCKET_NFDS(f) ((f)+1) /* select() arg for a single fd */ + #define SOCKET_READ read + #define SOCKET_WRITE write +-#define SOCKET_CONNECT connect ++static inline int ++socket_connect(int fd, const struct sockaddr *addr, socklen_t addrlen) ++{ ++ int st; ++#ifdef SO_NOSIGPIPE ++ int set = 1; ++#endif ++ ++ st = connect(fd, addr, addrlen); ++ if (st == -1) ++ return st; ++ ++#ifdef SO_NOSIGPIPE ++ st = setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &set, sizeof(set)); ++ if (st != 0) ++ st = -1; ++#endif ++ ++ return st; ++} ++#define SOCKET_CONNECT socket_connect + #define SOCKET_GETSOCKNAME getsockname + #define SOCKET_CLOSE close + #define SOCKET_EINTR EINTR + #define SOCKET_WRITEV_TEMP int ++static inline ssize_t ++socket_sendmsg(SOCKET fd, sg_buf *iov, int iovcnt) ++{ ++ struct msghdr msg; ++ int flags = 0; ++ ++#ifdef MSG_NOSIGNAL ++ flags |= MSG_NOSIGNAL; ++#endif ++ ++ memset(&msg, 0, sizeof(msg)); ++ msg.msg_iov = iov; ++ msg.msg_iovlen = iovcnt; ++ ++ return sendmsg(fd, &msg, flags); ++} + /* Use TMP to avoid compiler warnings and keep things consistent with + * Windows version. */ +-#define SOCKET_WRITEV(FD, SG, LEN, TMP) \ +- ((TMP) = writev((FD), (SG), (LEN)), (TMP)) ++#define SOCKET_WRITEV(FD, SG, LEN, TMP) \ ++ ((TMP) = socket_sendmsg((FD), (SG), (LEN)), (TMP)) + + #define SHUTDOWN_READ 0 + #define SHUTDOWN_WRITE 1 diff --git a/Use-port-sockets.h-macros-in-cc_kcm-sendto_kdc.patch b/Use-port-sockets.h-macros-in-cc_kcm-sendto_kdc.patch new file mode 100644 index 0000000..56b83c3 --- /dev/null +++ b/Use-port-sockets.h-macros-in-cc_kcm-sendto_kdc.patch @@ -0,0 +1,138 @@ +From 76fc514d3d00b8ac9f7844ade35c08eaa7c8a1fc Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Mon, 15 Oct 2018 19:12:45 -0400 +Subject: [PATCH] Use port-sockets.h macros in cc_kcm, sendto_kdc + +Use SOCKET_CONNECT in cc_kcm.c and sendto_kdc.c to prevent SIGPIPE on +BSD-like systems. Use other port-sockets.h macros in cc_kcm.c in case +it is ever used on Windows. + +ticket: 8753 +(cherry picked from commit 2aaf0e74805e295358627ac1e5d589d625d8e6b0) +--- + src/lib/krb5/ccache/cc_kcm.c | 34 ++++++++++++++++++---------------- + src/lib/krb5/os/sendto_kdc.c | 3 ++- + 2 files changed, 20 insertions(+), 17 deletions(-) + +diff --git a/src/lib/krb5/ccache/cc_kcm.c b/src/lib/krb5/ccache/cc_kcm.c +index a777f2710..b260cd81b 100644 +--- a/src/lib/krb5/ccache/cc_kcm.c ++++ b/src/lib/krb5/ccache/cc_kcm.c +@@ -42,6 +42,7 @@ + #include "k5-input.h" + #include "cc-int.h" + #include "kcm.h" ++#include "../os/os-proto.h" + #include + #include + #ifdef __APPLE__ +@@ -61,7 +62,7 @@ struct uuid_list { + }; + + struct kcmio { +- int fd; ++ SOCKET fd; + #ifdef __APPLE__ + mach_port_t mport; + #endif +@@ -252,7 +253,7 @@ static krb5_error_code + kcmio_unix_socket_connect(krb5_context context, struct kcmio *io) + { + krb5_error_code ret; +- int fd = -1; ++ SOCKET fd = INVALID_SOCKET; + struct sockaddr_un addr; + char *path = NULL; + +@@ -267,25 +268,25 @@ kcmio_unix_socket_connect(krb5_context context, struct kcmio *io) + } + + fd = socket(AF_UNIX, SOCK_STREAM, 0); +- if (fd == -1) { +- ret = errno; ++ if (fd == INVALID_SOCKET) { ++ ret = SOCKET_ERRNO; + goto cleanup; + } + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strlcpy(addr.sun_path, path, sizeof(addr.sun_path)); +- if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) { +- ret = (errno == ENOENT) ? KRB5_KCM_NO_SERVER : errno; ++ if (SOCKET_CONNECT(fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) { ++ ret = (SOCKET_ERRNO == ENOENT) ? KRB5_KCM_NO_SERVER : SOCKET_ERRNO; + goto cleanup; + } + + io->fd = fd; +- fd = -1; ++ fd = INVALID_SOCKET; + + cleanup: +- if (fd != -1) +- close(fd); ++ if (fd != INVALID_SOCKET) ++ closesocket(fd); + profile_release_string(path); + return ret; + } +@@ -297,11 +298,12 @@ kcmio_unix_socket_write(krb5_context context, struct kcmio *io, void *request, + size_t len) + { + char lenbytes[4]; ++ sg_buf sg[2]; + ++ SG_SET(&sg[0], lenbytes, sizeof(lenbytes)); ++ SG_SET(&sg[1], request, len); + store_32_be(len, lenbytes); +- if (krb5_net_write(context, io->fd, lenbytes, 4) < 0) +- return errno; +- if (krb5_net_write(context, io->fd, request, len) < 0) ++ if (krb5int_net_writev(context, io->fd, sg, 2) < 0) + return errno; + return 0; + } +@@ -358,7 +360,7 @@ kcmio_connect(krb5_context context, struct kcmio **io_out) + io = calloc(1, sizeof(*io)); + if (io == NULL) + return ENOMEM; +- io->fd = -1; ++ io->fd = INVALID_SOCKET; + + /* Try Mach RPC (macOS only), then fall back to Unix domain sockets */ + ret = kcmio_mach_connect(context, io); +@@ -384,7 +386,7 @@ kcmio_call(krb5_context context, struct kcmio *io, struct kcmreq *req) + if (k5_buf_status(&req->reqbuf) != 0) + return ENOMEM; + +- if (io->fd != -1) { ++ if (io->fd != INVALID_SOCKET) { + ret = kcmio_unix_socket_write(context, io, req->reqbuf.data, + req->reqbuf.len); + if (ret) +@@ -411,8 +413,8 @@ kcmio_close(struct kcmio *io) + { + if (io != NULL) { + kcmio_mach_close(io); +- if (io->fd != -1) +- close(io->fd); ++ if (io->fd != INVALID_SOCKET) ++ closesocket(io->fd); + free(io); + } + } +diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c +index e8bc0ad6e..0ed6b1d70 100644 +--- a/src/lib/krb5/os/sendto_kdc.c ++++ b/src/lib/krb5/os/sendto_kdc.c +@@ -880,7 +880,8 @@ start_connection(krb5_context context, struct conn_state *state, + } + + /* Start connecting to KDC. */ +- e = connect(fd, (struct sockaddr *)&state->addr.saddr, state->addr.len); ++ e = SOCKET_CONNECT(fd, (struct sockaddr *)&state->addr.saddr, ++ state->addr.len); + if (e != 0) { + /* + * This is the path that should be followed for non-blocking diff --git a/krb5.spec b/krb5.spec index 4aea62d..abfc7fd 100644 --- a/krb5.spec +++ b/krb5.spec @@ -18,7 +18,7 @@ Summary: The Kerberos network authentication system Name: krb5 Version: 1.16.1 # for prerelease, should be e.g., 0.% {prerelease}.1% { ?dist } (without spaces) -Release: 23%{?dist} +Release: 24%{?dist} # lookaside-cached sources; two downloads and a build artifact Source0: https://web.mit.edu/kerberos/dist/krb5/1.16/krb5-%{version}%{prerelease}.tar.gz @@ -105,6 +105,8 @@ Patch85: Fix-k5test-prompts-for-Python-3.patch Patch86: In-FIPS-mode-add-plaintext-fallback-for-RC4-usages-a.patch Patch87: Prefer-TCP-to-UDP-for-password-changes.patch Patch88: Correct-kpasswd_server-description-in-krb5.conf-5.patch +Patch89: Prevent-SIGPIPE-from-socket-writes-on-UNIX-likes.patch +Patch90: Use-port-sockets.h-macros-in-cc_kcm-sendto_kdc.patch License: MIT URL: http://web.mit.edu/kerberos/www/ @@ -751,6 +753,10 @@ exit 0 %{_libdir}/libkadm5srv_mit.so.* %changelog +* Wed Oct 17 2018 Robbie Harwood - 1.16.1-24 +- Use port-sockets.h macros in cc_kcm, sendto_kdc +- Resolves: #1631998 + * Wed Oct 17 2018 Robbie Harwood - 1.16.1-23 - Correct kpasswd_server description in krb5.conf(5) - Resolves: #1640272