summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorXin Long <lucien.xin@gmail.com>2021-07-23 18:46:01 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-08-04 12:46:43 +0200
commit4951ffa3fac8892949a09b630191ff12f35f4b72 (patch)
treeca42d6c8d427d99084574df1eeb632685998d621 /net
parent7eefa0b74f3e55dec85edfe5f5270c6f8b598155 (diff)
downloadlinux-stable-4951ffa3fac8892949a09b630191ff12f35f4b72.tar.gz
linux-stable-4951ffa3fac8892949a09b630191ff12f35f4b72.tar.bz2
linux-stable-4951ffa3fac8892949a09b630191ff12f35f4b72.zip
tipc: do not write skb_shinfo frags when doing decrytion
[ Upstream commit 3cf4375a090473d240281a0d2b04a3a5aaeac34b ] One skb's skb_shinfo frags are not writable, and they can be shared with other skbs' like by pskb_copy(). To write the frags may cause other skb's data crash. So before doing en/decryption, skb_cow_data() should always be called for a cloned or nonlinear skb if req dst is using the same sg as req src. While at it, the likely branch can be removed, as it will be covered by skb_cow_data(). Note that esp_input() has the same issue, and I will fix it in another patch. tipc_aead_encrypt() doesn't have this issue, as it only processes linear data in the unlikely branch. Fixes: fc1b6d6de220 ("tipc: introduce TIPC encryption & authentication") Reported-by: Shuang Li <shuali@redhat.com> Signed-off-by: Xin Long <lucien.xin@gmail.com> Acked-by: Jon Maloy <jmaloy@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net')
-rw-r--r--net/tipc/crypto.c14
1 files changed, 4 insertions, 10 deletions
diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c
index 2301b66280de..f8e73c4a0093 100644
--- a/net/tipc/crypto.c
+++ b/net/tipc/crypto.c
@@ -891,16 +891,10 @@ static int tipc_aead_decrypt(struct net *net, struct tipc_aead *aead,
if (unlikely(!aead))
return -ENOKEY;
- /* Cow skb data if needed */
- if (likely(!skb_cloned(skb) &&
- (!skb_is_nonlinear(skb) || !skb_has_frag_list(skb)))) {
- nsg = 1 + skb_shinfo(skb)->nr_frags;
- } else {
- nsg = skb_cow_data(skb, 0, &unused);
- if (unlikely(nsg < 0)) {
- pr_err("RX: skb_cow_data() returned %d\n", nsg);
- return nsg;
- }
+ nsg = skb_cow_data(skb, 0, &unused);
+ if (unlikely(nsg < 0)) {
+ pr_err("RX: skb_cow_data() returned %d\n", nsg);
+ return nsg;
}
/* Allocate memory for the AEAD operation */