ipsec-2024-05-02

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEH7ZpcWbFyOOp6OJbrB3Eaf9PW7cFAmYzUX4ACgkQrB3Eaf9P
 W7e7qQ/+LgkDkL/LyXv3kAPN8b2SapIiIajarlRfgdPYdM6PP+kzGJxC/t5NZ2HE
 Q1N6K0hIL042rna1/grkUKHeQn4PXUlfT6y8YgjiuCvpFDVNb2ofyl3AmxjJnH1A
 iwMWf6EhwGoxbVs3DbDJ554U8T0nBJeZ+MXLF/4BI13bNdj7stbcKRqj6KHC5sQO
 JgtFVX+ip6LLGL7rR4YMv2h2p1sSu3Vp6bMcfM85I4ENec0UIjgsAF9P0buPl4gr
 2oKtMxga86CQWcymKo6DI+MsBBk91wvM+5/T9zQtpdxDuNEQNrotCoCc0Kd03xmP
 EGzJagwVGFj08kYJ7qICDwpXWCpLDVumoxWFNBWmAW9uNEkUW8Tiqmm8eW2Azs3d
 VAUFcyzHr7mkAaqSDDdE4J+L276Z+dS+BHPnoF6Sp+ctuvSmmeS6lyY9mGnFGH7H
 OiqFKonjBEC5iNAMIXF3WRKueMDdbbDFwHK4NEiTIUSeAMqETUP2sBC1GNTaN8YJ
 soKYtwUtiag2P44ZYy5UYeKJlaBnT1FOZHLs24iCOY1XjqJerwjefQuBO6HDBz/I
 vkaSY6ak6uRsAdfst45uQNPfxlJkFDbwRDowFCdhu5qG7bifqnXstQmNta2U1109
 4e3vt5jPowN/9bCtMx7Z+ftmmTsapxYCu5ZYRVAq82WahsXFPtE=
 =aeD1
 -----END PGP SIGNATURE-----

Merge tag 'ipsec-2024-05-02' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec

Steffen Klassert says:

====================
pull request (net): ipsec 2024-05-02

1) Fix an error pointer dereference in xfrm_in_fwd_icmp.
   From Antony Antony.

2) Preserve vlan tags for ESP transport mode software GRO.
   From Paul Davey.

3) Fix a spelling mistake in an uapi xfrm.h comment.
   From Anotny Antony.

* tag 'ipsec-2024-05-02' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec:
  xfrm: Correct spelling mistake in xfrm.h comment
  xfrm: Preserve vlan tags for transport mode software GRO
  xfrm: fix possible derferencing in error path
====================

Link: https://lore.kernel.org/r/20240502084838.2269355-1-steffen.klassert@secunet.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2024-05-03 15:56:15 -07:00
commit d0de616739
7 changed files with 39 additions and 3 deletions

View File

@ -3031,6 +3031,21 @@ static inline void skb_mac_header_rebuild(struct sk_buff *skb)
} }
} }
/* Move the full mac header up to current network_header.
* Leaves skb->data pointing at offset skb->mac_len into the mac_header.
* Must be provided the complete mac header length.
*/
static inline void skb_mac_header_rebuild_full(struct sk_buff *skb, u32 full_mac_len)
{
if (skb_mac_header_was_set(skb)) {
const unsigned char *old_mac = skb_mac_header(skb);
skb_set_mac_header(skb, -full_mac_len);
memmove(skb_mac_header(skb), old_mac, full_mac_len);
__skb_push(skb, full_mac_len - skb->mac_len);
}
}
static inline int skb_checksum_start_offset(const struct sk_buff *skb) static inline int skb_checksum_start_offset(const struct sk_buff *skb)
{ {
return skb->csum_start - skb_headroom(skb); return skb->csum_start - skb_headroom(skb);

View File

@ -1049,6 +1049,9 @@ struct xfrm_offload {
#define CRYPTO_INVALID_PACKET_SYNTAX 64 #define CRYPTO_INVALID_PACKET_SYNTAX 64
#define CRYPTO_INVALID_PROTOCOL 128 #define CRYPTO_INVALID_PROTOCOL 128
/* Used to keep whole l2 header for transport mode GRO */
__u32 orig_mac_len;
__u8 proto; __u8 proto;
__u8 inner_ipproto; __u8 inner_ipproto;
}; };

View File

@ -228,7 +228,7 @@ enum {
#define XFRM_NR_MSGTYPES (XFRM_MSG_MAX + 1 - XFRM_MSG_BASE) #define XFRM_NR_MSGTYPES (XFRM_MSG_MAX + 1 - XFRM_MSG_BASE)
/* /*
* Generic LSM security context for comunicating to user space * Generic LSM security context for communicating to user space
* NOTE: Same format as sadb_x_sec_ctx * NOTE: Same format as sadb_x_sec_ctx
*/ */
struct xfrm_user_sec_ctx { struct xfrm_user_sec_ctx {

View File

@ -63,7 +63,11 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async)
ip_send_check(iph); ip_send_check(iph);
if (xo && (xo->flags & XFRM_GRO)) { if (xo && (xo->flags & XFRM_GRO)) {
skb_mac_header_rebuild(skb); /* The full l2 header needs to be preserved so that re-injecting the packet at l2
* works correctly in the presence of vlan tags.
*/
skb_mac_header_rebuild_full(skb, xo->orig_mac_len);
skb_reset_network_header(skb);
skb_reset_transport_header(skb); skb_reset_transport_header(skb);
return 0; return 0;
} }

View File

@ -58,7 +58,11 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async)
skb_postpush_rcsum(skb, skb_network_header(skb), nhlen); skb_postpush_rcsum(skb, skb_network_header(skb), nhlen);
if (xo && (xo->flags & XFRM_GRO)) { if (xo && (xo->flags & XFRM_GRO)) {
skb_mac_header_rebuild(skb); /* The full l2 header needs to be preserved so that re-injecting the packet at l2
* works correctly in the presence of vlan tags.
*/
skb_mac_header_rebuild_full(skb, xo->orig_mac_len);
skb_reset_network_header(skb);
skb_reset_transport_header(skb); skb_reset_transport_header(skb);
return 0; return 0;
} }

View File

@ -389,11 +389,15 @@ static int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb)
*/ */
static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb) static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb)
{ {
struct xfrm_offload *xo = xfrm_offload(skb);
int ihl = skb->data - skb_transport_header(skb); int ihl = skb->data - skb_transport_header(skb);
if (skb->transport_header != skb->network_header) { if (skb->transport_header != skb->network_header) {
memmove(skb_transport_header(skb), memmove(skb_transport_header(skb),
skb_network_header(skb), ihl); skb_network_header(skb), ihl);
if (xo)
xo->orig_mac_len =
skb_mac_header_was_set(skb) ? skb_mac_header_len(skb) : 0;
skb->network_header = skb->transport_header; skb->network_header = skb->transport_header;
} }
ip_hdr(skb)->tot_len = htons(skb->len + ihl); ip_hdr(skb)->tot_len = htons(skb->len + ihl);
@ -404,11 +408,15 @@ static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb)
static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb) static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb)
{ {
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
struct xfrm_offload *xo = xfrm_offload(skb);
int ihl = skb->data - skb_transport_header(skb); int ihl = skb->data - skb_transport_header(skb);
if (skb->transport_header != skb->network_header) { if (skb->transport_header != skb->network_header) {
memmove(skb_transport_header(skb), memmove(skb_transport_header(skb),
skb_network_header(skb), ihl); skb_network_header(skb), ihl);
if (xo)
xo->orig_mac_len =
skb_mac_header_was_set(skb) ? skb_mac_header_len(skb) : 0;
skb->network_header = skb->transport_header; skb->network_header = skb->transport_header;
} }
ipv6_hdr(skb)->payload_len = htons(skb->len + ihl - ipv6_hdr(skb)->payload_len = htons(skb->len + ihl -

View File

@ -3593,6 +3593,8 @@ xfrm_policy *xfrm_in_fwd_icmp(struct sk_buff *skb,
return pol; return pol;
pol = xfrm_policy_lookup(net, &fl1, family, XFRM_POLICY_FWD, if_id); pol = xfrm_policy_lookup(net, &fl1, family, XFRM_POLICY_FWD, if_id);
if (IS_ERR(pol))
pol = NULL;
} }
return pol; return pol;