* [PATCH ipsec] xfrm: ah6: validate routing header segments_left
@ 2026-07-21 22:28 Asim Viladi Oglu Manizada
2026-07-23 8:05 ` Steffen Klassert
0 siblings, 1 reply; 3+ messages in thread
From: Asim Viladi Oglu Manizada @ 2026-07-21 22:28 UTC (permalink / raw)
To: netdev; +Cc: steffen.klassert, herbert, davem, edumazet, kuba, pabeni, horms
AH6 rearranges routing-header addresses before computing or verifying the
ICV. ipv6_rearrange_rthdr() assumes that segments_left is not larger than
the number of addresses described by the routing header's hdrlen field.
That assumption does not hold for raw IPv6 HDRINCL packets. A packet with
hdrlen equal to 2 describes one address, but can carry an arbitrary
segments_left value. With segments_left equal to 255, the function moves
its address pointer 4,064 bytes backwards and passes a 4,064-byte length to
memmove(), resulting in an out-of-bounds access.
Validate the invariant locally before modifying the routing header or
performing any address-pointer arithmetic, and propagate malformed-header
errors to the existing AH6 input and output error paths.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Assisted-by: avom-custom-harness:gpt-5.5-qwen3.6-mod-mix
Signed-off-by: Asim Viladi Oglu Manizada <manizada@pm.me>
---
net/ipv6/ah6.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 76f7a2de9108..0f01db802f35 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -233,25 +233,24 @@ static void ipv6_rearrange_destopt(struct ipv6hdr *iph, struct ipv6_opt_hdr *des
* so that they appear in the order they will at the final destination.
* See Appendix A2 of RFC 2402 for details.
*/
-static void ipv6_rearrange_rthdr(struct ipv6hdr *iph, struct ipv6_rt_hdr *rthdr)
+static int ipv6_rearrange_rthdr(struct ipv6hdr *iph, struct ipv6_rt_hdr *rthdr)
{
- int segments, segments_left;
+ unsigned int segments, segments_left;
struct in6_addr *addrs;
struct in6_addr final_addr;
segments_left = rthdr->segments_left;
if (segments_left == 0)
- return;
- rthdr->segments_left = 0;
+ return 0;
- /* The value of rthdr->hdrlen has been verified either by the system
- * call if it is locally generated, or by ipv6_rthdr_rcv() for incoming
- * packets. So we can assume that it is even and that segments is
- * greater than or equal to segments_left.
- *
- * For the same reason we can assume that this option is of type 0.
+ /* Raw locally generated packets can reach AH6 without the invariant
+ * required by the rt0-style address rearrangement below.
*/
segments = rthdr->hdrlen >> 1;
+ if (segments_left > segments)
+ return -EINVAL;
+
+ rthdr->segments_left = 0;
addrs = ((struct rt0_hdr *)rthdr)->addr;
final_addr = addrs[segments - 1];
@@ -261,6 +260,8 @@ static void ipv6_rearrange_rthdr(struct ipv6hdr *iph, struct ipv6_rt_hdr *rthdr)
addrs[0] = iph->daddr;
iph->daddr = final_addr;
+
+ return 0;
}
static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len, int dir)
@@ -273,6 +274,7 @@ static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len, int dir)
} exthdr = { .iph = iph };
char *end = exthdr.raw + len;
int nexthdr = iph->nexthdr;
+ int err;
exthdr.iph++;
@@ -292,7 +294,9 @@ static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len, int dir)
break;
case NEXTHDR_ROUTING:
- ipv6_rearrange_rthdr(iph, exthdr.rth);
+ err = ipv6_rearrange_rthdr(iph, exthdr.rth);
+ if (err)
+ return err;
break;
default:
--
2.53.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH ipsec] xfrm: ah6: validate routing header segments_left
2026-07-21 22:28 [PATCH ipsec] xfrm: ah6: validate routing header segments_left Asim Viladi Oglu Manizada
@ 2026-07-23 8:05 ` Steffen Klassert
2026-07-23 15:07 ` manizada
0 siblings, 1 reply; 3+ messages in thread
From: Steffen Klassert @ 2026-07-23 8:05 UTC (permalink / raw)
To: Asim Viladi Oglu Manizada
Cc: netdev, herbert, davem, edumazet, kuba, pabeni, horms
On Tue, Jul 21, 2026 at 10:28:52PM +0000, Asim Viladi Oglu Manizada wrote:
> AH6 rearranges routing-header addresses before computing or verifying the
> ICV. ipv6_rearrange_rthdr() assumes that segments_left is not larger than
> the number of addresses described by the routing header's hdrlen field.
>
> That assumption does not hold for raw IPv6 HDRINCL packets. A packet with
> hdrlen equal to 2 describes one address, but can carry an arbitrary
> segments_left value. With segments_left equal to 255, the function moves
> its address pointer 4,064 bytes backwards and passes a 4,064-byte length to
> memmove(), resulting in an out-of-bounds access.
>
> Validate the invariant locally before modifying the routing header or
> performing any address-pointer arithmetic, and propagate malformed-header
> errors to the existing AH6 input and output error paths.
>
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Cc: stable@vger.kernel.org
> Assisted-by: avom-custom-harness:gpt-5.5-qwen3.6-mod-mix
> Signed-off-by: Asim Viladi Oglu Manizada <manizada@pm.me>
> ---
> net/ipv6/ah6.c | 26 +++++++++++++++-----------
> 1 file changed, 15 insertions(+), 11 deletions(-)
>
> diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
> index 76f7a2de9108..0f01db802f35 100644
> --- a/net/ipv6/ah6.c
> +++ b/net/ipv6/ah6.c
> @@ -233,25 +233,24 @@ static void ipv6_rearrange_destopt(struct ipv6hdr *iph, struct ipv6_opt_hdr *des
> * so that they appear in the order they will at the final destination.
> * See Appendix A2 of RFC 2402 for details.
> */
> -static void ipv6_rearrange_rthdr(struct ipv6hdr *iph, struct ipv6_rt_hdr *rthdr)
> +static int ipv6_rearrange_rthdr(struct ipv6hdr *iph, struct ipv6_rt_hdr *rthdr)
You changed the return of this function from void to int. Please update
the comment on that function to reflect this. See:
https://netdev-ctrl.bots.linux.dev/logs/build/1131973/14702013/kdoc/summary
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH ipsec] xfrm: ah6: validate routing header segments_left
2026-07-23 8:05 ` Steffen Klassert
@ 2026-07-23 15:07 ` manizada
0 siblings, 0 replies; 3+ messages in thread
From: manizada @ 2026-07-23 15:07 UTC (permalink / raw)
To: Steffen Klassert; +Cc: netdev, herbert, davem, edumazet, kuba, pabeni, horms
On Thursday, July 23rd, 2026 at 1:05 AM, Steffen Klassert <steffen.klassert@secunet.com> wrote:
> On Tue, Jul 21, 2026 at 10:28:52PM +0000, Asim Viladi Oglu Manizada wrote:
> > AH6 rearranges routing-header addresses before computing or verifying the
> > ICV. ipv6_rearrange_rthdr() assumes that segments_left is not larger than
> > the number of addresses described by the routing header's hdrlen field.
> >
> > That assumption does not hold for raw IPv6 HDRINCL packets. A packet with
> > hdrlen equal to 2 describes one address, but can carry an arbitrary
> > segments_left value. With segments_left equal to 255, the function moves
> > its address pointer 4,064 bytes backwards and passes a 4,064-byte length to
> > memmove(), resulting in an out-of-bounds access.
> >
> > Validate the invariant locally before modifying the routing header or
> > performing any address-pointer arithmetic, and propagate malformed-header
> > errors to the existing AH6 input and output error paths.
> >
> > Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> > Cc: stable@vger.kernel.org
> > Assisted-by: avom-custom-harness:gpt-5.5-qwen3.6-mod-mix
> > Signed-off-by: Asim Viladi Oglu Manizada <manizada@pm.me>
> > ---
> > net/ipv6/ah6.c | 26 +++++++++++++++-----------
> > 1 file changed, 15 insertions(+), 11 deletions(-)
> >
> > diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
> > index 76f7a2de9108..0f01db802f35 100644
> > --- a/net/ipv6/ah6.c
> > +++ b/net/ipv6/ah6.c
> > @@ -233,25 +233,24 @@ static void ipv6_rearrange_destopt(struct ipv6hdr *iph, struct ipv6_opt_hdr *des
> > * so that they appear in the order they will at the final destination.
> > * See Appendix A2 of RFC 2402 for details.
> > */
> > -static void ipv6_rearrange_rthdr(struct ipv6hdr *iph, struct ipv6_rt_hdr *rthdr)
> > +static int ipv6_rearrange_rthdr(struct ipv6hdr *iph, struct ipv6_rt_hdr *rthdr)
>
> You changed the return of this function from void to int. Please update
> the comment on that function to reflect this. See:
>
> https://netdev-ctrl.bots.linux.dev/logs/build/1131973/14702013/kdoc/summary
Thanks, this is now at https://lore.kernel.org/netdev/20260723093524.3672512-1-manizada@pm.me/
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-07-23 15:07 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-21 22:28 [PATCH ipsec] xfrm: ah6: validate routing header segments_left Asim Viladi Oglu Manizada
2026-07-23 8:05 ` Steffen Klassert
2026-07-23 15:07 ` manizada
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.