summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2012-02-15 18:40:26 -0600
committerAnthony Liguori <aliguori@us.ibm.com>2012-02-15 18:40:26 -0600
commit006c891fc9d4f044ad3f41b6e019442523b45a54 (patch)
tree5126f84a0eb0411daf55951ec45656a3b242404d
parent7718564ba1295f35188a5fb3ac8633c29d43b166 (diff)
parent6612db12d56c68fff3e56ca4ea8c41d9d55c12e4 (diff)
downloadfocaccia-qemu-006c891fc9d4f044ad3f41b6e019442523b45a54.tar.gz
focaccia-qemu-006c891fc9d4f044ad3f41b6e019442523b45a54.zip
Merge remote-tracking branch 'kiszka/queues/slirp' into staging
* kiszka/queues/slirp:
  slirp: Prevent sending ICMP error replies to source-only addresses
  slirp: Remove unused variable and unused code
-rw-r--r--slirp/ip_icmp.c5
-rw-r--r--slirp/misc.c67
2 files changed, 31 insertions, 41 deletions
diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 4b43994dbc..5dbf21da9d 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -262,6 +262,11 @@ icmp_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
 #endif
   if(ip->ip_off & IP_OFFMASK) goto end_error;    /* Only reply to fragment 0 */
 
+  /* Do not reply to source-only IPs */
+  if ((ip->ip_src.s_addr & htonl(~(0xf << 28))) == 0) {
+      goto end_error;
+  }
+
   shlen=ip->ip_hl << 2;
   s_ip_len=ip->ip_len;
   if(ip->ip_p == IPPROTO_ICMP) {
diff --git a/slirp/misc.c b/slirp/misc.c
index 6c80e69685..3432fbfeb7 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -113,7 +113,6 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
 	struct sockaddr_in addr;
 	socklen_t addrlen = sizeof(addr);
 	int opt;
-        int master = -1;
 	const char *argv[256];
 	/* don't want to clobber the original */
 	char *bptr;
@@ -148,32 +147,23 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
 	 case -1:
 		lprint("Error: fork failed: %s\n", strerror(errno));
 		close(s);
-		if (do_pty == 2)
-		   close(master);
 		return 0;
 
 	 case 0:
                 setsid();
 
 		/* Set the DISPLAY */
-		if (do_pty == 2) {
-			(void) close(master);
-#ifdef TIOCSCTTY /* XXXXX */
-			ioctl(s, TIOCSCTTY, (char *)NULL);
-#endif
-		} else {
-			getsockname(s, (struct sockaddr *)&addr, &addrlen);
-			close(s);
-			/*
-			 * Connect to the socket
-			 * XXX If any of these fail, we're in trouble!
-	 		 */
-			s = qemu_socket(AF_INET, SOCK_STREAM, 0);
-			addr.sin_addr = loopback_addr;
-                        do {
-                            ret = connect(s, (struct sockaddr *)&addr, addrlen);
-                        } while (ret < 0 && errno == EINTR);
-		}
+                getsockname(s, (struct sockaddr *)&addr, &addrlen);
+                close(s);
+                /*
+                 * Connect to the socket
+                 * XXX If any of these fail, we're in trouble!
+                 */
+                s = qemu_socket(AF_INET, SOCK_STREAM, 0);
+                addr.sin_addr = loopback_addr;
+                do {
+                    ret = connect(s, (struct sockaddr *)&addr, addrlen);
+                } while (ret < 0 && errno == EINTR);
 
 		dup2(s, 0);
 		dup2(s, 1);
@@ -210,26 +200,21 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
 
 	 default:
 		qemu_add_child_watch(pid);
-		if (do_pty == 2) {
-			close(s);
-			so->s = master;
-		} else {
-			/*
-			 * XXX this could block us...
-			 * XXX Should set a timer here, and if accept() doesn't
-		 	 * return after X seconds, declare it a failure
-		 	 * The only reason this will block forever is if socket()
-		 	 * of connect() fail in the child process
-		 	 */
-                        do {
-                            so->s = accept(s, (struct sockaddr *)&addr, &addrlen);
-                        } while (so->s < 0 && errno == EINTR);
-                        closesocket(s);
-			opt = 1;
-			setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int));
-			opt = 1;
-			setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
-		}
+                /*
+                 * XXX this could block us...
+                 * XXX Should set a timer here, and if accept() doesn't
+                 * return after X seconds, declare it a failure
+                 * The only reason this will block forever is if socket()
+                 * of connect() fail in the child process
+                 */
+                do {
+                    so->s = accept(s, (struct sockaddr *)&addr, &addrlen);
+                } while (so->s < 0 && errno == EINTR);
+                closesocket(s);
+                opt = 1;
+                setsockopt(so->s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int));
+                opt = 1;
+                setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, (char *)&opt, sizeof(int));
 		fd_nonblock(so->s);
 
 		/* Append the telnet options now */