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)
committerDanny Wood <danwood76@gmail.com>
Tue, 29 Jan 2019 13:05:54 +0000 (13:05 +0000)
commit9ed43b392da16e5328c0203897458966389b95db
treeb148b6cee6e7559bbd06ebefc300608f13f6c8e2
parent81356b5f06c8bad6b63636376fb9e5dadd6637a6
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