[Devel] [PATCH RHEL7 COMMIT] ms/net: adjust skb->truesize in pskb_expand_head()
Konstantin Khorenko
khorenko at virtuozzo.com
Mon Apr 20 20:56:58 MSK 2020
The commit is pushed to "branch-rh7-3.10.0-1127.vz7.150.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1127.vz7.150.2
------>
commit 13a3a2eb26a97afaea34b3a4165b5ff663d5173e
Author: Eric Dumazet <edumazet at google.com>
Date: Fri Jan 27 07:11:27 2017 -0800
ms/net: adjust skb->truesize in pskb_expand_head()
Slava Shwartsman reported a warning in skb_try_coalesce(), when we
detect skb->truesize is completely wrong.
In his case, issue came from IPv6 reassembly coping with malicious
datagrams, that forced various pskb_may_pull() to reallocate a bigger
skb->head than the one allocated by NIC driver before entering GRO
layer.
Current code does not change skb->truesize, leaving this burden to
callers if they care enough.
Blindly changing skb->truesize in pskb_expand_head() is not
easy, as some producers might track skb->truesize, for example
in xmit path for back pressure feedback (sk->sk_wmem_alloc)
We can detect the cases where it should be safe to change
skb->truesize :
1) skb is not attached to a socket.
2) If it is attached to a socket, destructor is sock_edemux()
My audit gave only two callers doing their own skb->truesize
manipulation.
I had to remove skb parameter in sock_edemux macro when
CONFIG_INET is not set to avoid a compile error.
Signed-off-by: Eric Dumazet <edumazet at google.com>
Reported-by: Slava Shwartsman <slavash at mellanox.com>
Signed-off-by: David S. Miller <davem at davemloft.net>
https://jira.sw.ru/browse/PSBM-102386
https://github.com/tempesta-tech/tempesta/issues/926
(cherry picked from commit 158f323b9868b59967ad96957c4ca388161be321)
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
Backport notes: ieee80211_data_from_8023() hunk has been dropped,
seems the functional has been removed by RedHat, anyway, not used since 2012.
---
net/core/skbuff.c | 14 +++++++++++---
net/netlink/af_netlink.c | 4 +---
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 4f826dca83104..ccd585789f3d8 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1251,10 +1251,10 @@ EXPORT_SYMBOL(__pskb_copy);
int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
gfp_t gfp_mask)
{
- int i;
- u8 *data;
- int size = nhead + skb_end_offset(skb) + ntail;
+ int i, osize = skb_end_offset(skb);
+ int size = osize + nhead + ntail;
long off;
+ u8 *data;
BUG_ON(nhead < 0);
@@ -1316,6 +1316,14 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
skb->hdr_len = 0;
skb->nohdr = 0;
atomic_set(&skb_shinfo(skb)->dataref, 1);
+
+ /* It is not generally safe to change skb->truesize.
+ * For the moment, we really care of rx path, or
+ * when skb is orphaned (not attached to a socket).
+ */
+ if (!skb->sk || skb->destructor == sock_edemux)
+ skb->truesize += size - osize;
+
return 0;
nofrags:
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index efaa94abfc03e..382141c8a0d71 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1166,9 +1166,7 @@ static struct sk_buff *netlink_trim(struct sk_buff *skb, gfp_t allocation)
skb = nskb;
}
- if (!pskb_expand_head(skb, 0, -delta, allocation))
- skb->truesize -= delta;
-
+ pskb_expand_head(skb, 0, -delta, allocation);
return skb;
}
More information about the Devel
mailing list