Skip to content
/ linux Public

Commit 31ca4fb

Browse files
Stanislav FomichevSasha Levin
authored andcommitted
net: Add skb_dstref_steal and skb_dstref_restore
[ Upstream commit c3f0c02 ] Going forward skb_dst_set will assert that skb dst_entry is empty during skb_dst_set to prevent potential leaks. There are few places that still manually manage dst_entry not using the helpers. Convert them to the following new helpers: - skb_dstref_steal that resets dst_entry and returns previous dst_entry value - skb_dstref_restore that restores dst_entry previously reset via skb_dstref_steal Signed-off-by: Stanislav Fomichev <sdf@fomichev.me> Link: https://patch.msgid.link/20250818154032.3173645-2-sdf@fomichev.me Signed-off-by: Jakub Kicinski <kuba@kernel.org> Stable-dep-of: 81b84de ("xfrm: fix ip_rt_bug race in icmp_route_lookup reverse path") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent dea1465 commit 31ca4fb

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

include/linux/skbuff.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,6 +1122,38 @@ static inline struct dst_entry *skb_dst(const struct sk_buff *skb)
11221122
return (struct dst_entry *)(skb->_skb_refdst & SKB_DST_PTRMASK);
11231123
}
11241124

1125+
/**
1126+
* skb_dstref_steal() - return current dst_entry value and clear it
1127+
* @skb: buffer
1128+
*
1129+
* Resets skb dst_entry without adjusting its reference count. Useful in
1130+
* cases where dst_entry needs to be temporarily reset and restored.
1131+
* Note that the returned value cannot be used directly because it
1132+
* might contain SKB_DST_NOREF bit.
1133+
*
1134+
* When in doubt, prefer skb_dst_drop() over skb_dstref_steal() to correctly
1135+
* handle dst_entry reference counting.
1136+
*
1137+
* Returns: original skb dst_entry.
1138+
*/
1139+
static inline unsigned long skb_dstref_steal(struct sk_buff *skb)
1140+
{
1141+
unsigned long refdst = skb->_skb_refdst;
1142+
1143+
skb->_skb_refdst = 0;
1144+
return refdst;
1145+
}
1146+
1147+
/**
1148+
* skb_dstref_restore() - restore skb dst_entry removed via skb_dstref_steal()
1149+
* @skb: buffer
1150+
* @refdst: dst entry from a call to skb_dstref_steal()
1151+
*/
1152+
static inline void skb_dstref_restore(struct sk_buff *skb, unsigned long refdst)
1153+
{
1154+
skb->_skb_refdst = refdst;
1155+
}
1156+
11251157
/**
11261158
* skb_dst_set - sets skb dst
11271159
* @skb: buffer

0 commit comments

Comments
 (0)