From: Greg Kroah-Hartman Date: Thu, 1 Jun 2023 09:30:33 +0000 (+0100) Subject: 4.19-stable patches X-Git-Tag: v5.4.245~16 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=aa2575551cdf0908bc02970e133f387d82484a8d;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: ipv-4-6-raw-fix-output-xfrm-lookup-wrt-protocol.patch --- diff --git a/queue-4.19/ipv-4-6-raw-fix-output-xfrm-lookup-wrt-protocol.patch b/queue-4.19/ipv-4-6-raw-fix-output-xfrm-lookup-wrt-protocol.patch new file mode 100644 index 00000000000..e44fa8a88a8 --- /dev/null +++ b/queue-4.19/ipv-4-6-raw-fix-output-xfrm-lookup-wrt-protocol.patch @@ -0,0 +1,127 @@ +From 3632679d9e4f879f49949bb5b050e0de553e4739 Mon Sep 17 00:00:00 2001 +From: Nicolas Dichtel +Date: Mon, 22 May 2023 14:08:20 +0200 +Subject: ipv{4,6}/raw: fix output xfrm lookup wrt protocol + +From: Nicolas Dichtel + +commit 3632679d9e4f879f49949bb5b050e0de553e4739 upstream. + +With a raw socket bound to IPPROTO_RAW (ie with hdrincl enabled), the +protocol field of the flow structure, build by raw_sendmsg() / +rawv6_sendmsg()), is set to IPPROTO_RAW. This breaks the ipsec policy +lookup when some policies are defined with a protocol in the selector. + +For ipv6, the sin6_port field from 'struct sockaddr_in6' could be used to +specify the protocol. Just accept all values for IPPROTO_RAW socket. + +For ipv4, the sin_port field of 'struct sockaddr_in' could not be used +without breaking backward compatibility (the value of this field was never +checked). Let's add a new kind of control message, so that the userland +could specify which protocol is used. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +CC: stable@vger.kernel.org +Signed-off-by: Nicolas Dichtel +Link: https://lore.kernel.org/r/20230522120820.1319391-1-nicolas.dichtel@6wind.com +Signed-off-by: Paolo Abeni +Signed-off-by: Nicolas Dichtel +Signed-off-by: Greg Kroah-Hartman +--- + include/net/ip.h | 2 ++ + include/uapi/linux/in.h | 2 ++ + net/ipv4/ip_sockglue.c | 12 +++++++++++- + net/ipv4/raw.c | 5 ++++- + net/ipv6/raw.c | 3 ++- + 5 files changed, 21 insertions(+), 3 deletions(-) + +--- a/include/net/ip.h ++++ b/include/net/ip.h +@@ -73,6 +73,7 @@ struct ipcm_cookie { + __be32 addr; + int oif; + struct ip_options_rcu *opt; ++ __u8 protocol; + __u8 ttl; + __s16 tos; + char priority; +@@ -92,6 +93,7 @@ static inline void ipcm_init_sk(struct i + ipcm->sockc.tsflags = inet->sk.sk_tsflags; + ipcm->oif = inet->sk.sk_bound_dev_if; + ipcm->addr = inet->inet_saddr; ++ ipcm->protocol = inet->inet_num; + } + + #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb)) +--- a/include/uapi/linux/in.h ++++ b/include/uapi/linux/in.h +@@ -154,6 +154,8 @@ struct in_addr { + #define MCAST_MSFILTER 48 + #define IP_MULTICAST_ALL 49 + #define IP_UNICAST_IF 50 ++#define IP_LOCAL_PORT_RANGE 51 ++#define IP_PROTOCOL 52 + + #define MCAST_EXCLUDE 0 + #define MCAST_INCLUDE 1 +--- a/net/ipv4/ip_sockglue.c ++++ b/net/ipv4/ip_sockglue.c +@@ -316,7 +316,14 @@ int ip_cmsg_send(struct sock *sk, struct + ipc->tos = val; + ipc->priority = rt_tos2priority(ipc->tos); + break; +- ++ case IP_PROTOCOL: ++ if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) ++ return -EINVAL; ++ val = *(int *)CMSG_DATA(cmsg); ++ if (val < 1 || val > 255) ++ return -EINVAL; ++ ipc->protocol = val; ++ break; + default: + return -EINVAL; + } +@@ -1522,6 +1529,9 @@ static int do_ip_getsockopt(struct sock + case IP_MINTTL: + val = inet->min_ttl; + break; ++ case IP_PROTOCOL: ++ val = inet_sk(sk)->inet_num; ++ break; + default: + release_sock(sk); + return -ENOPROTOOPT; +--- a/net/ipv4/raw.c ++++ b/net/ipv4/raw.c +@@ -563,6 +563,9 @@ static int raw_sendmsg(struct sock *sk, + } + + ipcm_init_sk(&ipc, inet); ++ /* Keep backward compat */ ++ if (hdrincl) ++ ipc.protocol = IPPROTO_RAW; + + if (msg->msg_controllen) { + err = ip_cmsg_send(sk, msg, &ipc, false); +@@ -630,7 +633,7 @@ static int raw_sendmsg(struct sock *sk, + + flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, + RT_SCOPE_UNIVERSE, +- hdrincl ? IPPROTO_RAW : sk->sk_protocol, ++ hdrincl ? ipc.protocol : sk->sk_protocol, + inet_sk_flowi_flags(sk) | + (hdrincl ? FLOWI_FLAG_KNOWN_NH : 0), + daddr, saddr, 0, 0, sk->sk_uid); +--- a/net/ipv6/raw.c ++++ b/net/ipv6/raw.c +@@ -832,7 +832,8 @@ static int rawv6_sendmsg(struct sock *sk + + if (!proto) + proto = inet->inet_num; +- else if (proto != inet->inet_num) ++ else if (proto != inet->inet_num && ++ inet->inet_num != IPPROTO_RAW) + return -EINVAL; + + if (proto > 255) diff --git a/queue-4.19/series b/queue-4.19/series index 881b16bc90b..1a7356082f1 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -5,3 +5,4 @@ power-supply-core-refactor-power_supply_set_input_cu.patch power-supply-bq24190-call-power_supply_changed-after.patch cdc_ncm-fix-the-build-warning.patch bluetooth-add-cmd-validity-checks-at-the-start-of-hci_sock_ioctl.patch +ipv-4-6-raw-fix-output-xfrm-lookup-wrt-protocol.patch