FAILED: patch "[PATCH] batman-adv: v: stop OGMv2 on disabled interface" failed to apply to 6.6-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.6-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.6.y
git checkout FETCH_HEAD
git cherry-pick -x f8ce8b8331a1bc44ad4905886a482214d428b253
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026052857-uncanny-papyrus-8490@gregkh' --subject-prefix 'PATCH 6.6.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From f8ce8b8331a1bc44ad4905886a482214d428b253 Mon Sep 17 00:00:00 2001
From: Sven Eckelmann <[email protected]>
Date: Sat, 9 May 2026 22:44:12 +0200
Subject: [PATCH] batman-adv: v: stop OGMv2 on disabled interface
When a batadv_hard_iface is disabled, its mesh_iface pointer is set to NULL. However, batadv_v_ogm_send_meshif() may still dispatch OGMs via batadv_v_ogm_queue_on_if() for interfaces that have since lost their mesh_iface association. This results in a NULL pointer dereference when batadv_v_ogm_queue_on_if() unconditionally calls netdev_priv() on the now NULL hard_iface->mesh_iface to retrieve the batadv_priv.
It is necessary to ensure that the batadv_v_ogm_queue_on_if() checks that it is using the same mesh_iface for which batadv_v_ogm_send_meshif() was called.
net/batman-adv/bat_v_ogm.c +21 -12
@@ -113,14 +113,14 @@ static void batadv_v_ogm_start_timer(struct batadv_priv *bat_priv)/** * batadv_v_ogm_send_to_if() - send a batman ogm using a given interface +* @bat_priv: the bat priv with all the mesh interface information * @skb: the OGM to send * @hard_iface: the interface to use to send the OGM */ -static void batadv_v_ogm_send_to_if (struct sk_buff *skb, +static void batadv_v_ogm_send_to_if (struct batadv_priv *bat_priv, +struct sk_buff *skb,struct batadv_hard_iface *hard_iface) { -struct batadv_priv *bat_priv =netdev_priv (hard_iface->mesh_iface); -if (hard_iface->if_status !=BATADV_IF_ACTIVE ) {kfree_skb (skb);return ;
@@ -187,6 +187,7 @@ static void batadv_v_ogm_aggr_list_free(struct batadv_hard_iface *hard_iface)/** * batadv_v_ogm_aggr_send() - flush & send aggregation queue +* @bat_priv: the bat priv with all the mesh interface information * @hard_iface: the interface with the aggregation queue to flush * * Aggregates all OGMv2 packets currently in the aggregation queue into a
@@ -196,7 +197,8 @@ static void batadv_v_ogm_aggr_list_free(struct batadv_hard_iface *hard_iface)* * Caller needs to hold the hard_iface->bat_v.aggr_list.lock. */ -static void batadv_v_ogm_aggr_send (struct batadv_hard_iface *hard_iface) +static void batadv_v_ogm_aggr_send (struct batadv_priv *bat_priv, +struct batadv_hard_iface *hard_iface) {unsigned int aggr_len = hard_iface->bat_v.aggr_len;struct sk_buff *skb_aggr;
@@ -226,27 +228,32 @@ static void batadv_v_ogm_aggr_send(struct batadv_hard_iface *hard_iface)consume_skb (skb); } -batadv_v_ogm_send_to_if (skb_aggr, hard_iface); +batadv_v_ogm_send_to_if (bat_priv, skb_aggr, hard_iface); }/** * batadv_v_ogm_queue_on_if() - queue a batman ogm on a given interface +* @bat_priv: the bat priv with all the mesh interface information * @skb: the OGM to queue * @hard_iface: the interface to queue the OGM on */ -static void batadv_v_ogm_queue_on_if (struct sk_buff *skb, +static void batadv_v_ogm_queue_on_if (struct batadv_priv *bat_priv, +struct sk_buff *skb,struct batadv_hard_iface *hard_iface) { -struct batadv_priv *bat_priv =netdev_priv (hard_iface->mesh_iface); +if (hard_iface->mesh_iface != bat_priv->mesh_iface) { +kfree_skb (skb); +return ; + }if (!atomic_read (&bat_priv->aggregated_ogms)) { -batadv_v_ogm_send_to_if (skb, hard_iface); +batadv_v_ogm_send_to_if (bat_priv, skb, hard_iface);return ; }spin_lock_bh (&hard_iface->bat_v.aggr_list.lock);if (!batadv_v_ogm_queue_left (skb, hard_iface)) -batadv_v_ogm_aggr_send (hard_iface); +batadv_v_ogm_aggr_send (bat_priv, hard_iface); hard_iface->bat_v.aggr_len +=batadv_v_ogm_len (skb);__skb_queue_tail (&hard_iface->bat_v.aggr_list, skb);
@@ -343,7 +350,7 @@ static void batadv_v_ogm_send_meshif(struct batadv_priv *bat_priv)break ; } -batadv_v_ogm_queue_on_if (skb_tmp, hard_iface); +batadv_v_ogm_queue_on_if (bat_priv, skb_tmp, hard_iface);batadv_hardif_put (hard_iface); }rcu_read_unlock ();
@@ -383,12 +390,14 @@ void batadv_v_ogm_aggr_work(struct work_struct *work) {struct batadv_hard_iface_bat_v *batv;struct batadv_hard_iface *hard_iface; +struct batadv_priv *bat_priv; batv = container_of(work, struct batadv_hard_iface_bat_v, aggr_wq.work); hard_iface = container_of(batv, struct batadv_hard_iface, bat_v); + bat_priv =netdev_priv (hard_iface->mesh_iface);spin_lock_bh (&hard_iface->bat_v.aggr_list.lock); -batadv_v_ogm_aggr_send (hard_iface); +batadv_v_ogm_aggr_send (bat_priv, hard_iface);spin_unlock_bh (&hard_iface->bat_v.aggr_list.lock);batadv_v_ogm_start_queue_timer (hard_iface);
@@ -578,7 +587,7 @@ static void batadv_v_ogm_forward(struct batadv_priv *bat_priv, if_outgoing->net_dev->name,ntohl (ogm_forward->throughput), ogm_forward->ttl, if_incoming->net_dev->name); -batadv_v_ogm_queue_on_if (skb, if_outgoing); +batadv_v_ogm_queue_on_if (bat_priv, skb, if_outgoing); out:batadv_orig_ifinfo_put (orig_ifinfo);
Sven Eckelmann
maintainerPATCH 1/1 batman-adv: v: stop OGMv2 on disabled interface
commit f8ce8b8331a1bc44ad4905886a482214d428b253 upstream.
When a batadv_hard_iface is disabled, its mesh_iface pointer is set to NULL. However, batadv_v_ogm_send_meshif() may still dispatch OGMs via batadv_v_ogm_queue_on_if() for interfaces that have since lost their mesh_iface association. This results in a NULL pointer dereference when batadv_v_ogm_queue_on_if() unconditionally calls netdev_priv() on the now NULL hard_iface->mesh_iface to retrieve the batadv_priv.
It is necessary to ensure that the batadv_v_ogm_queue_on_if() checks that it is using the same mesh_iface for which batadv_v_ogm_send_meshif() was called.
--- net/batman-adv/bat_v_ogm.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-)
net/batman-adv/bat_v_ogm.c +21 -12
@@ -115,14 +115,14 @@ static void batadv_v_ogm_start_timer(struct batadv_priv *bat_priv)/** * batadv_v_ogm_send_to_if() - send a batman ogm using a given interface +* @bat_priv: the bat priv with all the mesh interface information * @skb: the OGM to send * @hard_iface: the interface to use to send the OGM */ -static void batadv_v_ogm_send_to_if (struct sk_buff *skb, +static void batadv_v_ogm_send_to_if (struct batadv_priv *bat_priv, +struct sk_buff *skb,struct batadv_hard_iface *hard_iface) { -struct batadv_priv *bat_priv =netdev_priv (hard_iface->soft_iface); -if (hard_iface->if_status !=BATADV_IF_ACTIVE ) {kfree_skb (skb);return ;
@@ -189,6 +189,7 @@ static void batadv_v_ogm_aggr_list_free(struct batadv_hard_iface *hard_iface)/** * batadv_v_ogm_aggr_send() - flush & send aggregation queue +* @bat_priv: the bat priv with all the mesh interface information * @hard_iface: the interface with the aggregation queue to flush * * Aggregates all OGMv2 packets currently in the aggregation queue into a
@@ -198,7 +199,8 @@ static void batadv_v_ogm_aggr_list_free(struct batadv_hard_iface *hard_iface)* * Caller needs to hold the hard_iface->bat_v.aggr_list.lock. */ -static void batadv_v_ogm_aggr_send (struct batadv_hard_iface *hard_iface) +static void batadv_v_ogm_aggr_send (struct batadv_priv *bat_priv, +struct batadv_hard_iface *hard_iface) {unsigned int aggr_len = hard_iface->bat_v.aggr_len;struct sk_buff *skb_aggr;
@@ -228,27 +230,32 @@ static void batadv_v_ogm_aggr_send(struct batadv_hard_iface *hard_iface)consume_skb (skb); } -batadv_v_ogm_send_to_if (skb_aggr, hard_iface); +batadv_v_ogm_send_to_if (bat_priv, skb_aggr, hard_iface); }/** * batadv_v_ogm_queue_on_if() - queue a batman ogm on a given interface +* @bat_priv: the bat priv with all the mesh interface information * @skb: the OGM to queue * @hard_iface: the interface to queue the OGM on */ -static void batadv_v_ogm_queue_on_if (struct sk_buff *skb, +static void batadv_v_ogm_queue_on_if (struct batadv_priv *bat_priv, +struct sk_buff *skb,struct batadv_hard_iface *hard_iface) { -struct batadv_priv *bat_priv =netdev_priv (hard_iface->soft_iface); +if (hard_iface->soft_iface != bat_priv->soft_iface) { +kfree_skb (skb); +return ; + }if (!atomic_read (&bat_priv->aggregated_ogms)) { -batadv_v_ogm_send_to_if (skb, hard_iface); +batadv_v_ogm_send_to_if (bat_priv, skb, hard_iface);return ; }spin_lock_bh (&hard_iface->bat_v.aggr_list.lock);if (!batadv_v_ogm_queue_left (skb, hard_iface)) -batadv_v_ogm_aggr_send (hard_iface); +batadv_v_ogm_aggr_send (bat_priv, hard_iface); hard_iface->bat_v.aggr_len +=batadv_v_ogm_len (skb);__skb_queue_tail (&hard_iface->bat_v.aggr_list, skb);
@@ -347,7 +354,7 @@ static void batadv_v_ogm_send_softif(struct batadv_priv *bat_priv)break ; } -batadv_v_ogm_queue_on_if (skb_tmp, hard_iface); +batadv_v_ogm_queue_on_if (bat_priv, skb_tmp, hard_iface);batadv_hardif_put (hard_iface); }rcu_read_unlock ();
@@ -387,12 +394,14 @@ void batadv_v_ogm_aggr_work(struct work_struct *work) {struct batadv_hard_iface_bat_v *batv;struct batadv_hard_iface *hard_iface; +struct batadv_priv *bat_priv; batv = container_of(work, struct batadv_hard_iface_bat_v, aggr_wq.work); hard_iface = container_of(batv, struct batadv_hard_iface, bat_v); + bat_priv =netdev_priv (hard_iface->soft_iface);spin_lock_bh (&hard_iface->bat_v.aggr_list.lock); -batadv_v_ogm_aggr_send (hard_iface); +batadv_v_ogm_aggr_send (bat_priv, hard_iface);spin_unlock_bh (&hard_iface->bat_v.aggr_list.lock);batadv_v_ogm_start_queue_timer (hard_iface);
@@ -582,7 +591,7 @@ static void batadv_v_ogm_forward(struct batadv_priv *bat_priv, if_outgoing->net_dev->name,ntohl (ogm_forward->throughput), ogm_forward->ttl, if_incoming->net_dev->name); -batadv_v_ogm_queue_on_if (skb, if_outgoing); +batadv_v_ogm_queue_on_if (bat_priv, skb, if_outgoing); out:batadv_orig_ifinfo_put (orig_ifinfo);
Signature · 1 line
2.47.3