diff options
author | Linus Lüssing <linus.luessing@web.de> | 2011-03-14 18:43:37 -0400 |
---|---|---|
committer | Sven Eckelmann <sven@narfation.org> | 2011-04-17 15:11:01 -0400 |
commit | e1a5382f978b67b5cc36eec65e6046730ce07714 (patch) | |
tree | f7ca07cde3a49858d0cfa33e0189a659a1fcc95d /net/batman-adv/icmp_socket.c | |
parent | 57f0c07c4d0da8bcc23e21c330fe9c7c5cf776b5 (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.c | 18 |
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 | ||
255 | unlock: | ||
256 | rcu_read_unlock(); | ||
257 | dst_unreach: | 245 | dst_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); |