lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 25 Aug 2015 20:17:12 -0700 (PDT)
From:	David Miller <davem@...emloft.net>
To:	chamaken@...il.com
Cc:	netdev@...r.kernel.org, daniel@...earbox.net, fw@...len.de
Subject: Re: [PATCH net] netlink: rx mmap: fix POLLIN condition

From: Ken-ichirou MATSUZAWA <chamaken@...il.com>
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 <chamas@...dion.ne.jp>

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.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ