From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org
Cc: Justin Forbes <jmforbes@linuxtx.org>,
Zwane Mwaikambo <zwane@arm.linux.org.uk>,
"Theodore Ts'o" <tytso@mit.edu>,
Randy Dunlap <rdunlap@xenotime.net>,
Dave Jones <davej@redhat.com>,
Chuck Wolber <chuckw@quantumlinux.com>,
Chris Wedgwood <reviews@ml.cw.f00f.org>,
Michael Krufky <mkrufky@linuxtv.org>,
Chuck Ebbert <cebbert@redhat.com>,
Domenico Andreoli <cavokz@gmail.com>,
torvalds@linux-foundation.org, akpm@linux-foundation.org,
alan@lxorguk.ukuu.org.uk, bunk@kernel.org,
"David S. Miller" <davem@davemloft.net>
Subject: [patch 11/23] Fix endianness bug in U32 classifier.
Date: Wed, 14 Nov 2007 22:20:38 -0800 [thread overview]
Message-ID: <20071115062038.GL8282@kroah.com> (raw)
In-Reply-To: <20071115061806.GA8282@kroah.com>
[-- Attachment #1: fix-endianness-bug-in-u32-classifier.patch --]
[-- Type: text/plain, Size: 3045 bytes --]
-stable review patch. If anyone has any objections, please let us know.
------------------
From: Radu Rendec <radu.rendec@ines.ro>
changeset 543821c6f5dea5221426eaf1eac98b100249c7ac in mainline.
[PKT_SCHED] CLS_U32: Fix endianness problem with u32 classifier hash masks.
While trying to implement u32 hashes in my shaping machine I ran into
a possible bug in the u32 hash/bucket computing algorithm
(net/sched/cls_u32.c).
The problem occurs only with hash masks that extend over the octet
boundary, on little endian machines (where htonl() actually does
something).
Let's say that I would like to use 0x3fc0 as the hash mask. This means
8 contiguous "1" bits starting at b6. With such a mask, the expected
(and logical) behavior is to hash any address in, for instance,
192.168.0.0/26 in bucket 0, then any address in 192.168.0.64/26 in
bucket 1, then 192.168.0.128/26 in bucket 2 and so on.
This is exactly what would happen on a big endian machine, but on
little endian machines, what would actually happen with current
implementation is 0x3fc0 being reversed (into 0xc03f0000) by htonl()
in the userspace tool and then applied to 192.168.x.x in the u32
classifier. When shifting right by 16 bits (rank of first "1" bit in
the reversed mask) and applying the divisor mask (0xff for divisor
256), what would actually remain is 0x3f applied on the "168" octet of
the address.
One could say is this can be easily worked around by taking endianness
into account in userspace and supplying an appropriate mask (0xfc03)
that would be turned into contiguous "1" bits when reversed
(0x03fc0000). But the actual problem is the network address (inside
the packet) not being converted to host order, but used as a
host-order value when computing the bucket.
Let's say the network address is written as n31 n30 ... n0, with n0
being the least significant bit. When used directly (without any
conversion) on a little endian machine, it becomes n7 ... n0 n8 ..n15
etc in the machine's registers. Thus bits n7 and n8 would no longer be
adjacent and 192.168.64.0/26 and 192.168.128.0/26 would no longer be
consecutive.
The fix is to apply ntohl() on the hmask before computing fshift,
and in u32_hash_fold() convert the packet data to host order before
shifting down by fshift.
With helpful feedback from Jamal Hadi Salim and Jarek Poplawski.
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
net/sched/cls_u32.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -91,7 +91,7 @@ static struct tc_u_common *u32_list;
static __inline__ unsigned u32_hash_fold(u32 key, struct tc_u32_sel *sel, u8 fshift)
{
- unsigned h = (key & sel->hmask)>>fshift;
+ unsigned h = ntohl(key & sel->hmask)>>fshift;
return h;
}
@@ -615,7 +615,7 @@ static int u32_change(struct tcf_proto *
n->handle = handle;
{
u8 i = 0;
- u32 mask = s->hmask;
+ u32 mask = ntohl(s->hmask);
if (mask) {
while (!(mask & 1)) {
i++;
--
next prev parent reply other threads:[~2007-11-15 6:28 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20071115055238.692814352@mini.kroah.org>
2007-11-15 6:18 ` [patch 00/23] 2.6.23-stable review, network changes Greg KH
2007-11-15 6:20 ` [patch 01/23] mac80211: filter locally-originated multicast frames Greg KH
2007-11-15 6:20 ` [patch 02/23] mac80211: Improve sanity checks on injected packets Greg KH
2007-11-15 6:20 ` [patch 03/23] Add get_unaligned to ieee80211_get_radiotap_len Greg KH
2007-11-15 6:20 ` [patch 04/23] Fix advertised packet scheduler timer resolution Greg KH
2007-11-15 6:20 ` [patch 05/23] Fix 9P protocol build Greg KH
2007-11-15 6:20 ` [patch 06/23] Fix SKB_WITH_OVERHEAD calculations Greg KH
2007-11-15 6:29 ` Herbert Xu
2007-11-15 7:00 ` David Miller
2007-11-15 7:31 ` Herbert Xu
2007-11-16 0:31 ` [stable] " Greg KH
2007-11-16 2:42 ` David Miller
2007-11-15 6:20 ` [patch 07/23] Fix kernel_accept() return handling Greg KH
2007-11-15 6:20 ` [patch 08/23] softmac: fix wext MLME request reason code endianness Greg KH
2007-11-15 6:20 ` [patch 09/23] Fix error returns in sys_socketpair() Greg KH
2007-11-15 6:20 ` [patch 10/23] Fix TEQL oops Greg KH
2007-11-15 6:20 ` Greg KH [this message]
2007-11-15 6:20 ` [patch 12/23] Fix VLAN address syncing Greg KH
2007-11-15 6:20 ` [patch 13/23] Fix SET_VLAN_INGRESS_PRIORITY_CMD error return Greg KH
2007-11-15 6:20 ` [patch 14/23] Fix crypto_alloc_comp() error checking Greg KH
2007-11-15 6:20 ` [patch 15/23] Fix netlink timeouts Greg KH
2007-11-15 6:20 ` [patch 16/23] NETFILTER: nf_conntrack_tcp: fix connection reopening Greg KH
2007-11-15 6:20 ` [patch 17/23] ieee80211: fix TKIP QoS bug Greg KH
2007-11-15 6:21 ` [patch 18/23] mac80211: reorder association debug output Greg KH
2007-11-15 6:21 ` [patch 19/23] mac80211: store channel info in sta_bss_list Greg KH
2007-11-15 6:21 ` [patch 20/23] mac80211: store SSID " Greg KH
2007-11-15 6:21 ` [patch 21/23] mac80211: honor IW_SCAN_THIS_ESSID in siwscan ioctl Greg KH
2007-11-15 6:21 ` [patch 22/23] mac80211: only honor IW_SCAN_THIS_ESSID in STA, IBSS, and AP modes Greg KH
2007-11-15 6:21 ` [patch 23/23] mac80211: make ieee802_11_parse_elems return void Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20071115062038.GL8282@kroah.com \
--to=gregkh@suse.de \
--cc=akpm@linux-foundation.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=bunk@kernel.org \
--cc=cavokz@gmail.com \
--cc=cebbert@redhat.com \
--cc=chuckw@quantumlinux.com \
--cc=davej@redhat.com \
--cc=davem@davemloft.net \
--cc=jmforbes@linuxtx.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mkrufky@linuxtv.org \
--cc=rdunlap@xenotime.net \
--cc=reviews@ml.cw.f00f.org \
--cc=stable@kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=tytso@mit.edu \
--cc=zwane@arm.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox