ipsec: fix compilation problem

Message ID 1547481483-25978-1-git-send-email-konstantin.ananyev@intel.com (mailing list archive)
State Accepted, archived
Headers
Series ipsec: fix compilation problem |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK
ci/mellanox-Performance-Testing success Performance Testing PASS
ci/intel-Performance-Testing success Performance Testing PASS

Commit Message

Ananyev, Konstantin Jan. 14, 2019, 3:58 p.m. UTC
  gcc 6.2 and 6.4 fails to compile lib/librte_ipsec/sa.c
with the following errors:
/local/kananye1/dpdk.org/lib/librte_ipsec/sa.c:
 In function âinline_outb_tun_pkt_processâ:
 dpdk.org/x86_64-native-linuxapp-gcc/include/rte_memcpy.h:337:2:
 error: array subscript is above array bounds [-Werror=array-bounds]
  rte_mov32((uint8_t *)dst + 1 * 32, (const uint8_t *)src + 1 * 32);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ...

It complains about the following lines of code:
esp_outb_tun_pkt_prepare(struct rte_ipsec_sa *sa, rte_be64_t
        ....
        /* update spi, seqn and iv */
        esph = (struct esp_hdr *)(ph + sa->hdr_len);
        iv = (uint64_t *)(esph + 1);
        rte_memcpy(iv, ivp, sa->iv_len);

While I believe it is a false positive,
it is too excessive to use rte_memcpy() here,
as IV length could be only 0/8/16 bytes.
So introduce small helper function to copy IV and use it
instead of rte_memcpy().

Fixes: 4d7ea3e1459b ("ipsec: implement SA data-path API")
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
 lib/librte_ipsec/crypto.h | 25 +++++++++++++++++++++++++
 lib/librte_ipsec/sa.c     |  6 +++---
 2 files changed, 28 insertions(+), 3 deletions(-)
  

Comments

Thomas Monjalon Jan. 14, 2019, 10:17 p.m. UTC | #1
14/01/2019 16:58, Konstantin Ananyev:
> gcc 6.2 and 6.4 fails to compile lib/librte_ipsec/sa.c
> with the following errors:
> /local/kananye1/dpdk.org/lib/librte_ipsec/sa.c:
>  In function âinline_outb_tun_pkt_processâ:
>  dpdk.org/x86_64-native-linuxapp-gcc/include/rte_memcpy.h:337:2:
>  error: array subscript is above array bounds [-Werror=array-bounds]
>   rte_mov32((uint8_t *)dst + 1 * 32, (const uint8_t *)src + 1 * 32);
>   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>  ...
> 
> It complains about the following lines of code:
> esp_outb_tun_pkt_prepare(struct rte_ipsec_sa *sa, rte_be64_t
>         ....
>         /* update spi, seqn and iv */
>         esph = (struct esp_hdr *)(ph + sa->hdr_len);
>         iv = (uint64_t *)(esph + 1);
>         rte_memcpy(iv, ivp, sa->iv_len);
> 
> While I believe it is a false positive,
> it is too excessive to use rte_memcpy() here,
> as IV length could be only 0/8/16 bytes.
> So introduce small helper function to copy IV and use it
> instead of rte_memcpy().
> 
> Fixes: 4d7ea3e1459b ("ipsec: implement SA data-path API")
> Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

Applied, thanks
  

Patch

diff --git a/lib/librte_ipsec/crypto.h b/lib/librte_ipsec/crypto.h
index 61f5c1433..b5f264831 100644
--- a/lib/librte_ipsec/crypto.h
+++ b/lib/librte_ipsec/crypto.h
@@ -76,6 +76,31 @@  gen_iv(uint64_t iv[IPSEC_MAX_IV_QWORD], rte_be64_t sqn)
 	iv[1] = 0;
 }
 
+/*
+ * Helper routine to copy IV
+ * Righ now we support only algorithms with IV length equals 0/8/16 bytes.
+ */
+static inline void
+copy_iv(uint64_t dst[IPSEC_MAX_IV_QWORD],
+	const uint64_t src[IPSEC_MAX_IV_QWORD], uint32_t len)
+{
+	RTE_BUILD_BUG_ON(IPSEC_MAX_IV_SIZE != 2 * sizeof(uint64_t));
+
+	switch (len) {
+	case IPSEC_MAX_IV_SIZE:
+		dst[1] = src[1];
+		/* fallthrough */
+	case sizeof(uint64_t):
+		dst[0] = src[0];
+		/* fallthrough */
+	case 0:
+		break;
+	default:
+		/* should never happen */
+		RTE_ASSERT(NULL);
+	}
+}
+
 /*
  * from RFC 4303 3.3.2.1.4:
  * If the ESN option is enabled for the SA, the high-order 32
diff --git a/lib/librte_ipsec/sa.c b/lib/librte_ipsec/sa.c
index 8d4ce1ac6..5f55c2a4e 100644
--- a/lib/librte_ipsec/sa.c
+++ b/lib/librte_ipsec/sa.c
@@ -526,7 +526,7 @@  esp_outb_tun_pkt_prepare(struct rte_ipsec_sa *sa, rte_be64_t sqc,
 	/* update spi, seqn and iv */
 	esph = (struct esp_hdr *)(ph + sa->hdr_len);
 	iv = (uint64_t *)(esph + 1);
-	rte_memcpy(iv, ivp, sa->iv_len);
+	copy_iv(iv, ivp, sa->iv_len);
 
 	esph->spi = sa->spi;
 	esph->seq = sqn_low32(sqc);
@@ -689,7 +689,7 @@  esp_outb_trs_pkt_prepare(struct rte_ipsec_sa *sa, rte_be64_t sqc,
 	/* update spi, seqn and iv */
 	esph = (struct esp_hdr *)(ph + uhlen);
 	iv = (uint64_t *)(esph + 1);
-	rte_memcpy(iv, ivp, sa->iv_len);
+	copy_iv(iv, ivp, sa->iv_len);
 
 	esph->spi = sa->spi;
 	esph->seq = sqn_low32(sqc);
@@ -821,7 +821,7 @@  esp_inb_tun_cop_prepare(struct rte_crypto_op *cop,
 		ivc = rte_crypto_op_ctod_offset(cop, uint64_t *, sa->iv_ofs);
 		ivp = rte_pktmbuf_mtod_offset(mb, uint64_t *,
 			pofs + sizeof(struct esp_hdr));
-		rte_memcpy(ivc, ivp, sa->iv_len);
+		copy_iv(ivc, ivp, sa->iv_len);
 	}
 	return 0;
 }