Thread (35 messages) 35 messages, 4 authors, 2015-09-09

Re: [PATCH net] netlink: rx mmap: fix POLLIN condition

From: David Miller <davem@davemloft.net>
Date: 2015-08-26 03:17:16

From: Ken-ichirou MATSUZAWA <redacted>
Date: Thu, 20 Aug 2015 14:54:47 +0900
Now poll() returns immediately after setting kernel current frame
(ring->head) to SKIP from user space even if there are no new
frames. And in a case of all frames is VALID, user space program
unintensionally sets (only) kernel current frame to UNUSED, then
calls poll(), it will not return immediately even though there are
VALID frames.

To avoid situations like above, I think we need to scan all frames
to find a VALID frame at poll() like netlink_alloc_skb(),
netlink_forward_ring() finding an UNUSED frame at skb allocation.

Signed-off-by: Ken-ichirou MATSUZAWA <redacted>
There seems to be a few issues here.

Taking a look at netlink_forward_ring(), it appears buggy.

	static void netlink_forward_ring(struct netlink_ring *ring)
	{
		unsigned int head = ring->head, pos = head;
		const struct nl_mmap_hdr *hdr;

		do {
			hdr = __netlink_lookup_frame(ring, pos);
			if (hdr->nm_status == NL_MMAP_STATUS_UNUSED)
				break;
			if (hdr->nm_status != NL_MMAP_STATUS_SKIP)
				break;
			netlink_increment_head(ring);
		} while (ring->head != head);
	}

No matter what any of this code does, __netlink_lookup_frame() is always
called with the same "pos" value.

So, as far as I can tell, it will look at the same ring entry header over
and over again, every time through this loop.

netlink_increment_head() changes ring->head, but this has no influence
upon the calculations made inside of __netlink_lookup_frame().

So if netlink_forward_ring() _actually_ sees an entry that we should
advance past, it will cycle through the whole ring, advancing ring->head
until it equals the "ring->head != head" loop test fails.

We should definitely fix this bug first.

As per your patch, I wonder if a backwards scan would be faster.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help