aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/icmp_socket.c
diff options
context:
space:
mode:
authorLinus Lüssing <linus.luessing@web.de>2011-03-14 18:43:37 -0400
committerSven Eckelmann <sven@narfation.org>2011-04-17 15:11:01 -0400
commite1a5382f978b67b5cc36eec65e6046730ce07714 (patch)
treef7ca07cde3a49858d0cfa33e0189a659a1fcc95d /net/batman-adv/icmp_socket.c
parent57f0c07c4d0da8bcc23e21c330fe9c7c5cf776b5 (diff)
batman-adv: Make orig_node->router an rcu protected pointer
The rcu protected macros rcu_dereference() and rcu_assign_pointer() for the orig_node->router need to be used, as well as spin/rcu locking. Otherwise we might end up using a router pointer pointing to already freed memory. Therefore this commit introduces the safe getter method orig_node_get_router(). Signed-off-by: Linus Lüssing <linus.luessing@web.de> Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> Signed-off-by: Sven Eckelmann <sven@narfation.org>
Diffstat (limited to 'net/batman-adv/icmp_socket.c')
-rw-r--r--net/batman-adv/icmp_socket.c18
1 files changed, 3 insertions, 15 deletions
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c
index 34ce56c358e5..49079c254476 100644
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -218,23 +218,13 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
218 if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) 218 if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
219 goto dst_unreach; 219 goto dst_unreach;
220 220
221 rcu_read_lock();
222 orig_node = orig_hash_find(bat_priv, icmp_packet->dst); 221 orig_node = orig_hash_find(bat_priv, icmp_packet->dst);
223
224 if (!orig_node) 222 if (!orig_node)
225 goto unlock; 223 goto dst_unreach;
226
227 neigh_node = orig_node->router;
228 224
225 neigh_node = orig_node_get_router(orig_node);
229 if (!neigh_node) 226 if (!neigh_node)
230 goto unlock; 227 goto dst_unreach;
231
232 if (!atomic_inc_not_zero(&neigh_node->refcount)) {
233 neigh_node = NULL;
234 goto unlock;
235 }
236
237 rcu_read_unlock();
238 228
239 if (!neigh_node->if_incoming) 229 if (!neigh_node->if_incoming)
240 goto dst_unreach; 230 goto dst_unreach;
@@ -252,8 +242,6 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
252 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 242 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
253 goto out; 243 goto out;
254 244
255unlock:
256 rcu_read_unlock();
257dst_unreach: 245dst_unreach:
258 icmp_packet->msg_type = DESTINATION_UNREACHABLE; 246 icmp_packet->msg_type = DESTINATION_UNREACHABLE;
259 bat_socket_add_packet(socket_client, icmp_packet, packet_len); 247 bat_socket_add_packet(socket_client, icmp_packet, packet_len);