* [PATCH] xfrm: Fix wraparound in xfrm_policy_addr_delta()
@ 2020-12-29 14:58 Visa Hankala
2020-12-29 16:01 ` Florian Westphal
0 siblings, 1 reply; 4+ messages in thread
From: Visa Hankala @ 2020-12-29 14:58 UTC (permalink / raw)
To: Florian Westphal, Steffen Klassert, Herbert Xu, David S. Miller; +Cc: netdev
Use three-way comparison for address elements to avoid integer
wraparound in the result of xfrm_policy_addr_delta().
This ensures that the search trees are built and traversed correctly
when the difference between compared address elements is larger
than INT_MAX.
Fixes: 9cf545ebd591d ("xfrm: policy: store inexact policies in a tree ordered by destination address")
Signed-off-by: Visa Hankala <visa@hankala.org>
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index d622c2548d22..d74902f11dde 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -793,15 +793,20 @@ static int xfrm_policy_addr_delta(const xfrm_address_t *a,
const xfrm_address_t *b,
u8 prefixlen, u16 family)
{
+ u32 ma, mb, mask;
unsigned int pdw, pbi;
int delta = 0;
switch (family) {
case AF_INET:
- if (sizeof(long) == 4 && prefixlen == 0)
- return ntohl(a->a4) - ntohl(b->a4);
- return (ntohl(a->a4) & ((~0UL << (32 - prefixlen)))) -
- (ntohl(b->a4) & ((~0UL << (32 - prefixlen))));
+ mask = ~0U << (32 - prefixlen);
+ ma = ntohl(a->a4) & mask;
+ mb = ntohl(b->a4) & mask;
+ if (ma < mb)
+ delta = -1;
+ else if (ma > mb)
+ delta = 1;
+ break;
case AF_INET6:
pdw = prefixlen >> 5;
pbi = prefixlen & 0x1f;
@@ -812,10 +817,13 @@ static int xfrm_policy_addr_delta(const xfrm_address_t *a,
return delta;
}
if (pbi) {
- u32 mask = ~0u << (32 - pbi);
-
- delta = (ntohl(a->a6[pdw]) & mask) -
- (ntohl(b->a6[pdw]) & mask);
+ mask = ~0U << (32 - pbi);
+ ma = ntohl(a->a6[pdw]) & mask;
+ mb = ntohl(b->a6[pdw]) & mask;
+ if (ma < mb)
+ delta = -1;
+ else if (ma > mb)
+ delta = 1;
}
break;
default:
asd
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] xfrm: Fix wraparound in xfrm_policy_addr_delta()
2020-12-29 14:58 [PATCH] xfrm: Fix wraparound in xfrm_policy_addr_delta() Visa Hankala
@ 2020-12-29 16:01 ` Florian Westphal
2020-12-30 12:06 ` Visa Hankala
0 siblings, 1 reply; 4+ messages in thread
From: Florian Westphal @ 2020-12-29 16:01 UTC (permalink / raw)
To: Visa Hankala
Cc: Florian Westphal, Steffen Klassert, Herbert Xu, David S. Miller, netdev
Visa Hankala <visa@hankala.org> wrote:
> Use three-way comparison for address elements to avoid integer
> wraparound in the result of xfrm_policy_addr_delta().
>
> This ensures that the search trees are built and traversed correctly
> when the difference between compared address elements is larger
> than INT_MAX.
Please provide an update to tools/testing/selftests/net/xfrm_policy.sh
that shows that this is a problem.
> switch (family) {
> case AF_INET:
> - if (sizeof(long) == 4 && prefixlen == 0)
> - return ntohl(a->a4) - ntohl(b->a4);
> - return (ntohl(a->a4) & ((~0UL << (32 - prefixlen)))) -
> - (ntohl(b->a4) & ((~0UL << (32 - prefixlen))));
> + mask = ~0U << (32 - prefixlen);
> + ma = ntohl(a->a4) & mask;
> + mb = ntohl(b->a4) & mask;
This is suspicious. Is prefixlen == 0 impossible?
If not, then after patch
mask = ~0U << 32;
... and function returns 0.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] xfrm: Fix wraparound in xfrm_policy_addr_delta()
2020-12-29 16:01 ` Florian Westphal
@ 2020-12-30 12:06 ` Visa Hankala
2020-12-30 12:46 ` Florian Westphal
0 siblings, 1 reply; 4+ messages in thread
From: Visa Hankala @ 2020-12-30 12:06 UTC (permalink / raw)
To: Florian Westphal; +Cc: Steffen Klassert, Herbert Xu, David S. Miller, netdev
On Tue, Dec 29, 2020 at 05:01:27PM +0100, Florian Westphal wrote:
> Visa Hankala <visa@hankala.org> wrote:
> > Use three-way comparison for address elements to avoid integer
> > wraparound in the result of xfrm_policy_addr_delta().
> >
> > This ensures that the search trees are built and traversed correctly
> > when the difference between compared address elements is larger
> > than INT_MAX.
>
> Please provide an update to tools/testing/selftests/net/xfrm_policy.sh
> that shows that this is a problem.
I will do that in the next revision.
> > switch (family) {
> > case AF_INET:
> > - if (sizeof(long) == 4 && prefixlen == 0)
> > - return ntohl(a->a4) - ntohl(b->a4);
> > - return (ntohl(a->a4) & ((~0UL << (32 - prefixlen)))) -
> > - (ntohl(b->a4) & ((~0UL << (32 - prefixlen))));
> > + mask = ~0U << (32 - prefixlen);
> > + ma = ntohl(a->a4) & mask;
> > + mb = ntohl(b->a4) & mask;
>
> This is suspicious. Is prefixlen == 0 impossible?
>
> If not, then after patch
> mask = ~0U << 32;
>
> ... and function returns 0.
prefixlen == 0 is possible. However, I now realize that left shift
by 32 should be avoided with 32-bit integers.
With prefixlen == 0, there is only one equivalence class, so
returning 0 seems reasonable to me.
Is there a reason why the function has treated /0 prefix as /32
with IPv4? IPv6 does not have this treatment.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] xfrm: Fix wraparound in xfrm_policy_addr_delta()
2020-12-30 12:06 ` Visa Hankala
@ 2020-12-30 12:46 ` Florian Westphal
0 siblings, 0 replies; 4+ messages in thread
From: Florian Westphal @ 2020-12-30 12:46 UTC (permalink / raw)
To: Visa Hankala
Cc: Florian Westphal, Steffen Klassert, Herbert Xu, David S. Miller, netdev
Visa Hankala <visa@hankala.org> wrote:
> On Tue, Dec 29, 2020 at 05:01:27PM +0100, Florian Westphal wrote:
> > This is suspicious. Is prefixlen == 0 impossible?
> >
> > If not, then after patch
> > mask = ~0U << 32;
> >
> > ... and function returns 0.
>
> With prefixlen == 0, there is only one equivalence class, so
> returning 0 seems reasonable to me.
Right, that seems reasonable indeed.
> Is there a reason why the function has treated /0 prefix as /32
> with IPv4? IPv6 does not have this treatment.
Not that I recall, looks like a bug.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2020-12-30 12:47 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-29 14:58 [PATCH] xfrm: Fix wraparound in xfrm_policy_addr_delta() Visa Hankala
2020-12-29 16:01 ` Florian Westphal
2020-12-30 12:06 ` Visa Hankala
2020-12-30 12:46 ` Florian Westphal
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).