From eaf934785d547b90f2f1c99b4d6f7d766ca82856 Mon Sep 17 00:00:00 2001 From: albert-lopez Date: Fri, 16 Sep 2016 11:18:01 +0200 Subject: [PATCH] Fix segmentation fault when receiving a port scan --- oor/cmdline.h | 2 +- oor/control/control-data-plane/tun/cdp_tun.c | 6 +++ .../control-data-plane/vpnapi/cdp_vpnapi.c | 5 +++ oor/data-plane/tun/tun_input.c | 5 ++- oor/data-plane/vpnapi/vpnapi_input.c | 4 +- oor/defs.h | 2 +- oor/lib/mem_util.h | 7 ---- oor/lib/packets.c | 41 +++++++------------ oor/lib/packets.h | 23 +++++++++++ oor/liblisp/liblisp.c | 13 ++---- oor/oor.ggo | 2 +- openWRT/oor.uci.example | 1 - 12 files changed, 62 insertions(+), 49 deletions(-) diff --git a/oor/cmdline.h b/oor/cmdline.h index 6f07f3c..fe0f265 100644 --- a/oor/cmdline.h +++ b/oor/cmdline.h @@ -31,7 +31,7 @@ extern "C" { #ifndef CMDLINE_PARSER_VERSION /** @brief the program version */ -#define CMDLINE_PARSER_VERSION "1.1" +#define CMDLINE_PARSER_VERSION "1.1.1" #endif enum enum_debug { debug__NULL = -1, debug_arg_0 = 0, debug_arg_1, debug_arg_2, debug_arg_3 }; diff --git a/oor/control/control-data-plane/tun/cdp_tun.c b/oor/control/control-data-plane/tun/cdp_tun.c index dcaa24a..71b9199 100644 --- a/oor/control/control-data-plane/tun/cdp_tun.c +++ b/oor/control/control-data-plane/tun/cdp_tun.c @@ -155,6 +155,12 @@ tun_control_dp_recv_msg(sock_t *sl) return (BAD); } + if (lbuf_size(b) < 4){ + OOR_LOG(LDBG_3, "Received a non LISP message in the " + "control port! Discarding packet!"); + return (BAD); + } + lbuf_reset_lisp(b); OOR_LOG(LDBG_1, "Received %s, IP: %s -> %s, UDP: %d -> %d", lisp_msg_hdr_to_char(b), lisp_addr_to_char(&uc.ra), diff --git a/oor/control/control-data-plane/vpnapi/cdp_vpnapi.c b/oor/control/control-data-plane/vpnapi/cdp_vpnapi.c index 7b72adc..9a22e54 100644 --- a/oor/control/control-data-plane/vpnapi/cdp_vpnapi.c +++ b/oor/control/control-data-plane/vpnapi/cdp_vpnapi.c @@ -142,6 +142,11 @@ vpnapi_control_dp_recv_msg(sock_t *sl) lbuf_del(b); return (BAD); } + if (lbuf_size(b) < 4){ + OOR_LOG(LDBG_3, "Received a non LISP message in the " + "control port! Discarding packet!"); + return (BAD); + } lbuf_reset_lisp(b); OOR_LOG(LDBG_1, "Received %s, IP: %s -> %s, UDP: %d -> %d", diff --git a/oor/data-plane/tun/tun_input.c b/oor/data-plane/tun/tun_input.c index 45a5886..63d520a 100644 --- a/oor/data-plane/tun/tun_input.c +++ b/oor/data-plane/tun/tun_input.c @@ -59,10 +59,13 @@ tun_read_and_decap_pkt(int sock, lbuf_t *b, uint32_t *iid) } udph = pkt_pull_udp(b); + if (ntohs(udplen(udph)) < 16){//8 udp header + 8 lisp header + return (ERR_NOT_ENCAP); + } /* FILTER UDP: with input RAW UDP sockets, we receive all UDP packets, * we only want LISP data ones */ - switch (ntohs(udph->dest)){ + switch (ntohs(udpdport(udph))){ case LISP_DATA_PORT: lisph = lisp_data_pull_hdr(b); if (LDHDR_LSB_BIT(lisph)){ diff --git a/oor/data-plane/vpnapi/vpnapi_input.c b/oor/data-plane/vpnapi/vpnapi_input.c index b2e7850..737c422 100644 --- a/oor/data-plane/vpnapi/vpnapi_input.c +++ b/oor/data-plane/vpnapi/vpnapi_input.c @@ -50,7 +50,9 @@ vpnapi_read_and_decap_pkt(int sock, lbuf_t *b, uint32_t *iid) if (sock_data_recv(sock, b, &afi, &ttl, &tos) != GOOD) { return(BAD); } - + if (lbuf_size(b) < 8){ // 8-> At least LISP header size + return (ERR_NOT_ENCAP); + } switch (data->encap_type){ case ENCP_LISP: diff --git a/oor/defs.h b/oor/defs.h index 4450195..126e6d2 100644 --- a/oor/defs.h +++ b/oor/defs.h @@ -88,7 +88,7 @@ typedef struct htable_nonces_ htable_nonces_t; */ #define EVER ;; -#define OOR_VERSION "v1.1" +#define OOR_VERSION "v1.1.1" #define OOR "oor" #define PID_FILE "/var/run/oor.pid" diff --git a/oor/lib/mem_util.h b/oor/lib/mem_util.h index e74276b..497929b 100644 --- a/oor/lib/mem_util.h +++ b/oor/lib/mem_util.h @@ -64,13 +64,6 @@ #define ARRAY_SIZE(x) ((sizeof x) / (sizeof *x)) -/* names for where the udp checksum goes */ -#ifdef BSD -#define udpsum(x) x->uh_sum -#else -#define udpsum(x) x->check -#endif - /* compile attributes */ #define NO_RETURN __attribute__((__noreturn__)) diff --git a/oor/lib/packets.c b/oor/lib/packets.c index fc9fecb..151c5ef 100644 --- a/oor/lib/packets.c +++ b/oor/lib/packets.c @@ -96,17 +96,11 @@ pkt_push_udp(lbuf_t *b, uint16_t sp, uint16_t dp) udp_len = sizeof(struct udphdr) + lbuf_size(b); uh = lbuf_push_uninit(b, sizeof(struct udphdr)); -#ifdef BSD - uh->uh_sport = htons(port_from); - uh->uh_dport = htons(port_dest); - uh->uh_ulen = htons(udp_payload_len); - uh->uh_sum = 0; -#else - uh->source = htons(sp); - uh->dest = htons(dp); - uh->len = htons(udp_len); - uh->check = 0; /* to be filled in after IP is pushed */ -#endif + udpsport(uh) = htons(sp); + udpdport(uh) = htons(dp); + udplen(uh) = htons(udp_len); + udpsum(uh) = 0; /* to be filled in after IP is pushed */ + return(uh); } @@ -199,7 +193,7 @@ pkt_push_udp_and_ip(lbuf_t *b, uint16_t sp, uint16_t dp, ip_addr_t *sip, lbuf_reset_ip(b); uh = lbuf_udp(b); - udpsum = udp_checksum(uh, ntohs(uh->len), lbuf_ip(b), ip_addr_afi(sip)); + udpsum = udp_checksum(uh, ntohs(udplen(uh)), lbuf_ip(b), ip_addr_afi(sip)); if (udpsum == -1) { OOR_LOG(LDBG_1, "Failed UDP checksum! Discarding"); return (BAD); @@ -246,12 +240,12 @@ pkt_parse_5_tuple(lbuf_t *b, packet_tuple_t *tuple) if (tuple->protocol == IPPROTO_UDP) { udp = lbuf_data(&packet); - tuple->src_port = ntohs(udp->source); - tuple->dst_port = ntohs(udp->dest); + tuple->src_port = ntohs(udpsport(udp)); + tuple->dst_port = ntohs(udpdport(udp)); } else if (tuple->protocol == IPPROTO_TCP) { tcp = lbuf_data(&packet); - tuple->src_port = ntohs(tcp->source); - tuple->dst_port = ntohs(tcp->dest); + tuple->src_port = ntohs(tcpsport(tcp)); + tuple->dst_port = ntohs(tcpdport(tcp)); } else { /* If protocol is not TCP or UDP, ports of the tuple set to 0 */ tuple->src_port = 0; @@ -560,18 +554,11 @@ build_ip_udp_pcket(uint8_t *orig_pkt, int orig_pkt_len,lisp_addr_t *addr_from, } /* UDP header */ + udpsport(udph_ptr) = htons(port_from); + udpdport(udph_ptr) = htons(port_dest); + udplen(udph_ptr) = htons(udp_hdr_and_payload_len); + udpsum(udph_ptr) = 0; -#ifdef BSD - udph_ptr->uh_sport = htons(port_from); - udph_ptr->uh_dport = htons(port_dest); - udph_ptr->uh_ulen = htons(udp_payload_len); - udph_ptr->uh_sum = 0; -#else - udph_ptr->source = htons(port_from); - udph_ptr->dest = htons(port_dest); - udph_ptr->len = htons(udp_hdr_and_payload_len); - udph_ptr->check = 0; -#endif /* Copy original packet after the headers */ memcpy(CO(udph_ptr, udp_hdr_len), orig_pkt, orig_pkt_len); diff --git a/oor/lib/packets.h b/oor/lib/packets.h index cea8290..31087dd 100644 --- a/oor/lib/packets.h +++ b/oor/lib/packets.h @@ -39,6 +39,28 @@ #define MAX_IP_HDR_LEN 40 /* without options or IPv6 hdr extensions */ #define UDP_HDR_LEN 8 +#ifdef BSD +#define udpsport(x) x->uh_sport +#define udpdport(x) x->uh_dport +#define udplen(x) x->uh_ulen +#define udpsum(x) x->uh_sum +#else +#define udpsport(x) x->source +#define udpdport(x) x->dest +#define udplen(x) x->len +#define udpsum(x) x->check +#endif + +#ifdef BSD +#define tcpsport(x) x->th_sport +#define tcpdport(x) x->th_dport +#else +#define tcpsport(x) x->source +#define tcpdport(x) x->dest +#endif + + + /* shared between data and control */ typedef struct packet_tuple { lisp_addr_t src_addr; @@ -50,6 +72,7 @@ typedef struct packet_tuple { } packet_tuple_t; + /* * Generate IP header. Returns the poninter to the transport header */ diff --git a/oor/liblisp/liblisp.c b/oor/liblisp/liblisp.c index 3944c14..bb11adb 100644 --- a/oor/liblisp/liblisp.c +++ b/oor/liblisp/liblisp.c @@ -67,13 +67,8 @@ lisp_msg_ecm_decap(lbuf_t *pkt, uint16_t *src_port) /* This should overwrite the external port (dst_port in map-reply = * inner src_port in encap map-request) */ - *src_port = ntohs(udph->source); - - #ifdef BSD - udp_len = ntohs(udph->uh_ulen); - #else - udp_len = ntohs(udph->len); - #endif + *src_port = ntohs(udpsport(udph)); + udp_len = ntohs(udplen(udph)); /* Verify the checksums. */ if (iph->ip_v == IPVERSION) { @@ -86,7 +81,7 @@ lisp_msg_ecm_decap(lbuf_t *pkt, uint16_t *src_port) /* Verify UDP checksum only if different from 0. * This means we ACCEPT UDP checksum 0! */ - if (udph->check != 0) { + if (udpsum(udph) != 0) { udpsum = udp_checksum(udph, udp_len, iph, ip_version_to_sock_afi(iph->ip_v)); if (udpsum != 0) { @@ -99,7 +94,7 @@ lisp_msg_ecm_decap(lbuf_t *pkt, uint16_t *src_port) lisp_msg_hdr_to_char(pkt), ip_to_char(&iph->ip_src, ip_version_to_sock_afi(iph->ip_v)), ip_to_char(&iph->ip_dst, ip_version_to_sock_afi(iph->ip_v)), - ntohs(udph->source), ntohs(udph->dest)); + ntohs(udpsport(udph)), ntohs(udpdport(udph))); return (GOOD); } diff --git a/oor/oor.ggo b/oor/oor.ggo index dcfedfe..b3084cf 100644 --- a/oor/oor.ggo +++ b/oor/oor.ggo @@ -19,7 +19,7 @@ package "oor" -version "1.0.2" +version "1.1.1" defmode "oorconfig" diff --git a/openWRT/oor.uci.example b/openWRT/oor.uci.example index 3264c1d..b24dcbe 100644 --- a/openWRT/oor.uci.example +++ b/openWRT/oor.uci.example @@ -15,7 +15,6 @@ config 'daemon' option 'log_file' '/tmp/oor.log' option 'map_request_retries' '2' option 'operating_mode' 'xTR' - option 'nat_traversal_support' 'off' #---------------------------------------------------------------------------------------------------------------------