public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Ben Hutchings <ben@decadent.org.uk>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: akpm@linux-foundation.org,
	"Marek Lindner" <mareklindner@neomailbox.ch>,
	"Amadeus Alfa" <amadeus@chemnitz.freifunk.net>,
	"Sven Eckelmann" <sven@narfation.org>,
	"Martin Weinelt" <martin@darmstadt.freifunk.net>,
	"David S. Miller" <davem@davemloft.net>
Subject: [PATCH 3.2 75/94] batman-adv: Fix use-after-free/double-free of tt_req_node
Date: Sat, 13 Aug 2016 18:42:58 +0100	[thread overview]
Message-ID: <lsq.1471110178.698656387@decadent.org.uk> (raw)
In-Reply-To: <lsq.1471110177.296693567@decadent.org.uk>

3.2.82-rc1 review patch.  If anyone has any objections, please let me know.

------------------

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>
[bwh: Backported to 3.2:
 - Adjust context
 - Use struct tt_req_node instead of struct batadv_tt_req_node
 - Use list_empty() instead of hlist_unhashed()
 - Drop kernel-doc change]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
 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
@@ -952,6 +952,29 @@ uint16_t tt_local_crc(struct bat_priv *b
 	return total;
 }
 
+/**
+ * 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 tt_req_node *tt_req_node;
+
+	tt_req_node = container_of(ref, struct 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 tt_req_node *tt_req_node)
+{
+	kref_put(&tt_req_node->refcount, batadv_tt_req_node_release);
+}
+
 static void tt_req_list_free(struct bat_priv *bat_priv)
 {
 	struct tt_req_node *node, *safe;
@@ -960,7 +983,7 @@ static void tt_req_list_free(struct bat_
 
 	list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
 		list_del(&node->list);
-		kfree(node);
+		batadv_tt_req_node_put(node);
 	}
 
 	spin_unlock_bh(&bat_priv->tt_req_list_lock);
@@ -995,7 +1018,7 @@ static void tt_req_purge(struct bat_priv
 		if (is_out_of_time(node->issued_at,
 		    TT_REQUEST_TIMEOUT * 1000)) {
 			list_del(&node->list);
-			kfree(node);
+			batadv_tt_req_node_put(node);
 		}
 	}
 	spin_unlock_bh(&bat_priv->tt_req_list_lock);
@@ -1020,9 +1043,11 @@ static struct tt_req_node *new_tt_req_no
 	if (!tt_req_node)
 		goto unlock;
 
+	kref_init(&tt_req_node->refcount);
 	memcpy(tt_req_node->addr, orig_node->orig, ETH_ALEN);
 	tt_req_node->issued_at = jiffies;
 
+	kref_get(&tt_req_node->refcount);
 	list_add(&tt_req_node->list, &bat_priv->tt_req_list);
 unlock:
 	spin_unlock_bh(&bat_priv->tt_req_list_lock);
@@ -1174,12 +1199,19 @@ out:
 		hardif_free_ref(primary_if);
 	if (ret)
 		kfree_skb(skb);
+
 	if (ret && tt_req_node) {
 		spin_lock_bh(&bat_priv->tt_req_list_lock);
-		list_del(&tt_req_node->list);
+		if (!list_empty(&tt_req_node->list)) {
+			list_del(&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);
+
 	return ret;
 }
 
@@ -1552,7 +1584,7 @@ void handle_tt_response(struct bat_priv
 		if (!compare_eth(node->addr, tt_response->src))
 			continue;
 		list_del(&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
@@ -250,6 +250,7 @@ struct tt_change_node {
 struct tt_req_node {
 	uint8_t addr[ETH_ALEN];
 	unsigned long issued_at;
+	struct kref refcount;
 	struct list_head list;
 };
 

  parent reply	other threads:[~2016-08-14 18:14 UTC|newest]

Thread overview: 99+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-13 17:42 [PATCH 3.2 00/94] 3.2.82-rc1 review Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 88/94] ALSA: timer: Fix leak in SNDRV_TIMER_IOCTL_PARAMS Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 51/94] kprobes/x86: Clear TF bit in fault on single-stepping Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 89/94] ALSA: timer: Fix leak in events via snd_timer_user_ccallback Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 18/94] powerpc/mm/hash64: Factor out hash preload psize check Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 01/94] regmap: cache: Fix typo in cache_bypass parameter description Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 44/94] wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel Ben Hutchings
2016-08-15  5:51   ` Johannes Berg
2016-08-15 22:05     ` Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 70/94] fs/nilfs2: fix potential underflow in call to crc32_le Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 10/94] char: Drop bogus dependency of DEVPORT on !M68K Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 73/94] ALSA: echoaudio: Fix memory allocation Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 19/94] powerpc/mm/hash64: Fix subpage protection with 4K HPTE config Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 47/94] usb: musb: Stop bulk endpoint while queue is rotated Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 37/94] Input: pwm-beeper - fix - scheduling while atomic Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 90/94] ALSA: timer: Fix leak in events via snd_timer_user_tinterrupt Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 22/94] net/mlx4_core: Fix access to uninitialized index Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 50/94] drm/radeon: fix asic initialization for virtualized environments Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 57/94] isa: Call isa_bus_init before dependent ISA bus drivers register Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 48/94] staging:iio: trigger fixes for repeat request of same trigger and allocation failure Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 87/94] USB: usbfs: fix potential infoleak in devio Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 29/94] sunrpc: Update RPCBIND_MAXNETIDLEN Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 25/94] fs/cifs: correctly to anonymous authentication via NTLMSSP Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 56/94] IB/mlx4: Properly initialize GRH TClass and FlowLabel in AHs Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 66/94] Input: wacom_w8001 - w8001_MAX_LENGTH should be 13 Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 20/94] sched/loadavg: Fix loadavg artifacts on fully idle and on fully loaded systems Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 64/94] xen/pciback: Fix conf_space read/write overlap check Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 65/94] IB/mlx4: Fix the SQ size of an RC QP Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 69/94] ALSA: dummy: Fix a use-after-free at closing Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 12/94] USB: serial: option: add more ZTE device ids Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 24/94] PCI: Disable all BAR sizing for devices with non-compliant BARs Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 60/94] ubi: Make recover_peb power cut aware Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 94/94] audit: fix a double fetch in audit_log_single_execve_arg() Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 83/94] ecryptfs: don't allow mmap when the lower fs doesn't support it Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 36/94] Input: pwm-beeper - remove useless call to pwm_config() Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 27/94] fs/cifs: correctly to anonymous authentication for the NTLM(v1) authentication Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 67/94] Input: elantech - add more IC body types to the list Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 68/94] HID: hiddev: validate num_values for HIDIOCGUSAGES, HIDIOCSUSAGES commands Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 77/94] x86/amd_nb: Fix boot crash on non-AMD systems Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 23/94] x86/PCI: Mark Broadwell-EP Home Agent 1 as having non-compliant BARs Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 71/94] staging: iio: accel: fix error check Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 79/94] bonding: prevent out of bound accesses Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 63/94] can: fix oops caused by wrong rtnl dellink usage Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 43/94] fix d_walk()/non-delayed __d_free() race Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 58/94] hwmon: (dell-smm) Restrict fan control and serial number to CAP_SYS_ADMIN by default Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 15/94] MIPS: Adjust set_pte() SMP fix to handle R10000_LLSC_WAR Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 26/94] fs/cifs: correctly to anonymous authentication for the LANMAN authentication Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 08/94] aacraid: Fix for aac_command_thread hang Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 34/94] RDMA/cxgb3: device driver frees DMA memory with different size Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 45/94] usb: f_fs: off by one bug in _ffs_func_bind() Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 52/94] kernel/sysrq, watchdog, sched/core: Reset watchdog on all CPUs while processing sysrq-w Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 86/94] proc: prevent stacking filesystems on top Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 05/94] alpha/PCI: Call iomem_is_exclusive() for IORESOURCE_MEM, but not IORESOURCE_IO Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 59/94] can: at91_can: RX queue could get stuck at high bus load Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 84/94] cifs: dynamic allocation of ntlmssp blob Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 62/94] UBIFS: Implement ->migratepage() Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 16/94] gcov: disable tree-loop-im to reduce stack usage Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 82/94] xenbus: don't BUG() on user mode induced condition Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 93/94] tcp: make challenge acks less predictable Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 30/94] net: ehea: avoid null pointer dereference Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 06/94] crypto: s5p-sss - fix incorrect usage of scatterlists api Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 54/94] kvm: Fix irq route entries exceeding KVM_MAX_IRQ_ROUTES Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 17/94] ata: sata_dwc_460ex: remove incorrect locking Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 61/94] mm: Export migrate_page_move_mapping and migrate_page_copy Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 14/94] ACPI / sysfs: fix error code in get_status() Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 41/94] parisc: Fix pagefault crash in unaligned __get_user() call Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 21/94] mmc: mmc: Fix partition switch timeout for some eMMCs Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 11/94] tty: vt, return error when con_startup fails Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 28/94] fs/cifs: correctly to anonymous authentication for the NTLM(v2) authentication Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 40/94] KVM: x86: fix OOPS after invalid KVM_SET_DEBUGREGS Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 55/94] KEYS: potential uninitialized variable Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 92/94] rds: fix an infoleak in rds_inc_info_copy Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 39/94] ARM: fix PTRACE_SETVFPREGS on SMP systems Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 76/94] ALSA: au88x0: Fix calculation in vortex_wtdma_bufshift() Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 04/94] PCI: Supply CPU physical address (not bus address) to iomem_is_exclusive() Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 02/94] ath5k: Change led pin configuration for compaq c700 laptop Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 72/94] iio: accel: kxsd9: fix the usage of spi_w8r8() Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 74/94] NFS: Fix another OPEN_DOWNGRADE bug Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 53/94] base: make module_create_drivers_dir race-free Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 31/94] Input: uinput - handle compat ioctl for UI_SET_PHYS Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 09/94] ext4: fix hang when processing corrupted orphaned inode list Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 85/94] fs: limit filesystem stacking depth Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 33/94] xen/events: Don't move disabled irqs Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 81/94] qeth: delete napi struct when removing a qeth device Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 03/94] crypto: s5p-sss - Fix missed interrupts when working with 8 kB blocks Ben Hutchings
2016-08-13 17:42 ` Ben Hutchings [this message]
2016-08-13 17:42 ` [PATCH 3.2 49/94] iio: Fix error handling in iio_trigger_attach_poll_func Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 32/94] wait/ptrace: assume __WALL if the child is traced Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 38/94] mac80211_hwsim: Add missing check for HWSIM_ATTR_SIGNAL Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 42/94] x86, build: copy ldlinux.c32 to image.iso Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 80/94] ALSA: timer: Fix negative queue usage by racy accesses Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 46/94] usb: musb: Ensure rx reinit occurs for shared_fifo endpoints Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 91/94] tipc: fix an infoleak in tipc_nl_compat_link_dump Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 07/94] btrfs: bugfix: handle FS_IOC32_{GETFLAGS,SETFLAGS,GETVERSION} in btrfs_ioctl Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 78/94] etherdevice: introduce help function eth_zero_addr() Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 35/94] Input: xpad - prevent spurious input from wired Xbox 360 controllers Ben Hutchings
2016-08-13 17:42 ` [PATCH 3.2 13/94] USB: serial: option: add even more ZTE device ids Ben Hutchings
2016-08-13 20:42 ` [PATCH 3.2 00/94] 3.2.82-rc1 review Guenter Roeck
2016-08-14  7:56   ` Ben Hutchings

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=lsq.1471110178.698656387@decadent.org.uk \
    --to=ben@decadent.org.uk \
    --cc=akpm@linux-foundation.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