| From de8602f4b6801bf45ee7a61f20a14429e4684355 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 23 Jul 2021 18:46:01 -0400 |
| Subject: tipc: do not write skb_shinfo frags when doing decrytion |
| |
| From: Xin Long <lucien.xin@gmail.com> |
| |
| [ 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> |
| --- |
| net/tipc/crypto.c | 14 ++++---------- |
| 1 file 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 */ |
| -- |
| 2.30.2 |
| |