Fixed possible undefined behaviour when UDP RX buffer fills

This commit is contained in:
Joseph Henry
2016-08-31 15:54:56 -07:00
parent 33d3e72261
commit bf9bc511b0
5 changed files with 20 additions and 17 deletions

View File

@@ -21,6 +21,7 @@ endif
INCLUDES?=
DEFS?=
LDLIBS?=
CFLAGS=
include objects.mk
@@ -110,7 +111,7 @@ one: $(OBJS) $(ZT1)/service/OneService.o $(ZT1)/one.o $(ZT1)/osdep/LinuxEthernet
# Build only the intercept library
linux_intercept:
# Use gcc not clang to build standalone intercept library since gcc is typically used for libc and we want to ensure maximal ABI compatibility
cd src ; gcc $(DEFS) -O2 -Wall -std=c99 -fPIC -DVERBOSE -D_GNU_SOURCE -DSDK_INTERCEPT -I. -I../$(ZT1)/node -nostdlib -shared -o ../$(INTERCEPT) SDK_Sockets.c SDK_Intercept.c SDK_Debug.c SDK_RPC.c -ldl
cd src ; gcc $(CFLAGS) $(DEFS) -O2 -Wall -std=c99 -fPIC -DVERBOSE -D_GNU_SOURCE -DSDK_INTERCEPT -I. -I../$(ZT1)/node -nostdlib -shared -o ../$(INTERCEPT) SDK_Sockets.c SDK_Intercept.c SDK_Debug.c SDK_RPC.c -ldl
# Build only the SDK service
linux_sdk_service: lwip $(OBJS)

View File

@@ -18,6 +18,7 @@ INCLUDES=
DEFS=
LIBS=
ARCH_FLAGS=-arch x86_64
CFLAGS=
include objects.mk
@@ -136,7 +137,7 @@ osx_shared_lib: remove_only_intermediates $(OBJS)
osx_intercept:
# Use gcc not clang to build standalone intercept library since gcc is typically used for libc and we want to ensure maximal ABI compatibility
cd src ; gcc $(DEFS) -O2 -Wall -std=c99 -fPIC -fno-common -dynamiclib -flat_namespace -DVERBOSE -D_GNU_SOURCE -DNETCON_INTERCEPT -I. -I../zerotierone/node -nostdlib -shared -o ../$(INTERCEPT) SDK_Sockets.c SDK_Intercept.c SDK_Debug.c SDK_RPC.c -ldl
cd src ; gcc $(CFLAGS) $(DEFS) -O2 -Wall -std=c99 -fPIC -fno-common -dynamiclib -flat_namespace -DVERBOSE -D_GNU_SOURCE -DNETCON_INTERCEPT -I. -I../zerotierone/node -nostdlib -shared -o ../$(INTERCEPT) SDK_Sockets.c SDK_Intercept.c SDK_Debug.c SDK_RPC.c -ldl
#mv src/$(INTERCEPT_NAME) $(INTERCEPT)
# Build only the SDK service

View File

@@ -119,16 +119,16 @@ NetconEthernetTap::NetconEthernetTap(
const char *friendlyName,
void (*handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int),
void *arg) :
_nwid(nwid),
_handler(handler),
_arg(arg),
_phy(this,false,true),
_unixListenSocket((PhySocket *)0),
_mac(mac),
_homePath(homePath),
_mtu(mtu),
_enabled(true),
_run(true)
_homePath(homePath),
_mac(mac),
_mtu(mtu),
_nwid(nwid),
_handler(handler),
_arg(arg),
_phy(this,false,true),
_unixListenSocket((PhySocket *)0),
_enabled(true),
_run(true)
{
sockstate = -1;
char sockPath[4096],lwipPath[4096];
@@ -763,11 +763,12 @@ void NetconEthernetTap::nc_udp_recved(void * arg, struct udp_pcb * upcb, struct
// Cycle through pbufs and write them to the RX buffer
// The RX "buffer" will be emptied via phyOnUnixWritable()
if(p) {
// Intra-API "packetization" structure: [addr_len|addr|payload_len|payload]
// Intra-API "packetization" scheme: [addr_len|addr|payload_len|payload]
if(l->conn->rxsz == DEFAULT_UDP_RX_BUF_SZ) { // if UDP buffer full
dwr(MSG_DEBUG, "nc_udp_recved(): UDP RX buffer full. Discarding oldest payload segment\n");
memmove(l->conn->rxbuf, l->conn->rxbuf + ZT_MAX_MTU, DEFAULT_UDP_RX_BUF_SZ - ZT_MAX_MTU);
sz_pos = l->conn->rxbuf + (DEFAULT_UDP_RX_BUF_SZ - ZT_MAX_MTU) + sizeof(struct sockaddr_storage);
addr_pos = l->conn->rxbuf + (DEFAULT_UDP_RX_BUF_SZ - ZT_MAX_MTU); // TODO:
sz_pos = addr_pos + sizeof(struct sockaddr_storage);
l->conn->rxsz -= ZT_MAX_MTU;
}
else {

View File

@@ -36,7 +36,7 @@
#define SENDMSG_SIG int socket, const struct msghdr *message, int flags
#define SENDTO_SIG int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addr_len
#define RECV_SIG int socket, void *buffer, size_t length, int flags
#define RECVFROM_SIG int socket, void * buffer, size_t length, int flags, struct sockaddr_in * address, socklen_t * address_len
#define RECVFROM_SIG int socket, void * buffer, size_t length, int flags, struct sockaddr * address, socklen_t * address_len
#define RECVMSG_SIG int socket, struct msghdr *message,int flags
#define SEND_SIG int socket, const void *buffer, size_t length, int flags

View File

@@ -260,7 +260,7 @@ int (*realclose)(CLOSE_SIG);
jbyte *body = (*env)->GetByteArrayElements(env, buf, 0);
unsigned char buffer[ZT_MAX_MTU];
int payload_offset = sizeof(int) + sizeof(struct sockaddr_storage);
int rxbytes = zts_recvfrom(fd, &buffer, len, flags, &addr, sizeof(struct sockaddr));
int rxbytes = zts_recvfrom(fd, &buffer, len, flags, &addr, sizeof(struct sockaddr_storage));
if(rxbytes > 0)
memcpy(body, (jbyte*)buffer + payload_offset, rxbytes);
(*env)->ReleaseByteArrayElements(env, buf, body, 0);