mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
Merge branch 'net-drop_monitor-fix-concurrency-issues-preemption-warning-and-buffer-overrun'
Eric Dumazet says: ==================== net: drop_monitor: fix concurrency issues, preemption warning, and buffer overrun This series addresses several issues discovered in the drop_monitor subsystem: Patch 1 adds missing tracepoint unregistration synchronization to the net_dm_trace_on_set() error unwind path, preventing in-flight probes from scheduling work after the module reference has been dropped. Patch 2 resolves a race condition during monitoring teardown where per-CPU timers can be re-armed after deletion if a concurrent worker encounters a memory allocation failure, switching to timer_shutdown_sync(). Patch 3 fixes a CONFIG_DEBUG_PREEMPT warning reported by syzbot when kfree_skb() is invoked from preemptible process context, using raw_cpu_ptr() since each per-CPU queue is safely protected by its own spinlock. Patch 4 fixes an out-of-bounds write in reset_per_cpu_data() where memset() overwrote the allocated SKB tailroom by sizeof(struct nlattr) bytes. ==================== Link: https://patch.msgid.link/20260910204612.3762015-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
ad77dba64d
|
|
@ -141,9 +141,8 @@ static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data)
|
|||
|
||||
al = sizeof(struct net_dm_alert_msg);
|
||||
al += dm_hit_limit * sizeof(struct net_dm_drop_point);
|
||||
al += sizeof(struct nlattr);
|
||||
|
||||
skb = genlmsg_new(al, GFP_KERNEL);
|
||||
skb = genlmsg_new(nla_total_size(al), GFP_KERNEL);
|
||||
|
||||
if (!skb)
|
||||
goto err;
|
||||
|
|
@ -448,7 +447,7 @@ net_dm_hw_trap_summary_probe(void *ignore, const struct devlink *devlink,
|
|||
if (metadata->trap_type == DEVLINK_TRAP_TYPE_CONTROL)
|
||||
return;
|
||||
|
||||
hw_data = this_cpu_ptr(&dm_hw_cpu_data);
|
||||
hw_data = raw_cpu_ptr(&dm_hw_cpu_data);
|
||||
raw_spin_lock_irqsave(&hw_data->lock, flags);
|
||||
hw_entries = hw_data->hw_entries;
|
||||
|
||||
|
|
@ -516,7 +515,7 @@ static void net_dm_packet_trace_kfree_skb_hit(void *ignore,
|
|||
*/
|
||||
nskb->tstamp = tstamp;
|
||||
|
||||
data = this_cpu_ptr(&dm_cpu_data);
|
||||
data = raw_cpu_ptr(&dm_cpu_data);
|
||||
|
||||
spin_lock_irqsave(&data->drop_queue.lock, flags);
|
||||
if (skb_queue_len(&data->drop_queue) < net_dm_queue_len)
|
||||
|
|
@ -983,7 +982,7 @@ net_dm_hw_trap_packet_probe(void *ignore, const struct devlink *devlink,
|
|||
NET_DM_SKB_CB(nskb)->hw_metadata = n_hw_metadata;
|
||||
nskb->tstamp = tstamp;
|
||||
|
||||
hw_data = this_cpu_ptr(&dm_hw_cpu_data);
|
||||
hw_data = raw_cpu_ptr(&dm_hw_cpu_data);
|
||||
|
||||
spin_lock_irqsave(&hw_data->drop_queue.lock, flags);
|
||||
if (skb_queue_len(&hw_data->drop_queue) < net_dm_queue_len)
|
||||
|
|
@ -1083,7 +1082,7 @@ static int net_dm_hw_monitor_start(struct netlink_ext_ack *extack)
|
|||
struct per_cpu_dm_data *hw_data = &per_cpu(dm_hw_cpu_data, cpu);
|
||||
struct sk_buff *skb;
|
||||
|
||||
timer_delete_sync(&hw_data->send_timer);
|
||||
timer_shutdown_sync(&hw_data->send_timer);
|
||||
cancel_work_sync(&hw_data->dm_alert_work);
|
||||
while ((skb = __skb_dequeue(&hw_data->drop_queue))) {
|
||||
struct devlink_trap_metadata *hw_metadata;
|
||||
|
|
@ -1117,7 +1116,7 @@ static void net_dm_hw_monitor_stop(struct netlink_ext_ack *extack)
|
|||
struct per_cpu_dm_data *hw_data = &per_cpu(dm_hw_cpu_data, cpu);
|
||||
struct sk_buff *skb;
|
||||
|
||||
timer_delete_sync(&hw_data->send_timer);
|
||||
timer_shutdown_sync(&hw_data->send_timer);
|
||||
cancel_work_sync(&hw_data->dm_alert_work);
|
||||
while ((skb = __skb_dequeue(&hw_data->drop_queue))) {
|
||||
struct devlink_trap_metadata *hw_metadata;
|
||||
|
|
@ -1173,12 +1172,13 @@ static int net_dm_trace_on_set(struct netlink_ext_ack *extack)
|
|||
|
||||
err_unregister_trace:
|
||||
unregister_trace_kfree_skb(ops->kfree_skb_probe, NULL);
|
||||
tracepoint_synchronize_unregister();
|
||||
err_module_put:
|
||||
for_each_possible_cpu(cpu) {
|
||||
struct per_cpu_dm_data *data = &per_cpu(dm_cpu_data, cpu);
|
||||
struct sk_buff *skb;
|
||||
|
||||
timer_delete_sync(&data->send_timer);
|
||||
timer_shutdown_sync(&data->send_timer);
|
||||
cancel_work_sync(&data->dm_alert_work);
|
||||
while ((skb = __skb_dequeue(&data->drop_queue)))
|
||||
consume_skb(skb);
|
||||
|
|
@ -1206,7 +1206,7 @@ static void net_dm_trace_off_set(void)
|
|||
struct per_cpu_dm_data *data = &per_cpu(dm_cpu_data, cpu);
|
||||
struct sk_buff *skb;
|
||||
|
||||
timer_delete_sync(&data->send_timer);
|
||||
timer_shutdown_sync(&data->send_timer);
|
||||
cancel_work_sync(&data->dm_alert_work);
|
||||
while ((skb = __skb_dequeue(&data->drop_queue)))
|
||||
consume_skb(skb);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user