net: psp: add more validation
Subsystems (3)
Jakub Kicinski
maintainercover net: psp: add more validation
Address some AI code-scan issues with the PSP code. I don't think any of these are real bugs, but they may become bugs in the future. The two real bugs discovered were posted separately for net. AI reports 3 more which seem plain wrong (rx SPI "leak" on error etc.).
Jakub Kicinski (3):
psp: validate protocol before mutating skb in psp_dev_encapsulate()
psp: add a comment about a psp_dev add netlink notification
psp: validate IPv4 header fields in psp_dev_rcv()
net/psp/psp_main.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-)
Signature · 1 line
2.54.0
Jakub Kicinski
maintainerPATCH 1/3 psp: validate protocol before mutating skb in psp_dev_encapsulate()
Code checkers / AI scans will complain that we have already modified the packet by the time we realize that protocol is not IP.
Move the skb->protocol check to before skb_push()/memmove() so that the skb is not left in a corrupted state when the function returns false for an unsupported protocol. psp_dev_rcv() follows similar pattern.
Today this path is unreachable because both in-tree callers (mlx5 and netdevsim) only reach psp_dev_encapsulate() from TCP socket TX paths where skb->protocol is always ETH_P_IP or ETH_P_IPV6, and both drop the skb on a false return, anyway.
--- net/psp/psp_main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
net/psp/psp_main.c +5 -3
@@ -228,6 +228,10 @@ bool psp_dev_encapsulate(struct net *net, struct sk_buff *skb, __be32 spi,u32 ethr_len =skb_mac_header_len (skb);u32 bufflen = ethr_len + network_len; +if (skb->protocol !=htons (ETH_P_IP ) && + skb->protocol !=htons (ETH_P_IPV6 )) +return false; +if (skb_cow_head (skb,PSP_ENCAP_HLEN ))return false;
@@ -243,11 +247,9 @@ bool psp_dev_encapsulate(struct net *net, struct sk_buff *skb, __be32 spi,ip_hdr (skb)->check =0 ;ip_hdr (skb)->check =ip_fast_csum ((u8 *)ip_hdr (skb),ip_hdr (skb)->ihl); - }else if (skb->protocol ==htons (ETH_P_IPV6 )) { + }else {ipv6_hdr (skb)->nexthdr =IPPROTO_UDP ;be16_add_cpu (&ipv6_hdr (skb)->payload_len,PSP_ENCAP_HLEN ); - }else { -return false; }skb_set_inner_ipproto (skb,IPPROTO_TCP );
Signature · 1 line
2.54.0
Re: [PATCH net-next 1/3] psp: validate protocol before mutating skb in psp_dev_encapsulate()
Quoted 9 lines · Jakub Kicinski
Code checkers / AI scans will complain that we have already modified the packet by the time we realize that protocol is not IP.
Move the
skb->protocolcheck to before skb_push()/memmove() so that the skb is not left in a corrupted state when the function returns false for an unsupported protocol.psp_dev_rcv()follows similar pattern.
Quoted 7 lines
Today this path is unreachable because both in-tree callers (mlx5 and netdevsim) only reach
psp_dev_encapsulate()from TCP socket TX paths whereskb->protocolis alwaysETH_P_IPorETH_P_IPV6, and both drop the skb on a false return, anyway.Signed-off-by Jakub Kicinski <[email protected]>---
Re: [PATCH net-next 1/3] psp: validate protocol before mutating skb in psp_dev_encapsulate()
In reply to Jakub KicinskiQuoted 8 lines · Jakub Kicinski
Code checkers / AI scans will complain that we have already modified the packet by the time we realize that protocol is not IP.
Move the
skb->protocolcheck to before skb_push()/memmove() so that the skb is not left in a corrupted state when the function returns false for an unsupported protocol.psp_dev_rcv()follows similar pattern.
Quoted 6 lines
Today this path is unreachable because both in-tree callers (mlx5 and netdevsim) only reach
psp_dev_encapsulate()from TCP socket TX paths whereskb->protocolis alwaysETH_P_IPorETH_P_IPV6, and both drop the skb on a false return, anyway.Signed-off-by Jakub Kicinski <[email protected]>
Quoted 35 lines
--- net/psp/psp_main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)net/psp/psp_main.c +5
-3@@ -228,6 +228,10 @@ bool psp_dev_encapsulate(struct net *net, struct sk_buff *skb, __be32 spi,u32 ethr_len =skb_mac_header_len (skb);u32 bufflen = ethr_len + network_len; +if (skb->protocol !=htons (ETH_P_IP ) && + skb->protocol !=htons (ETH_P_IPV6 )) +return false; +if (skb_cow_head (skb,PSP_ENCAP_HLEN ))return false;@@ -243,11 +247,9 @@ bool psp_dev_encapsulate(struct net *net, struct sk_buff *skb, __be32 spi,ip_hdr (skb)->check =0 ;ip_hdr (skb)->check =ip_fast_csum ((u8 *)ip_hdr (skb),ip_hdr (skb)->ihl); - }else if (skb->protocol ==htons (ETH_P_IPV6 )) { + }else {ipv6_hdr (skb)->nexthdr =IPPROTO_UDP ;be16_add_cpu (&ipv6_hdr (skb)->payload_len,PSP_ENCAP_HLEN ); - }else { -return false; }skb_set_inner_ipproto (skb,IPPROTO_TCP );Signature · 1 line
2.54.0
Jakub Kicinski
maintainerPATCH 2/3 psp: add a comment about a psp_dev add netlink notification
In reply to Jakub KicinskiIn psp_dev_create(), the DEV_ADD_NTF netlink notification is sent before the device is published to the netdev via rcu_assign_pointer(). IIRC this is intentional because a single PSP device is expected to be shared with multiple netdevs. So we are trying to default to not having the netdev info. We can change it if someone complains but for now just add a comment that it's intentional.
--- net/psp/psp_main.c | 4 ++++ 1 file changed, 4 insertions(+)
net/psp/psp_main.c +4 -0
@@ -90,6 +90,10 @@ psp_dev_create(struct net_device *netdev,mutex_lock (&psd->lock);mutex_unlock (&psp_devs_lock); +/* notify before netdev assignment +* There's no strong reason for it, but thinking is to avoid creating +* implicit expectations about the PSP dev <> netdev relationship. +*/ psp_nl_notify_dev (psd,PSP_CMD_DEV_ADD_NTF );rcu_assign_pointer (netdev->psp_dev, psd);
Signature · 1 line
2.54.0
Re: [PATCH net-next 2/3] psp: add a comment about a psp_dev add netlink notification
Quoted 8 lines · Jakub Kicinski
In
psp_dev_create(), theDEV_ADD_NTFnetlink notification is sent before the device is published to the netdev viarcu_assign_pointer(). IIRC this is intentional because a single PSP device is expected to be shared with multiple netdevs. So we are trying to default to not having the netdev info. We can change it if someone complains but for now just add a comment that it's intentional.Signed-off-by Jakub Kicinski <[email protected]>
Jakub Kicinski
maintainerPATCH 3/3 psp: validate IPv4 header fields in psp_dev_rcv()
In reply to Jakub Kicinskipsp_dev_rcv() is called from the NIC driver's RX completion path before the frame reaches ip_rcv_core(), so the IP header has not been validated in SW, yet. We expect that the device has done all this validation, but let's also add the SW checks, to avoid surprises.
--- net/psp/psp_main.c | 9 +++++++++ 1 file changed, 9 insertions(+)
net/psp/psp_main.c +9 -0
@@ -300,6 +300,9 @@ int psp_dev_rcv(struct sk_buff *skb, u16 dev_id, u8 generation, bool strip_icv)if (proto ==htons (ETH_P_IP )) {struct iphdr *iph = (struct iphdr *)(skb->data + l2_hlen); +if (unlikely (iph->ihl <5 )) +return -EINVAL ; + is_udp = iph->protocol ==IPPROTO_UDP ; l3_hlen = iph->ihl *4 ; if (l3_hlen != sizeof(struct iphdr) &&
@@ -335,6 +338,9 @@ int psp_dev_rcv(struct sk_buff *skb, u16 dev_id, u8 generation, bool strip_icv)if (proto ==htons (ETH_P_IP )) {struct iphdr *iph = (struct iphdr *)(skb->data + l2_hlen); +if (unlikely (ntohs (iph->tot_len) < l3_hlen + encap)) +return -EINVAL ; + iph->protocol = psph->nexthdr; iph->tot_len =htons (ntohs (iph->tot_len) - encap); iph->check =0 ;
@@ -342,6 +348,9 @@ int psp_dev_rcv(struct sk_buff *skb, u16 dev_id, u8 generation, bool strip_icv) }else {struct ipv6hdr *ipv6h = (struct ipv6hdr *)(skb->data + l2_hlen); +if (unlikely (ntohs (ipv6h->payload_len) < encap)) +return -EINVAL ; + ipv6h->nexthdr = psph->nexthdr; ipv6h->payload_len =htons (ntohs (ipv6h->payload_len) - encap); }
Signature · 1 line
2.54.0
Re: [PATCH net-next 3/3] psp: validate IPv4 header fields in psp_dev_rcv()
Quoted 8 lines · Jakub Kicinski
psp_dev_rcv()is called from the NIC driver's RX completion path before the frame reachesip_rcv_core(), so the IP header has not been validated in SW, yet. We expect that the device has done all this validation, but let's also add the SW checks, to avoid surprises.Signed-off-by Jakub Kicinski <[email protected]>
Willem de Bruijn
maintainerRe: [PATCH net-next 3/3] psp: validate IPv4 header fields in psp_dev_rcv()
In reply to Jakub KicinskiQuoted 5 lines · Jakub Kicinski
psp_dev_rcv()is called from the NIC driver's RX completion path before the frame reachesip_rcv_core(), so the IP header has not been validated in SW, yet. We expect that the device has done all this validation, but let's also add the SW checks, to avoid surprises.
If devices are expected to have verified this, should these be more noisy checks, similar to netdev_rx_csum_fault?
Quoted 42 lines
Signed-off-by Jakub Kicinski <[email protected]>--- net/psp/psp_main.c | 9 +++++++++ 1 file changed, 9 insertions(+)net/psp/psp_main.c +9
-0@@ -300,6 +300,9 @@ int psp_dev_rcv(struct sk_buff *skb, u16 dev_id, u8 generation, bool strip_icv)if (proto ==htons (ETH_P_IP )) {struct iphdr *iph = (struct iphdr *)(skb->data + l2_hlen); +if (unlikely (iph->ihl <5 )) +return -EINVAL ; + is_udp = iph->protocol ==IPPROTO_UDP ; l3_hlen = iph->ihl *4 ; if (l3_hlen != sizeof(struct iphdr) &&@@ -335,6 +338,9 @@ int psp_dev_rcv(struct sk_buff *skb, u16 dev_id, u8 generation, bool strip_icv)if (proto ==htons (ETH_P_IP )) {struct iphdr *iph = (struct iphdr *)(skb->data + l2_hlen); +if (unlikely (ntohs (iph->tot_len) < l3_hlen + encap)) +return -EINVAL ; + iph->protocol = psph->nexthdr; iph->tot_len =htons (ntohs (iph->tot_len) - encap); iph->check =0 ;@@ -342,6 +348,9 @@ int psp_dev_rcv(struct sk_buff *skb, u16 dev_id, u8 generation, bool strip_icv) }else {struct ipv6hdr *ipv6h = (struct ipv6hdr *)(skb->data + l2_hlen); +if (unlikely (ntohs (ipv6h->payload_len) < encap)) +return -EINVAL ; + ipv6h->nexthdr = psph->nexthdr; ipv6h->payload_len =htons (ntohs (ipv6h->payload_len) - encap); }Signature · 1 line
2.54.0
Jakub Kicinski
maintainerRe: [PATCH net-next 3/3] psp: validate IPv4 header fields in psp_dev_rcv()
Quoted 9 lines · On Tue, 28 Apr 2026 20:22:34 -0400 Willem de Bruijn wrote:
Quoted 5 lines · Jakub Kicinski
psp_dev_rcv()is called from the NIC driver's RX completion path before the frame reachesip_rcv_core(), so the IP header has not been validated in SW, yet. We expect that the device has done all this validation, but let's also add the SW checks, to avoid surprises.If devices are expected to have verified this, should these be more noisy checks, similar to
netdev_rx_csum_fault?
Maybe "expect" is a bit of a strong word, I meant "anticipate" / "suspect". Dropping invalid packet in SW doesn't seem like a huge problem, other paths in this function already do. For rx csum the problem is that we got a incorrectly math'ed out value for what is likely a valid packet.
That's just to explain my thinking, if you prefer we warn / dump skb I can respin.
Re: [PATCH net-next 3/3] psp: validate IPv4 header fields in psp_dev_rcv()
Quoted 11 lines · Jakub Kicinski
Quoted 9 lines · On Tue, 28 Apr 2026 20:22:34 -0400 Willem de Bruijn wrote:
Quoted 5 lines · Jakub Kicinski
psp_dev_rcv()is called from the NIC driver's RX completion path before the frame reachesip_rcv_core(), so the IP header has not been validated in SW, yet. We expect that the device has done all this validation, but let's also add the SW checks, to avoid surprises.If devices are expected to have verified this, should these be more noisy checks, similar to
netdev_rx_csum_fault?
Quoted 8 lines
Maybe "expect" is a bit of a strong word, I meant "anticipate" / "suspect". Dropping invalid packet in SW doesn't seem like a huge problem, other paths in this function already do. For rx csum the problem is that we got a incorrectly math'ed out value for what is likely a valid packet.
That's just to explain my thinking, if you prefer we warn / dump skb I can respin.
No, sounds good.
This series was applied to netdev/net-next.git (main) by Jakub Kicinski <[email protected]>:
Hello:
This series was applied to netdev/net-next.git (main) by Jakub Kicinski <[email protected]>:
Quoted 6 lines · On Tue, 28 Apr 2026 13:53:49 -0700 you wrote:
Address some AI code-scan issues with the PSP code. I don't think any of these are real bugs, but they may become bugs in the future. The two real bugs discovered were posted separately for net. AI reports 3 more which seem plain wrong (rx SPI "leak" on error etc.).
Quoted 6 lines
Jakub Kicinski (3):
psp: validate protocol before mutating skb inpsp_dev_encapsulate()
psp: add a comment about apsp_devadd netlink notification
psp: validate IPv4 header fields inpsp_dev_rcv()[...]
Here is the summary with links:
- [net-next,1/3] psp: validate protocol before mutating skb in psp_dev_encapsulate()
https://git.kernel.org/netdev/net-next/c/28e71cb51cdf - [net-next,2/3] psp: add a comment about a psp_dev add netlink notification https://git.kernel.org/netdev/net-next/c/5637fcb11c91 - [net-next,3/3] psp: validate IPv4 header fields in psp_dev_rcv() https://git.kernel.org/netdev/net-next/c/c2b22277ad89
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html