Skip to content

Commit 48044eb

Browse files
jmberg-inteldavem330
authored andcommitted
netlink: fix netlink_ack() extack race
It seems that it's possible to toggle NETLINK_F_EXT_ACK through setsockopt() while another thread/CPU is building a message inside netlink_ack(), which could then trigger the WARN_ON()s I added since if it goes from being turned off to being turned on between allocating and filling the message, the skb could end up being too small. Avoid this whole situation by storing the value of this flag in a separate variable and using that throughout the function instead. Fixes: 2d4bc93 ("netlink: extended ACK reporting") Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 2de0968 commit 48044eb

1 file changed

Lines changed: 4 additions & 4 deletions

File tree

net/netlink/af_netlink.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2307,6 +2307,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
23072307
size_t tlvlen = 0;
23082308
struct netlink_sock *nlk = nlk_sk(NETLINK_CB(in_skb).sk);
23092309
unsigned int flags = 0;
2310+
bool nlk_has_extack = nlk->flags & NETLINK_F_EXT_ACK;
23102311

23112312
/* Error messages get the original request appened, unless the user
23122313
* requests to cap the error message, and get extra error data if
@@ -2317,7 +2318,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
23172318
payload += nlmsg_len(nlh);
23182319
else
23192320
flags |= NLM_F_CAPPED;
2320-
if (nlk->flags & NETLINK_F_EXT_ACK && extack) {
2321+
if (nlk_has_extack && extack) {
23212322
if (extack->_msg)
23222323
tlvlen += nla_total_size(strlen(extack->_msg) + 1);
23232324
if (extack->bad_attr)
@@ -2326,8 +2327,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
23262327
} else {
23272328
flags |= NLM_F_CAPPED;
23282329

2329-
if (nlk->flags & NETLINK_F_EXT_ACK &&
2330-
extack && extack->cookie_len)
2330+
if (nlk_has_extack && extack && extack->cookie_len)
23312331
tlvlen += nla_total_size(extack->cookie_len);
23322332
}
23332333

@@ -2355,7 +2355,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
23552355
errmsg->error = err;
23562356
memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg) ? nlh->nlmsg_len : sizeof(*nlh));
23572357

2358-
if (nlk->flags & NETLINK_F_EXT_ACK && extack) {
2358+
if (nlk_has_extack && extack) {
23592359
if (err) {
23602360
if (extack->_msg)
23612361
WARN_ON(nla_put_string(skb, NLMSGERR_ATTR_MSG,

0 commit comments

Comments
 (0)