From 0912d4be59165f2a5b70b296c947fd76d9b7c3a0 Mon Sep 17 00:00:00 2001 From: Joseph Henry Date: Tue, 13 Oct 2015 17:05:11 -0400 Subject: [PATCH] Fixed socket protocol check logic in socket() --- ext/lwipopts.h | 2 +- netcon/NetconEthernetTap.cpp | 17 +++++++++++++---- netcon/intercept.c | 12 +++++++----- netcon/libintercept.so.1.0 | Bin 52552 -> 52304 bytes 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/ext/lwipopts.h b/ext/lwipopts.h index 4f867e71c..e7b78a8fc 100644 --- a/ext/lwipopts.h +++ b/ext/lwipopts.h @@ -130,7 +130,7 @@ * MEMP_NUM_RAW_PCB: Number of raw connection PCBs * (requires the LWIP_RAW option) */ -#define MEMP_NUM_RAW_PCB 1 +#define MEMP_NUM_RAW_PCB 128 /** * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One diff --git a/netcon/NetconEthernetTap.cpp b/netcon/NetconEthernetTap.cpp index 824f1734a..11c877cc0 100644 --- a/netcon/NetconEthernetTap.cpp +++ b/netcon/NetconEthernetTap.cpp @@ -520,8 +520,12 @@ err_t NetconEthernetTap::nc_accept(void *arg, struct tcp_pcb *newpcb, err_t err) if(conn) { ZT_PHY_SOCKFD_TYPE fds[2]; - socketpair(PF_LOCAL, SOCK_STREAM, 0, fds); - + if(socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) < 0) { + if(errno < 0) { + l->tap->send_return_value(conn, -1, errno); + return ERR_MEM; + } + } TcpConnection *new_tcp_conn = new TcpConnection(); new_tcp_conn->dataSock = tap->_phy.wrapSocket(fds[0], new_tcp_conn); new_tcp_conn->rpcSock = conn->rpcSock; @@ -916,7 +920,12 @@ void NetconEthernetTap::handle_socket(PhySocket *sock, void **uptr, struct socke struct tcp_pcb *newpcb = lwipstack->tcp_new(); if(newpcb != NULL) { ZT_PHY_SOCKFD_TYPE fds[2]; - socketpair(PF_LOCAL, SOCK_STREAM, 0, fds); + if(socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) < 0) { + if(errno < 0) { + send_return_value(_phy.getDescriptor(sock), -1, errno); + return; + } + } TcpConnection *new_conn = new TcpConnection(); new_conn->dataSock = _phy.wrapSocket(fds[0], new_conn); *uptr = new_conn; @@ -950,7 +959,7 @@ void NetconEthernetTap::handle_socket(PhySocket *sock, void **uptr, struct socke [i] EACCES - For UNIX domain sockets, which are identified by pathname: Write permission is denied ... [ ] EACCES, EPERM - The user tried to connect to a broadcast address without having the socket broadcast flag enabled ... [i] EADDRINUSE - Local address is already in use. - [i] EAFNOSUPPORT - The passed address didn't have the correct address family in its sa_family field. + [?] EAFNOSUPPORT - The passed address didn't have the correct address family in its sa_family field. [ ] EAGAIN - No more free local ports or insufficient entries in the routing cache. [ ] EALREADY - The socket is nonblocking and a previous connection attempt has not yet been completed. [ ] EBADF - The file descriptor is not a valid index in the descriptor table. diff --git a/netcon/intercept.c b/netcon/intercept.c index 41ad804c8..a2d6e31a4 100755 --- a/netcon/intercept.c +++ b/netcon/intercept.c @@ -515,15 +515,16 @@ void sock_domain_to_str(int domain) int socket(SOCKET_SIG) { #ifdef CHECKS + /* Check that type makes sense */ + int flags = socket_type & ~SOCK_TYPE_MASK; + if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) + return -EINVAL; + socket_type &= SOCK_TYPE_MASK; /* Check protocol is in range */ if (socket_family < 0 || socket_family >= NPROTO) return -EAFNOSUPPORT; if (socket_type < 0 || socket_type >= SOCK_MAX) return -EINVAL; - /* Check that type makes sense */ - int flags = socket_type & ~SOCK_TYPE_MASK; - if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) - return -EINVAL; #endif #ifdef DUMMY @@ -658,7 +659,8 @@ int connect(CONNECT_SIG) ---------------------------------- select() ------------------------------------ ------------------------------------------------------------------------------*/ -/* int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout */ +/* int n, fd_set *readfds, fd_set *writefds, +fd_set *exceptfds, struct timeval *timeout */ int select(SELECT_SIG) { #ifdef DUMMY diff --git a/netcon/libintercept.so.1.0 b/netcon/libintercept.so.1.0 index 221d24287c13813e7f2a8e5d05e15f71769a409c..d0b5ffda6929f9ef6626eeed7524ea566dee7051 100755 GIT binary patch delta 12709 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%0A&qMEW0Lvz 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