From a1f8ea0e490160c145327fbb4e8959324f5b8e8e Mon Sep 17 00:00:00 2001 From: Kernel Build Daemon Date: May 30 2023 05:53:25 +0000 Subject: Merge branch 'SLE12-SP5' into SLE12-SP5-AZURE --- diff --git a/blacklist.conf b/blacklist.conf index 188421b..02df041 100644 --- a/blacklist.conf +++ b/blacklist.conf @@ -2847,3 +2847,4 @@ d823685486a3446d061fed7c7d2f80af984f119a # driver not enabled: fbdev: intelfb: F 44a3b36b42acfc433aaaf526191dd12fbb919fdb # driver not enabled: fbdev: au1200fb: Fix potential divide by zero 5a6bef734247c7a8c19511664ff77634ab86f45b # driver not enabled: fbdev: arcfb: Fix error handling in arcfb_probe() ed9de4ed39875706607fb08118a58344ae6c5f42 # driver not enabled: fbdev: udlfb: Fix endpoint check +12d5796d55f9fd9e4b621003127c99e176665064 # not needed; maybe fragile: Revert "fbcon: don't lose the console font across generic->chip driver switch" diff --git a/patches.suse/0001-backlight-lm3630a-Fix-return-code-of-.update_status-.patch b/patches.suse/0001-backlight-lm3630a-Fix-return-code-of-.update_status-.patch new file mode 100644 index 0000000..704aa42 --- /dev/null +++ b/patches.suse/0001-backlight-lm3630a-Fix-return-code-of-.update_status-.patch @@ -0,0 +1,73 @@ +From b9481a667a90ec739995e85f91f3672ca44d6ffa Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Mon, 21 Jun 2021 14:21:47 +0200 +Subject: backlight: lm3630a: Fix return code of .update_status() callback +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Git-commit: b9481a667a90ec739995e85f91f3672ca44d6ffa +Patch-mainline: v5.14-rc1 +References: bsc#1129770 + +According to .update_status() is supposed to +return 0 on success and a negative error code otherwise. Adapt +lm3630a_bank_a_update_status() and lm3630a_bank_b_update_status() to +actually do it. + +While touching that also add the error code to the failure message. + +Signed-off-by: Uwe Kleine-König +Reviewed-by: Daniel Thompson +Signed-off-by: Lee Jones +Acked-by: Thomas Zimmermann +--- + drivers/video/backlight/lm3630a_bl.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/video/backlight/lm3630a_bl.c b/drivers/video/backlight/lm3630a_bl.c +index 662029d6a3dc..419b0334cf08 100644 +--- a/drivers/video/backlight/lm3630a_bl.c ++++ b/drivers/video/backlight/lm3630a_bl.c +@@ -190,7 +190,7 @@ static int lm3630a_bank_a_update_status(struct backlight_device *bl) + if ((pwm_ctrl & LM3630A_PWM_BANK_A) != 0) { + lm3630a_pwm_ctrl(pchip, bl->props.brightness, + bl->props.max_brightness); +- return bl->props.brightness; ++ return 0; + } + + /* disable sleep */ +@@ -210,8 +210,8 @@ static int lm3630a_bank_a_update_status(struct backlight_device *bl) + return 0; + + out_i2c_err: +- dev_err(pchip->dev, "i2c failed to access\n"); +- return bl->props.brightness; ++ dev_err(pchip->dev, "i2c failed to access (%pe)\n", ERR_PTR(ret)); ++ return ret; + } + + static int lm3630a_bank_a_get_brightness(struct backlight_device *bl) +@@ -267,7 +267,7 @@ static int lm3630a_bank_b_update_status(struct backlight_device *bl) + if ((pwm_ctrl & LM3630A_PWM_BANK_B) != 0) { + lm3630a_pwm_ctrl(pchip, bl->props.brightness, + bl->props.max_brightness); +- return bl->props.brightness; ++ return 0; + } + + /* disable sleep */ +@@ -287,8 +287,8 @@ static int lm3630a_bank_b_update_status(struct backlight_device *bl) + return 0; + + out_i2c_err: +- dev_err(pchip->dev, "i2c failed to access REG_CTRL\n"); +- return bl->props.brightness; ++ dev_err(pchip->dev, "i2c failed to access (%pe)\n", ERR_PTR(ret)); ++ return ret; + } + + static int lm3630a_bank_b_get_brightness(struct backlight_device *bl) +-- +2.40.1 + diff --git a/patches.suse/0002-fbdev-uvesafb-Fixes-an-error-handling-path-in-uvesaf.patch b/patches.suse/0002-fbdev-uvesafb-Fixes-an-error-handling-path-in-uvesaf.patch new file mode 100644 index 0000000..74b9b23 --- /dev/null +++ b/patches.suse/0002-fbdev-uvesafb-Fixes-an-error-handling-path-in-uvesaf.patch @@ -0,0 +1,38 @@ +From a94371040712031ba129c7e9d8ff04a06a2f8207 Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Sat, 10 Dec 2022 12:35:22 +0100 +Subject: fbdev: uvesafb: Fixes an error handling path in uvesafb_probe() +Git-commit: a94371040712031ba129c7e9d8ff04a06a2f8207 +Patch-mainline: v6.2-rc1 +References: bsc#1154048 + +If an error occurs after a successful uvesafb_init_mtrr() call, it must be +undone by a corresponding arch_phys_wc_del() call, as already done in the +remove function. + +This has been added in the remove function in commit 63e28a7a5ffc +("uvesafb: Clean up MTRR code") + +Fixes: 8bdb3a2d7df4 ("uvesafb: the driver core") +Signed-off-by: Christophe JAILLET +Signed-off-by: Helge Deller +Acked-by: Thomas Zimmermann +--- + drivers/video/fbdev/uvesafb.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c +index 00d789b6c0fa..0e3cabbec4b4 100644 +--- a/drivers/video/fbdev/uvesafb.c ++++ b/drivers/video/fbdev/uvesafb.c +@@ -1758,6 +1758,7 @@ static int uvesafb_probe(struct platform_device *dev) + out_unmap: + iounmap(info->screen_base); + out_mem: ++ arch_phys_wc_del(par->mtrr_handle); + release_mem_region(info->fix.smem_start, info->fix.smem_len); + out_reg: + release_region(0x3c0, 32); +-- +2.40.1 + diff --git a/patches.suse/0003-fbcon-Check-font-dimension-limits.patch b/patches.suse/0003-fbcon-Check-font-dimension-limits.patch new file mode 100644 index 0000000..50c6ce3 --- /dev/null +++ b/patches.suse/0003-fbcon-Check-font-dimension-limits.patch @@ -0,0 +1,54 @@ +From 2b09d5d364986f724f17001ccfe4126b9b43a0be Mon Sep 17 00:00:00 2001 +From: Samuel Thibault +Date: Sun, 29 Jan 2023 16:17:40 +0100 +Subject: fbcon: Check font dimension limits +Git-commit: 2b09d5d364986f724f17001ccfe4126b9b43a0be +Patch-mainline: v6.2-rc7 +References: bsc#1154048 + +blit_x and blit_y are u32, so fbcon currently cannot support fonts +larger than 32x32. + +The 32x32 case also needs shifting an unsigned int, to properly set bit +31, otherwise we get "UBSAN: shift-out-of-bounds in fbcon_set_font", +as reported on: + +http://lore.kernel.org/all/IA1PR07MB98308653E259A6F2CE94A4AFABCE9@IA1PR07MB9830.namprd07.prod.outlook.com +Kernel Branch: 6.2.0-rc5-next-20230124 +Kernel config: https://drive.google.com/file/d/1F-LszDAizEEH0ZX0HcSR06v5q8FPl2Uv/view?usp=sharing +Reproducer: https://drive.google.com/file/d/1mP1jcLBY7vWCNM60OMf-ogw-urQRjNrm/view?usp=sharing + +Reported-by: Sanan Hasanov +Signed-off-by: Samuel Thibault +Fixes: 2d2699d98492 ("fbcon: font setting should check limitation of driver") +Cc: stable@vger.kernel.org +Tested-by: Miko Larsson +Reviewed-by: Greg Kroah-Hartman +Signed-off-by: Helge Deller +Acked-by: Thomas Zimmermann +--- + drivers/video/console/fbcon.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c +index 14a7d404062c..1b14c21af2b7 100644 +--- a/drivers/video/console/fbcon.c ++++ b/drivers/video/console/fbcon.c +@@ -2495,9 +2495,12 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, + h > FBCON_SWAP(info->var.rotate, info->var.yres, info->var.xres)) + return -EINVAL; + ++ if (font->width > 32 || font->height > 32) ++ return -EINVAL; ++ + /* Make sure drawing engine can handle the font */ +- if (!(info->pixmap.blit_x & (1 << (font->width - 1))) || +- !(info->pixmap.blit_y & (1 << (font->height - 1)))) ++ if (!(info->pixmap.blit_x & BIT(font->width - 1)) || ++ !(info->pixmap.blit_y & BIT(font->height - 1))) + return -EINVAL; + + /* Make sure driver can handle the font length */ +-- +2.40.1 + diff --git a/patches.suse/RDMA-cma-Do-not-change-route.addr.src_addr-outside-s.patch b/patches.suse/RDMA-cma-Do-not-change-route.addr.src_addr-outside-s.patch new file mode 100644 index 0000000..9c3bef2 --- /dev/null +++ b/patches.suse/RDMA-cma-Do-not-change-route.addr.src_addr-outside-s.patch @@ -0,0 +1,119 @@ +From 22e9f71072fa605cbf033158db58e0790101928d Mon Sep 17 00:00:00 2001 +From: Jason Gunthorpe +Date: Wed, 23 Feb 2022 11:23:57 -0400 +Subject: [PATCH 1/1] RDMA/cma: Do not change route.addr.src_addr outside state + checks +Git-commit: 22e9f71072fa605cbf033158db58e0790101928d +Patch-mainline: v5.17 +References: bsc#1210629 CVE-2023-2176 + +If the state is not idle then resolve_prepare_src() should immediately +fail and no change to global state should happen. However, it +unconditionally overwrites the src_addr trying to build a temporary any +address. + +For instance if the state is already RDMA_CM_LISTEN then this will corrupt +the src_addr and would cause the test in cma_cancel_operation(): + + if (cma_any_addr(cma_src_addr(id_priv)) && !id_priv->cma_dev) + +Which would manifest as this trace from syzkaller: + + BUG: KASAN: use-after-free in __list_add_valid+0x93/0xa0 lib/list_debug.c:26 + Read of size 8 at addr ffff8881546491e0 by task syz-executor.1/32204 + + CPU: 1 PID: 32204 Comm: syz-executor.1 Not tainted 5.12.0-rc8-syzkaller #0 + Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 + Call Trace: + __dump_stack lib/dump_stack.c:79 [inline] + dump_stack+0x141/0x1d7 lib/dump_stack.c:120 + print_address_description.constprop.0.cold+0x5b/0x2f8 mm/kasan/report.c:232 + __kasan_report mm/kasan/report.c:399 [inline] + kasan_report.cold+0x7c/0xd8 mm/kasan/report.c:416 + __list_add_valid+0x93/0xa0 lib/list_debug.c:26 + __list_add include/linux/list.h:67 [inline] + list_add_tail include/linux/list.h:100 [inline] + cma_listen_on_all drivers/infiniband/core/cma.c:2557 [inline] + rdma_listen+0x787/0xe00 drivers/infiniband/core/cma.c:3751 + ucma_listen+0x16a/0x210 drivers/infiniband/core/ucma.c:1102 + ucma_write+0x259/0x350 drivers/infiniband/core/ucma.c:1732 + vfs_write+0x28e/0xa30 fs/read_write.c:603 + ksys_write+0x1ee/0x250 fs/read_write.c:658 + do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46 + entry_SYSCALL_64_after_hwframe+0x44/0xae + +This is indicating that an rdma_id_private was destroyed without doing +cma_cancel_listens(). + +Instead of trying to re-use the src_addr memory to indirectly create an +any address derived from the dst build one explicitly on the stack and +bind to that as any other normal flow would do. rdma_bind_addr() will copy +it over the src_addr once it knows the state is valid. + +This is similar to commit bc0bdc5afaa7 ("RDMA/cma: Do not change +route.addr.src_addr.ss_family") + +Link: https://lore.kernel.org/r/0-v2-e975c8fd9ef2+11e-syz_cma_srcaddr_jgg@nvidia.com +Cc: stable@vger.kernel.org +Fixes: 732d41c545bb ("RDMA/cma: Make the locking for automatic state transition more clear") +Reported-by: syzbot+c94a3675a626f6333d74@syzkaller.appspotmail.com +Reviewed-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Acked-by: Nicolas Morey +--- + drivers/infiniband/core/cma.c | 40 +++++++++++++++++++++-------------- + 1 file changed, 24 insertions(+), 16 deletions(-) + +diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c +index c447526288f4..50c53409ceb6 100644 +--- a/drivers/infiniband/core/cma.c ++++ b/drivers/infiniband/core/cma.c +@@ -3370,22 +3370,30 @@ err: + static int cma_bind_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, + const struct sockaddr *dst_addr) + { +- if (!src_addr || !src_addr->sa_family) { +- src_addr = (struct sockaddr *) &id->route.addr.src_addr; +- src_addr->sa_family = dst_addr->sa_family; +- if (IS_ENABLED(CONFIG_IPV6) && +- dst_addr->sa_family == AF_INET6) { +- struct sockaddr_in6 *src_addr6 = (struct sockaddr_in6 *) src_addr; +- struct sockaddr_in6 *dst_addr6 = (struct sockaddr_in6 *) dst_addr; +- src_addr6->sin6_scope_id = dst_addr6->sin6_scope_id; +- if (ipv6_addr_type(&dst_addr6->sin6_addr) & IPV6_ADDR_LINKLOCAL) +- id->route.addr.dev_addr.bound_dev_if = dst_addr6->sin6_scope_id; +- } else if (dst_addr->sa_family == AF_IB) { +- ((struct sockaddr_ib *) src_addr)->sib_pkey = +- ((struct sockaddr_ib *) dst_addr)->sib_pkey; +- } ++ struct sockaddr_storage zero_sock = {}; ++ ++ if (src_addr && src_addr->sa_family) ++ return rdma_bind_addr(id, src_addr); ++ ++ /* ++ * When the src_addr is not specified, automatically supply an any addr ++ */ ++ zero_sock.ss_family = dst_addr->sa_family; ++ if (IS_ENABLED(CONFIG_IPV6) && dst_addr->sa_family == AF_INET6) { ++ struct sockaddr_in6 *src_addr6 = ++ (struct sockaddr_in6 *)&zero_sock; ++ struct sockaddr_in6 *dst_addr6 = ++ (struct sockaddr_in6 *)dst_addr; ++ ++ src_addr6->sin6_scope_id = dst_addr6->sin6_scope_id; ++ if (ipv6_addr_type(&dst_addr6->sin6_addr) & IPV6_ADDR_LINKLOCAL) ++ id->route.addr.dev_addr.bound_dev_if = ++ dst_addr6->sin6_scope_id; ++ } else if (dst_addr->sa_family == AF_IB) { ++ ((struct sockaddr_ib *)&zero_sock)->sib_pkey = ++ ((struct sockaddr_ib *)dst_addr)->sib_pkey; + } +- return rdma_bind_addr(id, src_addr); ++ return rdma_bind_addr(id, (struct sockaddr *)&zero_sock); + } + + /* +-- +2.39.1.1.gbe015eda0162 + diff --git a/patches.suse/RDMA-cma-Make-the-locking-for-automatic-state-transi.patch b/patches.suse/RDMA-cma-Make-the-locking-for-automatic-state-transi.patch new file mode 100644 index 0000000..73b5765 --- /dev/null +++ b/patches.suse/RDMA-cma-Make-the-locking-for-automatic-state-transi.patch @@ -0,0 +1,129 @@ +From 732d41c545bb359cbb8c94698bdc1f8bcf82279c Mon Sep 17 00:00:00 2001 +From: Jason Gunthorpe +Date: Wed, 2 Sep 2020 11:11:16 +0300 +Subject: [PATCH 1/1] RDMA/cma: Make the locking for automatic state transition + more clear +Git-commit: 732d41c545bb359cbb8c94698bdc1f8bcf82279c +Patch-mainline: v5.10 +References: bsc#1210629 CVE-2023-2176 + +Re-organize things so the state variable is not read unlocked. The first +attempt to go directly from ADDR_BOUND immediately tells us if the ID is +already bound, if we can't do that then the attempt inside +rdma_bind_addr() to go from IDLE to ADDR_BOUND confirms the ID needs +binding. + +Link: https://lore.kernel.org/r/20200902081122.745412-3-leon@kernel.org +Signed-off-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Acked-by: Nicolas Morey +--- + drivers/infiniband/core/cma.c | 67 +++++++++++++++++++++++------------ + 1 file changed, 45 insertions(+), 22 deletions(-) + +diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c +index 6f492906939b..11d369b7faca 100644 +--- a/drivers/infiniband/core/cma.c ++++ b/drivers/infiniband/core/cma.c +@@ -3098,32 +3098,54 @@ static int cma_bind_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, + return rdma_bind_addr(id, src_addr); + } + +-int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, +- const struct sockaddr *dst_addr, unsigned long timeout_ms) ++/* ++ * If required, resolve the source address for bind and leave the id_priv in ++ * state RDMA_CM_ADDR_BOUND. This oddly uses the state to determine the prior ++ * calls made by ULP, a previously bound ID will not be re-bound and src_addr is ++ * ignored. ++ */ ++static int resolve_prepare_src(struct rdma_id_private *id_priv, ++ struct sockaddr *src_addr, ++ const struct sockaddr *dst_addr) + { +- struct rdma_id_private *id_priv; + int ret; + +- id_priv = container_of(id, struct rdma_id_private, id); + memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr)); +- if (id_priv->state == RDMA_CM_IDLE) { +- ret = cma_bind_addr(id, src_addr, dst_addr); +- if (ret) { +- memset(cma_dst_addr(id_priv), 0, +- rdma_addr_size(dst_addr)); +- return ret; ++ if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) { ++ /* For a well behaved ULP state will be RDMA_CM_IDLE */ ++ ret = cma_bind_addr(&id_priv->id, src_addr, dst_addr); ++ if (ret) ++ goto err_dst; ++ if (WARN_ON(!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, ++ RDMA_CM_ADDR_QUERY))) { ++ ret = -EINVAL; ++ goto err_dst; + } + } + + if (cma_family(id_priv) != dst_addr->sa_family) { +- memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr)); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_state; + } ++ return 0; + +- if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) { +- memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr)); +- return -EINVAL; +- } ++err_state: ++ cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND); ++err_dst: ++ memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr)); ++ return ret; ++} ++ ++int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, ++ const struct sockaddr *dst_addr, unsigned long timeout_ms) ++{ ++ struct rdma_id_private *id_priv = ++ container_of(id, struct rdma_id_private, id); ++ int ret; ++ ++ ret = resolve_prepare_src(id_priv, src_addr, dst_addr); ++ if (ret) ++ return ret; + + if (cma_any_addr(dst_addr)) { + ret = cma_resolve_loopback(id_priv); +@@ -3511,20 +3533,21 @@ static int cma_check_linklocal(struct rdma_dev_addr *dev_addr, + + int rdma_listen(struct rdma_cm_id *id, int backlog) + { +- struct rdma_id_private *id_priv; ++ struct rdma_id_private *id_priv = ++ container_of(id, struct rdma_id_private, id); + int ret; + +- id_priv = container_of(id, struct rdma_id_private, id); +- if (id_priv->state == RDMA_CM_IDLE) { ++ if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_LISTEN)) { ++ /* For a well behaved ULP state will be RDMA_CM_IDLE */ + id->route.addr.src_addr.ss_family = AF_INET; + ret = rdma_bind_addr(id, cma_src_addr(id_priv)); + if (ret) + return ret; ++ if (WARN_ON(!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, ++ RDMA_CM_LISTEN))) ++ return -EINVAL; + } + +- if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_LISTEN)) +- return -EINVAL; +- + if (id_priv->reuseaddr) { + ret = cma_bind_listen(id_priv); + if (ret) +-- +2.39.1.1.gbe015eda0162 + diff --git a/patches.suse/RDMA-core-Refactor-rdma_bind_addr.patch b/patches.suse/RDMA-core-Refactor-rdma_bind_addr.patch new file mode 100644 index 0000000..fb09654 --- /dev/null +++ b/patches.suse/RDMA-core-Refactor-rdma_bind_addr.patch @@ -0,0 +1,330 @@ +From 8d037973d48c026224ab285e6a06985ccac6f7bf Mon Sep 17 00:00:00 2001 +From: Patrisious Haddad +Date: Wed, 4 Jan 2023 10:01:38 +0200 +Subject: [PATCH 1/1] RDMA/core: Refactor rdma_bind_addr +Git-commit: 8d037973d48c026224ab285e6a06985ccac6f7bf +Patch-mainline: v6.3-rc1 +References: bsc#1210629 CVE-2023-2176 + +Refactor rdma_bind_addr function so that it doesn't require that the +cma destination address be changed before calling it. + +So now it will update the destination address internally only when it is +really needed and after passing all the required checks. + +Which in turn results in a cleaner and more sensible call and error +handling flows for the functions that call it directly or indirectly. + +Signed-off-by: Patrisious Haddad +Reported-by: Wei Chen +Reviewed-by: Mark Zhang +Link: https://lore.kernel.org/r/3d0e9a2fd62bc10ba02fed1c7c48a48638952320.1672819273.git.leonro@nvidia.com +Signed-off-by: Leon Romanovsky +Acked-by: Nicolas Morey +--- + drivers/infiniband/core/cma.c | 253 +++++++++++++++++----------------- + 1 file changed, 130 insertions(+), 123 deletions(-) + +diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c +index 68721ff10255..b9da636fe1fb 100644 +--- a/drivers/infiniband/core/cma.c ++++ b/drivers/infiniband/core/cma.c +@@ -3541,121 +3541,6 @@ err: + return ret; + } + +-static int cma_bind_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, +- const struct sockaddr *dst_addr) +-{ +- struct sockaddr_storage zero_sock = {}; +- +- if (src_addr && src_addr->sa_family) +- return rdma_bind_addr(id, src_addr); +- +- /* +- * When the src_addr is not specified, automatically supply an any addr +- */ +- zero_sock.ss_family = dst_addr->sa_family; +- if (IS_ENABLED(CONFIG_IPV6) && dst_addr->sa_family == AF_INET6) { +- struct sockaddr_in6 *src_addr6 = +- (struct sockaddr_in6 *)&zero_sock; +- struct sockaddr_in6 *dst_addr6 = +- (struct sockaddr_in6 *)dst_addr; +- +- src_addr6->sin6_scope_id = dst_addr6->sin6_scope_id; +- if (ipv6_addr_type(&dst_addr6->sin6_addr) & IPV6_ADDR_LINKLOCAL) +- id->route.addr.dev_addr.bound_dev_if = +- dst_addr6->sin6_scope_id; +- } else if (dst_addr->sa_family == AF_IB) { +- ((struct sockaddr_ib *)&zero_sock)->sib_pkey = +- ((struct sockaddr_ib *)dst_addr)->sib_pkey; +- } +- return rdma_bind_addr(id, (struct sockaddr *)&zero_sock); +-} +- +-/* +- * If required, resolve the source address for bind and leave the id_priv in +- * state RDMA_CM_ADDR_BOUND. This oddly uses the state to determine the prior +- * calls made by ULP, a previously bound ID will not be re-bound and src_addr is +- * ignored. +- */ +-static int resolve_prepare_src(struct rdma_id_private *id_priv, +- struct sockaddr *src_addr, +- const struct sockaddr *dst_addr) +-{ +- int ret; +- +- memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr)); +- if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) { +- /* For a well behaved ULP state will be RDMA_CM_IDLE */ +- ret = cma_bind_addr(&id_priv->id, src_addr, dst_addr); +- if (ret) +- goto err_dst; +- if (WARN_ON(!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, +- RDMA_CM_ADDR_QUERY))) { +- ret = -EINVAL; +- goto err_dst; +- } +- } +- +- if (cma_family(id_priv) != dst_addr->sa_family) { +- ret = -EINVAL; +- goto err_state; +- } +- return 0; +- +-err_state: +- cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND); +-err_dst: +- memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr)); +- return ret; +-} +- +-int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, +- const struct sockaddr *dst_addr, unsigned long timeout_ms) +-{ +- struct rdma_id_private *id_priv = +- container_of(id, struct rdma_id_private, id); +- int ret; +- +- ret = resolve_prepare_src(id_priv, src_addr, dst_addr); +- if (ret) +- return ret; +- +- if (cma_any_addr(dst_addr)) { +- ret = cma_resolve_loopback(id_priv); +- } else { +- if (dst_addr->sa_family == AF_IB) { +- ret = cma_resolve_ib_addr(id_priv); +- } else { +- /* +- * The FSM can return back to RDMA_CM_ADDR_BOUND after +- * rdma_resolve_ip() is called, eg through the error +- * path in addr_handler(). If this happens the existing +- * request must be canceled before issuing a new one. +- * Since canceling a request is a bit slow and this +- * oddball path is rare, keep track once a request has +- * been issued. The track turns out to be a permanent +- * state since this is the only cancel as it is +- * immediately before rdma_resolve_ip(). +- */ +- if (id_priv->used_resolve_ip) +- rdma_addr_cancel(&id->route.addr.dev_addr); +- else +- id_priv->used_resolve_ip = 1; +- ret = rdma_resolve_ip(cma_src_addr(id_priv), dst_addr, +- &id->route.addr.dev_addr, +- timeout_ms, addr_handler, +- false, id_priv); +- } +- } +- if (ret) +- goto err; +- +- return 0; +-err: +- cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND); +- return ret; +-} +-EXPORT_SYMBOL(rdma_resolve_addr); +- + int rdma_set_reuseaddr(struct rdma_cm_id *id, int reuse) + { + struct rdma_id_private *id_priv; +@@ -4058,27 +3943,26 @@ err: + } + EXPORT_SYMBOL(rdma_listen); + +-int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) ++static int rdma_bind_addr_dst(struct rdma_id_private *id_priv, ++ struct sockaddr *addr, const struct sockaddr *daddr) + { +- struct rdma_id_private *id_priv; ++ struct sockaddr *id_daddr; + int ret; +- struct sockaddr *daddr; + + if (addr->sa_family != AF_INET && addr->sa_family != AF_INET6 && + addr->sa_family != AF_IB) + return -EAFNOSUPPORT; + +- id_priv = container_of(id, struct rdma_id_private, id); + if (!cma_comp_exch(id_priv, RDMA_CM_IDLE, RDMA_CM_ADDR_BOUND)) + return -EINVAL; + +- ret = cma_check_linklocal(&id->route.addr.dev_addr, addr); ++ ret = cma_check_linklocal(&id_priv->id.route.addr.dev_addr, addr); + if (ret) + goto err1; + + memcpy(cma_src_addr(id_priv), addr, rdma_addr_size(addr)); + if (!cma_any_addr(addr)) { +- ret = cma_translate_addr(addr, &id->route.addr.dev_addr); ++ ret = cma_translate_addr(addr, &id_priv->id.route.addr.dev_addr); + if (ret) + goto err1; + +@@ -4098,8 +3982,10 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) + } + #endif + } +- daddr = cma_dst_addr(id_priv); +- daddr->sa_family = addr->sa_family; ++ id_daddr = cma_dst_addr(id_priv); ++ if (daddr != id_daddr) ++ memcpy(id_daddr, daddr, rdma_addr_size(addr)); ++ id_daddr->sa_family = addr->sa_family; + + ret = cma_get_port(id_priv); + if (ret) +@@ -4115,6 +4001,127 @@ err1: + cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_IDLE); + return ret; + } ++ ++static int cma_bind_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, ++ const struct sockaddr *dst_addr) ++{ ++ struct rdma_id_private *id_priv = ++ container_of(id, struct rdma_id_private, id); ++ struct sockaddr_storage zero_sock = {}; ++ ++ if (src_addr && src_addr->sa_family) ++ return rdma_bind_addr_dst(id_priv, src_addr, dst_addr); ++ ++ /* ++ * When the src_addr is not specified, automatically supply an any addr ++ */ ++ zero_sock.ss_family = dst_addr->sa_family; ++ if (IS_ENABLED(CONFIG_IPV6) && dst_addr->sa_family == AF_INET6) { ++ struct sockaddr_in6 *src_addr6 = ++ (struct sockaddr_in6 *)&zero_sock; ++ struct sockaddr_in6 *dst_addr6 = ++ (struct sockaddr_in6 *)dst_addr; ++ ++ src_addr6->sin6_scope_id = dst_addr6->sin6_scope_id; ++ if (ipv6_addr_type(&dst_addr6->sin6_addr) & IPV6_ADDR_LINKLOCAL) ++ id->route.addr.dev_addr.bound_dev_if = ++ dst_addr6->sin6_scope_id; ++ } else if (dst_addr->sa_family == AF_IB) { ++ ((struct sockaddr_ib *)&zero_sock)->sib_pkey = ++ ((struct sockaddr_ib *)dst_addr)->sib_pkey; ++ } ++ return rdma_bind_addr_dst(id_priv, (struct sockaddr *)&zero_sock, dst_addr); ++} ++ ++/* ++ * If required, resolve the source address for bind and leave the id_priv in ++ * state RDMA_CM_ADDR_BOUND. This oddly uses the state to determine the prior ++ * calls made by ULP, a previously bound ID will not be re-bound and src_addr is ++ * ignored. ++ */ ++static int resolve_prepare_src(struct rdma_id_private *id_priv, ++ struct sockaddr *src_addr, ++ const struct sockaddr *dst_addr) ++{ ++ int ret; ++ ++ if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) { ++ /* For a well behaved ULP state will be RDMA_CM_IDLE */ ++ ret = cma_bind_addr(&id_priv->id, src_addr, dst_addr); ++ if (ret) ++ return ret; ++ if (WARN_ON(!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, ++ RDMA_CM_ADDR_QUERY))) ++ return -EINVAL; ++ ++ } ++ ++ if (cma_family(id_priv) != dst_addr->sa_family) { ++ ret = -EINVAL; ++ goto err_state; ++ } ++ return 0; ++ ++err_state: ++ cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND); ++ return ret; ++} ++ ++int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, ++ const struct sockaddr *dst_addr, unsigned long timeout_ms) ++{ ++ struct rdma_id_private *id_priv = ++ container_of(id, struct rdma_id_private, id); ++ int ret; ++ ++ ret = resolve_prepare_src(id_priv, src_addr, dst_addr); ++ if (ret) ++ return ret; ++ ++ if (cma_any_addr(dst_addr)) { ++ ret = cma_resolve_loopback(id_priv); ++ } else { ++ if (dst_addr->sa_family == AF_IB) { ++ ret = cma_resolve_ib_addr(id_priv); ++ } else { ++ /* ++ * The FSM can return back to RDMA_CM_ADDR_BOUND after ++ * rdma_resolve_ip() is called, eg through the error ++ * path in addr_handler(). If this happens the existing ++ * request must be canceled before issuing a new one. ++ * Since canceling a request is a bit slow and this ++ * oddball path is rare, keep track once a request has ++ * been issued. The track turns out to be a permanent ++ * state since this is the only cancel as it is ++ * immediately before rdma_resolve_ip(). ++ */ ++ if (id_priv->used_resolve_ip) ++ rdma_addr_cancel(&id->route.addr.dev_addr); ++ else ++ id_priv->used_resolve_ip = 1; ++ ret = rdma_resolve_ip(cma_src_addr(id_priv), dst_addr, ++ &id->route.addr.dev_addr, ++ timeout_ms, addr_handler, ++ false, id_priv); ++ } ++ } ++ if (ret) ++ goto err; ++ ++ return 0; ++err: ++ cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND); ++ return ret; ++} ++EXPORT_SYMBOL(rdma_resolve_addr); ++ ++int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) ++{ ++ struct rdma_id_private *id_priv = ++ container_of(id, struct rdma_id_private, id); ++ ++ return rdma_bind_addr_dst(id_priv, addr, cma_dst_addr(id_priv)); ++} + EXPORT_SYMBOL(rdma_bind_addr); + + static int cma_format_hdr(void *hdr, struct rdma_id_private *id_priv) +-- +2.39.1.1.gbe015eda0162 + diff --git a/patches.suse/tcp-Fix-data-races-around-icsk-icsk_af_ops.patch b/patches.suse/tcp-Fix-data-races-around-icsk-icsk_af_ops.patch new file mode 100644 index 0000000..355dc76 --- /dev/null +++ b/patches.suse/tcp-Fix-data-races-around-icsk-icsk_af_ops.patch @@ -0,0 +1,131 @@ +From 0fc1f2b8d809c944b6228c5f115d147737ee17e4 Mon Sep 17 00:00:00 2001 +From: Kuniyuki Iwashima +Date: Thu, 6 Oct 2022 11:53:49 -0700 +Subject: [PATCH] tcp: Fix data races around icsk->icsk_af_ops. +Git-commit: f49cd2f4d6170d27a2c61f1fecb03d8a70c91f57 +Patch-mainline: v6.1-rc1 +References: bsc#1204405 CVE-2022-3566 + +setsockopt(IPV6_ADDRFORM) and tcp_v6_connect() change icsk->icsk_af_ops +under lock_sock(), but tcp_(get|set)sockopt() read it locklessly. To +avoid load/store tearing, we need to add READ_ONCE() and WRITE_ONCE() +for the reads and writes. + +Thanks to Eric Dumazet for providing the syzbot report: + +BUG: KCSAN: data-race in tcp_setsockopt / tcp_v6_connect + +write to 0xffff88813c624518 of 8 bytes by task 23936 on cpu 0: +tcp_v6_connect+0x5b3/0xce0 net/ipv6/tcp_ipv6.c:240 +__inet_stream_connect+0x159/0x6d0 net/ipv4/af_inet.c:660 +inet_stream_connect+0x44/0x70 net/ipv4/af_inet.c:724 +__sys_connect_file net/socket.c:1976 [inline] +__sys_connect+0x197/0x1b0 net/socket.c:1993 +__do_sys_connect net/socket.c:2003 [inline] +__se_sys_connect net/socket.c:2000 [inline] +__x64_sys_connect+0x3d/0x50 net/socket.c:2000 +do_syscall_x64 arch/x86/entry/common.c:50 [inline] +do_syscall_64+0x2b/0x70 arch/x86/entry/common.c:80 +entry_SYSCALL_64_after_hwframe+0x63/0xcd + +read to 0xffff88813c624518 of 8 bytes by task 23937 on cpu 1: +tcp_setsockopt+0x147/0x1c80 net/ipv4/tcp.c:3789 +sock_common_setsockopt+0x5d/0x70 net/core/sock.c:3585 +__sys_setsockopt+0x212/0x2b0 net/socket.c:2252 +__do_sys_setsockopt net/socket.c:2263 [inline] +__se_sys_setsockopt net/socket.c:2260 [inline] +__x64_sys_setsockopt+0x62/0x70 net/socket.c:2260 +do_syscall_x64 arch/x86/entry/common.c:50 [inline] +do_syscall_64+0x2b/0x70 arch/x86/entry/common.c:80 +entry_SYSCALL_64_after_hwframe+0x63/0xcd + +value changed: 0xffffffff8539af68 -> 0xffffffff8539aff8 + +Reported by Kernel Concurrency Sanitizer on: +CPU: 1 PID: 23937 Comm: syz-executor.5 Not tainted +6.0.0-rc4-syzkaller-00331-g4ed9c1e971b1-dirty #0 + +Hardware name: Google Google Compute Engine/Google Compute Engine, +BIOS Google 08/26/2022 + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: syzbot +Reported-by: Eric Dumazet +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + net/ipv4/tcp.c | 9 ++++++--- + net/ipv6/ipv6_sockglue.c | 3 ++- + net/ipv6/tcp_ipv6.c | 6 ++++-- + 3 files changed, 12 insertions(+), 6 deletions(-) + +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 9fb5ff7890e0..928105671cf4 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -2661,8 +2661,9 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval, + const struct inet_connection_sock *icsk = inet_csk(sk); + + if (level != SOL_TCP) +- return icsk->icsk_af_ops->setsockopt(sk, level, optname, +- optval, optlen); ++ /* Paired with WRITE_ONCE() in do_ipv6_setsockopt() and tcp_v6_connect() */ ++ return READ_ONCE(icsk->icsk_af_ops)->setsockopt(sk, level, optname, ++ optval, optlen); + return do_tcp_setsockopt(sk, level, optname, optval, optlen); + } + EXPORT_SYMBOL(tcp_setsockopt); +@@ -3061,8 +3062,10 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, + struct inet_connection_sock *icsk = inet_csk(sk); + + if (level != SOL_TCP) +- return icsk->icsk_af_ops->getsockopt(sk, level, optname, ++ /* Paired with WRITE_ONCE() in do_ipv6_setsockopt() and tcp_v6_connect() */ ++ return READ_ONCE(icsk->icsk_af_ops)->getsockopt(sk, level, optname, + optval, optlen); ++ + return do_tcp_getsockopt(sk, level, optname, optval, optlen); + } + EXPORT_SYMBOL(tcp_getsockopt); +diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c +index 7d6cfc829257..95910bcee24b 100644 +--- a/net/ipv6/ipv6_sockglue.c ++++ b/net/ipv6/ipv6_sockglue.c +@@ -224,7 +224,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, + + /* Paired with READ_ONCE(sk->sk_prot) in inet6_stream_ops */ + WRITE_ONCE(sk->sk_prot, &tcp_prot); +- icsk->icsk_af_ops = &ipv4_specific; ++ /* Paired with READ_ONCE() in tcp_(get|set)sockopt() */ ++ WRITE_ONCE(icsk->icsk_af_ops, &ipv4_specific); + sk->sk_socket->ops = &inet_stream_ops; + sk->sk_family = PF_INET; + tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); +diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c +index a248309a5446..eed189413372 100644 +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -213,7 +213,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, + sin.sin_port = usin->sin6_port; + sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3]; + +- icsk->icsk_af_ops = &ipv6_mapped; ++ /* Paired with READ_ONCE() in tcp_(get|set)sockopt() */ ++ WRITE_ONCE(icsk->icsk_af_ops, &ipv6_mapped); + sk->sk_backlog_rcv = tcp_v4_do_rcv; + #ifdef CONFIG_TCP_MD5SIG + tp->af_specific = &tcp_sock_ipv6_mapped_specific; +@@ -223,7 +224,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, + + if (err) { + icsk->icsk_ext_hdr_len = exthdrlen; +- icsk->icsk_af_ops = &ipv6_specific; ++ /* Paired with READ_ONCE() in tcp_(get|set)sockopt() */ ++ WRITE_ONCE(icsk->icsk_af_ops, &ipv6_specific); + sk->sk_backlog_rcv = tcp_v6_do_rcv; + #ifdef CONFIG_TCP_MD5SIG + tp->af_specific = &tcp_sock_ipv6_specific; +-- +2.16.4 + diff --git a/series.conf b/series.conf index 51ba39d..22c92af 100644 --- a/series.conf +++ b/series.conf @@ -58649,6 +58649,7 @@ patches.suse/RDMA-qedr-Fix-doorbell-setting.patch patches.suse/RDMA-qedr-Fix-use-of-uninitialized-field.patch patches.suse/RDMA-qedr-Fix-inline-size-returned-for-iWARP.patch + patches.suse/RDMA-cma-Make-the-locking-for-automatic-state-transi.patch patches.suse/RDMA-hns-Set-the-unsupported-wr-opcode.patch patches.suse/RDMA-ucma-Rework-ucma_migrate_id-to-avoid-races-with.patch patches.suse/RDMA-hns-Correct-typo-of-hns_roce_create_cq.patch @@ -61161,6 +61162,7 @@ patches.suse/mmc-core-clear-flags-before-allowing-to-retune.patch patches.suse/mmc-sdhci-Fix-warning-message-when-accessing-RPMB-in.patch patches.suse/mfd-da9052-stmpe-Add-and-modify-MODULE_DEVICE_TABLE.patch + patches.suse/0001-backlight-lm3630a-Fix-return-code-of-.update_status-.patch patches.suse/w1-ds2438-fixing-bug-that-would-always-get-page0.patch patches.suse/char-pcmcia-error-out-if-num_bytes_read-is-greater-t.patch patches.suse/fpga-stratix10-soc-Add-missing-fpga_mgr_free-call.patch @@ -62351,6 +62353,7 @@ patches.suse/USB-serial-option-add-support-for-DW5829e.patch patches.suse/USB-serial-option-add-Telit-LE910R1-compositions.patch patches.suse/RDMA-ib_srp-Fix-a-deadlock.patch + patches.suse/RDMA-cma-Do-not-change-route.addr.src_addr-outside-s.patch patches.suse/tracing-Dump-stacktrace-trigger-to-the-corresponding-instance.patch patches.suse/tracing-Have-traceon-and-traceoff-trigger-honor-the-instance.patch patches.suse/tracing-Ensure-trace-buffer-is-at-least-4096-bytes-large.patch @@ -63136,6 +63139,7 @@ patches.suse/0001-ipv6-ping-fix-wrong-checksum-for-large-frames.patch patches.suse/tcp-udp-Fix-memory-leak-in-ipv6_renew_options.patch patches.suse/ipv6-Fix-data-races-around-sk-sk_prot.patch + patches.suse/tcp-Fix-data-races-around-icsk-icsk_af_ops.patch patches.suse/kcm-avoid-potential-race-in-kcm_tx_work.patch patches.suse/net-sched-fix-race-condition-in-qdisc_graft.patch patches.suse/x86-microcode-AMD-Apply-the-patch-early-on-every-log.patch @@ -63242,6 +63246,7 @@ patches.suse/PCI-Check-for-alloc-failure-in-pci_request_irq.patch patches.suse/PCI-sysfs-Fix-double-free-in-error-path.patch patches.suse/crypto-arm64-Fix-unused-variable-compilation-warnings-of-cpu_feature.patch + patches.suse/0002-fbdev-uvesafb-Fixes-an-error-handling-path-in-uvesaf.patch patches.suse/tracing-Fix-infinite-loop-in-tracing_read_pipe-on-overflowed-print_trace_line.patch patches.suse/usb-typec-Check-for-ops-exit-instead-of-ops-enter-in.patch patches.suse/usb-dwc3-Fix-race-between-dwc3_set_mode-and-__dwc3_s.patch @@ -63283,6 +63288,7 @@ patches.suse/sctp-fail-if-no-bound-addresses-can-be-used-for-a-gi.patch patches.suse/tracing-Make-sure-trace_printk-can-output-as-soon-as-it-can-be-used.patch patches.suse/0001-netrom-Fix-use-after-free-caused-by-accept-on-alread.patch + patches.suse/0003-fbcon-Check-font-dimension-limits.patch patches.suse/net-USB-Fix-wrong-direction-WARNING-in-plusb.c.patch patches.suse/usb-typec-altmodes-displayport-Fix-probe-pin-assign-.patch patches.suse/net-sched-tcindex-update-imperfect-hash-filters-resp.patch @@ -63328,6 +63334,7 @@ patches.suse/fotg210-udc-Add-missing-completion-handler.patch patches.suse/usb-early-xhci-dbc-Fix-a-potential-out-of-bound-memo.patch patches.suse/applicom-Fix-PCI-device-refcount-leak-in-applicom_in.patch + patches.suse/RDMA-core-Refactor-rdma_bind_addr.patch patches.suse/powerpc-powernv-ioda-Skip-unallocated-resources-when.patch patches.suse/powerpc-pseries-lpar-add-missing-RTAS-retry-status-h.patch patches.suse/powerpc-pseries-lparcfg-add-missing-RTAS-retry-statu.patch