mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-05 15:49:42 -04:00
net: Add skb_dst_check_unset
To prevent dst_entry leaks, add warning when the non-NULL dst_entry is rewritten. Signed-off-by: Stanislav Fomichev <sdf@fomichev.me> Link: https://patch.msgid.link/20250818154032.3173645-8-sdf@fomichev.me Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
3e31075a11
commit
a890348adc
@@ -1159,6 +1159,12 @@ static inline struct dst_entry *skb_dst(const struct sk_buff *skb)
|
||||
return (struct dst_entry *)(skb->_skb_refdst & SKB_DST_PTRMASK);
|
||||
}
|
||||
|
||||
static inline void skb_dst_check_unset(struct sk_buff *skb)
|
||||
{
|
||||
DEBUG_NET_WARN_ON_ONCE((skb->_skb_refdst & SKB_DST_PTRMASK) &&
|
||||
!(skb->_skb_refdst & SKB_DST_NOREF));
|
||||
}
|
||||
|
||||
/**
|
||||
* skb_dstref_steal() - return current dst_entry value and clear it
|
||||
* @skb: buffer
|
||||
@@ -1188,6 +1194,7 @@ static inline unsigned long skb_dstref_steal(struct sk_buff *skb)
|
||||
*/
|
||||
static inline void skb_dstref_restore(struct sk_buff *skb, unsigned long refdst)
|
||||
{
|
||||
skb_dst_check_unset(skb);
|
||||
skb->_skb_refdst = refdst;
|
||||
}
|
||||
|
||||
@@ -1201,6 +1208,7 @@ static inline void skb_dstref_restore(struct sk_buff *skb, unsigned long refdst)
|
||||
*/
|
||||
static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst)
|
||||
{
|
||||
skb_dst_check_unset(skb);
|
||||
skb->slow_gro |= !!dst;
|
||||
skb->_skb_refdst = (unsigned long)dst;
|
||||
}
|
||||
@@ -1217,6 +1225,7 @@ static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst)
|
||||
*/
|
||||
static inline void skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst)
|
||||
{
|
||||
skb_dst_check_unset(skb);
|
||||
WARN_ON(!rcu_read_lock_held() && !rcu_read_lock_bh_held());
|
||||
skb->slow_gro |= !!dst;
|
||||
skb->_skb_refdst = (unsigned long)dst | SKB_DST_NOREF;
|
||||
|
||||
Reference in New Issue
Block a user