Skip to content

Commit f10e001

Browse files
suyj-fnstklassert
authored andcommitted
net: xfrm: Add '_rcu' tag for rcu protected pointer in netns_xfrm
For rcu protected pointers, we'd better add '__rcu' for them. Once added '__rcu' tag for rcu protected pointer, the sparse tool reports warnings. net/xfrm/xfrm_user.c:1198:39: sparse: expected struct sock *sk net/xfrm/xfrm_user.c:1198:39: sparse: got struct sock [noderef] <asn:4> *nlsk [...] So introduce a new wrapper function of nlmsg_unicast to handle type conversions. This patch also fixes a direct access of a rcu protected socket. Fixes: be33690("[XFRM]: Fix aevent related crash") Signed-off-by: Su Yanjun <[email protected]> Signed-off-by: Steffen Klassert <[email protected]>
1 parent 6ed6918 commit f10e001

File tree

2 files changed

+24
-8
lines changed

2 files changed

+24
-8
lines changed

include/net/netns/xfrm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ struct netns_xfrm {
5757
struct list_head inexact_bins;
5858

5959

60-
struct sock *nlsk;
60+
struct sock __rcu *nlsk;
6161
struct sock *nlsk_stash;
6262

6363
u32 sysctl_aevent_etime;

net/xfrm/xfrm_user.c

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,6 +1071,22 @@ static inline int xfrm_nlmsg_multicast(struct net *net, struct sk_buff *skb,
10711071
return nlmsg_multicast(nlsk, skb, pid, group, GFP_ATOMIC);
10721072
}
10731073

1074+
/* A similar wrapper like xfrm_nlmsg_multicast checking that nlsk is still
1075+
* available.
1076+
*/
1077+
static inline int xfrm_nlmsg_unicast(struct net *net, struct sk_buff *skb,
1078+
u32 pid)
1079+
{
1080+
struct sock *nlsk = rcu_dereference(net->xfrm.nlsk);
1081+
1082+
if (!nlsk) {
1083+
kfree_skb(skb);
1084+
return -EPIPE;
1085+
}
1086+
1087+
return nlmsg_unicast(nlsk, skb, pid);
1088+
}
1089+
10741090
static inline unsigned int xfrm_spdinfo_msgsize(void)
10751091
{
10761092
return NLMSG_ALIGN(4)
@@ -1195,7 +1211,7 @@ static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
11951211
err = build_spdinfo(r_skb, net, sportid, seq, *flags);
11961212
BUG_ON(err < 0);
11971213

1198-
return nlmsg_unicast(net->xfrm.nlsk, r_skb, sportid);
1214+
return xfrm_nlmsg_unicast(net, r_skb, sportid);
11991215
}
12001216

12011217
static inline unsigned int xfrm_sadinfo_msgsize(void)
@@ -1254,7 +1270,7 @@ static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
12541270
err = build_sadinfo(r_skb, net, sportid, seq, *flags);
12551271
BUG_ON(err < 0);
12561272

1257-
return nlmsg_unicast(net->xfrm.nlsk, r_skb, sportid);
1273+
return xfrm_nlmsg_unicast(net, r_skb, sportid);
12581274
}
12591275

12601276
static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -1274,7 +1290,7 @@ static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
12741290
if (IS_ERR(resp_skb)) {
12751291
err = PTR_ERR(resp_skb);
12761292
} else {
1277-
err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).portid);
1293+
err = xfrm_nlmsg_unicast(net, resp_skb, NETLINK_CB(skb).portid);
12781294
}
12791295
xfrm_state_put(x);
12801296
out_noput:
@@ -1337,7 +1353,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
13371353
goto out;
13381354
}
13391355

1340-
err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).portid);
1356+
err = xfrm_nlmsg_unicast(net, resp_skb, NETLINK_CB(skb).portid);
13411357

13421358
out:
13431359
xfrm_state_put(x);
@@ -1903,8 +1919,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
19031919
if (IS_ERR(resp_skb)) {
19041920
err = PTR_ERR(resp_skb);
19051921
} else {
1906-
err = nlmsg_unicast(net->xfrm.nlsk, resp_skb,
1907-
NETLINK_CB(skb).portid);
1922+
err = xfrm_nlmsg_unicast(net, resp_skb,
1923+
NETLINK_CB(skb).portid);
19081924
}
19091925
} else {
19101926
xfrm_audit_policy_delete(xp, err ? 0 : 1, true);
@@ -2062,7 +2078,7 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
20622078
err = build_aevent(r_skb, x, &c);
20632079
BUG_ON(err < 0);
20642080

2065-
err = nlmsg_unicast(net->xfrm.nlsk, r_skb, NETLINK_CB(skb).portid);
2081+
err = xfrm_nlmsg_unicast(net, r_skb, NETLINK_CB(skb).portid);
20662082
spin_unlock_bh(&x->lock);
20672083
xfrm_state_put(x);
20682084
return err;

0 commit comments

Comments
 (0)