]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Replace backport of a netfilter patch
authorSasha Levin <sashal@kernel.org>
Tue, 29 Oct 2024 15:12:07 +0000 (11:12 -0400)
committerSasha Levin <sashal@kernel.org>
Tue, 29 Oct 2024 16:38:00 +0000 (12:38 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
13 files changed:
queue-4.19/series
queue-4.19/xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch [new file with mode: 0644]
queue-6.1/series
queue-6.1/xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch [new file with mode: 0644]
queue-6.6/series
queue-6.6/xfrm-add-direction-to-the-sa-in-or-out.patch [deleted file]
queue-6.6/xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch

index f56576d20d91e5364e90648467e26d7af3a1b2f8..fd3bbb7979c591d77b2dfca909e9b4472fa778e7 100644 (file)
@@ -319,3 +319,4 @@ nilfs2-fix-kernel-bug-due-to-missing-clearing-of-buffer-delay-flag.patch
 hv_netvsc-fix-vf-namespace-also-in-synthetic-nic-netdev_register-event.patch
 selinux-improve-error-checking-in-sel_write_load.patch
 arm64-uprobes-change-the-uprobe_opcode_t-typedef-to-fix-the-sparse-warning.patch
+xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch
diff --git a/queue-4.19/xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch b/queue-4.19/xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch
new file mode 100644 (file)
index 0000000..73a5010
--- /dev/null
@@ -0,0 +1,61 @@
+From 8639a1158c1ece4cc854babd1236942b4ceb17d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Oct 2024 18:48:14 +0200
+Subject: xfrm: validate new SA's prefixlen using SA family when sel.family is
+ unset
+
+From: Sabrina Dubroca <sd@queasysnail.net>
+
+[ Upstream commit 3f0ab59e6537c6a8f9e1b355b48f9c05a76e8563 ]
+
+This expands the validation introduced in commit 07bf7908950a ("xfrm:
+Validate address prefix lengths in the xfrm selector.")
+
+syzbot created an SA with
+    usersa.sel.family = AF_UNSPEC
+    usersa.sel.prefixlen_s = 128
+    usersa.family = AF_INET
+
+Because of the AF_UNSPEC selector, verify_newsa_info doesn't put
+limits on prefixlen_{s,d}. But then copy_from_user_state sets
+x->sel.family to usersa.family (AF_INET). Do the same conversion in
+verify_newsa_info before validating prefixlen_{s,d}, since that's how
+prefixlen is going to be used later on.
+
+Reported-by: syzbot+cc39f136925517aed571@syzkaller.appspotmail.com
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Antony Antony <antony.antony@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_user.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
+index 5892ff68d1680..8146ef538ab3d 100644
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -148,6 +148,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
+                            struct nlattr **attrs)
+ {
+       int err;
++      u16 family = p->sel.family;
+       err = -EINVAL;
+       switch (p->family) {
+@@ -166,7 +167,10 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
+               goto out;
+       }
+-      switch (p->sel.family) {
++      if (!family && !(p->flags & XFRM_STATE_AF_UNSPEC))
++              family = p->family;
++
++      switch (family) {
+       case AF_UNSPEC:
+               break;
+-- 
+2.43.0
+
index 0fc04cf662a10c807a9102f95a93f956a783f442..00f753354af7862d7cc2d0c30a70a1d0a371808e 100644 (file)
@@ -53,3 +53,4 @@ serial-protect-uart_port_dtr_rts-in-uart_shutdown-to.patch
 net-phy-dp83822-fix-reset-pin-definitions.patch
 asoc-qcom-fix-null-dereference-in-asoc_qcom_lpass_cpu_platform_probe.patch
 arm64-uprobes-change-the-uprobe_opcode_t-typedef-to-fix-the-sparse-warning.patch
+xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch
diff --git a/queue-5.10/xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch b/queue-5.10/xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch
new file mode 100644 (file)
index 0000000..e314968
--- /dev/null
@@ -0,0 +1,61 @@
+From c009c94a3da3072d2231e44a8e5b38c730214e8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Oct 2024 18:48:14 +0200
+Subject: xfrm: validate new SA's prefixlen using SA family when sel.family is
+ unset
+
+From: Sabrina Dubroca <sd@queasysnail.net>
+
+[ Upstream commit 3f0ab59e6537c6a8f9e1b355b48f9c05a76e8563 ]
+
+This expands the validation introduced in commit 07bf7908950a ("xfrm:
+Validate address prefix lengths in the xfrm selector.")
+
+syzbot created an SA with
+    usersa.sel.family = AF_UNSPEC
+    usersa.sel.prefixlen_s = 128
+    usersa.family = AF_INET
+
+Because of the AF_UNSPEC selector, verify_newsa_info doesn't put
+limits on prefixlen_{s,d}. But then copy_from_user_state sets
+x->sel.family to usersa.family (AF_INET). Do the same conversion in
+verify_newsa_info before validating prefixlen_{s,d}, since that's how
+prefixlen is going to be used later on.
+
+Reported-by: syzbot+cc39f136925517aed571@syzkaller.appspotmail.com
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Antony Antony <antony.antony@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_user.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
+index 070946d093817..e28e49499713f 100644
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -149,6 +149,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
+                            struct nlattr **attrs)
+ {
+       int err;
++      u16 family = p->sel.family;
+       err = -EINVAL;
+       switch (p->family) {
+@@ -167,7 +168,10 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
+               goto out;
+       }
+-      switch (p->sel.family) {
++      if (!family && !(p->flags & XFRM_STATE_AF_UNSPEC))
++              family = p->family;
++
++      switch (family) {
+       case AF_UNSPEC:
+               break;
+-- 
+2.43.0
+
index 55712f6de77d22a06adc8e8b0c6e14e7762db8c0..6906082c93abe55131d2375d72e7aa95426d9091 100644 (file)
@@ -78,3 +78,4 @@ selinux-improve-error-checking-in-sel_write_load.patch
 serial-protect-uart_port_dtr_rts-in-uart_shutdown-to.patch
 net-phy-dp83822-fix-reset-pin-definitions.patch
 asoc-qcom-fix-null-dereference-in-asoc_qcom_lpass_cpu_platform_probe.patch
+xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch
diff --git a/queue-5.15/xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch b/queue-5.15/xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch
new file mode 100644 (file)
index 0000000..49c3f6f
--- /dev/null
@@ -0,0 +1,61 @@
+From 57cc83fa44d1ef0245d10bfea579d53b77f4793b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Oct 2024 18:48:14 +0200
+Subject: xfrm: validate new SA's prefixlen using SA family when sel.family is
+ unset
+
+From: Sabrina Dubroca <sd@queasysnail.net>
+
+[ Upstream commit 3f0ab59e6537c6a8f9e1b355b48f9c05a76e8563 ]
+
+This expands the validation introduced in commit 07bf7908950a ("xfrm:
+Validate address prefix lengths in the xfrm selector.")
+
+syzbot created an SA with
+    usersa.sel.family = AF_UNSPEC
+    usersa.sel.prefixlen_s = 128
+    usersa.family = AF_INET
+
+Because of the AF_UNSPEC selector, verify_newsa_info doesn't put
+limits on prefixlen_{s,d}. But then copy_from_user_state sets
+x->sel.family to usersa.family (AF_INET). Do the same conversion in
+verify_newsa_info before validating prefixlen_{s,d}, since that's how
+prefixlen is going to be used later on.
+
+Reported-by: syzbot+cc39f136925517aed571@syzkaller.appspotmail.com
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Antony Antony <antony.antony@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_user.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
+index 33110f3ef7863..1ebd54afe34c9 100644
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -149,6 +149,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
+                            struct nlattr **attrs)
+ {
+       int err;
++      u16 family = p->sel.family;
+       err = -EINVAL;
+       switch (p->family) {
+@@ -167,7 +168,10 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
+               goto out;
+       }
+-      switch (p->sel.family) {
++      if (!family && !(p->flags & XFRM_STATE_AF_UNSPEC))
++              family = p->family;
++
++      switch (family) {
+       case AF_UNSPEC:
+               break;
+-- 
+2.43.0
+
index 3f618dbd7a6dda185ea8b193f693249223e4caf7..22cb57f3ef2104025e51322c9386c0fe686ede00 100644 (file)
@@ -422,3 +422,4 @@ alsa-hda-realtek-add-subwoofer-quirk-for-acer-predator-g9-593.patch
 hv_netvsc-fix-vf-namespace-also-in-synthetic-nic-netdev_register-event.patch
 selinux-improve-error-checking-in-sel_write_load.patch
 arm64-uprobes-change-the-uprobe_opcode_t-typedef-to-fix-the-sparse-warning.patch
+xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch
diff --git a/queue-5.4/xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch b/queue-5.4/xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch
new file mode 100644 (file)
index 0000000..a910cbb
--- /dev/null
@@ -0,0 +1,61 @@
+From f13dd1b634291a2f4c3d0f3306d3fedba4577b61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Oct 2024 18:48:14 +0200
+Subject: xfrm: validate new SA's prefixlen using SA family when sel.family is
+ unset
+
+From: Sabrina Dubroca <sd@queasysnail.net>
+
+[ Upstream commit 3f0ab59e6537c6a8f9e1b355b48f9c05a76e8563 ]
+
+This expands the validation introduced in commit 07bf7908950a ("xfrm:
+Validate address prefix lengths in the xfrm selector.")
+
+syzbot created an SA with
+    usersa.sel.family = AF_UNSPEC
+    usersa.sel.prefixlen_s = 128
+    usersa.family = AF_INET
+
+Because of the AF_UNSPEC selector, verify_newsa_info doesn't put
+limits on prefixlen_{s,d}. But then copy_from_user_state sets
+x->sel.family to usersa.family (AF_INET). Do the same conversion in
+verify_newsa_info before validating prefixlen_{s,d}, since that's how
+prefixlen is going to be used later on.
+
+Reported-by: syzbot+cc39f136925517aed571@syzkaller.appspotmail.com
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Antony Antony <antony.antony@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_user.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
+index f76033d1898a5..d9a32b13032a7 100644
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -149,6 +149,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
+                            struct nlattr **attrs)
+ {
+       int err;
++      u16 family = p->sel.family;
+       err = -EINVAL;
+       switch (p->family) {
+@@ -167,7 +168,10 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
+               goto out;
+       }
+-      switch (p->sel.family) {
++      if (!family && !(p->flags & XFRM_STATE_AF_UNSPEC))
++              family = p->family;
++
++      switch (family) {
+       case AF_UNSPEC:
+               break;
+-- 
+2.43.0
+
index c1e922d8ac0d94def2d86cad6f3b7d0d04adf65a..23676df948e2defd0bd57e7c60f5c2c7a181d6a1 100644 (file)
@@ -134,3 +134,4 @@ asoc-qcom-fix-null-dereference-in-asoc_qcom_lpass_cpu_platform_probe.patch
 platform-x86-dell-wmi-ignore-suspend-notifications.patch
 acpi-prm-clean-up-guid-type-in-struct-prm_handler_info.patch
 arm64-uprobes-change-the-uprobe_opcode_t-typedef-to-fix-the-sparse-warning.patch
+xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch
diff --git a/queue-6.1/xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch b/queue-6.1/xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch
new file mode 100644 (file)
index 0000000..bf5e4e9
--- /dev/null
@@ -0,0 +1,61 @@
+From 8211d022b977eb4be6a3b79be9d50ee87c64d56d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Oct 2024 18:48:14 +0200
+Subject: xfrm: validate new SA's prefixlen using SA family when sel.family is
+ unset
+
+From: Sabrina Dubroca <sd@queasysnail.net>
+
+[ Upstream commit 3f0ab59e6537c6a8f9e1b355b48f9c05a76e8563 ]
+
+This expands the validation introduced in commit 07bf7908950a ("xfrm:
+Validate address prefix lengths in the xfrm selector.")
+
+syzbot created an SA with
+    usersa.sel.family = AF_UNSPEC
+    usersa.sel.prefixlen_s = 128
+    usersa.family = AF_INET
+
+Because of the AF_UNSPEC selector, verify_newsa_info doesn't put
+limits on prefixlen_{s,d}. But then copy_from_user_state sets
+x->sel.family to usersa.family (AF_INET). Do the same conversion in
+verify_newsa_info before validating prefixlen_{s,d}, since that's how
+prefixlen is going to be used later on.
+
+Reported-by: syzbot+cc39f136925517aed571@syzkaller.appspotmail.com
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Antony Antony <antony.antony@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_user.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
+index 442b1271057a1..2f6e0513dee51 100644
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -176,6 +176,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
+                            struct netlink_ext_ack *extack)
+ {
+       int err;
++      u16 family = p->sel.family;
+       err = -EINVAL;
+       switch (p->family) {
+@@ -196,7 +197,10 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
+               goto out;
+       }
+-      switch (p->sel.family) {
++      if (!family && !(p->flags & XFRM_STATE_AF_UNSPEC))
++              family = p->family;
++
++      switch (family) {
+       case AF_UNSPEC:
+               break;
+-- 
+2.43.0
+
index 8fcecda424fbe5c4ae51ce946c5d4de5969579c0..756ff08a93182f0a76e4c239c5b09608e87153c5 100644 (file)
@@ -130,8 +130,6 @@ tracing-probes-fix-max_trace_args-limit-handling.patch
 tracing-consider-the-null-character-when-validating-.patch
 xfrm-extract-dst-lookup-parameters-into-a-struct.patch
 xfrm-respect-ip-protocols-rules-criteria-when-perfor.patch
-xfrm-add-direction-to-the-sa-in-or-out.patch
-xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch
 netfilter-bpf-must-hold-reference-on-net-namespace.patch
 net-sun3_82586-fix-potential-memory-leak-in-sun3_825.patch
 be2net-fix-potential-memory-leak-in-be_xmit.patch
@@ -205,3 +203,4 @@ rdma-bnxt_re-avoid-creating-fence-mr-for-newer-adapters.patch
 rdma-bnxt_re-fix-unconditional-fence-for-newer-adapters.patch
 tracing-probes-fix-to-zero-initialize-a-local-variable.patch
 task_work-make-twa_nmi_current-handling-conditional-on-irq_work.patch
+xfrm-validate-new-sa-s-prefixlen-using-sa-family-whe.patch
diff --git a/queue-6.6/xfrm-add-direction-to-the-sa-in-or-out.patch b/queue-6.6/xfrm-add-direction-to-the-sa-in-or-out.patch
deleted file mode 100644 (file)
index 9321c75..0000000
+++ /dev/null
@@ -1,429 +0,0 @@
-From 3f97c69c749f417158bc3d69478204562fc8c98d Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 30 Apr 2024 09:08:52 +0200
-Subject: xfrm: Add Direction to the SA in or out
-
-From: Antony Antony <antony.antony@secunet.com>
-
-[ Upstream commit a4a87fa4e96c7746e009de06a567688fd9af6013 ]
-
-This patch introduces the 'dir' attribute, 'in' or 'out', to the
-xfrm_state, SA, enhancing usability by delineating the scope of values
-based on direction. An input SA will restrict values pertinent to input,
-effectively segregating them from output-related values.
-And an output SA will restrict attributes for output. This change aims
-to streamline the configuration process and improve the overall
-consistency of SA attributes during configuration.
-
-This feature sets the groundwork for future patches, including
-the upcoming IP-TFS patch.
-
-Signed-off-by: Antony Antony <antony.antony@secunet.com>
-Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
-Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
-Stable-dep-of: 3f0ab59e6537 ("xfrm: validate new SA's prefixlen using SA family when sel.family is unset")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/net/xfrm.h        |   1 +
- include/uapi/linux/xfrm.h |   6 ++
- net/xfrm/xfrm_compat.c    |   7 +-
- net/xfrm/xfrm_device.c    |   6 ++
- net/xfrm/xfrm_replay.c    |   3 +-
- net/xfrm/xfrm_state.c     |   8 +++
- net/xfrm/xfrm_user.c      | 138 ++++++++++++++++++++++++++++++++++++--
- 7 files changed, 160 insertions(+), 9 deletions(-)
-
-diff --git a/include/net/xfrm.h b/include/net/xfrm.h
-index 93a9866ee481f..c5cf062afd4a2 100644
---- a/include/net/xfrm.h
-+++ b/include/net/xfrm.h
-@@ -292,6 +292,7 @@ struct xfrm_state {
-       /* Private data of this transformer, format is opaque,
-        * interpreted by xfrm_type methods. */
-       void                    *data;
-+      u8                      dir;
- };
- static inline struct net *xs_net(struct xfrm_state *x)
-diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h
-index 23543c33fee82..7cd491caef354 100644
---- a/include/uapi/linux/xfrm.h
-+++ b/include/uapi/linux/xfrm.h
-@@ -140,6 +140,11 @@ enum {
-       XFRM_POLICY_MAX = 3
- };
-+enum xfrm_sa_dir {
-+      XFRM_SA_DIR_IN  = 1,
-+      XFRM_SA_DIR_OUT = 2
-+};
-+
- enum {
-       XFRM_SHARE_ANY,         /* No limitations */
-       XFRM_SHARE_SESSION,     /* For this session only */
-@@ -314,6 +319,7 @@ enum xfrm_attr_type_t {
-       XFRMA_SET_MARK_MASK,    /* __u32 */
-       XFRMA_IF_ID,            /* __u32 */
-       XFRMA_MTIMER_THRESH,    /* __u32 in seconds for input SA */
-+      XFRMA_SA_DIR,           /* __u8 */
-       __XFRMA_MAX
- #define XFRMA_OUTPUT_MARK XFRMA_SET_MARK      /* Compatibility */
-diff --git a/net/xfrm/xfrm_compat.c b/net/xfrm/xfrm_compat.c
-index 655fe4ff86212..703d4172c7d73 100644
---- a/net/xfrm/xfrm_compat.c
-+++ b/net/xfrm/xfrm_compat.c
-@@ -98,6 +98,7 @@ static const int compat_msg_min[XFRM_NR_MSGTYPES] = {
- };
- static const struct nla_policy compat_policy[XFRMA_MAX+1] = {
-+      [XFRMA_UNSPEC]          = { .strict_start_type = XFRMA_SA_DIR },
-       [XFRMA_SA]              = { .len = XMSGSIZE(compat_xfrm_usersa_info)},
-       [XFRMA_POLICY]          = { .len = XMSGSIZE(compat_xfrm_userpolicy_info)},
-       [XFRMA_LASTUSED]        = { .type = NLA_U64},
-@@ -129,6 +130,7 @@ static const struct nla_policy compat_policy[XFRMA_MAX+1] = {
-       [XFRMA_SET_MARK_MASK]   = { .type = NLA_U32 },
-       [XFRMA_IF_ID]           = { .type = NLA_U32 },
-       [XFRMA_MTIMER_THRESH]   = { .type = NLA_U32 },
-+      [XFRMA_SA_DIR]          = NLA_POLICY_RANGE(NLA_U8, XFRM_SA_DIR_IN, XFRM_SA_DIR_OUT),
- };
- static struct nlmsghdr *xfrm_nlmsg_put_compat(struct sk_buff *skb,
-@@ -277,9 +279,10 @@ static int xfrm_xlate64_attr(struct sk_buff *dst, const struct nlattr *src)
-       case XFRMA_SET_MARK_MASK:
-       case XFRMA_IF_ID:
-       case XFRMA_MTIMER_THRESH:
-+      case XFRMA_SA_DIR:
-               return xfrm_nla_cpy(dst, src, nla_len(src));
-       default:
--              BUILD_BUG_ON(XFRMA_MAX != XFRMA_MTIMER_THRESH);
-+              BUILD_BUG_ON(XFRMA_MAX != XFRMA_SA_DIR);
-               pr_warn_once("unsupported nla_type %d\n", src->nla_type);
-               return -EOPNOTSUPP;
-       }
-@@ -434,7 +437,7 @@ static int xfrm_xlate32_attr(void *dst, const struct nlattr *nla,
-       int err;
-       if (type > XFRMA_MAX) {
--              BUILD_BUG_ON(XFRMA_MAX != XFRMA_MTIMER_THRESH);
-+              BUILD_BUG_ON(XFRMA_MAX != XFRMA_SA_DIR);
-               NL_SET_ERR_MSG(extack, "Bad attribute");
-               return -EOPNOTSUPP;
-       }
-diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
-index 04dc0c8a83707..fc18b9b4f22f3 100644
---- a/net/xfrm/xfrm_device.c
-+++ b/net/xfrm/xfrm_device.c
-@@ -253,6 +253,12 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
-               return -EINVAL;
-       }
-+      if ((xuo->flags & XFRM_OFFLOAD_INBOUND && x->dir == XFRM_SA_DIR_OUT) ||
-+          (!(xuo->flags & XFRM_OFFLOAD_INBOUND) && x->dir == XFRM_SA_DIR_IN)) {
-+              NL_SET_ERR_MSG(extack, "Mismatched SA and offload direction");
-+              return -EINVAL;
-+      }
-+
-       is_packet_offload = xuo->flags & XFRM_OFFLOAD_PACKET;
-       /* We don't yet support UDP encapsulation and TFC padding. */
-diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
-index ce56d659c55a6..bc56c63057252 100644
---- a/net/xfrm/xfrm_replay.c
-+++ b/net/xfrm/xfrm_replay.c
-@@ -778,7 +778,8 @@ int xfrm_init_replay(struct xfrm_state *x, struct netlink_ext_ack *extack)
-               }
-               if (x->props.flags & XFRM_STATE_ESN) {
--                      if (replay_esn->replay_window == 0) {
-+                      if (replay_esn->replay_window == 0 &&
-+                          (!x->dir || x->dir == XFRM_SA_DIR_IN)) {
-                               NL_SET_ERR_MSG(extack, "ESN replay window must be > 0");
-                               return -EINVAL;
-                       }
-diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
-index 8a6e8656d014f..93c19f64746fa 100644
---- a/net/xfrm/xfrm_state.c
-+++ b/net/xfrm/xfrm_state.c
-@@ -1349,6 +1349,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
-               if (km_query(x, tmpl, pol) == 0) {
-                       spin_lock_bh(&net->xfrm.xfrm_state_lock);
-                       x->km.state = XFRM_STATE_ACQ;
-+                      x->dir = XFRM_SA_DIR_OUT;
-                       list_add(&x->km.all, &net->xfrm.state_all);
-                       XFRM_STATE_INSERT(bydst, &x->bydst,
-                                         net->xfrm.state_bydst + h,
-@@ -1801,6 +1802,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
-       x->lastused = orig->lastused;
-       x->new_mapping = 0;
-       x->new_mapping_sport = 0;
-+      x->dir = orig->dir;
-       return x;
-@@ -1921,8 +1923,14 @@ int xfrm_state_update(struct xfrm_state *x)
-       }
-       if (x1->km.state == XFRM_STATE_ACQ) {
-+              if (x->dir && x1->dir != x->dir)
-+                      goto out;
-+
-               __xfrm_state_insert(x);
-               x = NULL;
-+      } else {
-+              if (x1->dir != x->dir)
-+                      goto out;
-       }
-       err = 0;
-diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
-index 979f23cded401..4328e81ea6a31 100644
---- a/net/xfrm/xfrm_user.c
-+++ b/net/xfrm/xfrm_user.c
-@@ -130,7 +130,7 @@ static inline int verify_sec_ctx_len(struct nlattr **attrs, struct netlink_ext_a
- }
- static inline int verify_replay(struct xfrm_usersa_info *p,
--                              struct nlattr **attrs,
-+                              struct nlattr **attrs, u8 sa_dir,
-                               struct netlink_ext_ack *extack)
- {
-       struct nlattr *rt = attrs[XFRMA_REPLAY_ESN_VAL];
-@@ -168,6 +168,30 @@ static inline int verify_replay(struct xfrm_usersa_info *p,
-               return -EINVAL;
-       }
-+      if (sa_dir == XFRM_SA_DIR_OUT)  {
-+              if (rs->replay_window) {
-+                      NL_SET_ERR_MSG(extack, "Replay window should be 0 for output SA");
-+                      return -EINVAL;
-+              }
-+              if (rs->seq || rs->seq_hi) {
-+                      NL_SET_ERR_MSG(extack,
-+                                     "Replay seq and seq_hi should be 0 for output SA");
-+                      return -EINVAL;
-+              }
-+              if (rs->bmp_len) {
-+                      NL_SET_ERR_MSG(extack, "Replay bmp_len should 0 for output SA");
-+                      return -EINVAL;
-+              }
-+      }
-+
-+      if (sa_dir == XFRM_SA_DIR_IN)  {
-+              if (rs->oseq || rs->oseq_hi) {
-+                      NL_SET_ERR_MSG(extack,
-+                                     "Replay oseq and oseq_hi should be 0 for input SA");
-+                      return -EINVAL;
-+              }
-+      }
-+
-       return 0;
- }
-@@ -176,6 +200,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
-                            struct netlink_ext_ack *extack)
- {
-       int err;
-+      u8 sa_dir = attrs[XFRMA_SA_DIR] ? nla_get_u8(attrs[XFRMA_SA_DIR]) : 0;
-       err = -EINVAL;
-       switch (p->family) {
-@@ -334,7 +359,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
-               goto out;
-       if ((err = verify_sec_ctx_len(attrs, extack)))
-               goto out;
--      if ((err = verify_replay(p, attrs, extack)))
-+      if ((err = verify_replay(p, attrs, sa_dir, extack)))
-               goto out;
-       err = -EINVAL;
-@@ -358,6 +383,77 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
-                       err = -EINVAL;
-                       goto out;
-               }
-+
-+              if (sa_dir == XFRM_SA_DIR_OUT) {
-+                      NL_SET_ERR_MSG(extack,
-+                                     "MTIMER_THRESH attribute should not be set on output SA");
-+                      err = -EINVAL;
-+                      goto out;
-+              }
-+      }
-+
-+      if (sa_dir == XFRM_SA_DIR_OUT) {
-+              if (p->flags & XFRM_STATE_DECAP_DSCP) {
-+                      NL_SET_ERR_MSG(extack, "Flag DECAP_DSCP should not be set for output SA");
-+                      err = -EINVAL;
-+                      goto out;
-+              }
-+
-+              if (p->flags & XFRM_STATE_ICMP) {
-+                      NL_SET_ERR_MSG(extack, "Flag ICMP should not be set for output SA");
-+                      err = -EINVAL;
-+                      goto out;
-+              }
-+
-+              if (p->flags & XFRM_STATE_WILDRECV) {
-+                      NL_SET_ERR_MSG(extack, "Flag WILDRECV should not be set for output SA");
-+                      err = -EINVAL;
-+                      goto out;
-+              }
-+
-+              if (p->replay_window) {
-+                      NL_SET_ERR_MSG(extack, "Replay window should be 0 for output SA");
-+                      err = -EINVAL;
-+                      goto out;
-+              }
-+
-+              if (attrs[XFRMA_REPLAY_VAL]) {
-+                      struct xfrm_replay_state *replay;
-+
-+                      replay = nla_data(attrs[XFRMA_REPLAY_VAL]);
-+
-+                      if (replay->seq || replay->bitmap) {
-+                              NL_SET_ERR_MSG(extack,
-+                                             "Replay seq and bitmap should be 0 for output SA");
-+                              err = -EINVAL;
-+                              goto out;
-+                      }
-+              }
-+      }
-+
-+      if (sa_dir == XFRM_SA_DIR_IN) {
-+              if (p->flags & XFRM_STATE_NOPMTUDISC) {
-+                      NL_SET_ERR_MSG(extack, "Flag NOPMTUDISC should not be set for input SA");
-+                      err = -EINVAL;
-+                      goto out;
-+              }
-+
-+              if (attrs[XFRMA_SA_EXTRA_FLAGS]) {
-+                      u32 xflags = nla_get_u32(attrs[XFRMA_SA_EXTRA_FLAGS]);
-+
-+                      if (xflags & XFRM_SA_XFLAG_DONT_ENCAP_DSCP) {
-+                              NL_SET_ERR_MSG(extack, "Flag DONT_ENCAP_DSCP should not be set for input SA");
-+                              err = -EINVAL;
-+                              goto out;
-+                      }
-+
-+                      if (xflags & XFRM_SA_XFLAG_OSEQ_MAY_WRAP) {
-+                              NL_SET_ERR_MSG(extack, "Flag OSEQ_MAY_WRAP should not be set for input SA");
-+                              err = -EINVAL;
-+                              goto out;
-+                      }
-+
-+              }
-       }
- out:
-@@ -734,6 +830,9 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,
-       if (attrs[XFRMA_IF_ID])
-               x->if_id = nla_get_u32(attrs[XFRMA_IF_ID]);
-+      if (attrs[XFRMA_SA_DIR])
-+              x->dir = nla_get_u8(attrs[XFRMA_SA_DIR]);
-+
-       err = __xfrm_init_state(x, false, attrs[XFRMA_OFFLOAD_DEV], extack);
-       if (err)
-               goto error;
-@@ -1182,8 +1281,13 @@ static int copy_to_user_state_extra(struct xfrm_state *x,
-               if (ret)
-                       goto out;
-       }
--      if (x->mapping_maxage)
-+      if (x->mapping_maxage) {
-               ret = nla_put_u32(skb, XFRMA_MTIMER_THRESH, x->mapping_maxage);
-+              if (ret)
-+                      goto out;
-+      }
-+      if (x->dir)
-+              ret = nla_put_u8(skb, XFRMA_SA_DIR, x->dir);
- out:
-       return ret;
- }
-@@ -1618,6 +1722,9 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
-       if (err)
-               goto out;
-+      if (attrs[XFRMA_SA_DIR])
-+              x->dir = nla_get_u8(attrs[XFRMA_SA_DIR]);
-+
-       resp_skb = xfrm_state_netlink(skb, x, nlh->nlmsg_seq);
-       if (IS_ERR(resp_skb)) {
-               err = PTR_ERR(resp_skb);
-@@ -2401,7 +2508,8 @@ static inline unsigned int xfrm_aevent_msgsize(struct xfrm_state *x)
-              + nla_total_size_64bit(sizeof(struct xfrm_lifetime_cur))
-              + nla_total_size(sizeof(struct xfrm_mark))
-              + nla_total_size(4) /* XFRM_AE_RTHR */
--             + nla_total_size(4); /* XFRM_AE_ETHR */
-+             + nla_total_size(4) /* XFRM_AE_ETHR */
-+             + nla_total_size(sizeof(x->dir)); /* XFRMA_SA_DIR */
- }
- static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, const struct km_event *c)
-@@ -2458,6 +2566,12 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, const struct
-       if (err)
-               goto out_cancel;
-+      if (x->dir) {
-+              err = nla_put_u8(skb, XFRMA_SA_DIR, x->dir);
-+              if (err)
-+                      goto out_cancel;
-+      }
-+
-       nlmsg_end(skb, nlh);
-       return 0;
-@@ -3017,6 +3131,7 @@ EXPORT_SYMBOL_GPL(xfrm_msg_min);
- #undef XMSGSIZE
- const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
-+      [XFRMA_UNSPEC]          = { .strict_start_type = XFRMA_SA_DIR },
-       [XFRMA_SA]              = { .len = sizeof(struct xfrm_usersa_info)},
-       [XFRMA_POLICY]          = { .len = sizeof(struct xfrm_userpolicy_info)},
-       [XFRMA_LASTUSED]        = { .type = NLA_U64},
-@@ -3048,6 +3163,7 @@ const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
-       [XFRMA_SET_MARK_MASK]   = { .type = NLA_U32 },
-       [XFRMA_IF_ID]           = { .type = NLA_U32 },
-       [XFRMA_MTIMER_THRESH]   = { .type = NLA_U32 },
-+      [XFRMA_SA_DIR]          = NLA_POLICY_RANGE(NLA_U8, XFRM_SA_DIR_IN, XFRM_SA_DIR_OUT),
- };
- EXPORT_SYMBOL_GPL(xfrma_policy);
-@@ -3188,8 +3304,9 @@ static void xfrm_netlink_rcv(struct sk_buff *skb)
- static inline unsigned int xfrm_expire_msgsize(void)
- {
--      return NLMSG_ALIGN(sizeof(struct xfrm_user_expire))
--             + nla_total_size(sizeof(struct xfrm_mark));
-+      return NLMSG_ALIGN(sizeof(struct xfrm_user_expire)) +
-+             nla_total_size(sizeof(struct xfrm_mark)) +
-+             nla_total_size(sizeof_field(struct xfrm_state, dir));
- }
- static int build_expire(struct sk_buff *skb, struct xfrm_state *x, const struct km_event *c)
-@@ -3216,6 +3333,12 @@ static int build_expire(struct sk_buff *skb, struct xfrm_state *x, const struct
-       if (err)
-               return err;
-+      if (x->dir) {
-+              err = nla_put_u8(skb, XFRMA_SA_DIR, x->dir);
-+              if (err)
-+                      return err;
-+      }
-+
-       nlmsg_end(skb, nlh);
-       return 0;
- }
-@@ -3323,6 +3446,9 @@ static inline unsigned int xfrm_sa_len(struct xfrm_state *x)
-       if (x->mapping_maxage)
-               l += nla_total_size(sizeof(x->mapping_maxage));
-+      if (x->dir)
-+              l += nla_total_size(sizeof(x->dir));
-+
-       return l;
- }
--- 
-2.43.0
-
index a9b32afde2209a309e0779029771bb847195f381..ffbe933fb0dca5962ee6021e1aee1d7cf40d6f83 100644 (file)
@@ -1,4 +1,4 @@
-From 2509ee204c957aeb677d90083f814e8963ca813e Mon Sep 17 00:00:00 2001
+From d6d0bfa959c44463f513a87bc7296095939aa440 Mon Sep 17 00:00:00 2001
 From: Sasha Levin <sashal@kernel.org>
 Date: Tue, 1 Oct 2024 18:48:14 +0200
 Subject: xfrm: validate new SA's prefixlen using SA family when sel.family is
@@ -26,24 +26,25 @@ Reported-by: syzbot+cc39f136925517aed571@syzkaller.appspotmail.com
 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
 Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
 Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Antony Antony <antony.antony@secunet.com>
 Signed-off-by: Sasha Levin <sashal@kernel.org>
 ---
  net/xfrm/xfrm_user.c | 6 +++++-
  1 file changed, 5 insertions(+), 1 deletion(-)
 
 diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
-index 4328e81ea6a31..12e9d0e703e70 100644
+index 35b775cf233cd..1d91b42e79971 100644
 --- a/net/xfrm/xfrm_user.c
 +++ b/net/xfrm/xfrm_user.c
-@@ -201,6 +201,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
+@@ -176,6 +176,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
+                            struct netlink_ext_ack *extack)
  {
        int err;
-       u8 sa_dir = attrs[XFRMA_SA_DIR] ? nla_get_u8(attrs[XFRMA_SA_DIR]) : 0;
 +      u16 family = p->sel.family;
  
        err = -EINVAL;
        switch (p->family) {
-@@ -221,7 +222,10 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
+@@ -196,7 +197,10 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
                goto out;
        }