dbf47a2a09
Action sample doesn't properly handle psample_group pointer in overwrite case. Following issues need to be fixed: - In tcf_sample_init() function RCU_INIT_POINTER() is used to set s->psample_group, even though we neither setting the pointer to NULL, nor preventing concurrent readers from accessing the pointer in some way. Use rcu_swap_protected() instead to safely reset the pointer. - Old value of s->psample_group is not released or deallocated in any way, which results resource leak. Use psample_group_put() on non-NULL value obtained with rcu_swap_protected(). - The function psample_group_put() that released reference to struct psample_group pointed by rcu-pointer s->psample_group doesn't respect rcu grace period when deallocating it. Extend struct psample_group with rcu head and use kfree_rcu when freeing it. Fixes: 5c5670fae430 ("net/sched: Introduce sample tc action") Signed-off-by: Vlad Buslov <vladbu@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
38 lines
817 B
C
38 lines
817 B
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef __NET_PSAMPLE_H
|
|
#define __NET_PSAMPLE_H
|
|
|
|
#include <uapi/linux/psample.h>
|
|
#include <linux/list.h>
|
|
|
|
struct psample_group {
|
|
struct list_head list;
|
|
struct net *net;
|
|
u32 group_num;
|
|
u32 refcount;
|
|
u32 seq;
|
|
struct rcu_head rcu;
|
|
};
|
|
|
|
struct psample_group *psample_group_get(struct net *net, u32 group_num);
|
|
void psample_group_put(struct psample_group *group);
|
|
|
|
#if IS_ENABLED(CONFIG_PSAMPLE)
|
|
|
|
void psample_sample_packet(struct psample_group *group, struct sk_buff *skb,
|
|
u32 trunc_size, int in_ifindex, int out_ifindex,
|
|
u32 sample_rate);
|
|
|
|
#else
|
|
|
|
static inline void psample_sample_packet(struct psample_group *group,
|
|
struct sk_buff *skb, u32 trunc_size,
|
|
int in_ifindex, int out_ifindex,
|
|
u32 sample_rate)
|
|
{
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif /* __NET_PSAMPLE_H */
|