Browse Source

Added some parameter checks from linux kernel syscall source

Joseph Henry 9 years ago
parent
commit
73145de618
4 changed files with 39 additions and 16 deletions
  1. 7 11
      netcon/NetconEthernetTap.cpp
  2. 31 4
      netcon/intercept.c
  3. BIN
      netcon/libintercept.so.1.0
  4. 1 1
      netcon/make-intercept.mk

+ 7 - 11
netcon/NetconEthernetTap.cpp

@@ -700,17 +700,13 @@ void NetconEthernetTap::nc_err(void *arg, err_t err)
  */
 err_t NetconEthernetTap::nc_poll(void* arg, struct tcp_pcb *tpcb)
 {
-	uint64_t now = OSUtils::now();
-	//fprintf(stderr, "nc_poll(): now = %u\n", now);
-	//fprintf(stderr, "nc_poll\n");
-
-
+	/*
 	Larg *l = (Larg*)arg;
 	TcpConnection *conn = l->conn;
 	NetconEthernetTap *tap = l->tap;
 	if(conn && conn->idx) // if valid connection and non-zero index (indicating data present)
 		tap->handle_write(conn);
-
+	*/
 	return ERR_OK;
 }
 
@@ -736,7 +732,6 @@ err_t NetconEthernetTap::nc_sent(void* arg, struct tcp_pcb *tpcb, u16_t len)
 		//uint64_t now = OSUtils::now();
 		//fprintf(stderr, "nc_sent(): now = %u\n", now);
 		l->tap->_phy.whack();
-		//l->tap->handle_write(l->conn);
 	}
 	return ERR_OK;
 }
@@ -856,10 +851,10 @@ void NetconEthernetTap::handle_bind(PhySocket *sock, void **uptr, struct bind_st
  * @param structure containing the data and parameters for this client's RPC
  *
 
-  [ ] EADDRINUSE - Another socket is already listening on the same port.
+  [?] EADDRINUSE - Another socket is already listening on the same port.
 	[X] EBADF - The argument sockfd is not a valid descriptor.
-	[ ] ENOTSOCK - The argument sockfd is not a socket.
-	[ ] EOPNOTSUPP - The socket is not of a type that supports the listen() operation.
+	[i] ENOTSOCK - The argument sockfd is not a socket.
+	[i] EOPNOTSUPP - The socket is not of a type that supports the listen() operation.
 
  */
 void NetconEthernetTap::handle_listen(PhySocket *sock, void **uptr, struct listen_st *listen_rpc)
@@ -886,6 +881,7 @@ void NetconEthernetTap::handle_listen(PhySocket *sock, void **uptr, struct liste
     }
   }
   else {
+		// We can't find a connection mapped to the socket fd provided
     fprintf(stderr, "handle_listen(): can't locate connection for PCB\n");
 		send_return_value(conn, -1, EBADF);
   }
@@ -954,7 +950,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.
-	[?] EAFNOSUPPORT - The passed address didn't have the correct address family in its sa_family field.
+	[i] 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.

+ 31 - 4
netcon/intercept.c

@@ -66,12 +66,19 @@ char *progname = "";
 #include <sys/mman.h>
 
 #ifdef USE_SOCKS_DNS
-#include <resolv.h>
+  #include <resolv.h>
 #endif
 
 #include "intercept.h"
 #include "common.h"
 
+#ifdef CHECKS
+  #include <linux/net.h> /* for NPROTO */
+
+  #define SOCK_MAX (SOCK_PACKET + 1)
+  #define SOCK_TYPE_MASK 0xf
+#endif
+
 /* Global Declarations */
 #ifdef USE_SOCKS_DNS
 static int (*realresinit)(void);
@@ -504,8 +511,21 @@ void sock_domain_to_str(int domain)
 
 /* int socket_family, int socket_type, int protocol
    socket() intercept function */
+
 int socket(SOCKET_SIG)
 {
+#ifdef CHECKS
+  /* 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
   dwr("socket(fam=%d, type=%d, prot=%d)\n", socket_family, socket_type, protocol);
   return realsocket(socket_family, socket_type, protocol);
@@ -520,9 +540,6 @@ int socket(SOCKET_SIG)
     return realsocket(socket_family, socket_type, protocol);
   }
 
-  /* FIXME: Check type, protocol, return EINVAL errno */
-  /* FIXME: Check family, return EAFNOSUPPORT errno */
-
   /* Assemble and route command */
   struct socket_st rpc_st;
   rpc_st.socket_family = socket_family;
@@ -573,6 +590,9 @@ int socket(SOCKET_SIG)
    connect() intercept function */
 int connect(CONNECT_SIG)
 {
+
+  /* FIXME: Check that address is in user space, return EFAULT ? */
+
 #ifdef DUMMY
   dwr("connect(%d)\n", __fd);
   return realconnect(__fd, __addr, __len);
@@ -728,6 +748,10 @@ int bind(BIND_SIG)
 /* int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags */
 int accept4(ACCEPT4_SIG)
 {
+#ifdef CHECKS
+  if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
+    return -EINVAL;
+#endif
 #ifdef DUMMY
   dwr("accept4(%d)\n", sockfd);
   return accept(sockfd, addr, addrlen);
@@ -816,6 +840,9 @@ int accept(ACCEPT_SIG)
    listen() intercept function */
 int listen(LISTEN_SIG)
 {
+  /* FIXME: Check that this socket supports listen(), return EOPNOTSUPP */
+  /* FIXME: Check that the provided fd is a socket, return ENOTSOCK */
+
 #ifdef DUMMY
     dwr("listen(%d)\n", sockfd);
     return reallisten(sockfd, backlog);

BIN
netcon/libintercept.so.1.0


+ 1 - 1
netcon/make-intercept.mk

@@ -27,7 +27,7 @@
 
 SHCC=gcc
 
-intercept_CFLAGS = -c -fPIC -g -O2 -Wall -std=c99 -D_GNU_SOURCE -DNETCON_INTERCEPT
+intercept_CFLAGS = -c -fPIC -g -O2 -Wall -std=c99 -D_GNU_SOURCE -DCHECKS -DNETCON_INTERCEPT
 LIB_NAME = intercept
 SHLIB_EXT=dylib
 SHLIB_MAJOR = 1