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: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d3a25c980f
commit
5abf7f7e0f
@ -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);
|
|||||||
|
|
||||||
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)
|
|||||||
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,
|
|||||||
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
|
|||||||
__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)
|
|||||||
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user