X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=batman-adv%2Fpatches%2F0070-batman-adv-Avoid-free-alloc-race-when-handling-OGM2-.patch;fp=batman-adv%2Fpatches%2F0070-batman-adv-Avoid-free-alloc-race-when-handling-OGM2-.patch;h=d545a13e1deeaebb2c9ed192f0c9e7e0f56876ff;hb=5cba01e37a7805c31c84107c956331a615760be4;hp=0000000000000000000000000000000000000000;hpb=f659697eff1c40607ad947b338c5fab9e0820668;p=feed%2Frouting.git diff --git a/batman-adv/patches/0070-batman-adv-Avoid-free-alloc-race-when-handling-OGM2-.patch b/batman-adv/patches/0070-batman-adv-Avoid-free-alloc-race-when-handling-OGM2-.patch new file mode 100644 index 0000000..d545a13 --- /dev/null +++ b/batman-adv/patches/0070-batman-adv-Avoid-free-alloc-race-when-handling-OGM2-.patch @@ -0,0 +1,117 @@ +From: Sven Eckelmann +Date: Thu, 3 Oct 2019 17:02:01 +0200 +Subject: batman-adv: Avoid free/alloc race when handling OGM2 buffer + +A B.A.T.M.A.N. V virtual interface has an OGM2 packet buffer which is +initialized using data from the RTNL lock protected netdevice notifier and +other rtnetlink related hooks. It is sent regularly via various slave +interfaces of the batadv virtual interface and in this process also +modified (realloced) to integrate additional state information via TVLV +containers. + +It must be avoided that the worker item is executed without a common lock +with the netdevice notifier/rtnetlink helpers. Otherwise it can either +happen that half modified data is sent out or the functions modifying the +OGM2 buffer try to access already freed memory regions. + +Fixes: 632835348e65 ("batman-adv: OGMv2 - add basic infrastructure") +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/14ee24576213ff02272b7f8d975c7c61d5448aa2 + +diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c +index 5f4fe1889053d4ea7624e4500dcefe2601371024..f5feaa8c4fd228228fea519771e2c9e123b10345 100644 +--- a/net/batman-adv/bat_v_ogm.c ++++ b/net/batman-adv/bat_v_ogm.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -127,14 +128,12 @@ static void batadv_v_ogm_send_to_if(struct sk_buff *skb, + } + + /** +- * batadv_v_ogm_send - periodic worker broadcasting the own OGM +- * @work: work queue item ++ * batadv_v_ogm_send_softif() - periodic worker broadcasting the own OGM ++ * @bat_priv: the bat priv with all the soft interface information + */ +-static void batadv_v_ogm_send(struct work_struct *work) ++static void batadv_v_ogm_send_softif(struct batadv_priv *bat_priv) + { + struct batadv_hard_iface *hard_iface; +- struct batadv_priv_bat_v *bat_v; +- struct batadv_priv *bat_priv; + struct batadv_ogm2_packet *ogm_packet; + struct sk_buff *skb, *skb_tmp; + unsigned char *ogm_buff, *pkt_buff; +@@ -142,8 +141,7 @@ static void batadv_v_ogm_send(struct work_struct *work) + u16 tvlv_len = 0; + int ret; + +- bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work); +- bat_priv = container_of(bat_v, struct batadv_priv, bat_v); ++ ASSERT_RTNL(); + + if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) + goto out; +@@ -235,6 +233,22 @@ out: + return; + } + ++/** ++ * batadv_v_ogm_send() - periodic worker broadcasting the own OGM ++ * @work: work queue item ++ */ ++static void batadv_v_ogm_send(struct work_struct *work) ++{ ++ struct batadv_priv_bat_v *bat_v; ++ struct batadv_priv *bat_priv; ++ ++ rtnl_lock(); ++ bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work); ++ bat_priv = container_of(bat_v, struct batadv_priv, bat_v); ++ batadv_v_ogm_send_softif(bat_priv); ++ rtnl_unlock(); ++} ++ + /** + * batadv_v_ogm_iface_enable - prepare an interface for B.A.T.M.A.N. V + * @hard_iface: the interface to prepare +@@ -261,6 +275,8 @@ void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface) + struct batadv_priv *bat_priv = netdev_priv(primary_iface->soft_iface); + struct batadv_ogm2_packet *ogm_packet; + ++ ASSERT_RTNL(); ++ + if (!bat_priv->bat_v.ogm_buff) + return; + +@@ -870,6 +886,8 @@ int batadv_v_ogm_init(struct batadv_priv *bat_priv) + unsigned char *ogm_buff; + u32 random_seqno; + ++ ASSERT_RTNL(); ++ + bat_priv->bat_v.ogm_buff_len = BATADV_OGM2_HLEN; + ogm_buff = kzalloc(bat_priv->bat_v.ogm_buff_len, GFP_ATOMIC); + if (!ogm_buff) +diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h +index 5c5762f0f89c8b79b52288104d975dc3753bbf82..11ced015ab639f0d82f12ae533a92f356734cafa 100644 +--- a/net/batman-adv/types.h ++++ b/net/batman-adv/types.h +@@ -990,8 +990,8 @@ struct batadv_softif_vlan { + + /** + * struct batadv_priv_bat_v - B.A.T.M.A.N. V per soft-interface private data +- * @ogm_buff: buffer holding the OGM packet +- * @ogm_buff_len: length of the OGM packet buffer ++ * @ogm_buff: buffer holding the OGM packet. rtnl protected ++ * @ogm_buff_len: length of the OGM packet buffer. rtnl protected + * @ogm_seqno: OGM sequence number - used to identify each OGM + * @ogm_wq: workqueue used to schedule OGM transmissions + */