mirror of
https://github.com/lkl/linux.git
synced 2025-12-19 08:03:01 +09:00
net: add a refcount tracker for kernel sockets
Commit ffa84b5ffb ("net: add netns refcount tracker to struct sock")
added a tracker to sockets, but did not track kernel sockets.
We still have syzbot reports hinting about netns being destroyed
while some kernel TCP sockets had not been dismantled.
This patch tracks kernel sockets, and adds a ref_tracker_dir_print()
call to net_free() right before the netns is freed.
Normally, each layer is responsible for properly releasing its
kernel sockets before last call to net_free().
This debugging facility is enabled with CONFIG_NET_NS_REFCNT_TRACKER=y
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Tested-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
b29e0dece4
commit
0cafd77dcd
@@ -92,7 +92,9 @@ struct net {
|
||||
|
||||
struct ns_common ns;
|
||||
struct ref_tracker_dir refcnt_tracker;
|
||||
|
||||
struct ref_tracker_dir notrefcnt_tracker; /* tracker for objects not
|
||||
* refcounted against netns
|
||||
*/
|
||||
struct list_head dev_base_head;
|
||||
struct proc_dir_entry *proc_net;
|
||||
struct proc_dir_entry *proc_net_stat;
|
||||
@@ -320,19 +322,31 @@ static inline int check_net(const struct net *net)
|
||||
#endif
|
||||
|
||||
|
||||
static inline void netns_tracker_alloc(struct net *net,
|
||||
netns_tracker *tracker, gfp_t gfp)
|
||||
static inline void __netns_tracker_alloc(struct net *net,
|
||||
netns_tracker *tracker,
|
||||
bool refcounted,
|
||||
gfp_t gfp)
|
||||
{
|
||||
#ifdef CONFIG_NET_NS_REFCNT_TRACKER
|
||||
ref_tracker_alloc(&net->refcnt_tracker, tracker, gfp);
|
||||
ref_tracker_alloc(refcounted ? &net->refcnt_tracker :
|
||||
&net->notrefcnt_tracker,
|
||||
tracker, gfp);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void netns_tracker_free(struct net *net,
|
||||
netns_tracker *tracker)
|
||||
static inline void netns_tracker_alloc(struct net *net, netns_tracker *tracker,
|
||||
gfp_t gfp)
|
||||
{
|
||||
__netns_tracker_alloc(net, tracker, true, gfp);
|
||||
}
|
||||
|
||||
static inline void __netns_tracker_free(struct net *net,
|
||||
netns_tracker *tracker,
|
||||
bool refcounted)
|
||||
{
|
||||
#ifdef CONFIG_NET_NS_REFCNT_TRACKER
|
||||
ref_tracker_free(&net->refcnt_tracker, tracker);
|
||||
ref_tracker_free(refcounted ? &net->refcnt_tracker :
|
||||
&net->notrefcnt_tracker, tracker);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -346,7 +360,7 @@ static inline struct net *get_net_track(struct net *net,
|
||||
|
||||
static inline void put_net_track(struct net *net, netns_tracker *tracker)
|
||||
{
|
||||
netns_tracker_free(net, tracker);
|
||||
__netns_tracker_free(net, tracker, true);
|
||||
put_net(net);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user