提交 5abf7f7e 编写于 作者: E Eric Dumazet 提交者: David S. Miller

ipv4: fix rcu splat

free_nh_exceptions() should use rcu_dereference_protected(..., 1)
since its called after one RCU grace period.

Also add some const-ification in recent code.
Signed-off-by: NEric Dumazet <edumazet@google.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 d3a25c98
...@@ -148,11 +148,11 @@ static void free_nh_exceptions(struct fib_nh *nh) ...@@ -148,11 +148,11 @@ static void free_nh_exceptions(struct fib_nh *nh)
for (i = 0; i < FNHE_HASH_SIZE; i++) { for (i = 0; i < FNHE_HASH_SIZE; i++) {
struct fib_nh_exception *fnhe; struct fib_nh_exception *fnhe;
fnhe = rcu_dereference(hash[i].chain); fnhe = rcu_dereference_protected(hash[i].chain, 1);
while (fnhe) { while (fnhe) {
struct fib_nh_exception *next; struct fib_nh_exception *next;
next = rcu_dereference(fnhe->fnhe_next); next = rcu_dereference_protected(fnhe->fnhe_next, 1);
kfree(fnhe); kfree(fnhe);
fnhe = next; fnhe = next;
......
...@@ -806,8 +806,8 @@ EXPORT_SYMBOL_GPL(inet_csk_compat_setsockopt); ...@@ -806,8 +806,8 @@ EXPORT_SYMBOL_GPL(inet_csk_compat_setsockopt);
static struct dst_entry *inet_csk_rebuild_route(struct sock *sk, struct flowi *fl) static struct dst_entry *inet_csk_rebuild_route(struct sock *sk, struct flowi *fl)
{ {
struct inet_sock *inet = inet_sk(sk); const struct inet_sock *inet = inet_sk(sk);
struct ip_options_rcu *inet_opt; const struct ip_options_rcu *inet_opt;
__be32 daddr = inet->inet_daddr; __be32 daddr = inet->inet_daddr;
struct flowi4 *fl4; struct flowi4 *fl4;
struct rtable *rt; struct rtable *rt;
......
...@@ -1275,7 +1275,7 @@ static void rt_del(unsigned int hash, struct rtable *rt) ...@@ -1275,7 +1275,7 @@ static void rt_del(unsigned int hash, struct rtable *rt)
spin_unlock_bh(rt_hash_lock_addr(hash)); spin_unlock_bh(rt_hash_lock_addr(hash));
} }
static void __build_flow_key(struct flowi4 *fl4, struct sock *sk, static void __build_flow_key(struct flowi4 *fl4, const struct sock *sk,
const struct iphdr *iph, const struct iphdr *iph,
int oif, u8 tos, int oif, u8 tos,
u8 prot, u32 mark, int flow_flags) u8 prot, u32 mark, int flow_flags)
...@@ -1294,7 +1294,8 @@ static void __build_flow_key(struct flowi4 *fl4, struct sock *sk, ...@@ -1294,7 +1294,8 @@ static void __build_flow_key(struct flowi4 *fl4, struct sock *sk,
iph->daddr, iph->saddr, 0, 0); iph->daddr, iph->saddr, 0, 0);
} }
static void build_skb_flow_key(struct flowi4 *fl4, struct sk_buff *skb, struct sock *sk) static void build_skb_flow_key(struct flowi4 *fl4, const struct sk_buff *skb,
const struct sock *sk)
{ {
const struct iphdr *iph = ip_hdr(skb); const struct iphdr *iph = ip_hdr(skb);
int oif = skb->dev->ifindex; int oif = skb->dev->ifindex;
...@@ -1305,10 +1306,10 @@ static void build_skb_flow_key(struct flowi4 *fl4, struct sk_buff *skb, struct s ...@@ -1305,10 +1306,10 @@ static void build_skb_flow_key(struct flowi4 *fl4, struct sk_buff *skb, struct s
__build_flow_key(fl4, sk, iph, oif, tos, prot, mark, 0); __build_flow_key(fl4, sk, iph, oif, tos, prot, mark, 0);
} }
static void build_sk_flow_key(struct flowi4 *fl4, struct sock *sk) static void build_sk_flow_key(struct flowi4 *fl4, const struct sock *sk)
{ {
const struct inet_sock *inet = inet_sk(sk); const struct inet_sock *inet = inet_sk(sk);
struct ip_options_rcu *inet_opt; const struct ip_options_rcu *inet_opt;
__be32 daddr = inet->inet_daddr; __be32 daddr = inet->inet_daddr;
rcu_read_lock(); rcu_read_lock();
...@@ -1323,8 +1324,8 @@ static void build_sk_flow_key(struct flowi4 *fl4, struct sock *sk) ...@@ -1323,8 +1324,8 @@ static void build_sk_flow_key(struct flowi4 *fl4, struct sock *sk)
rcu_read_unlock(); rcu_read_unlock();
} }
static void ip_rt_build_flow_key(struct flowi4 *fl4, struct sock *sk, static void ip_rt_build_flow_key(struct flowi4 *fl4, const struct sock *sk,
struct sk_buff *skb) const struct sk_buff *skb)
{ {
if (skb) if (skb)
build_skb_flow_key(fl4, skb, sk); build_skb_flow_key(fl4, skb, sk);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册