netlink: Don't reorder loads/stores before marking mmap netlink frame as available
authorThomas Graf <tgraf@suug.ch>
Thu, 18 Dec 2014 10:30:26 +0000 (10:30 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 27 Jan 2015 15:52:30 +0000 (07:52 -0800)
commit57c374d382b4640eb5a95d8702ef1dec93970c4c
treec752fe213e4956bb02a946c8abd88c3685fca08c
parent5035c9a94424e4ca717a630a1dc052ba600753f4
netlink: Don't reorder loads/stores before marking mmap netlink frame as available

[ Upstream commit a18e6a186f53af06937a2c268c72443336f4ab56 ]

Each mmap Netlink frame contains a status field which indicates
whether the frame is unused, reserved, contains data or needs to
be skipped. Both loads and stores may not be reordeded and must
complete before the status field is changed and another CPU might
pick up the frame for use. Use an smp_mb() to cover needs of both
types of callers to netlink_set_status(), callers which have been
reading data frame from the frame, and callers which have been
filling or releasing and thus writing to the frame.

- Example code path requiring a smp_rmb():
  memcpy(skb->data, (void *)hdr + NL_MMAP_HDRLEN, hdr->nm_len);
  netlink_set_status(hdr, NL_MMAP_STATUS_UNUSED);

- Example code path requiring a smp_wmb():
  hdr->nm_uid = from_kuid(sk_user_ns(sk), NETLINK_CB(skb).creds.uid);
  hdr->nm_gid = from_kgid(sk_user_ns(sk), NETLINK_CB(skb).creds.gid);
  netlink_frame_flush_dcache(hdr);
  netlink_set_status(hdr, NL_MMAP_STATUS_VALID);

Fixes: f9c228 ("netlink: implement memory mapped recvmsg()")
Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/netlink/af_netlink.c