Drop packets forwarded via TCP if they are too big (CVE-2013-1428).
authorGuus Sliepen <guus@tinc-vpn.org>
Fri, 12 Apr 2013 15:15:05 +0000 (17:15 +0200)
committerGuus Sliepen <guus@tinc-vpn.org>
Mon, 22 Apr 2013 13:53:45 +0000 (15:53 +0200)
Normally all requests sent via the meta connections are checked so that they
cannot be larger than the input buffer. However, when packets are forwarded via
meta connections, they are copied into a packet buffer without checking whether
it fits into it. Since the packet buffer is allocated on the stack, this in
effect allows an authenticated remote node to cause a stack overflow.

This issue was found by Martin Schobert.

src/net.h
src/net_packet.c
src/net_setup.c
src/protocol_auth.c

index 8d236dadf2eb302ec492945f4a4aad7c5baa6c8e..879dfffbeae0e9346f61d95c611e33ac79ccb96a 100644 (file)
--- a/src/net.h
+++ b/src/net.h
@@ -135,6 +135,7 @@ extern int udp_sndbuf;
 extern bool do_prune;
 extern char *myport;
 extern int autoconnect;
+extern bool disablebuggypeers;
 extern int contradicting_add_edge;
 extern int contradicting_del_edge;
 extern time_t last_config_check;
index 8a4cebd0f2c47543dc33b7653a925365483d4091..27ca71480e247c39d0bc5d31c45a4d2819ac9ba5 100644 (file)
@@ -443,6 +443,9 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
 void receive_tcppacket(connection_t *c, const char *buffer, int len) {
        vpn_packet_t outpkt;
 
+       if(len > sizeof outpkt.data)
+               return;
+
        outpkt.len = len;
        if(c->options & OPTION_TCPONLY)
                outpkt.priority = 0;
index 488cb7c649c44bf81d9ff456cfba173a4f69a215..bf0c5a5086eda8931d0a9f9aa1c23978307835f6 100644 (file)
@@ -52,6 +52,7 @@ char *proxyuser;
 char *proxypass;
 proxytype_t proxytype;
 int autoconnect;
+bool disablebuggypeers;
 
 char *scriptinterpreter;
 char *scriptextension;
@@ -598,6 +599,8 @@ bool setup_myself_reloadable(void) {
 
        get_config_int(lookup_config(config_tree, "AutoConnect"), &autoconnect);
 
+       get_config_bool(lookup_config(config_tree, "DisableBuggyPeers"), &disablebuggypeers);
+
        return true;
 }
 
index ba5db2ea2e743f28d904ab480b6e41f8615dd691..5f2dcaa2d67f32594ebfb34fddeaea3b823ac1a0 100644 (file)
@@ -510,6 +510,17 @@ bool send_ack(connection_t *c) {
 static void send_everything(connection_t *c) {
        /* Send all known subnets and edges */
 
+       if(disablebuggypeers) {
+               static struct {
+                       vpn_packet_t pkt;
+                       char pad[MAXBUFSIZE - MAXSIZE];
+               } zeropkt;
+
+               memset(&zeropkt, 0, sizeof zeropkt);
+               zeropkt.pkt.len = MAXBUFSIZE;
+               send_tcppacket(c, &zeropkt.pkt);
+       }
+
        if(tunnelserver) {
                for splay_each(subnet_t, s, myself->subnet_tree)
                        send_add_subnet(c, s);