)]}'
{
  "commit": "6bb0fef489f667cf701853054f44579754f00a06",
  "tree": "65da22b6b07b2883c3171c256ef0e28482a49526",
  "parents": [
    "a66e36568e30ed3714c0e3a12bd3b64696343ff5"
  ],
  "author": {
    "name": "Daniel Borkmann",
    "email": "daniel@iogearbox.net",
    "time": "Thu Sep 10 02:10:57 2015 +0200"
  },
  "committer": {
    "name": "David S. Miller",
    "email": "davem@davemloft.net",
    "time": "Wed Sep 09 21:43:22 2015 -0700"
  },
  "message": "netlink, mmap: fix edge-case leakages in nf queue zero-copy\n\nWhen netlink mmap on receive side is the consumer of nf queue data,\nit can happen that in some edge cases, we write skb shared info into\nthe user space mmap buffer:\n\nAssume a possible rx ring frame size of only 4096, and the network skb,\nwhich is being zero-copied into the netlink skb, contains page frags\nwith an overall skb-\u003elen larger than the linear part of the netlink\nskb.\n\nskb_zerocopy(), which is generic and thus not aware of the fact that\nshared info cannot be accessed for such skbs then tries to write and\nfill frags, thus leaking kernel data/pointers and in some corner cases\npossibly writing out of bounds of the mmap area (when filling the\nlast slot in the ring buffer this way).\n\nI.e. the ring buffer slot is then of status NL_MMAP_STATUS_VALID, has\nan advertised length larger than 4096, where the linear part is visible\nat the slot beginning, and the leaked sizeof(struct skb_shared_info)\nhas been written to the beginning of the next slot (also corrupting\nthe struct nl_mmap_hdr slot header incl. status etc), since skb-\u003eend\npoints to skb-\u003edata + ring-\u003eframe_size - NL_MMAP_HDRLEN.\n\nThe fix adds and lets __netlink_alloc_skb() take the actual needed\nlinear room for the network skb + meta data into account. It\u0027s completely\nirrelevant for non-mmaped netlink sockets, but in case mmap sockets\nare used, it can be decided whether the available skb_tailroom() is\nreally large enough for the buffer, or whether it needs to internally\nfallback to a normal alloc_skb().\n\n\u003eFrom nf queue side, the information whether the destination port is\nan mmap RX ring is not really available without extra port-to-socket\nlookup, thus it can only be determined in lower layers i.e. when\n__netlink_alloc_skb() is called that checks internally for this. I\nchose to add the extra ldiff parameter as mmap will then still work:\nWe have data_len and hlen in nfqnl_build_packet_message(), data_len\nis the full length (capped at queue-\u003ecopy_range) for skb_zerocopy()\nand hlen some possible part of data_len that needs to be copied; the\nrem_len variable indicates the needed remaining linear mmap space.\n\nThe only other workaround in nf queue internally would be after\nallocation time by f.e. cap\u0027ing the data_len to the skb_tailroom()\niff we deal with an mmap skb, but that would 1) expose the fact that\nwe use a mmap skb to upper layers, and 2) trim the skb where we\notherwise could just have moved the full skb into the normal receive\nqueue.\n\nAfter the patch, in my test case the ring slot doesn\u0027t fit and therefore\nshows NL_MMAP_STATUS_COPY, where a full skb carries all the data and\nthus needs to be picked up via recv().\n\nFixes: 3ab1f683bf8b (\"nfnetlink: add support for memory mapped netlink\")\nSigned-off-by: Daniel Borkmann \u003cdaniel@iogearbox.net\u003e\nSigned-off-by: David S. Miller \u003cdavem@davemloft.net\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "9120edb650a068df60b0a2c390ae431ab78671cb",
      "old_mode": 33188,
      "old_path": "include/linux/netlink.h",
      "new_id": "639e9b8b0e4d9ff2c9b10ce5b44a8a328abe2a31",
      "new_mode": 33188,
      "new_path": "include/linux/netlink.h"
    },
    {
      "type": "modify",
      "old_id": "685cc6a17163ffaf1c7649d726f98c5118066fdd",
      "old_mode": 33188,
      "old_path": "net/netfilter/nfnetlink_queue_core.c",
      "new_id": "a5cd6d90b78b16ebd0c96c4d1d426ad7aea6e86b",
      "new_mode": 33188,
      "new_path": "net/netfilter/nfnetlink_queue_core.c"
    },
    {
      "type": "modify",
      "old_id": "173817a5dfad0690446735c975653618f3f51974",
      "old_mode": 33188,
      "old_path": "net/netlink/af_netlink.c",
      "new_id": "7f86d3b550601839f730d4c9f15951f5410e3fd4",
      "new_mode": 33188,
      "new_path": "net/netlink/af_netlink.c"
    }
  ]
}
