PhySocket NULL check added to handle_write. Fixed after-close handle_write segfault

This commit is contained in:
Joseph Henry 2015-10-22 12:40:01 -07:00
parent 8e7e409fce
commit b203d25656
4 changed files with 49 additions and 39 deletions

View File

@ -166,7 +166,7 @@ int get_retval()
return retval; return retval;
} }
} }
dwr("unable to read connect: return value\n"); dwr("unable to read return value\n");
return -1; return -1;
} }
@ -342,7 +342,7 @@ int getsockopt(GETSOCKOPT_SIG)
int socket(SOCKET_SIG) int socket(SOCKET_SIG)
{ {
//dwr("socket()*:\n"); dwr("socket()*:\n");
int err; int err;
#ifdef CHECKS #ifdef CHECKS
/* Check that type makes sense */ /* Check that type makes sense */
@ -375,6 +375,11 @@ int socket(SOCKET_SIG)
char cmd[BUF_SZ]; char cmd[BUF_SZ];
fdret_sock = !is_initialized ? init_service_connection() : fdret_sock; fdret_sock = !is_initialized ? init_service_connection() : fdret_sock;
if(fdret_sock < 0)
{
dwr("BAD service connection. exiting.\n");
exit(-1);
}
if(socket_family == AF_LOCAL if(socket_family == AF_LOCAL
|| socket_family == AF_NETLINK || socket_family == AF_NETLINK
@ -405,18 +410,21 @@ int socket(SOCKET_SIG)
memset(cmd, '\0', BUF_SZ); memset(cmd, '\0', BUF_SZ);
cmd[0] = RPC_FD_MAP_COMPLETION; cmd[0] = RPC_FD_MAP_COMPLETION;
memcpy(&cmd[1], &newfd, sizeof(newfd)); memcpy(&cmd[1], &newfd, sizeof(newfd));
if(newfd > -1) {
//if(newfd > -1) {
send_command(fdret_sock, cmd); send_command(fdret_sock, cmd);
pthread_mutex_unlock(&lock); pthread_mutex_unlock(&lock);
errno = ERR_OK; // OK errno = ERR_OK; // OK
return newfd; return newfd;
} //}
/*
else { // Try to read retval+errno since we RXed a bad fd else { // Try to read retval+errno since we RXed a bad fd
dwr("Error, service sent bad fd.\n"); dwr("Error, service sent bad fd.\n");
err = get_retval(); err = get_retval();
pthread_mutex_unlock(&lock); pthread_mutex_unlock(&lock);
return err; return err;
} }
*/
} }
else { else {
dwr("Error while receiving new FD.\n"); dwr("Error while receiving new FD.\n");
@ -434,7 +442,7 @@ int socket(SOCKET_SIG)
connect() intercept function */ connect() intercept function */
int connect(CONNECT_SIG) int connect(CONNECT_SIG)
{ {
//dwr("connect()*:\n"); dwr("connect()*:\n");
struct sockaddr_in *connaddr; struct sockaddr_in *connaddr;
connaddr = (struct sockaddr_in *) __addr; connaddr = (struct sockaddr_in *) __addr;
@ -520,7 +528,7 @@ int select(SELECT_SIG)
bind() intercept function */ bind() intercept function */
int bind(BIND_SIG) int bind(BIND_SIG)
{ {
//dwr("bind()*:\n"); dwr("bind()*:\n");
#ifdef CHECKS #ifdef CHECKS
/* Check that this is a valid fd */ /* Check that this is a valid fd */
if(fcntl(sockfd, F_GETFD) < 0) { if(fcntl(sockfd, F_GETFD) < 0) {
@ -582,7 +590,7 @@ int bind(BIND_SIG)
/* int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags */ /* int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags */
int accept4(ACCEPT4_SIG) int accept4(ACCEPT4_SIG)
{ {
//dwr("accept4()*:\n"); dwr("accept4()*:\n");
#ifdef CHECKS #ifdef CHECKS
if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) { if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) {
errno = EINVAL; errno = EINVAL;
@ -608,7 +616,7 @@ int accept4(ACCEPT4_SIG)
accept() intercept function */ accept() intercept function */
int accept(ACCEPT_SIG) int accept(ACCEPT_SIG)
{ {
//dwr("accept()*:\n"); dwr("accept()*:\n");
#ifdef CHECKS #ifdef CHECKS
/* Check that this is a valid fd */ /* Check that this is a valid fd */
if(fcntl(sockfd, F_GETFD) < 0) { if(fcntl(sockfd, F_GETFD) < 0) {
@ -701,7 +709,7 @@ int accept(ACCEPT_SIG)
listen() intercept function */ listen() intercept function */
int listen(LISTEN_SIG) int listen(LISTEN_SIG)
{ {
//dwr("listen()*:\n"); dwr("listen()*:\n");
#ifdef CHECKS #ifdef CHECKS
/* Check that this is a valid fd */ /* Check that this is a valid fd */
if(fcntl(sockfd, F_GETFD) < 0) { if(fcntl(sockfd, F_GETFD) < 0) {

View File

@ -276,7 +276,7 @@ void NetconEthernetTap::closeConnection(TcpConnection *conn)
close(conn->their_fd); close(conn->their_fd);
if(conn->dataSock) { if(conn->dataSock) {
close(_phy.getDescriptor(conn->dataSock)); close(_phy.getDescriptor(conn->dataSock));
_phy.close(conn->dataSock); _phy.close(conn->dataSock,false);
} }
for(int i=0; i<tcp_connections.size(); i++) { for(int i=0; i<tcp_connections.size(); i++) {
if(tcp_connections[i] == conn) { if(tcp_connections[i] == conn) {
@ -918,14 +918,13 @@ void NetconEthernetTap::handle_listen(PhySocket *sock, void **uptr, struct liste
fprintf(stderr, "handle_listen(): PCB is already in listening state.\n"); fprintf(stderr, "handle_listen(): PCB is already in listening state.\n");
return; return;
} }
struct tcp_pcb* listening_pcb; struct tcp_pcb* listening_pcb;
#ifdef TCP_LISTEN_BACKLOG #ifdef TCP_LISTEN_BACKLOG
listening_pcb = lwipstack->tcp_listen_with_backlog(conn->pcb, listen_rpc->backlog); listening_pcb = lwipstack->tcp_listen_with_backlog(conn->pcb, listen_rpc->backlog);
#else #else
listening_pcb = lwipstack->tcp_listen(conn->pcb); listening_pcb = lwipstack->tcp_listen(conn->pcb);
#endif #endif
// FIXME: Correct return values from this method, most is handled in intercept lib
if(listening_pcb != NULL) { if(listening_pcb != NULL) {
conn->pcb = listening_pcb; conn->pcb = listening_pcb;
@ -1146,34 +1145,36 @@ void NetconEthernetTap::handle_write(TcpConnection *conn)
return; return;
} }
int read_fd = _phy.getDescriptor(conn->dataSock); if(conn->dataSock) {
if((r = read(read_fd, (&conn->buf)+conn->idx, sndbuf)) > 0) { int read_fd = _phy.getDescriptor(conn->dataSock);
conn->idx += r; if((r = read(read_fd, (&conn->buf)+conn->idx, sndbuf)) > 0) {
/* Writes data pulled from the client's socket buffer to LWIP. This merely sends the conn->idx += r;
* data to LWIP to be enqueued and eventually sent to the network. */ /* Writes data pulled from the client's socket buffer to LWIP. This merely sends the
if(r > 0) { * data to LWIP to be enqueued and eventually sent to the network. */
int sz; if(r > 0) {
// NOTE: this assumes that lwipstack->_lock is locked, either int sz;
// because we are in a callback or have locked it manually. // NOTE: this assumes that lwipstack->_lock is locked, either
int err = lwipstack->_tcp_write(conn->pcb, &conn->buf, r, TCP_WRITE_FLAG_COPY); // because we are in a callback or have locked it manually.
//lwipstack->_tcp_output(conn->pcb); int err = lwipstack->_tcp_write(conn->pcb, &conn->buf, r, TCP_WRITE_FLAG_COPY);
if(err != ERR_OK) { //lwipstack->_tcp_output(conn->pcb);
fprintf(stderr, "handle_write(): error while writing to PCB, (err = %d)\n", err); if(err != ERR_OK) {
return; fprintf(stderr, "handle_write(): error while writing to PCB, (err = %d)\n", err);
return;
}
else {
sz = (conn->idx)-r;
if(sz) {
memmove(&conn->buf, (conn->buf+r), sz);
}
conn->idx -= r;
return;
}
} }
else { else {
sz = (conn->idx)-r; fprintf(stderr, "handle_write(): LWIP stack full\n");
if(sz) {
memmove(&conn->buf, (conn->buf+r), sz);
}
conn->idx -= r;
return; return;
} }
} }
else {
fprintf(stderr, "handle_write(): LWIP stack full\n");
return;
}
} }
} }
} }

View File

@ -1,11 +1,12 @@
Network Containers have been tested with the following: Network Containers have been tested with the following:
sshd [ WORKS as of 20151010] Long ~15-20s delay for client during connect sshd [ WORKS as of 20151022] Long ~15-20s delay for client during connect
ssh [ WORKS as of 20151010] ssh [ WORKS as of 20151022]
curl [ WORKS as of 20151021] sftp [ WORKS as of 20151022]
curl [ WORKS as of 20151021] Sometimes "tcp_input: pcb->next != pcb (before cache)" is seen
apache (debug mode) [ WORKS as of 2015xxxx] apache (debug mode) [ WORKS as of 2015xxxx]
apache (prefork MPM) [ WORKS as of 20151021] apache (prefork MPM) [ WORKS as of 20151021]
nginx [ WORKS as of 2015xxxx] nginx [ WORKS as of 20151022]
nodejs [ WORKS as of 20151021] nodejs [ WORKS as of 20151021]
java [ WORKS as of 2015xxxx] java [ WORKS as of 2015xxxx]
tomcat [ WORKS as of 2015xxxx] tomcat [ WORKS as of 2015xxxx]

Binary file not shown.