From: Greg Kroah-Hartman Date: Thu, 1 Jun 2023 09:30:51 +0000 (+0100) Subject: 5.10-stable patches X-Git-Tag: v5.4.245~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=871d535fe2e9e72e9c6ed67add7d3b68f68337b3;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: ipv-4-6-raw-fix-output-xfrm-lookup-wrt-protocol.patch --- diff --git a/queue-5.10/ipv-4-6-raw-fix-output-xfrm-lookup-wrt-protocol.patch b/queue-5.10/ipv-4-6-raw-fix-output-xfrm-lookup-wrt-protocol.patch new file mode 100644 index 00000000000..6d8335e40c8 --- /dev/null +++ b/queue-5.10/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 +@@ -75,6 +75,7 @@ struct ipcm_cookie { + __be32 addr; + int oif; + struct ip_options_rcu *opt; ++ __u8 protocol; + __u8 ttl; + __s16 tos; + char priority; +@@ -95,6 +96,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 +@@ -159,6 +159,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 +@@ -317,7 +317,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; + } +@@ -1724,6 +1731,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 +@@ -559,6 +559,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); +@@ -626,7 +629,7 @@ static int raw_sendmsg(struct sock *sk, + + flowi4_init_output(&fl4, ipc.oif, ipc.sockc.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 +@@ -828,7 +828,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-5.10/series b/queue-5.10/series index ebb86dc754a..122d8718cdf 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -18,3 +18,4 @@ net-mlx5-devcom-serialize-devcom-registration.patch net-phy-mscc-enable-vsc8501-2-rgmii-rx-clock.patch bluetooth-add-cmd-validity-checks-at-the-start-of-hci_sock_ioctl.patch binder-fix-uaf-caused-by-faulty-buffer-cleanup.patch +ipv-4-6-raw-fix-output-xfrm-lookup-wrt-protocol.patch