batman-adv: Add fixes from upcoming 2016.2 release 194/head
authorSven Eckelmann <sven@narfation.org>
Mon, 6 Jun 2016 17:00:42 +0000 (19:00 +0200)
committerSven Eckelmann <sven@narfation.org>
Tue, 7 Jun 2016 06:14:51 +0000 (08:14 +0200)
The upcoming batman-adv 2016.2 contains multiple new features, code
refactoring and similar things. These may not be fitting for Chaos Calmer
but the changes in the maintenance branch (bugfixes) should be integrated
to increase the stability.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
batman-adv/Makefile
batman-adv/patches/0007-batman-adv-Add-missing-include-for-batadv_v_neigh_is.patch [new file with mode: 0644]
batman-adv/patches/0008-batman-adv-fix-skb-deref-after-free.patch [new file with mode: 0644]
batman-adv/patches/0009-batman-adv-replace-WARN-with-rate-limited-output-on-.patch [new file with mode: 0644]
batman-adv/patches/0010-batman-adv-Fix-build-against-recent-Debian-Stretch-k.patch [new file with mode: 0644]
batman-adv/patches/0011-batman-adv-Clean-up-untagged-vlan-when-destroying-vi.patch [new file with mode: 0644]
batman-adv/patches/0012-batman-adv-Fix-ICMP-RR-ethernet-access-after-skb_lin.patch [new file with mode: 0644]
batman-adv/patches/0013-batman-adv-Fix-double-put-of-vlan-object.patch [new file with mode: 0644]
batman-adv/patches/0014-batman-adv-Fix-use-after-free-double-free-of-tt_req_.patch [new file with mode: 0644]

index 7de2eabe3cdfb46db8f5e63b3e865dc616130924..d222c0b26169a290586e8e9c2d452e99d70782fd 100644 (file)
@@ -11,7 +11,7 @@ include $(TOPDIR)/rules.mk
 PKG_NAME:=batman-adv
 
 PKG_VERSION:=2016.1
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 PKG_MD5SUM:=8c8e449009b4d29512d26ee308960bb5
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
diff --git a/batman-adv/patches/0007-batman-adv-Add-missing-include-for-batadv_v_neigh_is.patch b/batman-adv/patches/0007-batman-adv-Add-missing-include-for-batadv_v_neigh_is.patch
new file mode 100644 (file)
index 0000000..82ffd07
--- /dev/null
@@ -0,0 +1,28 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sat, 7 May 2016 09:50:44 +0200
+Subject: [PATCH] batman-adv: Add missing include for batadv_v_neigh_is_sob
+
+batadv_v_neigh_is_sob started to use false which is defined in
+linux/stddef.h.
+
+Fixes: 036aa7b7181e ("batman-adv: Avoid nullptr derefence in batadv_v_neigh_is_sob")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/9685688ae7dd85804aec2f6ce760611551fe9635
+---
+ net/batman-adv/bat_v.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
+index 0caca2f..1f960c9 100644
+--- a/net/batman-adv/bat_v.c
++++ b/net/batman-adv/bat_v.c
+@@ -27,6 +27,7 @@
+ #include <linux/rculist.h>
+ #include <linux/rcupdate.h>
+ #include <linux/seq_file.h>
++#include <linux/stddef.h>
+ #include <linux/types.h>
+ #include <linux/workqueue.h>
diff --git a/batman-adv/patches/0008-batman-adv-fix-skb-deref-after-free.patch b/batman-adv/patches/0008-batman-adv-fix-skb-deref-after-free.patch
new file mode 100644 (file)
index 0000000..5c8bfd8
--- /dev/null
@@ -0,0 +1,46 @@
+From: Florian Westphal <fw@strlen.de>
+Date: Tue, 10 May 2016 23:17:59 +0200
+Subject: [PATCH] batman-adv: fix skb deref after free
+
+batadv_send_skb_to_orig() calls dev_queue_xmit() so we can't use skb->len.
+
+Fixes: d28785996ad8 ("batman-adv: network coding - buffer unicast packets before forward")
+
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Reviewed-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/6863d3b59fd1f1bef3c4b86707a0b1c5d21e0a07
+---
+ net/batman-adv/routing.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
+index b781bf7..0c0c30e 100644
+--- a/net/batman-adv/routing.c
++++ b/net/batman-adv/routing.c
+@@ -601,6 +601,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
+       struct batadv_unicast_packet *unicast_packet;
+       struct ethhdr *ethhdr = eth_hdr(skb);
+       int res, hdr_len, ret = NET_RX_DROP;
++      unsigned int len;
+       unicast_packet = (struct batadv_unicast_packet *)skb->data;
+@@ -641,6 +642,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
+       if (hdr_len > 0)
+               batadv_skb_set_priority(skb, hdr_len);
++      len = skb->len;
+       res = batadv_send_skb_to_orig(skb, orig_node, recv_if);
+       /* translate transmit result into receive result */
+@@ -648,7 +650,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
+               /* skb was transmitted and consumed */
+               batadv_inc_counter(bat_priv, BATADV_CNT_FORWARD);
+               batadv_add_counter(bat_priv, BATADV_CNT_FORWARD_BYTES,
+-                                 skb->len + ETH_HLEN);
++                                 len + ETH_HLEN);
+               ret = NET_RX_SUCCESS;
+       } else if (res == NET_XMIT_POLICED) {
diff --git a/batman-adv/patches/0009-batman-adv-replace-WARN-with-rate-limited-output-on-.patch b/batman-adv/patches/0009-batman-adv-replace-WARN-with-rate-limited-output-on-.patch
new file mode 100644 (file)
index 0000000..07274b6
--- /dev/null
@@ -0,0 +1,40 @@
+From: Simon Wunderlich <sw@simonwunderlich.de>
+Date: Thu, 12 May 2016 18:52:03 +0200
+Subject: [PATCH] batman-adv: replace WARN with rate limited output on non-existing VLAN
+
+If a VLAN tagged frame is received and the corresponding VLAN is not
+configured on the soft interface, it will splat a WARN on every packet
+received. This is a quite annoying behaviour for some scenarios, e.g. if
+bat0 is bridged with eth0, and there are arbitrary VLAN tagged frames
+from Ethernet coming in without having any VLAN configuration on bat0.
+
+The code should probably create vlan objects on the fly and
+transparently transport these VLAN-tagged Ethernet frames, but until
+this is done, at least the WARN splat should be replaced by a rate
+limited output.
+
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/04792115d24408a72bf8fccd5c4059478fc15eae
+---
+ net/batman-adv/translation-table.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
+index 9b4551a..48adb91 100644
+--- a/net/batman-adv/translation-table.c
++++ b/net/batman-adv/translation-table.c
+@@ -650,8 +650,10 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr,
+       /* increase the refcounter of the related vlan */
+       vlan = batadv_softif_vlan_get(bat_priv, vid);
+-      if (WARN(!vlan, "adding TT local entry %pM to non-existent VLAN %d",
+-               addr, BATADV_PRINT_VID(vid))) {
++      if (!vlan) {
++              net_ratelimited_function(batadv_info, soft_iface,
++                                       "adding TT local entry %pM to non-existent VLAN %d\n",
++                                       addr, BATADV_PRINT_VID(vid));
+               kfree(tt_local);
+               tt_local = NULL;
+               goto out;
diff --git a/batman-adv/patches/0010-batman-adv-Fix-build-against-recent-Debian-Stretch-k.patch b/batman-adv/patches/0010-batman-adv-Fix-build-against-recent-Debian-Stretch-k.patch
new file mode 100644 (file)
index 0000000..127cac8
--- /dev/null
@@ -0,0 +1,58 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sat, 28 May 2016 10:32:48 +0200
+Subject: [PATCH] batman-adv: Fix build against recent Debian Stretch kernels
+
+The kernels for Debian stretch require some special CFLAGS settings which
+are only correctly defined when NOSTDINC_FLAGS is defined inside the
+execution of the Makefile via kbuild. But batman-adv sets it currently
+outside to insert compatibility include headers and compat-sources.
+
+This can be avoided by making the top Makefile kbuild compatible and
+redefining the NOSTDINC_FLAGS when kbuild include this Makefile. The actual
+build of the batman-adv module is then done by adding the subdirectory to
+obj-y.
+
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Tested-by: Martin Weinelt <martin@darmstadt.freifunk.net>
+
+Origin: https://git.open-mesh.org/batman-adv.git/commit/f8fd441e1e30f3a274c9bf44cc33372d4065cbb6
+---
+ Makefile | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index 5d2c058..2568fb2 100644
+--- a/Makefile
++++ b/Makefile
+@@ -43,7 +43,7 @@ RM ?= rm -f
+ REVISION= $(shell     if [ -d "$(PWD)/.git" ]; then \
+                               echo $$(git --git-dir="$(PWD)/.git" describe --always --dirty --match "v*" |sed 's/^v//' 2> /dev/null || echo "[unknown]"); \
+                       fi)
+-export NOSTDINC_FLAGS := \
++NOSTDINC_FLAGS += \
+       -I$(PWD)/compat-include/ \
+       -include $(PWD)/compat.h \
+       $(CFLAGS)
+@@ -52,8 +52,12 @@ ifneq ($(REVISION),)
+ NOSTDINC_FLAGS += -DBATADV_SOURCE_VERSION=\"$(REVISION)\"
+ endif
++obj-y += net/batman-adv/
++
+ BUILD_FLAGS := \
+-      M=$(PWD)/net/batman-adv \
++      M=$(PWD) \
++      PWD=$(PWD) \
++      REVISION=$(REVISION) \
+       CONFIG_BATMAN_ADV=m \
+       CONFIG_BATMAN_ADV_DEBUG=$(CONFIG_BATMAN_ADV_DEBUG) \
+       CONFIG_BATMAN_ADV_BLA=$(CONFIG_BATMAN_ADV_BLA) \
+@@ -61,7 +65,7 @@ BUILD_FLAGS := \
+       CONFIG_BATMAN_ADV_NC=$(CONFIG_BATMAN_ADV_NC) \
+       CONFIG_BATMAN_ADV_MCAST=$(CONFIG_BATMAN_ADV_MCAST) \
+       CONFIG_BATMAN_ADV_BATMAN_V=$(CONFIG_BATMAN_ADV_BATMAN_V) \
+-      INSTALL_MOD_DIR=updates/net/batman-adv/
++      INSTALL_MOD_DIR=updates/
+ all: config
+       $(MAKE) -C $(KERNELPATH) $(BUILD_FLAGS) modules
diff --git a/batman-adv/patches/0011-batman-adv-Clean-up-untagged-vlan-when-destroying-vi.patch b/batman-adv/patches/0011-batman-adv-Clean-up-untagged-vlan-when-destroying-vi.patch
new file mode 100644 (file)
index 0000000..b03d795
--- /dev/null
@@ -0,0 +1,45 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sat, 28 May 2016 14:38:26 +0200
+Subject: [PATCH] batman-adv: Clean up untagged vlan when destroying via rtnl-link
+
+The untagged vlan object is only destroyed when the interface is removed
+via the legacy sysfs interface. But it also has to be destroyed when the
+standard rtnl-link interface is used.
+
+Fixes: 952cebb57518 ("batman-adv: add per VLAN interface attribute framework")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Cc: Antonio Quartulli <a@unstable.cc>
+
+Origin: https://git.open-mesh.org/batman-adv.git/commit/e721749d57ff57d6df4017d62797626eab9902f1
+---
+ net/batman-adv/soft-interface.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
+index 8a136b6..3710620 100644
+--- a/net/batman-adv/soft-interface.c
++++ b/net/batman-adv/soft-interface.c
+@@ -1017,7 +1017,9 @@ void batadv_softif_destroy_sysfs(struct net_device *soft_iface)
+ static void batadv_softif_destroy_netlink(struct net_device *soft_iface,
+                                         struct list_head *head)
+ {
++      struct batadv_priv *bat_priv = netdev_priv(soft_iface);
+       struct batadv_hard_iface *hard_iface;
++      struct batadv_softif_vlan *vlan;
+       list_for_each_entry(hard_iface, &batadv_hardif_list, list) {
+               if (hard_iface->soft_iface == soft_iface)
+@@ -1025,6 +1027,13 @@ static void batadv_softif_destroy_netlink(struct net_device *soft_iface,
+                                                       BATADV_IF_CLEANUP_KEEP);
+       }
++      /* destroy the "untagged" VLAN */
++      vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS);
++      if (vlan) {
++              batadv_softif_destroy_vlan(bat_priv, vlan);
++              batadv_softif_vlan_put(vlan);
++      }
++
+       batadv_sysfs_del_meshif(soft_iface);
+       unregister_netdevice_queue(soft_iface, head);
+ }
diff --git a/batman-adv/patches/0012-batman-adv-Fix-ICMP-RR-ethernet-access-after-skb_lin.patch b/batman-adv/patches/0012-batman-adv-Fix-ICMP-RR-ethernet-access-after-skb_lin.patch
new file mode 100644 (file)
index 0000000..5204cdc
--- /dev/null
@@ -0,0 +1,31 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sun, 29 May 2016 21:25:52 +0200
+Subject: [PATCH] batman-adv: Fix ICMP RR ethernet access after skb_linearize
+
+The skb_linearize may reallocate the skb. This makes the calculated pointer
+for ethhdr invalid. But it the pointer is used later to fill in the RR
+field of the batadv_icmp_packet_rr packet.
+
+Instead re-evaluate eth_hdr after the skb_linearize+skb_cow to fix the
+pointer and avoid the invalid read.
+
+Fixes: bb69cb678d37 ("batman-adv: generalize batman-adv icmp packet handling")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/f6c80c29ef4e8b45b715976107b7ae06fc0be3a0
+---
+ net/batman-adv/routing.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
+index 0c0c30e..27e07dd 100644
+--- a/net/batman-adv/routing.c
++++ b/net/batman-adv/routing.c
+@@ -374,6 +374,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
+               if (skb_cow(skb, ETH_HLEN) < 0)
+                       goto out;
++              ethhdr = eth_hdr(skb);
+               icmph = (struct batadv_icmp_header *)skb->data;
+               icmp_packet_rr = (struct batadv_icmp_packet_rr *)icmph;
+               if (icmp_packet_rr->rr_cur >= BATADV_RR_LEN)
diff --git a/batman-adv/patches/0013-batman-adv-Fix-double-put-of-vlan-object.patch b/batman-adv/patches/0013-batman-adv-Fix-double-put-of-vlan-object.patch
new file mode 100644 (file)
index 0000000..6ea8311
--- /dev/null
@@ -0,0 +1,32 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Fri, 3 Jun 2016 00:00:44 +0100
+Subject: [PATCH] batman-adv: Fix double-put of vlan object
+
+Commit a33d970d0b54 "batman-adv: Fix reference counting of vlan object
+for tt_local_entry") makes each batadv_tt_local_entry hold a single
+reference to a batadv_softif_vlan.  In case a new entry cannot be
+added to the hash table, the error path puts the reference, but the
+reference will also now be dropped by batadv_tt_local_entry_release().
+
+Fixes: a33d970d0b54 ("batman-adv: Fix reference counting of vlan object ...")
+Cc: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Acked-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/22bb8b894900064d3fb09032a47577e89fc30d7c
+---
+ net/batman-adv/translation-table.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
+index 48adb91..5ed782b 100644
+--- a/net/batman-adv/translation-table.c
++++ b/net/batman-adv/translation-table.c
+@@ -693,7 +693,6 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr,
+       if (unlikely(hash_added != 0)) {
+               /* remove the reference for the hash */
+               batadv_tt_local_entry_put(tt_local);
+-              batadv_softif_vlan_put(vlan);
+               goto out;
+       }
diff --git a/batman-adv/patches/0014-batman-adv-Fix-use-after-free-double-free-of-tt_req_.patch b/batman-adv/patches/0014-batman-adv-Fix-use-after-free-double-free-of-tt_req_.patch
new file mode 100644 (file)
index 0000000..33c7f3b
--- /dev/null
@@ -0,0 +1,172 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sat, 4 Jun 2016 08:52:12 +0200
+Subject: [PATCH] batman-adv: Fix use-after-free/double-free of tt_req_node
+
+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: cea194d90b11 ("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>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/c3fef3d9ec6e8b882f321ec20f6f2cb2ee906503
+---
+ net/batman-adv/translation-table.c | 37 +++++++++++++++++++++++++++++++++----
+ net/batman-adv/types.h             |  2 ++
+ 2 files changed, 35 insertions(+), 4 deletions(-)
+
+diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
+index 5ed782b..23fb7ea 100644
+--- a/net/batman-adv/translation-table.c
++++ b/net/batman-adv/translation-table.c
+@@ -2271,6 +2271,29 @@ static u32 batadv_tt_local_crc(struct batadv_priv *bat_priv,
+       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;
+@@ -2280,7 +2303,7 @@ static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
+       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);
+@@ -2317,7 +2340,7 @@ static void batadv_tt_req_purge(struct batadv_priv *bat_priv)
+               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);
+@@ -2349,9 +2372,11 @@ batadv_tt_req_node_new(struct batadv_priv *bat_priv,
+       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);
+@@ -2618,9 +2643,13 @@ out:
+               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);
++              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;
+ }
+@@ -3056,7 +3085,7 @@ static void batadv_handle_tt_response(struct batadv_priv *bat_priv,
+               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);
+diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
+index 1e47fbe..d75beef 100644
+--- a/net/batman-adv/types.h
++++ b/net/batman-adv/types.h
+@@ -1129,11 +1129,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;
+ };