From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pa0-f66.google.com (mail-pa0-f66.google.com [209.85.220.66]) by dpdk.org (Postfix) with ESMTP id 1A0F92C37 for ; Thu, 21 Apr 2016 19:29:13 +0200 (CEST) Received: by mail-pa0-f66.google.com with SMTP id zy2so7919252pac.2 for ; Thu, 21 Apr 2016 10:29:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=d+7NaDcadWgSM4TVUH+FwIeMY0+If63MyAmHDuLnBHc=; b=A1n0DGhIaPSjvLMINUGrwrNYWjluFWOOYqmpUQ6UIx23UlLOLMc9PCALPuFh1aobkv /oL30TS8ATIQiJK+t9NEXlIC51Sl9njTPkQo2OdVGA0V1Av1tHGVAJ+YoDTESd3tvdHC zMoRwGJS7UfLw4kiRgSOmYugZPKvC45hm+1lf7J9m/1bhuZlQyD0ss+uitYXDzkvS9tC r+OhrSFpaJR8wq4WyS6PH1wuWTXGnhtXJHp9EULAMGBBumsf2Iu29pnQ0sHzm6/xvgsP Pz1d6A111Oypr8BDmExf/n2PZeVF+FH21S0mBTWW8ZAC5H236nHN4nFK7ChHh+pW1ZaS SnrA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=d+7NaDcadWgSM4TVUH+FwIeMY0+If63MyAmHDuLnBHc=; b=laayyiS5uZBIutVr1V8+GaP9dGjYldrLMLoambrh5/A02C/FC5sWpQX57uNrqxGh/t eP2uYv3Hb4M3cJtOyhg0on1v8uloM+AaXr20GA0vHvwPD0/n5LCbEiybyPoKgAtiZ7NZ 2wwvUd68H3ixq04wJWKn3rmmYVZiKyrsS/MJngJXRdPED+PHZ5tnZWNqpK16cb9i7OOf F3KpHJJltXKKcMDe0wzm86mGAoRBgpGV7Q1ij+cE0rua9icENQK7vjWmpnTbqtlrd1UR wua9OpR4j7jST9FmvA5N49OB6VnqPCCwVg6YxYVnk+Pw07Mr6l4YOPzO3VF2L5QOZ+wH ljZQ== X-Gm-Message-State: AOPr4FWvFSj7Zj0Ck3vxn6Uh/+KH2e2vmWsH558PiTluYAYxHdF4c6tKHTta/T/AgKgzeg== X-Received: by 10.66.142.73 with SMTP id ru9mr22021979pab.51.1461259752467; Thu, 21 Apr 2016 10:29:12 -0700 (PDT) Received: from localhost.localdomain ([121.135.225.44]) by smtp.gmail.com with ESMTPSA id 16sm2510615pfk.28.2016.04.21.10.29.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 21 Apr 2016 10:29:11 -0700 (PDT) From: cychong To: dev@dpdk.org Cc: cychong@gmail.com Date: Fri, 22 Apr 2016 02:28:01 +0900 Message-Id: <1461259681-67118-1-git-send-email-cychong@gmail.com> X-Mailer: git-send-email 1.9.1 Subject: [dpdk-dev] [PATCH] ip_frag : Fix double-free of chained mbufs X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 21 Apr 2016 17:29:13 -0000 If any fragment hole is found in ipv4_frag_reassemble() and ipv6_frag_reassemble(), whole ip_frag_pkt mbufs are moved to death-row. Any mbufs already chained to another mbuf are freed multiple times as there are still in ip_frag_pkt array. Signed-off-by: cychong --- lib/librte_ip_frag/ip_frag_common.h | 4 ++-- lib/librte_ip_frag/rte_ipv4_reassembly.c | 8 +++++++- lib/librte_ip_frag/rte_ipv6_reassembly.c | 8 +++++++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/librte_ip_frag/ip_frag_common.h b/lib/librte_ip_frag/ip_frag_common.h index cde6ed4..5542a38 100644 --- a/lib/librte_ip_frag/ip_frag_common.h +++ b/lib/librte_ip_frag/ip_frag_common.h @@ -76,8 +76,8 @@ struct ip_frag_pkt * ip_frag_lookup(struct rte_ip_frag_tbl *tbl, struct ip_frag_pkt **free, struct ip_frag_pkt **stale); /* these functions need to be declared here as ip_frag_process relies on them */ -struct rte_mbuf * ipv4_frag_reassemble(const struct ip_frag_pkt *fp); -struct rte_mbuf * ipv6_frag_reassemble(const struct ip_frag_pkt *fp); +struct rte_mbuf *ipv4_frag_reassemble(struct ip_frag_pkt *fp); +struct rte_mbuf *ipv6_frag_reassemble(struct ip_frag_pkt *fp); diff --git a/lib/librte_ip_frag/rte_ipv4_reassembly.c b/lib/librte_ip_frag/rte_ipv4_reassembly.c index 26d07f9..e084ca5 100644 --- a/lib/librte_ip_frag/rte_ipv4_reassembly.c +++ b/lib/librte_ip_frag/rte_ipv4_reassembly.c @@ -41,11 +41,12 @@ * Reassemble fragments into one packet. */ struct rte_mbuf * -ipv4_frag_reassemble(const struct ip_frag_pkt *fp) +ipv4_frag_reassemble(struct ip_frag_pkt *fp) { struct ipv4_hdr *ip_hdr; struct rte_mbuf *m, *prev; uint32_t i, n, ofs, first_len; + uint32_t curr_idx = 0; first_len = fp->frags[IP_FIRST_FRAG_IDX].len; n = fp->last_idx - 1; @@ -53,6 +54,7 @@ ipv4_frag_reassemble(const struct ip_frag_pkt *fp) /*start from the last fragment. */ m = fp->frags[IP_LAST_FRAG_IDX].mb; ofs = fp->frags[IP_LAST_FRAG_IDX].ofs; + curr_idx = IP_LAST_FRAG_IDX; while (ofs != first_len) { @@ -67,6 +69,10 @@ ipv4_frag_reassemble(const struct ip_frag_pkt *fp) rte_pktmbuf_adj(m, (uint16_t)(m->l2_len + m->l3_len)); rte_pktmbuf_chain(fp->frags[i].mb, m); + /* this mbuf should not be accessed directly */ + fp->frags[curr_idx].mb = NULL; + curr_idx = i; + /* update our last fragment and offset. */ m = fp->frags[i].mb; ofs = fp->frags[i].ofs; diff --git a/lib/librte_ip_frag/rte_ipv6_reassembly.c b/lib/librte_ip_frag/rte_ipv6_reassembly.c index d29cb1d..21a5ef5 100644 --- a/lib/librte_ip_frag/rte_ipv6_reassembly.c +++ b/lib/librte_ip_frag/rte_ipv6_reassembly.c @@ -59,13 +59,14 @@ ip_frag_memmove(char *dst, char *src, int len) * Reassemble fragments into one packet. */ struct rte_mbuf * -ipv6_frag_reassemble(const struct ip_frag_pkt *fp) +ipv6_frag_reassemble(struct ip_frag_pkt *fp) { struct ipv6_hdr *ip_hdr; struct ipv6_extension_fragment *frag_hdr; struct rte_mbuf *m, *prev; uint32_t i, n, ofs, first_len; uint32_t last_len, move_len, payload_len; + uint32_t curr_idx = 0; first_len = fp->frags[IP_FIRST_FRAG_IDX].len; n = fp->last_idx - 1; @@ -74,6 +75,7 @@ ipv6_frag_reassemble(const struct ip_frag_pkt *fp) m = fp->frags[IP_LAST_FRAG_IDX].mb; ofs = fp->frags[IP_LAST_FRAG_IDX].ofs; last_len = fp->frags[IP_LAST_FRAG_IDX].len; + curr_idx = IP_LAST_FRAG_IDX; payload_len = ofs + last_len; @@ -90,6 +92,10 @@ ipv6_frag_reassemble(const struct ip_frag_pkt *fp) rte_pktmbuf_adj(m, (uint16_t)(m->l2_len + m->l3_len)); rte_pktmbuf_chain(fp->frags[i].mb, m); + /* this mbuf should not be accessed directly */ + fp->frags[curr_idx].mb = NULL; + curr_idx = i; + /* update our last fragment and offset. */ m = fp->frags[i].mb; ofs = fp->frags[i].ofs; -- 1.9.1