stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Sven Eckelmann <sven@narfation.org>,
	Martin Weinelt <martin@darmstadt.freifunk.net>,
	Amadeus Alfa <amadeus@chemnitz.freifunk.net>,
	Marek Lindner <mareklindner@neomailbox.ch>,
	"David S. Miller" <davem@davemloft.net>
Subject: [PATCH 4.4 50/93] batman-adv: Fix use-after-free/double-free of tt_req_node
Date: Thu, 19 Mar 2020 13:59:54 +0100	[thread overview]
Message-ID: <20200319123940.847996821@linuxfoundation.org> (raw)
In-Reply-To: <20200319123924.795019515@linuxfoundation.org>

From: Sven Eckelmann <sven@narfation.org>

commit 9c4604a298e0a9807eaf2cd912d1ebf24d98fbeb upstream.

The tt_req_node is added and removed from a list inside a spinlock. But the
locking is sometimes removed even when the object is still referenced and
will be used later via this reference. For example batadv_send_tt_request
can create a new tt_req_node (including add to a list) and later
re-acquires the lock to remove it from the list and to free it. But at this
time another context could have already removed this tt_req_node from the
list and freed it.

CPU#0

    batadv_batman_skb_recv from net_device 0
    -> batadv_iv_ogm_receive
      -> batadv_iv_ogm_process
        -> batadv_iv_ogm_process_per_outif
          -> batadv_tvlv_ogm_receive
            -> batadv_tvlv_ogm_receive
              -> batadv_tvlv_containers_process
                -> batadv_tvlv_call_handler
                  -> batadv_tt_tvlv_ogm_handler_v1
                    -> batadv_tt_update_orig
                      -> batadv_send_tt_request
                        -> batadv_tt_req_node_new
                           spin_lock(...)
                           allocates new tt_req_node and adds it to list
                           spin_unlock(...)
                           return tt_req_node

CPU#1

    batadv_batman_skb_recv from net_device 1
    -> batadv_recv_unicast_tvlv
      -> batadv_tvlv_containers_process
        -> batadv_tvlv_call_handler
          -> batadv_tt_tvlv_unicast_handler_v1
            -> batadv_handle_tt_response
               spin_lock(...)
               tt_req_node gets removed from list and is freed
               spin_unlock(...)

CPU#0

                      <- returned to batadv_send_tt_request
                         spin_lock(...)
                         tt_req_node gets removed from list and is freed
                         MEMORY CORRUPTION/SEGFAULT/...
                         spin_unlock(...)

This can only be solved via reference counting to allow multiple contexts
to handle the list manipulation while making sure that only the last
context holding a reference will free the object.

Fixes: a73105b8d4c7 ("batman-adv: improved client announcement mechanism")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Tested-by: Martin Weinelt <martin@darmstadt.freifunk.net>
Tested-by: Amadeus Alfa <amadeus@chemnitz.freifunk.net>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/batman-adv/translation-table.c |   43 +++++++++++++++++++++++++++++++------
 net/batman-adv/types.h             |    2 +
 2 files changed, 39 insertions(+), 6 deletions(-)

--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -2206,6 +2206,29 @@ static u32 batadv_tt_local_crc(struct ba
 	return crc;
 }
 
+/**
+ * batadv_tt_req_node_release - free tt_req node entry
+ * @ref: kref pointer of the tt req_node entry
+ */
+static void batadv_tt_req_node_release(struct kref *ref)
+{
+	struct batadv_tt_req_node *tt_req_node;
+
+	tt_req_node = container_of(ref, struct batadv_tt_req_node, refcount);
+
+	kfree(tt_req_node);
+}
+
+/**
+ * batadv_tt_req_node_put - decrement the tt_req_node refcounter and
+ *  possibly release it
+ * @tt_req_node: tt_req_node to be free'd
+ */
+static void batadv_tt_req_node_put(struct batadv_tt_req_node *tt_req_node)
+{
+	kref_put(&tt_req_node->refcount, batadv_tt_req_node_release);
+}
+
 static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
 {
 	struct batadv_tt_req_node *node;
@@ -2215,7 +2238,7 @@ static void batadv_tt_req_list_free(stru
 
 	hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
 		hlist_del_init(&node->list);
-		kfree(node);
+		batadv_tt_req_node_put(node);
 	}
 
 	spin_unlock_bh(&bat_priv->tt.req_list_lock);
@@ -2252,7 +2275,7 @@ static void batadv_tt_req_purge(struct b
 		if (batadv_has_timed_out(node->issued_at,
 					 BATADV_TT_REQUEST_TIMEOUT)) {
 			hlist_del_init(&node->list);
-			kfree(node);
+			batadv_tt_req_node_put(node);
 		}
 	}
 	spin_unlock_bh(&bat_priv->tt.req_list_lock);
@@ -2284,9 +2307,11 @@ batadv_tt_req_node_new(struct batadv_pri
 	if (!tt_req_node)
 		goto unlock;
 
+	kref_init(&tt_req_node->refcount);
 	ether_addr_copy(tt_req_node->addr, orig_node->orig);
 	tt_req_node->issued_at = jiffies;
 
+	kref_get(&tt_req_node->refcount);
 	hlist_add_head(&tt_req_node->list, &bat_priv->tt.req_list);
 unlock:
 	spin_unlock_bh(&bat_priv->tt.req_list_lock);
@@ -2536,13 +2561,19 @@ static int batadv_send_tt_request(struct
 out:
 	if (primary_if)
 		batadv_hardif_free_ref(primary_if);
+
 	if (ret && tt_req_node) {
 		spin_lock_bh(&bat_priv->tt.req_list_lock);
-		/* hlist_del_init() verifies tt_req_node still is in the list */
-		hlist_del_init(&tt_req_node->list);
+		if (!hlist_unhashed(&tt_req_node->list)) {
+			hlist_del_init(&tt_req_node->list);
+			batadv_tt_req_node_put(tt_req_node);
+		}
 		spin_unlock_bh(&bat_priv->tt.req_list_lock);
-		kfree(tt_req_node);
 	}
+
+	if (tt_req_node)
+		batadv_tt_req_node_put(tt_req_node);
+
 	kfree(tvlv_tt_data);
 	return ret;
 }
@@ -2978,7 +3009,7 @@ static void batadv_handle_tt_response(st
 		if (!batadv_compare_eth(node->addr, resp_src))
 			continue;
 		hlist_del_init(&node->list);
-		kfree(node);
+		batadv_tt_req_node_put(node);
 	}
 
 	spin_unlock_bh(&bat_priv->tt.req_list_lock);
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1001,11 +1001,13 @@ struct batadv_tt_change_node {
  * struct batadv_tt_req_node - data to keep track of the tt requests in flight
  * @addr: mac address address of the originator this request was sent to
  * @issued_at: timestamp used for purging stale tt requests
+ * @refcount: number of contexts the object is used by
  * @list: list node for batadv_priv_tt::req_list
  */
 struct batadv_tt_req_node {
 	u8 addr[ETH_ALEN];
 	unsigned long issued_at;
+	struct kref refcount;
 	struct hlist_node list;
 };
 



  parent reply	other threads:[~2020-03-19 13:38 UTC|newest]

Thread overview: 100+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-19 12:59 [PATCH 4.4 00/93] 4.4.217-rc1 review Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 01/93] NFS: Remove superfluous kmap in nfs_readdir_xdr_to_array Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 02/93] r8152: check disconnect status after long sleep Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 03/93] net: nfc: fix bounds checking bugs on "pipe" Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 04/93] bnxt_en: reinitialize IRQs when MTU is modified Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 05/93] fib: add missing attribute validation for tun_id Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 06/93] nl802154: add missing attribute validation Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 07/93] nl802154: add missing attribute validation for dev_type Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 08/93] team: add missing attribute validation for port ifindex Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 09/93] team: add missing attribute validation for array index Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 10/93] nfc: add missing attribute validation for SE API Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 11/93] nfc: add missing attribute validation for vendor subcommand Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 12/93] ipvlan: add cond_resched_rcu() while processing muticast backlog Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 13/93] ipvlan: do not add hardware address of master to its unicast filter list Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 14/93] ipvlan: egress mcast packets are not exceptional Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 15/93] ipvlan: do not use cond_resched_rcu() in ipvlan_process_multicast() Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 16/93] ipvlan: dont deref eth hdr before checking its set Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 17/93] macvlan: add cond_resched() during multicast processing Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 18/93] net: fec: validate the new settings in fec_enet_set_coalesce() Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 19/93] slip: make slhc_compress() more robust against malicious packets Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 20/93] bonding/alb: make sure arp header is pulled before accessing it Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 21/93] net: fq: add missing attribute validation for orphan mask Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 22/93] iommu/vt-d: quirk_ioat_snb_local_iommu: replace WARN_TAINT with pr_warn + add_taint Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 23/93] drm/amd/display: remove duplicated assignment to grph_obj_type Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 24/93] gfs2_atomic_open(): fix O_EXCL|O_CREAT handling on cold dcache Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 25/93] KVM: x86: clear stale x86_emulate_ctxt->intercept value Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 26/93] ARC: define __ALIGN_STR and __ALIGN symbols for ARC Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 27/93] efi: Fix a race and a buffer overflow while reading efivars via sysfs Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 28/93] iommu/vt-d: dmar: replace WARN_TAINT with pr_warn + add_taint Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 29/93] iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 30/93] nl80211: add missing attribute validation for critical protocol indication Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 31/93] nl80211: add missing attribute validation for channel switch Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 32/93] netfilter: cthelper: add missing attribute validation for cthelper Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 33/93] iommu/vt-d: Fix the wrong printing in RHSA parsing Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 34/93] iommu/vt-d: Ignore devices with out-of-spec domain number Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 35/93] mwifiex: Fix heap overflow in mmwifiex_process_tdls_action_frame() Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 36/93] ipv6: restrict IPV6_ADDRFORM operation Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 37/93] efi: Add a sanity check to efivar_store_raw() Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 38/93] batman-adv: Fix invalid read while copying bat_iv.bcast_own Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 39/93] batman-adv: Only put gw_node list reference when removed Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 40/93] batman-adv: Only put orig_node_vlan " Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 41/93] batman-adv: Avoid endless loop in bat-on-bat netdevice check Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 42/93] batman-adv: Fix unexpected free of bcast_own on add_if error Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 43/93] batman-adv: Fix integer overflow in batadv_iv_ogm_calc_tq Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 44/93] batman-adv: init neigh node last seen field Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 45/93] batman-adv: Deactivate TO_BE_ACTIVATED hardif on shutdown Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 46/93] batman-adv: Drop reference to netdevice on last reference Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 47/93] batman-adv: Fix reference counting of vlan object for tt_local_entry Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 48/93] batman-adv: Avoid duplicate neigh_node additions Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 49/93] batman-adv: fix skb deref after free Greg Kroah-Hartman
2020-03-19 12:59 ` Greg Kroah-Hartman [this message]
2020-03-19 12:59 ` [PATCH 4.4 51/93] batman-adv: Fix ICMP RR ethernet access after skb_linearize Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 52/93] batman-adv: Clean up untagged vlan when destroying via rtnl-link Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 53/93] batman-adv: Avoid nullptr dereference in bla after vlan_insert_tag Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 54/93] batman-adv: Avoid nullptr dereference in dat " Greg Kroah-Hartman
2020-03-19 12:59 ` [PATCH 4.4 55/93] batman-adv: Fix orig_node_vlan leak on orig_node_release Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 56/93] batman-adv: lock crc access in bridge loop avoidance Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 57/93] batman-adv: Fix non-atomic bla_claim::backbone_gw access Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 58/93] batman-adv: Fix reference leak in batadv_find_router Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 59/93] batman-adv: Free last_bonding_candidate on release of orig_node Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 60/93] batman-adv: Fix speedy join in gateway client mode Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 61/93] batman-adv: Add missing refcnt for last_candidate Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 62/93] batman-adv: Fix double free during fragment merge error Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 63/93] batman-adv: Fix transmission of final, 16th fragment Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 64/93] batman-adv: Fix rx packet/bytes stats on local ARP reply Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 65/93] batman-adv: fix TT sync flag inconsistencies Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 66/93] batman-adv: Fix lock for ogm cnt access in batadv_iv_ogm_calc_tq Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 67/93] batman-adv: Fix internal interface indices types Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 68/93] batman-adv: update data pointers after skb_cow() Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 69/93] batman-adv: Fix skbuff rcsum on packet reroute Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 70/93] batman-adv: Avoid race in TT TVLV allocator helper Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 71/93] batman-adv: Fix TT sync flags for intermediate TT responses Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 72/93] batman-adv: prevent TT request storms by not sending inconsistent TT TLVLs Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 73/93] batman-adv: Fix debugfs path for renamed hardif Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 74/93] batman-adv: Fix debugfs path for renamed softif Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 75/93] batman-adv: Avoid storing non-TT-sync flags on singular entries too Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 76/93] batman-adv: Prevent duplicated gateway_node entry Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 77/93] batman-adv: Prevent duplicated nc_node entry Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 78/93] batman-adv: Prevent duplicated global TT entry Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 79/93] batman-adv: Prevent duplicated tvlv handler Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 80/93] batman-adv: Reduce claim hash refcnt only for removed entry Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 81/93] batman-adv: Reduce tt_local " Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 82/93] batman-adv: Reduce tt_global " Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 83/93] batman-adv: Only read OGM tvlv_len after buffer len check Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 84/93] batman-adv: Avoid free/alloc race when handling OGM buffer Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 85/93] batman-adv: Dont schedule OGM for disabled interface Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 86/93] perf/amd/uncore: Replace manual sampling check with CAP_NO_INTERRUPT flag Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 87/93] net: ks8851-ml: Fix IRQ handling and locking Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 88/93] signal: avoid double atomic counter increments for user accounting Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 89/93] jbd2: fix data races at struct journal_head Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 90/93] ARM: 8957/1: VDSO: Match ARMv8 timer in cntvct_functional() Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 91/93] ARM: 8958/1: rename missed uaccess .fixup section Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 92/93] mm: slub: add missing TID bump in kmem_cache_alloc_bulk() Greg Kroah-Hartman
2020-03-19 13:00 ` [PATCH 4.4 93/93] ipv4: ensure rcu_read_lock() in cipso_v4_error() Greg Kroah-Hartman
2020-03-19 23:35 ` [PATCH 4.4 00/93] 4.4.217-rc1 review Guenter Roeck
2020-03-20 20:54 ` Chris Paterson
2020-03-21  0:50 ` shuah
2020-03-21  7:12   ` Greg Kroah-Hartman
2020-03-21  4:01 ` Naresh Kamboju
2020-03-21  7:12   ` Greg Kroah-Hartman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200319123940.847996821@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=amadeus@chemnitz.freifunk.net \
    --cc=davem@davemloft.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mareklindner@neomailbox.ch \
    --cc=martin@darmstadt.freifunk.net \
    --cc=stable@vger.kernel.org \
    --cc=sven@narfation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).