aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobbie Harwood <rharwood@redhat.com>2018-10-12 16:57:05 -0400
committerGreg Hudson <ghudson@mit.edu>2018-10-17 15:00:16 -0400
commit98bf22027bd6e746f456a671ca5e257ca4bd371e (patch)
tree5ea83ba1286c8f251e5b5ceb3eb941e705f10a9b
parent762d804701f78fc76f728ec05a205eea6a2b2dd7 (diff)
downloadkrb5-98bf22027bd6e746f456a671ca5e257ca4bd371e.zip
krb5-98bf22027bd6e746f456a671ca5e257ca4bd371e.tar.gz
krb5-98bf22027bd6e746f456a671ca5e257ca4bd371e.tar.bz2
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)
-rw-r--r--src/include/port-sockets.h43
1 files changed, 40 insertions, 3 deletions
diff --git a/src/include/port-sockets.h b/src/include/port-sockets.h
index f0fc2b8..57e5d1d 100644
--- a/src/include/port-sockets.h
+++ b/src/include/port-sockets.h
@@ -159,6 +159,7 @@ typedef int socklen_t;
#include <netinet/in.h> /* For struct sockaddr_in and in_addr */
#include <arpa/inet.h> /* For inet_ntoa */
#include <netdb.h>
+#include <string.h> /* For memset */
#ifndef HAVE_NETDB_H_H_ERRNO
extern int h_errno; /* In case it's missing, e.g., HP-UX 10.20. */
@@ -219,15 +220,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