From abe75186d2634ad02ec901ab3ddac62a9319cfa6 Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Apr 05 2024 08:27:32 +0000 Subject: Merge remote-tracking branch 'origin/SLE12-SP5' into SLE12-SP5_EMBARGO --- diff --git a/blacklist.conf b/blacklist.conf index c7bbb45..1e69fd9 100644 --- a/blacklist.conf +++ b/blacklist.conf @@ -195,6 +195,7 @@ fs/qnx6/ # Not compiled drivers/bus/brcmstb_gisb.c # driver for an internal bus on a settop box drivers/ide # IDE not shipped since SLE12 +drivers/net/appletalk/ # CONFIG_ATALK is not set drivers/net/arcnet/ # CONFIG_ARCNET is not set drivers/net/ethernet/arc/emac_rockchip.c # not enabled drivers/net/ethernet/cirrus/ep93xx_eth.c # not enabled @@ -1956,7 +1957,6 @@ aa6a45850224fc19dbc6058598a9dc57db45b530 # breaks kAPI semantics in an unaccepta 4065158c4897533abc430c02f5071d2e3ddbb191 # breaks kAPI semantics in an unacceptable way 67a948779067f5b2e4e0c5aa67d010c525c8a0ad # breaks kAPI semantics in an unacceptable way b6be55625138c07627d7559ecdd11333545436ae # breaks kAPI semantics in an unacceptable way -f88359e1588b85cf0e8209ab7d6620085f3441d9 # not relevant in configurations supported in SLE12 d120198bd5ff1d41808b6914e1eb89aff937415c # doesn't apply 85d0011264da24be08ae907d7f29983a597ca9b1 # doesn't apply 2183de4161b90bd3851ccd3910c87b2c9adfc6ed # doesn't apply @@ -3146,4 +3146,4 @@ dc6306ad5b0dda040baf1fde3cfd458e6abfc4da # for MU update eeb9f34df065f42f0c9195b322ba6df420c9fc92 # for MU update 5758844105f7dd9a0a04990cd92499a1a593dd36 # for MU update d52734d00b8e86604a66b4cdfa9e8bb541daca2d # for MU update - +4179b00c04d18ea7013f68d578d80f3c9d13150a # reverted upstream diff --git a/doc/README.SUSE b/doc/README.SUSE index 7aa62b6..5ad6a15 100644 --- a/doc/README.SUSE +++ b/doc/README.SUSE @@ -187,8 +187,17 @@ will report one of the following: * third-party support: "supported: external", * unsupported modules: no supported tag. -At runtime, the setting of the "unsupported" kernel command line parameter and -`/proc/sys/kernel/unsupported` determines whether unsupported modules can be +At runtime, the support status of a module can be obtained by reading +`/sys/module/$MODULE/supported`. + +Note that this information is available only if the module was not built +directly into the kernel. Builtin modules are implicitly supported. + +The aggregated support status for the entire kernel can be inspected by reading +`/sys/kernel/supported`. The value is also included in Oopses. + +The setting of the "unsupported" kernel command line parameter and +`/proc/sys/kernel/unsupported` controls whether unsupported modules can be loaded or not, and whether or not loading an unsupported module causes a warning in the system log: @@ -196,9 +205,9 @@ in the system log: * 1 = warn when loading unsupported modules, * 2 = don't warn. -Irrespective of this setting, loading an externally supported or unsupported -module both set a kernel taint flag. The taint flags are included in Oopses. The -taint status of the kernel can be inspected in `/proc/sys/kernel/tainted`. +Irrespective of this setting, loading an unsupported module sets a kernel taint +flag. The taint status of the kernel can be inspected in +`/proc/sys/kernel/tainted`. The taint flags are also included in Oopses. Relevant bits have the following meaning: | Bit | Log | Number | Reason that got the kernel tainted | @@ -209,7 +218,9 @@ Relevant bits have the following meaning: | 16 | ␣/X | 65536 | module with third-party support was loaded | | 31 | ␣/N | 2147483648 | unsupported module was loaded | -Bits 16 and 31 are specific to the SUSE kernels. +Bits 16 and 31 are specific to the SUSE kernels. Since SLE15-SP6, loading an +externally supported module does not taint the kernel, but bit 16 (X) is still +tracked per module and can be read in `/sys/module/$MODULE/taint`. Out-of-tree modules do not have the supported flag set by default; that is, they are marked as unsupported. For building externally supported diff --git a/patches.kabi/SUNRPC-defer-slow-parts-of-rpc_free_client-to-a-work-kabi.patch b/patches.kabi/SUNRPC-defer-slow-parts-of-rpc_free_client-to-a-work-kabi.patch index b549435..73410d8 100644 --- a/patches.kabi/SUNRPC-defer-slow-parts-of-rpc_free_client-to-a-work-kabi.patch +++ b/patches.kabi/SUNRPC-defer-slow-parts-of-rpc_free_client-to-a-work-kabi.patch @@ -9,12 +9,12 @@ Acked-by: NeilBrown Signed-off-by: Neil Brown --- - include/linux/sunrpc/clnt.h | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) + include/linux/sunrpc/clnt.h | 4 ++++ + 1 file changed, 4 insertions(+) --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h -@@ -68,13 +68,17 @@ struct rpc_clnt { +@@ -68,6 +68,9 @@ struct rpc_clnt { #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) struct dentry *cl_debugfs; /* debugfs directory */ #endif @@ -24,10 +24,10 @@ Signed-off-by: Neil Brown /* cl_work is only needed after cl_xpi is no longer used, * and that are of similar size */ - union { - struct rpc_xprt_iter cl_xpi; +@@ -76,6 +79,7 @@ struct rpc_clnt { struct work_struct cl_work; }; + struct super_block *pipefs_sb; +#endif }; diff --git a/patches.kabi/dwc3-switch-to-a-global-mutex.patch b/patches.kabi/dwc3-switch-to-a-global-mutex.patch new file mode 100644 index 0000000..a3cb96b --- /dev/null +++ b/patches.kabi/dwc3-switch-to-a-global-mutex.patch @@ -0,0 +1,80 @@ +From 8c756c48ee007733632bfcb141a35e6bcda1b9ac Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Wed, 20 Mar 2024 16:30:33 +0100 +Subject: [PATCH] dwc3: switch to a global mutex +Patch-mainline: Never, kABI fixup +References: bsc#1220628 CVE-2021-46941 + +Preserve kABI by replacing the per instance mutex +with a global one. + +Signed-off-by: Oliver Neukum mutex); ++ mutex_lock(&suse_roleswitch_mutex); + + spin_lock_irqsave(&dwc->lock, flags); + desired_dr_role = dwc->desired_dr_role; +@@ -197,7 +198,7 @@ static void __dwc3_set_mode(struct work_ + break; + } + out: +- mutex_unlock(&dwc->mutex); ++ mutex_unlock(&suse_roleswitch_mutex); + } + + void dwc3_set_mode(struct dwc3 *dwc, u32 mode) +@@ -1270,7 +1271,6 @@ static int dwc3_probe(struct platform_de + dwc3_cache_hwparams(dwc); + + spin_lock_init(&dwc->lock); +- mutex_init(&dwc->mutex); + + pm_runtime_get_noresume(dev); + pm_runtime_set_active(dev); +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -21,7 +21,6 @@ + + #include + #include +-#include + #include + #include + #include +@@ -777,7 +776,6 @@ struct dwc3_scratchpad_array { + * @scratch_addr: dma address of scratchbuf + * @ep0_in_setup: one control transfer is completed and enter setup phase + * @lock: for synchronizing +- * @mutex: for mode switching + * @dev: pointer to our struct device + * @xhci: pointer to our xHCI child + * @event_buffer_list: a list of event buffers +@@ -885,9 +883,6 @@ struct dwc3 { + /* device lock */ + spinlock_t lock; + +- /* mode switching lock */ +- struct mutex mutex; +- + struct device *dev; + struct device *sysdev; + diff --git a/patches.kabi/pNFS-Fix-the-pnfs-block-driver-s-calculation-of-layo.patch b/patches.kabi/pNFS-Fix-the-pnfs-block-driver-s-calculation-of-layo.patch new file mode 100644 index 0000000..83b9415 --- /dev/null +++ b/patches.kabi/pNFS-Fix-the-pnfs-block-driver-s-calculation-of-layo.patch @@ -0,0 +1,72 @@ +From: NeilBrown +Subject: kabi fix for pNFS: Fix the pnfs block driver's calculation of layoutget size +Patch-mainline: Never, kabi +References: git-fixes + +Rather than changing the signature of an exported function, create a new +function with the new functionality and use that. + +--- + fs/nfs/blocklayout/blocklayout.c | 2 +- + fs/nfs/direct.c | 10 ++++++++-- + fs/nfs/internal.h | 3 ++- + fs/nfs/pnfs.c | 2 +- + 4 files changed, 12 insertions(+), 5 deletions(-) + +--- a/fs/nfs/blocklayout/blocklayout.c ++++ b/fs/nfs/blocklayout/blocklayout.c +@@ -849,7 +849,7 @@ bl_pg_init_write(struct nfs_pageio_descr + if (pgio->pg_dreq == NULL) + wb_size = pnfs_num_cont_bytes(pgio->pg_inode, req->wb_index); + else +- wb_size = nfs_dreq_bytes_left(pgio->pg_dreq, req_offset(req)); ++ wb_size = nfs_dreq_bytes_left_offset(pgio->pg_dreq, req_offset(req)); + + pnfs_generic_pg_init_write(pgio, req, wb_size); + } +--- a/fs/nfs/direct.c ++++ b/fs/nfs/direct.c +@@ -267,12 +267,18 @@ static void nfs_direct_req_release(struc + kref_put(&dreq->kref, nfs_direct_req_free); + } + +-ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq, loff_t offset) ++ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq) ++{ ++ return dreq->bytes_left; ++} ++EXPORT_SYMBOL_GPL(nfs_dreq_bytes_left); ++ ++ssize_t nfs_dreq_bytes_left_offset(struct nfs_direct_req *dreq, loff_t offset) + { + loff_t start = offset - dreq->io_start; + return dreq->max_count - start; + } +-EXPORT_SYMBOL_GPL(nfs_dreq_bytes_left); ++EXPORT_SYMBOL_GPL(nfs_dreq_bytes_left_offset); + + /* + * Collects and returns the final error value/byte-count. +--- a/fs/nfs/internal.h ++++ b/fs/nfs/internal.h +@@ -577,7 +577,8 @@ extern int nfs_sillyrename(struct inode + /* direct.c */ + void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo, + struct nfs_direct_req *dreq); +-extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq, loff_t offset); ++extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq); ++extern ssize_t nfs_dreq_bytes_left_offset(struct nfs_direct_req *dreq, loff_t offset); + + /* nfs4proc.c */ + extern struct nfs_client *nfs4_init_client(struct nfs_client *clp, +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -2173,7 +2173,7 @@ pnfs_generic_pg_init_read(struct nfs_pag + if (pgio->pg_dreq == NULL) + rd_size = i_size_read(pgio->pg_inode) - req_offset(req); + else +- rd_size = nfs_dreq_bytes_left(pgio->pg_dreq, ++ rd_size = nfs_dreq_bytes_left_offset(pgio->pg_dreq, + req_offset(req)); + + pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, diff --git a/patches.kabi/team-Hide-new-member-header-ops.patch b/patches.kabi/team-Hide-new-member-header-ops.patch index a34e274..edeea6c 100644 --- a/patches.kabi/team-Hide-new-member-header-ops.patch +++ b/patches.kabi/team-Hide-new-member-header-ops.patch @@ -9,9 +9,22 @@ Move the new member at the end of the struct and kABI protect it. Signed-off-by: Thomas Bogendoerfer --- + drivers/net/team/team.c | 3 +-- include/linux/if_team.h | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) + 2 files changed, 4 insertions(+), 4 deletions(-) +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -572,8 +572,7 @@ static int __team_change_mode(struct tea + team_mode_put(team->mode); + team_set_no_mode(team); + /* zero private data area */ +- memset(&team->mode_priv, 0, +- sizeof(struct team) - offsetof(struct team, mode_priv)); ++ memset(&team->mode_priv, 0, sizeof(team->mode_priv)); + } + + if (!new_mode) --- a/include/linux/if_team.h +++ b/include/linux/if_team.h @@ -178,8 +178,6 @@ struct team { diff --git a/patches.suse/0001-drm-bridge-panel-Cleanup-connector-on-bridge-detach.patch b/patches.suse/0001-drm-bridge-panel-Cleanup-connector-on-bridge-detach.patch new file mode 100644 index 0000000..e20ff6a --- /dev/null +++ b/patches.suse/0001-drm-bridge-panel-Cleanup-connector-on-bridge-detach.patch @@ -0,0 +1,57 @@ +From 4d906839d321c2efbf3fed4bc31ffd9ff55b75c0 Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Sat, 27 Mar 2021 11:57:40 +0000 +Subject: drm: bridge/panel: Cleanup connector on bridge detach +Git-commit: 4d906839d321c2efbf3fed4bc31ffd9ff55b75c0 +Patch-mainline: v5.13-rc1 +References: bsc#1220777, CVE-2021-47063 + +If we don't call drm_connector_cleanup() manually in +panel_bridge_detach(), the connector will be cleaned up with the other +DRM objects in the call to drm_mode_config_cleanup(). However, since our +drm_connector is devm-allocated, by the time drm_mode_config_cleanup() +will be called, our connector will be long gone. Therefore, the +connector must be cleaned up when the bridge is detached to avoid +use-after-free conditions. + +v2: Cleanup connector only if it was created + +v3: Add FIXME + +v4: (Use connector->dev) directly in if() block + +Fixes: 13dfc0540a57 ("drm/bridge: Refactor out the panel wrapper from the lvds-encoder bridge.") +Cc: # 4.12+ +Cc: Andrzej Hajda +Cc: Neil Armstrong +Cc: Laurent Pinchart +Cc: Jonas Karlman +Cc: Jernej Skrabec +Signed-off-by: Paul Cercueil +Reviewed-by: Laurent Pinchart +Link: https://patchwork.freedesktop.org/patch/msgid/20210327115742.18986-2-paul@crapouillou.net +Acked-by: Thomas Zimmermann +--- + drivers/gpu/drm/bridge/panel.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/gpu/drm/bridge/panel.c ++++ b/drivers/gpu/drm/bridge/panel.c +@@ -92,6 +92,17 @@ static int panel_bridge_attach(struct dr + static void panel_bridge_detach(struct drm_bridge *bridge) + { + struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge); ++ struct drm_connector *connector = &panel_bridge->connector; ++ ++ /* ++ * Cleanup the connector if we know it was initialized. ++ * ++ * FIXME: This wouldn't be needed if the panel_bridge structure was ++ * allocated with drmm_kzalloc(). This might be tricky since the ++ * drm_device pointer can only be retrieved when the bridge is attached. ++ */ ++ if (connector->dev) ++ drm_connector_cleanup(connector); + + drm_panel_detach(panel_bridge->panel); + } diff --git a/patches.suse/0019-dm-rq-fix-double-free-of-blk_mq_tag_set-in-dev-remov.patch b/patches.suse/0019-dm-rq-fix-double-free-of-blk_mq_tag_set-in-dev-remov.patch index 4f3f3da..8e48a4f 100644 --- a/patches.suse/0019-dm-rq-fix-double-free-of-blk_mq_tag_set-in-dev-remov.patch +++ b/patches.suse/0019-dm-rq-fix-double-free-of-blk_mq_tag_set-in-dev-remov.patch @@ -5,7 +5,7 @@ Subject: [PATCH] dm rq: fix double free of blk_mq_tag_set in dev remove after table load fails Git-commit: 8e947c8f4a5620df77e43c9c75310dc510250166 Patch-mainline: v5.13-rc1 -References: git fixes +References: git fixes CVE-2021-46938 bsc#1220554 When loading a device-mapper table for a request-based mapped device, and the allocation/initialization of the blk_mq_tag_set for the device diff --git a/patches.suse/ACPI-custom_method-fix-potential-use-after-free-issu.patch b/patches.suse/ACPI-custom_method-fix-potential-use-after-free-issu.patch index ea26fd4..7b14b54 100644 --- a/patches.suse/ACPI-custom_method-fix-potential-use-after-free-issu.patch +++ b/patches.suse/ACPI-custom_method-fix-potential-use-after-free-issu.patch @@ -4,7 +4,7 @@ Date: Fri, 23 Apr 2021 10:28:17 -0500 Subject: [PATCH] ACPI: custom_method: fix potential use-after-free issue Git-commit: e483bb9a991bdae29a0caa4b3a6d002c968f94aa Patch-mainline: v5.13-rc1 -References: git-fixes +References: git-fixes CVE-2021-46966 bsc#1220572 In cm_write(), buf is always freed when reaching the end of the function. If the requested count is less than table.length, the diff --git a/patches.suse/ARM-9064-1-hw_breakpoint-Do-not-directly-check-the-e.patch b/patches.suse/ARM-9064-1-hw_breakpoint-Do-not-directly-check-the-e.patch new file mode 100644 index 0000000..aef360e --- /dev/null +++ b/patches.suse/ARM-9064-1-hw_breakpoint-Do-not-directly-check-the-e.patch @@ -0,0 +1,46 @@ +From: Zhen Lei +Date: Thu, 18 Feb 2021 03:00:05 +0100 +Subject: ARM: 9064/1: hw_breakpoint: Do not directly check the event's + overflow_handler hook +Git-commit: a506bd5756290821a4314f502b4bafc2afcf5260 +Patch-mainline: v5.13-rc1 +References: bsc#1220751 CVE-2021-47006 + +The commit 1879445dfa7b ("perf/core: Set event's default +::overflow_handler()") set a default event->overflow_handler in +perf_event_alloc(), and replace the check event->overflow_handler with +is_default_overflow_handler(), but one is missing. + +Currently, the bp->overflow_handler can not be NULL. As a result, +enable_single_step() is always not invoked. + +Comments from Zhen Lei: + + https://patchwork.kernel.org/project/linux-arm-kernel/patch/20210207105934.2001-1-thunder.leizhen@huawei.com/ + +Fixes: 1879445dfa7b ("perf/core: Set event's default ::overflow_handler()") +Signed-off-by: Zhen Lei +Cc: Wang Nan +Acked-by: Will Deacon +Signed-off-by: Russell King +Signed-off-by: Matthias Brugger +--- + arch/arm/kernel/hw_breakpoint.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c +index 08660ae9dcbc..b1423fb130ea 100644 +--- a/arch/arm/kernel/hw_breakpoint.c ++++ b/arch/arm/kernel/hw_breakpoint.c +@@ -886,7 +886,7 @@ static void breakpoint_handler(unsigned long unknown, struct pt_regs *regs) + info->trigger = addr; + pr_debug("breakpoint fired: address = 0x%x\n", addr); + perf_bp_event(bp, regs); +- if (!bp->overflow_handler) ++ if (is_default_overflow_handler(bp)) + enable_single_step(bp, addr); + goto unlock; + } +-- +2.43.2 + diff --git a/patches.suse/ARM-footbridge-fix-PCI-interrupt-mapping.patch b/patches.suse/ARM-footbridge-fix-PCI-interrupt-mapping.patch index 90dd80e..7404e35 100644 --- a/patches.suse/ARM-footbridge-fix-PCI-interrupt-mapping.patch +++ b/patches.suse/ARM-footbridge-fix-PCI-interrupt-mapping.patch @@ -4,7 +4,7 @@ Subject: ARM: footbridge: fix PCI interrupt mapping Git-commit: 30e3b4f256b4e366a61658c294f6a21b8626dda7 Patch-mainline: v5.12-rc8 -References: git-fixes +References: git-fixes CVE-2021-46909 bsc#1220442 Since commit 30fdfb929e82 ("PCI: Add a call to pci_assign_irq() in pci_device_probe()"), the PCI code will call the IRQ mapping function diff --git a/patches.suse/Bluetooth-rfcomm-Fix-null-ptr-deref-in-rfcomm_check_-2535b848.patch b/patches.suse/Bluetooth-rfcomm-Fix-null-ptr-deref-in-rfcomm_check_-2535b848.patch new file mode 100644 index 0000000..e5c38fb --- /dev/null +++ b/patches.suse/Bluetooth-rfcomm-Fix-null-ptr-deref-in-rfcomm_check_-2535b848.patch @@ -0,0 +1,51 @@ +From: Yuxuan Hu <20373622@buaa.edu.cn> +Date: Wed, 3 Jan 2024 17:10:43 +0800 +Subject: Bluetooth: rfcomm: Fix null-ptr-deref in rfcomm_check_security +Patch-mainline: v6.8-rc7 +Git-commit: 2535b848fa0f42ddff3e5255cf5e742c9b77bb26 +References: bsc#1219170 CVE-2024-22099 + +During our fuzz testing of the connection and disconnection process at the +RFCOMM layer, we discovered this bug. By comparing the packets from a +normal connection and disconnection process with the testcase that +triggered a KASAN report. We analyzed the cause of this bug as follows: + +1. In the packets captured during a normal connection, the host sends a +`Read Encryption Key Size` type of `HCI_CMD` packet +(Command Opcode: 0x1408) to the controller to inquire the length of +encryption key.After receiving this packet, the controller immediately +replies with a Command Completepacket (Event Code: 0x0e) to return the +Encryption Key Size. + +2. In our fuzz test case, the timing of the controller's response to this +packet was delayed to an unexpected point: after the RFCOMM and L2CAP +layers had disconnected but before the HCI layer had disconnected. + +3. After receiving the Encryption Key Size Response at the time described +in point 2, the host still called the rfcomm_check_security function. +However, by this time `struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;` +had already been released, and when the function executed +`return hci_conn_security(conn->hcon, d->sec_level, auth_type, d->out);`, +specifically when accessing `conn->hcon`, a null-ptr-deref error occurred. + +To fix this bug, check if `sk->sk_state` is BT_CLOSED before calling +rfcomm_recv_frame in rfcomm_process_rx. + +Signed-off-by: Yuxuan Hu <20373622@buaa.edu.cn> +Signed-off-by: Luiz Augusto von Dentz +Acked-by: Chun-Yi Lee +--- + net/bluetooth/rfcomm/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/bluetooth/rfcomm/core.c ++++ b/net/bluetooth/rfcomm/core.c +@@ -1903,7 +1903,7 @@ static struct rfcomm_session *rfcomm_pro + /* Get data directly from socket receive queue without copying it. */ + while ((skb = skb_dequeue(&sk->sk_receive_queue))) { + skb_orphan(skb); +- if (!skb_linearize(skb)) { ++ if (!skb_linearize(skb) && sk->sk_state != BT_CLOSED) { + s = rfcomm_recv_frame(s, skb); + if (!s) + break; diff --git a/patches.suse/Documentation-hw-vuln-Add-documentation-for-RFDS.patch b/patches.suse/Documentation-hw-vuln-Add-documentation-for-RFDS.patch index 8a0a733..f94f015 100644 --- a/patches.suse/Documentation-hw-vuln-Add-documentation-for-RFDS.patch +++ b/patches.suse/Documentation-hw-vuln-Add-documentation-for-RFDS.patch @@ -1,7 +1,8 @@ From: Pawan Gupta Date: Tue, 5 Mar 2024 15:06:06 +0200 Subject: Documentation/hw-vuln: Add documentation for RFDS -Patch-mainline: Not yet, embargo +Git-commit: 4e42765d1be01111df0c0275bbaf1db1acef346e +Patch-mainline: v6.9-rc1 References: bsc#1213456 CVE-2023-28746 Add the documentation for transient execution vulnerability Register diff --git a/patches.suse/IB-hfi1-Fix-bugs-with-non-PAGE_SIZE-end-multi-iovec-.patch b/patches.suse/IB-hfi1-Fix-bugs-with-non-PAGE_SIZE-end-multi-iovec-.patch new file mode 100644 index 0000000..b79f032 --- /dev/null +++ b/patches.suse/IB-hfi1-Fix-bugs-with-non-PAGE_SIZE-end-multi-iovec-.patch @@ -0,0 +1,67 @@ +From: Nicolas Morey +Date: Wed, 27 Mar 2024 10:49:11 +0100 +Subject: [PATCH 1/1] IB/hfi1: Fix bugs with non-PAGE_SIZE-end multi-iovec user + SDMA requests +Patch-mainline: Never, SUSE specific backport +References: bsc#1220445, CVE-2023-52474 + +hfi1 user SDMA request processing has two bugs that can cause data +corruption for user SDMA requests that have multiple payload iovecs +where an iovec other than the tail iovec does not run up to the page +boundary for the buffer pointed to by that iovec.a + +Here are the specific bugs: +1. user_sdma_txadd() does not use struct user_sdma_iovec->iov.iov_len. + Rather, user_sdma_txadd() will add up to PAGE_SIZE bytes from iovec + to the packet, even if some of those bytes are past + iovec->iov.iov_len and are thus not intended to be in the packet. +2. user_sdma_txadd() and user_sdma_send_pkts() fail to advance to the + next iovec in user_sdma_request->iovs when the current iovec + is not PAGE_SIZE and does not contain enough data to complete the + packet. The transmitted packet will contain the wrong data from the + iovec pages. + +This has not been an issue with SDMA packets from hfi1 Verbs or PSM2 +because they only produce iovecs that end short of PAGE_SIZE as the tail +iovec of an SDMA request. + +Fixing these bugs exposes other bugs with the SDMA pin cache +(struct mmu_rb_handler) that get in way of supporting user SDMA requests +with multiple payload iovecs whose buffers do not end at PAGE_SIZE. +Upstream commit does fixes these issues but requires mmu_interval_notifier. + +Instead of trying to fix the MMU issues in older kernels, simply return + -EINVAL when an unsupported iovec (where an iovec other than the tail + iovec does not run up to the page boundary) is provided. +This will not impact currently working use-cases (Verbs, PSM2) but will +prevent data corruption in currently broken cases. + +Signed-off-by: Nicolas Morey +--- + drivers/infiniband/hw/hfi1/user_sdma.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/infiniband/hw/hfi1/user_sdma.c b/drivers/infiniband/hw/hfi1/user_sdma.c +index 4a4956f96a7e..993f0a87e679 100644 +--- a/drivers/infiniband/hw/hfi1/user_sdma.c ++++ b/drivers/infiniband/hw/hfi1/user_sdma.c +@@ -753,6 +753,16 @@ static int user_sdma_txadd(struct user_sdma_request *req, + len = offset + req->info.fragsize > PAGE_SIZE ? + PAGE_SIZE - offset : req->info.fragsize; + len = min((datalen - queued), len); ++ ++ /* ++ * Make sure we have not overflown the iov_len which may happen if iov_len % PAGE_SIZE != 0 ++ * and another iovec is required to fill the needed (datalen - queued) bytes. ++ * Prevents both bugs causing CVE-2023-52474 ++ * See 00cbce5cbf88 ("IB/hfi1: Fix bugs with non-PAGE_SIZE-end multi-iovec user SDMA requests") ++ */ ++ if (iov_offset + len > iovec->iov.iov_len) ++ return -EINVAL; ++ + ret = sdma_txadd_page(pq->dd, &tx->txreq, iovec->pages[pageidx], + offset, len); + if (ret) { +-- +2.44.0.1.gd14cf580c85d + diff --git a/patches.suse/IB-qib-Fix-memory-leak-in-qib_user_sdma_queue_pkts.patch b/patches.suse/IB-qib-Fix-memory-leak-in-qib_user_sdma_queue_pkts.patch index 180126a..c775def 100644 --- a/patches.suse/IB-qib-Fix-memory-leak-in-qib_user_sdma_queue_pkts.patch +++ b/patches.suse/IB-qib-Fix-memory-leak-in-qib_user_sdma_queue_pkts.patch @@ -7,7 +7,7 @@ Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Git-commit: bee90911e0138c76ee67458ac0d58b38a3190f65 Patch-mainline: v5.16 -References: git-fixes +References: git-fixes CVE-2021-47104 bsc#1220960 The wrong goto label was used for the error case and missed cleanup of the pkt allocation. diff --git a/patches.suse/Input-add-bounds-checking-to-input_set_capability.patch b/patches.suse/Input-add-bounds-checking-to-input_set_capability.patch new file mode 100644 index 0000000..b821fb5 --- /dev/null +++ b/patches.suse/Input-add-bounds-checking-to-input_set_capability.patch @@ -0,0 +1,58 @@ +From: Jeff LaBundy +Date: Sun, 20 Mar 2022 21:55:27 -0700 +Subject: Input: add bounds checking to input_set_capability() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Patch-mainline: v5.18-rc1 +Git-commit: 409353cbe9fe48f6bc196114c442b1cff05a39bc +References: bsc#1218220 CVE-2022-48619 + +Update input_set_capability() to prevent kernel panic in case the +event code exceeds the bitmap for the given event type. + +Suggested-by: Tomasz Moń +Signed-off-by: Jeff LaBundy +Reviewed-by: Tomasz Moń +Link: https://lore.kernel.org/r/20220320032537.545250-1-jeff@labundy.com +Signed-off-by: Dmitry Torokhov +Acked-by: Chun-Yi Lee +--- + drivers/input/input.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +--- a/drivers/input/input.c ++++ b/drivers/input/input.c +@@ -50,6 +50,17 @@ static DEFINE_MUTEX(input_mutex); + + static const struct input_value input_value_sync = { EV_SYN, SYN_REPORT, 1 }; + ++static const unsigned int input_max_code[EV_CNT] = { ++ [EV_KEY] = KEY_MAX, ++ [EV_REL] = REL_MAX, ++ [EV_ABS] = ABS_MAX, ++ [EV_MSC] = MSC_MAX, ++ [EV_SW] = SW_MAX, ++ [EV_LED] = LED_MAX, ++ [EV_SND] = SND_MAX, ++ [EV_FF] = FF_MAX, ++}; ++ + static inline int is_event_supported(unsigned int code, + unsigned long *bm, unsigned int max) + { +@@ -1913,6 +1924,14 @@ EXPORT_SYMBOL(input_free_device); + */ + void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code) + { ++ if (type < EV_CNT && input_max_code[type] && ++ code > input_max_code[type]) { ++ pr_err("%s: invalid code %u for type %u\n", __func__, code, ++ type); ++ dump_stack(); ++ return; ++ } ++ + switch (type) { + case EV_KEY: + __set_bit(code, dev->keybit); diff --git a/patches.suse/KVM-x86-Export-RFDS_NO-and-RFDS_CLEAR-to-guests.patch b/patches.suse/KVM-x86-Export-RFDS_NO-and-RFDS_CLEAR-to-guests.patch index fdf1cbd..72b8ed9 100644 --- a/patches.suse/KVM-x86-Export-RFDS_NO-and-RFDS_CLEAR-to-guests.patch +++ b/patches.suse/KVM-x86-Export-RFDS_NO-and-RFDS_CLEAR-to-guests.patch @@ -1,7 +1,8 @@ From: Pawan Gupta Date: Tue, 5 Mar 2024 15:22:10 +0200 Subject: KVM: x86: Export RFDS_NO and RFDS_CLEAR to guests -Patch-mainline: Not yet, embargo +Git-commit: 2a0180129d726a4b953232175857d442651b55a0 +Patch-mainline: v6.9-rc1 References: bsc#1213456 CVE-2023-28746 Mitigation for RFDS requires RFDS_CLEAR capability which is enumerated @@ -28,6 +29,6 @@ Acked-by: Nikolay Borisov data |= ARCH_CAP_MDS_NO; + if (!boot_cpu_has_bug(X86_BUG_RFDS)) + data |= ARCH_CAP_RFDS_NO; - + if (!boot_cpu_has(X86_FEATURE_RTM)) { /* diff --git a/patches.suse/NFC-nci-fix-memory-leak-in-nci_allocate_device.patch b/patches.suse/NFC-nci-fix-memory-leak-in-nci_allocate_device.patch index 962fb8c..b7e2b07 100644 --- a/patches.suse/NFC-nci-fix-memory-leak-in-nci_allocate_device.patch +++ b/patches.suse/NFC-nci-fix-memory-leak-in-nci_allocate_device.patch @@ -4,7 +4,7 @@ Date: Sat, 15 May 2021 07:29:06 +0800 Subject: [PATCH] NFC: nci: fix memory leak in nci_allocate_device Git-commit: e0652f8bb44d6294eeeac06d703185357f25d50b Patch-mainline: v5.13-rc4 -References: git-fixes +References: git-fixes CVE-2021-47180 bsc#1221999 nfcmrvl_disconnect fails to free the hci_dev field in struct nci_dev. Fix this by freeing hci_dev in nci_free_device. diff --git a/patches.suse/NFS-Don-t-corrupt-the-value-of-pg_bytes_written-in-n.patch b/patches.suse/NFS-Don-t-corrupt-the-value-of-pg_bytes_written-in-n.patch index 9d7f424..d7feccf 100644 --- a/patches.suse/NFS-Don-t-corrupt-the-value-of-pg_bytes_written-in-n.patch +++ b/patches.suse/NFS-Don-t-corrupt-the-value-of-pg_bytes_written-in-n.patch @@ -4,7 +4,7 @@ Subject: [PATCH] NFS: Don't corrupt the value of pg_bytes_written in nfs_do_recoalesce() Git-commit: 0d0ea309357dea0d85a82815f02157eb7fcda39f Patch-mainline: v5.13 -References: git-fixes +References: git-fixes CVE-2021-47166 bsc#1221998 The value of mirror->pg_bytes_written should only be updated after a successful attempt to flush out the requests on the list. diff --git a/patches.suse/NFS-Fix-O_DIRECT-commit-verifier-handling.patch b/patches.suse/NFS-Fix-O_DIRECT-commit-verifier-handling.patch new file mode 100644 index 0000000..b13e7d4 --- /dev/null +++ b/patches.suse/NFS-Fix-O_DIRECT-commit-verifier-handling.patch @@ -0,0 +1,240 @@ +From: Trond Myklebust +Date: Sat, 21 Mar 2020 09:27:46 -0400 +Subject: [PATCH] NFS: Fix O_DIRECT commit verifier handling +Git-commit: 1f28476dcb98797e838a0c1dd6eae2fda213dd81 +Patch-mainline: v5.7 +References: git-fixes + +Instead of trying to save the commit verifiers and checking them against +previous writes, adopt the same strategy as for buffered writes, of +just checking the verifiers at commit time. + +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + fs/nfs/direct.c | 135 +++++------------------------------------------------- + fs/nfs/internal.h | 8 +++ + fs/nfs/write.c | 3 - + 3 files changed, 22 insertions(+), 124 deletions(-) + +--- a/fs/nfs/direct.c ++++ b/fs/nfs/direct.c +@@ -104,7 +104,6 @@ struct nfs_direct_req { + /* for read */ + #define NFS_ODIRECT_SHOULD_DIRTY (3) /* dirty user-space page after read */ + #define NFS_ODIRECT_DONE INT_MAX /* write verification failed */ +- struct nfs_writeverf verf; /* unstable write verifier */ + }; + + static const struct nfs_pgio_completion_ops nfs_direct_write_completion_ops; +@@ -168,106 +167,6 @@ nfs_direct_count_bytes(struct nfs_direct + dreq->count = dreq_len; + } + +-/* +- * nfs_direct_select_verf - select the right verifier +- * @dreq - direct request possibly spanning multiple servers +- * @ds_clp - nfs_client of data server or NULL if MDS / non-pnfs +- * @commit_idx - commit bucket index for the DS +- * +- * returns the correct verifier to use given the role of the server +- */ +-static struct nfs_writeverf * +-nfs_direct_select_verf(struct nfs_direct_req *dreq, +- struct nfs_client *ds_clp, +- int commit_idx) +-{ +- struct nfs_writeverf *verfp = &dreq->verf; +- +-#ifdef CONFIG_NFS_V4_1 +- /* +- * pNFS is in use, use the DS verf except commit_through_mds is set +- * for layout segment where nbuckets is zero. +- */ +- if (ds_clp && dreq->ds_cinfo.nbuckets > 0) { +- if (commit_idx >= 0 && commit_idx < dreq->ds_cinfo.nbuckets) +- verfp = &dreq->ds_cinfo.buckets[commit_idx].direct_verf; +- else +- WARN_ON_ONCE(1); +- } +-#endif +- return verfp; +-} +- +- +-/* +- * nfs_direct_set_hdr_verf - set the write/commit verifier +- * @dreq - direct request possibly spanning multiple servers +- * @hdr - pageio header to validate against previously seen verfs +- * +- * Set the server's (MDS or DS) "seen" verifier +- */ +-static void nfs_direct_set_hdr_verf(struct nfs_direct_req *dreq, +- struct nfs_pgio_header *hdr) +-{ +- struct nfs_writeverf *verfp; +- +- verfp = nfs_direct_select_verf(dreq, hdr->ds_clp, hdr->ds_commit_idx); +- WARN_ON_ONCE(verfp->committed >= 0); +- memcpy(verfp, &hdr->verf, sizeof(struct nfs_writeverf)); +- WARN_ON_ONCE(verfp->committed < 0); +-} +- +-static int nfs_direct_cmp_verf(const struct nfs_writeverf *v1, +- const struct nfs_writeverf *v2) +-{ +- return nfs_write_verifier_cmp(&v1->verifier, &v2->verifier); +-} +- +-/* +- * nfs_direct_cmp_hdr_verf - compare verifier for pgio header +- * @dreq - direct request possibly spanning multiple servers +- * @hdr - pageio header to validate against previously seen verf +- * +- * set the server's "seen" verf if not initialized. +- * returns result of comparison between @hdr->verf and the "seen" +- * verf of the server used by @hdr (DS or MDS) +- */ +-static int nfs_direct_set_or_cmp_hdr_verf(struct nfs_direct_req *dreq, +- struct nfs_pgio_header *hdr) +-{ +- struct nfs_writeverf *verfp; +- +- verfp = nfs_direct_select_verf(dreq, hdr->ds_clp, hdr->ds_commit_idx); +- if (verfp->committed < 0) { +- nfs_direct_set_hdr_verf(dreq, hdr); +- return 0; +- } +- return nfs_direct_cmp_verf(verfp, &hdr->verf); +-} +- +-/* +- * nfs_direct_cmp_commit_data_verf - compare verifier for commit data +- * @dreq - direct request possibly spanning multiple servers +- * @data - commit data to validate against previously seen verf +- * +- * returns result of comparison between @data->verf and the verf of +- * the server used by @data (DS or MDS) +- */ +-static int nfs_direct_cmp_commit_data_verf(struct nfs_direct_req *dreq, +- struct nfs_commit_data *data) +-{ +- struct nfs_writeverf *verfp; +- +- verfp = nfs_direct_select_verf(dreq, data->ds_clp, +- data->ds_commit_index); +- +- /* verifier not set so always fail */ +- if (verfp->committed < 0 || data->res.verf->committed <= NFS_UNSTABLE) +- return 1; +- +- return nfs_direct_cmp_verf(verfp, data->res.verf); +-} +- + /** + * nfs_direct_IO - NFS address space operation for direct I/O + * @iocb: target I/O control block +@@ -334,7 +233,6 @@ static inline struct nfs_direct_req *nfs + kref_get(&dreq->kref); + init_completion(&dreq->completion); + INIT_LIST_HEAD(&dreq->mds_cinfo.list); +- dreq->verf.committed = NFS_INVALID_STABLE_HOW; /* not set yet */ + INIT_WORK(&dreq->work, nfs_direct_write_schedule_work); + dreq->mirror_count = 1; + spin_lock_init(&dreq->lock); +@@ -668,7 +566,6 @@ static void nfs_direct_write_reschedule( + dreq->max_count = 0; + list_for_each_entry(req, &reqs, wb_list) + dreq->max_count += req->wb_bytes; +- dreq->verf.committed = NFS_INVALID_STABLE_HOW; + nfs_clear_pnfs_ds_commit_verifiers(&dreq->ds_cinfo); + for (i = 0; i < dreq->mirror_count; i++) + dreq->mirrors[i].count = 0; +@@ -720,6 +617,7 @@ out_failed: + + static void nfs_direct_commit_complete(struct nfs_commit_data *data) + { ++ const struct nfs_writeverf *verf = data->res.verf; + struct nfs_direct_req *dreq = data->dreq; + struct nfs_commit_info cinfo; + struct nfs_page *req; +@@ -735,16 +633,14 @@ static void nfs_direct_commit_complete(s + status = dreq->error; + + nfs_init_cinfo_from_dreq(&cinfo, dreq); +- if (nfs_direct_cmp_commit_data_verf(dreq, data)) +- dreq->flags = NFS_ODIRECT_RESCHED_WRITES; + + while (!list_empty(&data->pages)) { + req = nfs_list_entry(data->pages.next); + nfs_list_remove_request(req); +- if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES) { +- /* Note the rewrite will go through mds */ ++ if (status >= 0 && !nfs_write_match_verf(verf, req)) { ++ dreq->flags = NFS_ODIRECT_RESCHED_WRITES; + nfs_mark_request_commit(req, NULL, &cinfo, 0); +- } else ++ } else /* Error or match */ + nfs_release_request(req); + nfs_unlock_and_release_request(req); + } +@@ -840,20 +736,15 @@ static void nfs_direct_write_completion( + } + + nfs_direct_count_bytes(dreq, hdr); +- if (hdr->good_bytes != 0) { +- if (nfs_write_need_commit(hdr)) { +- if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES) +- request_commit = true; +- else if (dreq->flags == 0) { +- nfs_direct_set_hdr_verf(dreq, hdr); +- request_commit = true; +- dreq->flags = NFS_ODIRECT_DO_COMMIT; +- } else if (dreq->flags == NFS_ODIRECT_DO_COMMIT) { +- request_commit = true; +- if (nfs_direct_set_or_cmp_hdr_verf(dreq, hdr)) +- dreq->flags = +- NFS_ODIRECT_RESCHED_WRITES; +- } ++ if (hdr->good_bytes != 0 && nfs_write_need_commit(hdr)) { ++ switch (dreq->flags) { ++ case 0: ++ dreq->flags = NFS_ODIRECT_DO_COMMIT; ++ request_commit = true; ++ break; ++ case NFS_ODIRECT_RESCHED_WRITES: ++ case NFS_ODIRECT_DO_COMMIT: ++ request_commit = true; + } + } + spin_unlock(&dreq->lock); +--- a/fs/nfs/internal.h ++++ b/fs/nfs/internal.h +@@ -559,6 +559,14 @@ nfs_write_verifier_cmp(const struct nfs_ + return memcmp(v1->data, v2->data, sizeof(v1->data)); + } + ++static inline bool ++nfs_write_match_verf(const struct nfs_writeverf *verf, ++ struct nfs_page *req) ++{ ++ return verf->committed > NFS_UNSTABLE && ++ !nfs_write_verifier_cmp(&req->wb_verf, &verf->verifier); ++} ++ + /* unlink.c */ + extern struct rpc_task * + nfs_async_rename(struct inode *old_dir, struct inode *new_dir, +--- a/fs/nfs/write.c ++++ b/fs/nfs/write.c +@@ -1864,8 +1864,7 @@ static void nfs_commit_release_pages(str + + /* Okay, COMMIT succeeded, apparently. Check the verifier + * returned by the server against all stored verfs. */ +- if (verf->committed > NFS_UNSTABLE && +- !nfs_write_verifier_cmp(&req->wb_verf, &verf->verifier)) { ++ if (nfs_write_match_verf(verf, req)) { + /* We have a match */ + if (req->wb_page) + nfs_inode_remove_request(req); diff --git a/patches.suse/NFS-Fix-O_DIRECT-locking-issues.patch b/patches.suse/NFS-Fix-O_DIRECT-locking-issues.patch new file mode 100644 index 0000000..7a98c8a --- /dev/null +++ b/patches.suse/NFS-Fix-O_DIRECT-locking-issues.patch @@ -0,0 +1,50 @@ +From: Trond Myklebust +Date: Mon, 4 Sep 2023 12:34:38 -0400 +Subject: [PATCH] NFS: Fix O_DIRECT locking issues +Git-commit: 7c6339322ce0c6128acbe36aacc1eeb986dd7bf1 +Patch-mainline: v6.6 +References: git-fixes + +The dreq fields are protected by the dreq->lock. + +Fixes: 954998b60caa ("NFS: Fix error handling for O_DIRECT write scheduling") +Signed-off-by: Trond Myklebust +Signed-off-by: Anna Schumaker +Acked-by: NeilBrown + +--- + fs/nfs/direct.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/fs/nfs/direct.c ++++ b/fs/nfs/direct.c +@@ -589,7 +589,7 @@ static void nfs_direct_write_reschedule( + while (!list_empty(&reqs)) { + req = nfs_list_entry(reqs.next); + if (!nfs_pageio_add_request(&desc, req)) { +- spin_lock(&cinfo.inode->i_lock); ++ spin_lock(&dreq->lock); + if (dreq->error < 0) { + desc.pg_error = dreq->error; + } else if (desc.pg_error != -EAGAIN) { +@@ -599,7 +599,7 @@ static void nfs_direct_write_reschedule( + dreq->error = desc.pg_error; + } else + dreq->flags = NFS_ODIRECT_RESCHED_WRITES; +- spin_unlock(&cinfo.inode->i_lock); ++ spin_unlock(&dreq->lock); + break; + } + nfs_release_request(req); +@@ -906,9 +906,9 @@ static ssize_t nfs_direct_write_schedule + + /* If the error is soft, defer remaining requests */ + nfs_init_cinfo_from_dreq(&cinfo, dreq); +- spin_lock(&cinfo.inode->i_lock); ++ spin_lock(&dreq->lock); + dreq->flags = NFS_ODIRECT_RESCHED_WRITES; +- spin_unlock(&cinfo.inode->i_lock); ++ spin_unlock(&dreq->lock); + nfs_unlock_request(req); + nfs_mark_request_commit(req, NULL, &cinfo, 0); + desc.pg_error = 0; diff --git a/patches.suse/NFS-Fix-a-request-reference-leak-in-nfs_direct_write.patch b/patches.suse/NFS-Fix-a-request-reference-leak-in-nfs_direct_write.patch new file mode 100644 index 0000000..ceb2f7c --- /dev/null +++ b/patches.suse/NFS-Fix-a-request-reference-leak-in-nfs_direct_write.patch @@ -0,0 +1,30 @@ +From: Trond Myklebust +Date: Mon, 30 Mar 2020 20:13:48 -0400 +Subject: [PATCH] NFS: Fix a request reference leak in + nfs_direct_write_clear_reqs() +Git-commit: f02cec9d33e0069c11e58f97529c1d697255889d +Patch-mainline: v5.7 +References: git-fixes + +nfs_direct_write_scan_commit_list() will lock the request and bump +the reference count, but we also need to account for the reference +that was taken when we initially added the request to the commit list. + +Fixes: fb5f7f20cdb9 ("NFS: commit errors should be fatal") +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + fs/nfs/direct.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/nfs/direct.c ++++ b/fs/nfs/direct.c +@@ -691,6 +691,7 @@ static void nfs_direct_write_clear_reqs( + while (!list_empty(&reqs)) { + req = nfs_list_entry(reqs.next); + nfs_list_remove_request(req); ++ nfs_release_request(req); + nfs_unlock_and_release_request(req); + } + } diff --git a/patches.suse/NFS-Fix-an-Oopsable-condition-in-__nfs_pageio_add_re.patch b/patches.suse/NFS-Fix-an-Oopsable-condition-in-__nfs_pageio_add_re.patch index 9f844dc..3007d86 100644 --- a/patches.suse/NFS-Fix-an-Oopsable-condition-in-__nfs_pageio_add_re.patch +++ b/patches.suse/NFS-Fix-an-Oopsable-condition-in-__nfs_pageio_add_re.patch @@ -3,7 +3,7 @@ Date: Tue, 25 May 2021 10:23:05 -0400 Subject: [PATCH] NFS: Fix an Oopsable condition in __nfs_pageio_add_request() Git-commit: 56517ab958b7c11030e626250c00b9b1a24b41eb Patch-mainline: v5.13 -References: git-fixes +References: git-fixes CVE-2021-47167 bsc#1221991 Ensure that nfs_pageio_error_cleanup() resets the mirror array contents, so that the structure reflects the fact that it is now empty. diff --git a/patches.suse/NFS-Fix-an-off-by-one-in-root_nfs_cat.patch b/patches.suse/NFS-Fix-an-off-by-one-in-root_nfs_cat.patch new file mode 100644 index 0000000..71e8c93 --- /dev/null +++ b/patches.suse/NFS-Fix-an-off-by-one-in-root_nfs_cat.patch @@ -0,0 +1,36 @@ +From: Christophe JAILLET +Date: Sun, 18 Feb 2024 22:16:53 +0100 +Subject: [PATCH] NFS: Fix an off by one in root_nfs_cat() +Git-commit: 698ad1a538da0b6bf969cfee630b4e3a026afb87 +Patch-mainline: v6.9-rc1 +References: git-fixes + +The intent is to check if 'dest' is truncated or not. So, >= should be +used instead of >, because strlcat() returns the length of 'dest' and 'src' +excluding the trailing NULL. + +Fixes: 56463e50d1fc ("NFS: Use super.c for NFSROOT mount option parsing") +Signed-off-by: Christophe JAILLET +Reviewed-by: Benjamin Coddington +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + fs/nfs/nfsroot.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/nfs/nfsroot.c ++++ b/fs/nfs/nfsroot.c +@@ -168,10 +168,10 @@ static int __init root_nfs_cat(char *des + size_t len = strlen(dest); + + if (len && dest[len - 1] != ',') +- if (strlcat(dest, ",", destlen) > destlen) ++ if (strlcat(dest, ",", destlen) >= destlen) + return -1; + +- if (strlcat(dest, src, destlen) > destlen) ++ if (strlcat(dest, src, destlen) >= destlen) + return -1; + return 0; + } diff --git a/patches.suse/NFS-Fix-direct-WRITE-throughput-regression.patch b/patches.suse/NFS-Fix-direct-WRITE-throughput-regression.patch new file mode 100644 index 0000000..8106ee5 --- /dev/null +++ b/patches.suse/NFS-Fix-direct-WRITE-throughput-regression.patch @@ -0,0 +1,44 @@ +From: Chuck Lever +Date: Fri, 29 May 2020 14:14:40 -0400 +Subject: [PATCH] NFS: Fix direct WRITE throughput regression +Git-commit: ba838a75e73f55a780f1ee896b8e3ecb032dba0f +Patch-mainline: v5.8 +References: git-fixes + +I measured a 50% throughput regression for large direct writes. + +The observed on-the-wire behavior is that the client sends every +NFS WRITE twice: once as an UNSTABLE WRITE plus a COMMIT, and once +as a FILE_SYNC WRITE. + +This is because the nfs_write_match_verf() check in +nfs_direct_commit_complete() fails for every WRITE. + +Buffered writes use nfs_write_completion(), which sets req->wb_verf +correctly. Direct writes use nfs_direct_write_completion(), which +does not set req->wb_verf at all. This leaves req->wb_verf set to +all zeroes for every direct WRITE, and thus +nfs_direct_commit_completion() always sets NFS_ODIRECT_RESCHED_WRITES. + +This fix appears to restore nearly all of the lost performance. + +Fixes: 1f28476dcb98 ("NFS: Fix O_DIRECT commit verifier handling") +Signed-off-by: Chuck Lever +Signed-off-by: Anna Schumaker +Acked-by: NeilBrown + +--- + fs/nfs/direct.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/nfs/direct.c ++++ b/fs/nfs/direct.c +@@ -771,6 +771,8 @@ static void nfs_direct_write_completion( + nfs_list_remove_request(req); + if (request_commit) { + kref_get(&req->wb_kref); ++ memcpy(&req->wb_verf, &hdr->verf.verifier, ++ sizeof(req->wb_verf)); + nfs_mark_request_commit(req, hdr->lseg, &cinfo, + hdr->ds_commit_idx); + } diff --git a/patches.suse/NFS-Fix-error-handling-for-O_DIRECT-write-scheduling.patch b/patches.suse/NFS-Fix-error-handling-for-O_DIRECT-write-scheduling.patch new file mode 100644 index 0000000..f026c3e --- /dev/null +++ b/patches.suse/NFS-Fix-error-handling-for-O_DIRECT-write-scheduling.patch @@ -0,0 +1,147 @@ +From: Trond Myklebust +Date: Mon, 4 Sep 2023 12:34:37 -0400 +Subject: [PATCH] NFS: Fix error handling for O_DIRECT write scheduling +Git-commit: 954998b60caa8f2a3bf3abe490de6f08d283687a +Patch-mainline: v6.6 +References: git-fixes + +If we fail to schedule a request for transmission, there are 2 +Possibilities: +1) Either we hit a fatal error, and we just want to drop the remaining + requests on the floor. +2) We were asked to try again, in which case we should allow the + outstanding RPC calls to complete, so that we can recoalesce requests + and try again. + +Fixes: d600ad1f2bdb ("NFS41: pop some layoutget errors to application") +Signed-off-by: Trond Myklebust +Signed-off-by: Anna Schumaker +Acked-by: NeilBrown + +--- + fs/nfs/direct.c | 67 +++++++++++++++++++++++++++++++++++++++----------------- + 1 file changed, 47 insertions(+), 20 deletions(-) + +--- a/fs/nfs/direct.c ++++ b/fs/nfs/direct.c +@@ -655,10 +655,9 @@ nfs_direct_write_scan_commit_list(struct + static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) + { + struct nfs_pageio_descriptor desc; +- struct nfs_page *req, *tmp; ++ struct nfs_page *req; + LIST_HEAD(reqs); + struct nfs_commit_info cinfo; +- LIST_HEAD(failed); + int i; + + nfs_init_cinfo_from_dreq(&cinfo, dreq); +@@ -680,32 +679,38 @@ static void nfs_direct_write_reschedule( + + req = nfs_list_entry(reqs.next); + nfs_direct_setup_mirroring(dreq, &desc, req); +- if (desc.pg_error < 0) { +- list_splice_init(&reqs, &failed); ++ if (desc.pg_error < 0) + goto out_failed; +- } + +- list_for_each_entry_safe(req, tmp, &reqs, wb_list) { ++ while (!list_empty(&reqs)) { ++ req = nfs_list_entry(reqs.next); + if (!nfs_pageio_add_request(&desc, req)) { +- nfs_list_remove_request(req); +- nfs_list_add_request(req, &failed); + spin_lock(&cinfo.inode->i_lock); +- dreq->flags = 0; +- if (desc.pg_error < 0) ++ if (dreq->error < 0) { ++ desc.pg_error = dreq->error; ++ } else if (desc.pg_error != -EAGAIN) { ++ dreq->flags = 0; ++ if (!desc.pg_error) ++ desc.pg_error = -EIO; + dreq->error = desc.pg_error; +- else +- dreq->error = -EIO; ++ } else ++ dreq->flags = NFS_ODIRECT_RESCHED_WRITES; + spin_unlock(&cinfo.inode->i_lock); ++ break; + } + nfs_release_request(req); + } + nfs_pageio_complete(&desc); + + out_failed: +- while (!list_empty(&failed)) { +- req = nfs_list_entry(failed.next); ++ while (!list_empty(&reqs)) { ++ req = nfs_list_entry(reqs.next); + nfs_list_remove_request(req); + nfs_unlock_and_release_request(req); ++ if (desc.pg_error == -EAGAIN) ++ nfs_mark_request_commit(req, NULL, &cinfo, 0); ++ else ++ nfs_release_request(req); + } + + if (put_dreq(dreq)) +@@ -893,9 +898,11 @@ static ssize_t nfs_direct_write_schedule + { + struct nfs_pageio_descriptor desc; + struct inode *inode = dreq->inode; ++ struct nfs_commit_info cinfo; + ssize_t result = 0; + size_t requested_bytes = 0; + size_t wsize = max_t(size_t, NFS_SERVER(inode)->wsize, PAGE_SIZE); ++ bool defer = false; + + nfs_pageio_init_write(&desc, inode, ioflags, false, + &nfs_direct_write_completion_ops); +@@ -936,19 +943,39 @@ static ssize_t nfs_direct_write_schedule + break; + } + ++ pgbase = 0; ++ bytes -= req_len; ++ requested_bytes += req_len; ++ pos += req_len; ++ dreq->bytes_left -= req_len; ++ ++ if (defer) { ++ nfs_mark_request_commit(req, NULL, &cinfo, 0); ++ continue; ++ } ++ + nfs_lock_request(req); + req->wb_index = pos >> PAGE_SHIFT; + req->wb_offset = pos & ~PAGE_MASK; +- if (!nfs_pageio_add_request(&desc, req)) { ++ if (nfs_pageio_add_request(&desc, req)) ++ continue; ++ ++ /* Exit on hard errors */ ++ if (desc.pg_error < 0 && desc.pg_error != -EAGAIN) { + result = desc.pg_error; + nfs_unlock_and_release_request(req); + break; + } +- pgbase = 0; +- bytes -= req_len; +- requested_bytes += req_len; +- pos += req_len; +- dreq->bytes_left -= req_len; ++ ++ /* If the error is soft, defer remaining requests */ ++ nfs_init_cinfo_from_dreq(&cinfo, dreq); ++ spin_lock(&cinfo.inode->i_lock); ++ dreq->flags = NFS_ODIRECT_RESCHED_WRITES; ++ spin_unlock(&cinfo.inode->i_lock); ++ nfs_unlock_request(req); ++ nfs_mark_request_commit(req, NULL, &cinfo, 0); ++ desc.pg_error = 0; ++ defer = true; + } + nfs_direct_release_pages(pagevec, npages); + kvfree(pagevec); diff --git a/patches.suse/NFS-More-O_DIRECT-accounting-fixes-for-error-paths.patch b/patches.suse/NFS-More-O_DIRECT-accounting-fixes-for-error-paths.patch new file mode 100644 index 0000000..7b5d2fc --- /dev/null +++ b/patches.suse/NFS-More-O_DIRECT-accounting-fixes-for-error-paths.patch @@ -0,0 +1,129 @@ +From: Trond Myklebust +Date: Mon, 4 Sep 2023 12:34:39 -0400 +Subject: [PATCH] NFS: More O_DIRECT accounting fixes for error paths +Git-commit: 8982f7aff39fb526aba4441fff2525fcedd5e1a3 +Patch-mainline: v6.6 +References: git-fixes + +If we hit a fatal error when retransmitting, we do need to record the +removal of the request from the count of written bytes. + +Fixes: 031d73ed768a ("NFS: Fix O_DIRECT accounting of number of bytes read/written") +Signed-off-by: Trond Myklebust +Signed-off-by: Anna Schumaker +Acked-by: NeilBrown + +--- + fs/nfs/direct.c | 47 +++++++++++++++++++++++++++++++---------------- + 1 file changed, 31 insertions(+), 16 deletions(-) + +--- a/fs/nfs/direct.c ++++ b/fs/nfs/direct.c +@@ -135,12 +135,10 @@ nfs_direct_handle_truncated(struct nfs_d + dreq->max_count = dreq_len; + if (dreq->count > dreq_len) + dreq->count = dreq_len; +- +- if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) +- dreq->error = hdr->error; +- else /* Clear outstanding error if this is EOF */ +- dreq->error = 0; + } ++ ++ if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) && !dreq->error) ++ dreq->error = hdr->error; + if (mirror->count > dreq_len) + mirror->count = dreq_len; + } +@@ -167,6 +165,18 @@ nfs_direct_count_bytes(struct nfs_direct + dreq->count = dreq_len; + } + ++static void nfs_direct_truncate_request(struct nfs_direct_req *dreq, ++ struct nfs_page *req) ++{ ++ loff_t offs = req_offset(req); ++ size_t req_start = (size_t)(offs - dreq->io_start); ++ ++ if (req_start < dreq->max_count) ++ dreq->max_count = req_start; ++ if (req_start < dreq->count) ++ dreq->count = req_start; ++} ++ + /** + * nfs_direct_IO - NFS address space operation for direct I/O + * @iocb: target I/O control block +@@ -562,10 +572,6 @@ static void nfs_direct_write_reschedule( + nfs_init_cinfo_from_dreq(&cinfo, dreq); + nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo); + +- dreq->count = 0; +- dreq->max_count = 0; +- list_for_each_entry(req, &reqs, wb_list) +- dreq->max_count += req->wb_bytes; + nfs_clear_pnfs_ds_commit_verifiers(&dreq->ds_cinfo); + for (i = 0; i < dreq->mirror_count; i++) + dreq->mirrors[i].count = 0; +@@ -605,10 +611,14 @@ out_failed: + req = nfs_list_entry(reqs.next); + nfs_list_remove_request(req); + nfs_unlock_and_release_request(req); +- if (desc.pg_error == -EAGAIN) ++ if (desc.pg_error == -EAGAIN) { + nfs_mark_request_commit(req, NULL, &cinfo, 0); +- else ++ } else { ++ spin_lock(&dreq->lock); ++ nfs_direct_truncate_request(dreq, req); ++ spin_unlock(&dreq->lock); + nfs_release_request(req); ++ } + } + + if (put_dreq(dreq)) +@@ -626,8 +636,6 @@ static void nfs_direct_commit_complete(s + if (status < 0) { + /* Errors in commit are fatal */ + dreq->error = status; +- dreq->max_count = 0; +- dreq->count = 0; + dreq->flags = NFS_ODIRECT_DONE; + } else if (dreq->flags == NFS_ODIRECT_DONE) + status = dreq->error; +@@ -637,10 +645,15 @@ static void nfs_direct_commit_complete(s + while (!list_empty(&data->pages)) { + req = nfs_list_entry(data->pages.next); + nfs_list_remove_request(req); +- if (status >= 0 && !nfs_write_match_verf(verf, req)) { ++ if (status < 0) { ++ spin_lock(&dreq->lock); ++ nfs_direct_truncate_request(dreq, req); ++ spin_unlock(&dreq->lock); ++ nfs_release_request(req); ++ } else if (!nfs_write_match_verf(verf, req)) { + dreq->flags = NFS_ODIRECT_RESCHED_WRITES; + nfs_mark_request_commit(req, NULL, &cinfo, 0); +- } else /* Error or match */ ++ } else + nfs_release_request(req); + nfs_unlock_and_release_request(req); + } +@@ -691,6 +704,7 @@ static void nfs_direct_write_clear_reqs( + while (!list_empty(&reqs)) { + req = nfs_list_entry(reqs.next); + nfs_list_remove_request(req); ++ nfs_direct_truncate_request(dreq, req); + nfs_release_request(req); + nfs_unlock_and_release_request(req); + } +@@ -737,7 +751,8 @@ static void nfs_direct_write_completion( + } + + nfs_direct_count_bytes(dreq, hdr); +- if (test_bit(NFS_IOHDR_UNSTABLE_WRITES, &hdr->flags)) { ++ if (test_bit(NFS_IOHDR_UNSTABLE_WRITES, &hdr->flags) && ++ !test_bit(NFS_IOHDR_ERROR, &hdr->flags)) { + switch (dreq->flags) { + case 0: + dreq->flags = NFS_ODIRECT_DO_COMMIT; diff --git a/patches.suse/NFS-add-atomic_open-for-NFSv3-to-handle-O_TRUNC-corr.patch b/patches.suse/NFS-add-atomic_open-for-NFSv3-to-handle-O_TRUNC-corr.patch new file mode 100644 index 0000000..4d8d7d8 --- /dev/null +++ b/patches.suse/NFS-add-atomic_open-for-NFSv3-to-handle-O_TRUNC-corr.patch @@ -0,0 +1,165 @@ +From: NeilBrown +Date: Mon, 4 Mar 2024 10:54:34 +1100 +Subject: [PATCH] NFS: add atomic_open for NFSv3 to handle O_TRUNC correctly. +Patch-mainline: Submitted - 05mar2024 linux-nfs +References: bsc#1219847 + +With two clients with NFSv3 mounts of the same directory, the sequence: + + client1 client2 + ls -l afile + echo hello there > afile + echo HELLO > afile + cat afile + +will show + HELLO + there + +because the O_TRUNC requested in the final 'echo' doesn't take effect. +This is because the "Negative dentry, just create a file" section in +lookup_open() assumes that the file *does* get created since the dentry +was negative, so it sets FMODE_CREATED, and this causes do_open() to +clear O_TRUNC and so the file doesn't get truncated. + +Even mounting with -o lookupcache=none does not help as +nfs_neg_need_reval() always returns false if LOOKUP_CREATE is set. + +This patch fixes the problem by providing an atomic_open inode operation +for NFSv3 (and v2). The code is largely the code from the branch in +lookup_open() when atomic_open is not provided. The significant change +is that the O_TRUNC flag is passed a new nfs_do_create() which add +'trunc' handling to nfs_create(). + +Signed-off-by: NeilBrown +Acked-by: NeilBrown + +--- + fs/nfs/dir.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++-- + fs/nfs/nfs3proc.c | 1 + fs/nfs/proc.c | 1 + include/linux/nfs_fs.h | 3 ++ + 4 files changed, 56 insertions(+), 2 deletions(-) + +--- a/fs/nfs/dir.c ++++ b/fs/nfs/dir.c +@@ -53,6 +53,9 @@ static int nfs_readdir(struct file *, st + static int nfs_fsync_dir(struct file *, loff_t, loff_t, int); + static loff_t nfs_llseek_dir(struct file *, loff_t, int); + static void nfs_readdir_clear_array(struct page*); ++static int nfs_do_create(struct inode *dir, ++ struct dentry *dentry, umode_t mode, ++ bool excl, bool trunc); + + const struct file_operations nfs_dir_operations = { + .llseek = nfs_llseek_dir, +@@ -1721,6 +1724,42 @@ static int nfs4_lookup_revalidate(struct + } + + #endif /* CONFIG_NFSV4 */ ++int nfs_atomic_open_v23(struct inode *dir, struct dentry *dentry, ++ struct file *file, unsigned int open_flags, ++ umode_t mode, int *opened) ++{ ++ ++ /* Same as look+open from lookup_open(), but with different O_TRUNC ++ * handling. ++ */ ++ int error = 0; ++ ++ if (d_in_lookup(dentry)) { ++ /* The only flag that nfs_lookup uses is LOOKUP_EXCL, ++ * and we don't want that set as it bypasses the lookup. ++ */ ++ struct dentry *res = nfs_lookup(dir, dentry, 0); ++ ++ d_lookup_done(dentry); ++ if (unlikely(res)) { ++ if (IS_ERR(res)) ++ return PTR_ERR(res); ++ return finish_no_open(file, res); ++ } ++ } ++ ++ /* Negative dentry, just create the file */ ++ if (!dentry->d_inode && (open_flags & O_CREAT)) { ++ *opened |= FILE_CREATED; ++ error = nfs_do_create(dir, dentry, mode, ++ open_flags & O_EXCL, ++ open_flags & O_TRUNC); ++ if (error) ++ return error; ++ } ++ return finish_open(file, dentry, NULL, opened); ++} ++EXPORT_SYMBOL_GPL(nfs_atomic_open_v23); + + /* + * Code common to create, mkdir, and mknod. +@@ -1771,8 +1810,8 @@ EXPORT_SYMBOL_GPL(nfs_instantiate); + * that the operation succeeded on the server, but an error in the + * reply path made it appear to have failed. + */ +-int nfs_create(struct inode *dir, struct dentry *dentry, +- umode_t mode, bool excl) ++static int nfs_do_create(struct inode *dir, struct dentry *dentry, ++ umode_t mode, bool excl, bool trunc) + { + struct iattr attr; + int open_flags = excl ? O_CREAT | O_EXCL : O_CREAT; +@@ -1783,6 +1822,10 @@ int nfs_create(struct inode *dir, struct + + attr.ia_mode = mode; + attr.ia_valid = ATTR_MODE; ++ if (trunc) { ++ attr.ia_size = 0; ++ attr.ia_valid |= ATTR_SIZE; ++ } + + trace_nfs_create_enter(dir, dentry, open_flags); + error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags); +@@ -1794,6 +1837,12 @@ out_err: + d_drop(dentry); + return error; + } ++ ++int nfs_create(struct inode *dir, ++ struct dentry *dentry, umode_t mode, bool excl) ++{ ++ return nfs_do_create(dir, dentry, mode, excl, false); ++} + EXPORT_SYMBOL_GPL(nfs_create); + + /* +--- a/fs/nfs/nfs3proc.c ++++ b/fs/nfs/nfs3proc.c +@@ -937,6 +937,7 @@ static int nfs3_return_delegation(struct + + static const struct inode_operations nfs3_dir_inode_operations = { + .create = nfs_create, ++ .atomic_open = nfs_atomic_open_v23, + .lookup = nfs_lookup, + .link = nfs_link, + .unlink = nfs_unlink, +--- a/fs/nfs/proc.c ++++ b/fs/nfs/proc.c +@@ -682,6 +682,7 @@ static int nfs_return_delegation(struct + static const struct inode_operations nfs_dir_inode_operations = { + .create = nfs_create, + .lookup = nfs_lookup, ++ .atomic_open = nfs_atomic_open_v23, + .link = nfs_link, + .unlink = nfs_unlink, + .symlink = nfs_symlink, +--- a/include/linux/nfs_fs.h ++++ b/include/linux/nfs_fs.h +@@ -457,6 +457,9 @@ extern int nfs_instantiate(struct dentry + struct nfs_fattr *fattr, struct nfs4_label *label); + extern int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags); + extern void nfs_access_zap_cache(struct inode *inode); ++extern int nfs_atomic_open_v23(struct inode *dir, struct dentry *dentry, ++ struct file *file, unsigned int open_flags, ++ umode_t mode, int *opened); + + /* + * linux/fs/nfs/symlink.c diff --git a/patches.suse/NFS-commit-errors-should-be-fatal.patch b/patches.suse/NFS-commit-errors-should-be-fatal.patch new file mode 100644 index 0000000..bf87313 --- /dev/null +++ b/patches.suse/NFS-commit-errors-should-be-fatal.patch @@ -0,0 +1,87 @@ +From: Trond Myklebust +Date: Sat, 21 Mar 2020 09:36:13 -0400 +Subject: [PATCH] NFS: commit errors should be fatal +Git-commit: fb5f7f20cdb91f8ef985aef09fa2217c49c38396 +Patch-mainline: v5.7 +References: git-fixes + +Fix the O_DIRECT code to avoid retries if the COMMIT fails with a fatal +error. + +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + fs/nfs/direct.c | 32 ++++++++++++++++++++++++++++++-- + 1 file changed, 30 insertions(+), 2 deletions(-) + +--- a/fs/nfs/direct.c ++++ b/fs/nfs/direct.c +@@ -103,6 +103,7 @@ struct nfs_direct_req { + #define NFS_ODIRECT_RESCHED_WRITES (2) /* write verification failed */ + /* for read */ + #define NFS_ODIRECT_SHOULD_DIRTY (3) /* dirty user-space page after read */ ++#define NFS_ODIRECT_DONE INT_MAX /* write verification failed */ + struct nfs_writeverf verf; /* unstable write verifier */ + }; + +@@ -724,8 +725,17 @@ static void nfs_direct_commit_complete(s + struct nfs_page *req; + int status = data->task.tk_status; + ++ if (status < 0) { ++ /* Errors in commit are fatal */ ++ dreq->error = status; ++ dreq->max_count = 0; ++ dreq->count = 0; ++ dreq->flags = NFS_ODIRECT_DONE; ++ } else if (dreq->flags == NFS_ODIRECT_DONE) ++ status = dreq->error; ++ + nfs_init_cinfo_from_dreq(&cinfo, dreq); +- if (status < 0 || nfs_direct_cmp_commit_data_verf(dreq, data)) ++ if (nfs_direct_cmp_commit_data_verf(dreq, data)) + dreq->flags = NFS_ODIRECT_RESCHED_WRITES; + + while (!list_empty(&data->pages)) { +@@ -749,7 +759,8 @@ static void nfs_direct_resched_write(str + struct nfs_direct_req *dreq = cinfo->dreq; + + spin_lock(&dreq->lock); +- dreq->flags = NFS_ODIRECT_RESCHED_WRITES; ++ if (dreq->flags != NFS_ODIRECT_DONE) ++ dreq->flags = NFS_ODIRECT_RESCHED_WRITES; + spin_unlock(&dreq->lock); + nfs_mark_request_commit(req, NULL, cinfo, 0); + } +@@ -772,6 +783,22 @@ static void nfs_direct_commit_schedule(s + nfs_direct_write_reschedule(dreq); + } + ++static void nfs_direct_write_clear_reqs(struct nfs_direct_req *dreq) ++{ ++ struct nfs_commit_info cinfo; ++ struct nfs_page *req; ++ LIST_HEAD(reqs); ++ ++ nfs_init_cinfo_from_dreq(&cinfo, dreq); ++ nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo); ++ ++ while (!list_empty(&reqs)) { ++ req = nfs_list_entry(reqs.next); ++ nfs_list_remove_request(req); ++ nfs_unlock_and_release_request(req); ++ } ++} ++ + static void nfs_direct_write_schedule_work(struct work_struct *work) + { + struct nfs_direct_req *dreq = container_of(work, struct nfs_direct_req, work); +@@ -786,6 +813,7 @@ static void nfs_direct_write_schedule_wo + nfs_direct_write_reschedule(dreq); + break; + default: ++ nfs_direct_write_clear_reqs(dreq); + nfs_zap_mapping(dreq->inode, dreq->inode->i_mapping); + nfs_direct_complete(dreq); + } diff --git a/patches.suse/NFS-fix-an-incorrect-limit-in-filelayout_decode_layo.patch b/patches.suse/NFS-fix-an-incorrect-limit-in-filelayout_decode_layo.patch index e92c205..8d6b1f5 100644 --- a/patches.suse/NFS-fix-an-incorrect-limit-in-filelayout_decode_layo.patch +++ b/patches.suse/NFS-fix-an-incorrect-limit-in-filelayout_decode_layo.patch @@ -3,7 +3,7 @@ Date: Tue, 11 May 2021 11:49:42 +0300 Subject: [PATCH] NFS: fix an incorrect limit in filelayout_decode_layout() Git-commit: 769b01ea68b6c49dc3cde6adf7e53927dacbd3a8 Patch-mainline: v5.13 -References: git-fixes +References: git-fixes CVE-2021-47168 bsc#1222002 The "sizeof(struct nfs_fh)" is two bytes too large and could lead to memory corruption. It should be NFS_MAXFHSIZE because that's the size diff --git a/patches.suse/NFSD-Reset-cb_seq_status-after-NFS4ERR_DELAY.patch b/patches.suse/NFSD-Reset-cb_seq_status-after-NFS4ERR_DELAY.patch new file mode 100644 index 0000000..62bd79b --- /dev/null +++ b/patches.suse/NFSD-Reset-cb_seq_status-after-NFS4ERR_DELAY.patch @@ -0,0 +1,40 @@ +From: Chuck Lever +Date: Fri, 26 Jan 2024 12:45:17 -0500 +Subject: [PATCH] NFSD: Reset cb_seq_status after NFS4ERR_DELAY +Git-commit: 961b4b5e86bf56a2e4b567f81682defa5cba957e +Patch-mainline: v6.9-rc1 +References: git-fixes + +I noticed that once an NFSv4.1 callback operation gets a +NFS4ERR_DELAY status on CB_SEQUENCE and then the connection is lost, +the callback client loops, resending it indefinitely. + +The switch arm in nfsd4_cb_sequence_done() that handles +NFS4ERR_DELAY uses rpc_restart_call() to rearm the RPC state machine +for the retransmit, but that path does not call the rpc_prepare_call +callback again. Thus cb_seq_status is set to -10008 by the first +NFS4ERR_DELAY result, but is never set back to 1 for the retransmits. + +nfsd4_cb_sequence_done() thinks it's getting nothing but a +long series of CB_SEQUENCE NFS4ERR_DELAY replies. + +Fixes: 7ba6cad6c88f ("nfsd: New helper nfsd4_cb_sequence_done() for processing more cb errors") +Reviewed-by: Jeff Layton +Reviewed-by: Benjamin Coddington +Signed-off-by: Chuck Lever +Acked-by: NeilBrown + +--- + fs/nfsd/nfs4callback.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/nfsd/nfs4callback.c ++++ b/fs/nfsd/nfs4callback.c +@@ -984,6 +984,7 @@ static bool nfsd4_cb_sequence_done(struc + ret = false; + break; + case -NFS4ERR_DELAY: ++ cb->cb_seq_status = 1; + if (!rpc_restart_call(task)) + goto out; + diff --git a/patches.suse/NFSD-Retransmit-callbacks-after-client-reconnects.patch b/patches.suse/NFSD-Retransmit-callbacks-after-client-reconnects.patch new file mode 100644 index 0000000..8b27309 --- /dev/null +++ b/patches.suse/NFSD-Retransmit-callbacks-after-client-reconnects.patch @@ -0,0 +1,47 @@ +From: Chuck Lever +Date: Fri, 26 Jan 2024 12:45:36 -0500 +Subject: [PATCH] NFSD: Retransmit callbacks after client reconnects +Git-commit: 43b02dba110e63e5f8180248920032422ac8c1e4 +Patch-mainline: v6.9-rc1 +References: git-fixes + +NFSv4.1 clients assume that if they disconnect, that will force the +server to resend pending callback operations once a fresh connection +has been established. + +Turns out NFSD has not been resending after reconnect. + +Fixes: 7ba6cad6c88f ("nfsd: New helper nfsd4_cb_sequence_done() for processing more cb errors") +Reviewed-by: Jeff Layton +Reviewed-by: Benjamin Coddington +Signed-off-by: Chuck Lever +Acked-by: NeilBrown + +--- + fs/nfsd/nfs4callback.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/fs/nfsd/nfs4callback.c ++++ b/fs/nfsd/nfs4callback.c +@@ -978,11 +978,20 @@ static bool nfsd4_cb_sequence_done(struc + break; + case -ESERVERFAULT: + ++session->se_cb_seq_nr; ++ nfsd4_mark_cb_fault(cb->cb_clp, cb->cb_seq_status); ++ ret = false; ++ break; + case 1: ++ /* ++ * cb_seq_status remains 1 if an RPC Reply was never ++ * received. NFSD can't know if the client processed ++ * the CB_SEQUENCE operation. Ask the client to send a ++ * DESTROY_SESSION to recover. ++ */ + case -NFS4ERR_BADSESSION: + nfsd4_mark_cb_fault(cb->cb_clp, cb->cb_seq_status); + ret = false; +- break; ++ goto need_restart; + case -NFS4ERR_DELAY: + cb->cb_seq_status = 1; + if (!rpc_restart_call(task)) diff --git a/patches.suse/NFSv4-Fix-a-NULL-pointer-dereference-in-pnfs_mark_ma.patch b/patches.suse/NFSv4-Fix-a-NULL-pointer-dereference-in-pnfs_mark_ma.patch index ad06404..401c27d 100644 --- a/patches.suse/NFSv4-Fix-a-NULL-pointer-dereference-in-pnfs_mark_ma.patch +++ b/patches.suse/NFSv4-Fix-a-NULL-pointer-dereference-in-pnfs_mark_ma.patch @@ -4,7 +4,7 @@ Subject: [PATCH] NFSv4: Fix a NULL pointer dereference in pnfs_mark_matching_lsegs_return() Git-commit: a421d218603ffa822a0b8045055c03eae394a7eb Patch-mainline: v5.13 -References: git-fixes +References: git-fixes CVE-2021-47179 bsc#1222001 Commit de144ff4234f changes _pnfs_return_layout() to call pnfs_mark_matching_lsegs_return() passing NULL as the struct diff --git a/patches.suse/NFSv4.1-pnfs-Ensure-we-handle-the-error-NFS4ERR_RETU.patch b/patches.suse/NFSv4.1-pnfs-Ensure-we-handle-the-error-NFS4ERR_RETU.patch new file mode 100644 index 0000000..ce380c4 --- /dev/null +++ b/patches.suse/NFSv4.1-pnfs-Ensure-we-handle-the-error-NFS4ERR_RETU.patch @@ -0,0 +1,48 @@ +From: Trond Myklebust +Date: Wed, 15 Nov 2023 13:55:29 -0500 +Subject: [PATCH] NFSv4.1/pnfs: Ensure we handle the error + NFS4ERR_RETURNCONFLICT +Git-commit: 037e56a22ff37f9a9c2330b66cff55d3d1ff9b90 +Patch-mainline: v6.8 +References: git-fixes + +Once the client has processed the CB_LAYOUTRECALL, but has not yet +successfully returned the layout, the server is supposed to switch to +returning NFS4ERR_RETURNCONFLICT. This patch ensures that we handle +that return value correctly. + +Fixes: 183d9e7b112a ("pnfs: rework LAYOUTGET retry handling") +Signed-off-by: Trond Myklebust +Signed-off-by: Anna Schumaker +Acked-by: NeilBrown + +--- + fs/nfs/nfs4proc.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -167,6 +167,7 @@ static int nfs4_map_errors(int err) + case -NFS4ERR_RESOURCE: + case -NFS4ERR_LAYOUTTRYLATER: + case -NFS4ERR_RECALLCONFLICT: ++ case -NFS4ERR_RETURNCONFLICT: + return -EREMOTEIO; + case -NFS4ERR_WRONGSEC: + case -NFS4ERR_WRONG_CRED: +@@ -483,6 +484,7 @@ static int nfs4_do_handle_exception(stru + case -NFS4ERR_GRACE: + case -NFS4ERR_LAYOUTTRYLATER: + case -NFS4ERR_RECALLCONFLICT: ++ case -NFS4ERR_RETURNCONFLICT: + exception->delay = 1; + return 0; + +@@ -8726,6 +8728,7 @@ nfs4_layoutget_handle_exception(struct r + status = -EBUSY; + break; + case -NFS4ERR_RECALLCONFLICT: ++ case -NFS4ERR_RETURNCONFLICT: + status = -ERECALLCONFLICT; + break; + case -NFS4ERR_DELEG_REVOKED: diff --git a/patches.suse/SUNRPC-Fix-RPC-client-cleaned-up-the-freed-pipefs-de.patch b/patches.suse/SUNRPC-Fix-RPC-client-cleaned-up-the-freed-pipefs-de.patch new file mode 100644 index 0000000..1d0d971 --- /dev/null +++ b/patches.suse/SUNRPC-Fix-RPC-client-cleaned-up-the-freed-pipefs-de.patch @@ -0,0 +1,113 @@ +From: felix +Date: Mon, 23 Oct 2023 09:40:19 +0800 +Subject: [PATCH] SUNRPC: Fix RPC client cleaned up the freed pipefs dentries +Git-commit: bfca5fb4e97c46503ddfc582335917b0cc228264 +Patch-mainline: v6.7 +References: git-fixes + +RPC client pipefs dentries cleanup is in separated rpc_remove_pipedir() +workqueue,which takes care about pipefs superblock locking. +In some special scenarios, when kernel frees the pipefs sb of the +current client and immediately alloctes a new pipefs sb, +rpc_remove_pipedir function would misjudge the existence of pipefs +sb which is not the one it used to hold. As a result, +the rpc_remove_pipedir would clean the released freed pipefs dentries. + +To fix this issue, rpc_remove_pipedir should check whether the +current pipefs sb is consistent with the original pipefs sb. + +This error can be catched by KASAN: +========================================================= +[ 250.497700] BUG: KASAN: slab-use-after-free in dget_parent+0x195/0x200 +[ 250.498315] Read of size 4 at addr ffff88800a2ab804 by task kworker/0:18/106503 +[ 250.500549] Workqueue: events rpc_free_client_work +[ 250.501001] Call Trace: +[ 250.502880] kasan_report+0xb6/0xf0 +[ 250.503209] ? dget_parent+0x195/0x200 +[ 250.503561] dget_parent+0x195/0x200 +[ 250.503897] ? __pfx_rpc_clntdir_depopulate+0x10/0x10 +[ 250.504384] rpc_rmdir_depopulate+0x1b/0x90 +[ 250.504781] rpc_remove_client_dir+0xf5/0x150 +[ 250.505195] rpc_free_client_work+0xe4/0x230 +[ 250.505598] process_one_work+0x8ee/0x13b0 +... +[ 22.039056] Allocated by task 244: +[ 22.039390] kasan_save_stack+0x22/0x50 +[ 22.039758] kasan_set_track+0x25/0x30 +[ 22.040109] __kasan_slab_alloc+0x59/0x70 +[ 22.040487] kmem_cache_alloc_lru+0xf0/0x240 +[ 22.040889] __d_alloc+0x31/0x8e0 +[ 22.041207] d_alloc+0x44/0x1f0 +[ 22.041514] __rpc_lookup_create_exclusive+0x11c/0x140 +[ 22.041987] rpc_mkdir_populate.constprop.0+0x5f/0x110 +[ 22.042459] rpc_create_client_dir+0x34/0x150 +[ 22.042874] rpc_setup_pipedir_sb+0x102/0x1c0 +[ 22.043284] rpc_client_register+0x136/0x4e0 +[ 22.043689] rpc_new_client+0x911/0x1020 +[ 22.044057] rpc_create_xprt+0xcb/0x370 +[ 22.044417] rpc_create+0x36b/0x6c0 +... +[ 22.049524] Freed by task 0: +[ 22.049803] kasan_save_stack+0x22/0x50 +[ 22.050165] kasan_set_track+0x25/0x30 +[ 22.050520] kasan_save_free_info+0x2b/0x50 +[ 22.050921] __kasan_slab_free+0x10e/0x1a0 +[ 22.051306] kmem_cache_free+0xa5/0x390 +[ 22.051667] rcu_core+0x62c/0x1930 +[ 22.051995] __do_softirq+0x165/0x52a +[ 22.052347] +[ 22.052503] Last potentially related work creation: +[ 22.052952] kasan_save_stack+0x22/0x50 +[ 22.053313] __kasan_record_aux_stack+0x8e/0xa0 +[ 22.053739] __call_rcu_common.constprop.0+0x6b/0x8b0 +[ 22.054209] dentry_free+0xb2/0x140 +[ 22.054540] __dentry_kill+0x3be/0x540 +[ 22.054900] shrink_dentry_list+0x199/0x510 +[ 22.055293] shrink_dcache_parent+0x190/0x240 +[ 22.055703] do_one_tree+0x11/0x40 +[ 22.056028] shrink_dcache_for_umount+0x61/0x140 +[ 22.056461] generic_shutdown_super+0x70/0x590 +[ 22.056879] kill_anon_super+0x3a/0x60 +[ 22.057234] rpc_kill_sb+0x121/0x200 + +Fixes: 0157d021d23a ("SUNRPC: handle RPC client pipefs dentries by network namespace aware routines") +Signed-off-by: felix +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + include/linux/sunrpc/clnt.h | 1 + + net/sunrpc/clnt.c | 5 ++++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +--- a/include/linux/sunrpc/clnt.h ++++ b/include/linux/sunrpc/clnt.h +@@ -69,6 +69,7 @@ struct rpc_clnt { + struct dentry *cl_debugfs; /* debugfs directory */ + #endif + struct rpc_xprt_iter cl_xpi; ++ struct super_block *pipefs_sb; + }; + + /* +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -113,7 +113,8 @@ static void rpc_clnt_remove_pipedir(stru + + pipefs_sb = rpc_get_sb_net(net); + if (pipefs_sb) { +- __rpc_clnt_remove_pipedir(clnt); ++ if (pipefs_sb == clnt->pipefs_sb) ++ __rpc_clnt_remove_pipedir(clnt); + rpc_put_sb_net(net); + } + } +@@ -153,6 +154,8 @@ rpc_setup_pipedir(struct super_block *pi + { + struct dentry *dentry; + ++ clnt->pipefs_sb = pipefs_sb; ++ + if (clnt->cl_program->pipe_dir_name != NULL) { + dentry = rpc_setup_pipedir_sb(pipefs_sb, clnt); + if (IS_ERR(dentry)) diff --git a/patches.suse/SUNRPC-defer-slow-parts-of-rpc_free_client-to-a-work.patch b/patches.suse/SUNRPC-defer-slow-parts-of-rpc_free_client-to-a-work.patch index 1b09c6f..25ee42e 100644 --- a/patches.suse/SUNRPC-defer-slow-parts-of-rpc_free_client-to-a-work.patch +++ b/patches.suse/SUNRPC-defer-slow-parts-of-rpc_free_client-to-a-work.patch @@ -61,12 +61,12 @@ Acked-by: NeilBrown + struct rpc_xprt_iter cl_xpi; + struct work_struct cl_work; + }; + struct super_block *pipefs_sb; }; - /* --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c -@@ -866,6 +866,21 @@ EXPORT_SYMBOL_GPL(rpc_shutdown_client); +@@ -876,6 +876,21 @@ EXPORT_SYMBOL_GPL(rpc_shutdown_client); /* * Free an RPC client */ @@ -88,7 +88,7 @@ Acked-by: NeilBrown static struct rpc_clnt * rpc_free_client(struct rpc_clnt *clnt) { -@@ -876,16 +891,14 @@ rpc_free_client(struct rpc_clnt *clnt) +@@ -886,16 +901,14 @@ rpc_free_client(struct rpc_clnt *clnt) rcu_dereference(clnt->cl_xprt)->servername); if (clnt->cl_parent != clnt) parent = clnt->cl_parent; diff --git a/patches.suse/SUNRPC-fix-a-memleak-in-gss_import_v2_context.patch b/patches.suse/SUNRPC-fix-a-memleak-in-gss_import_v2_context.patch new file mode 100644 index 0000000..784b98c --- /dev/null +++ b/patches.suse/SUNRPC-fix-a-memleak-in-gss_import_v2_context.patch @@ -0,0 +1,62 @@ +From: Zhipeng Lu +Date: Sun, 24 Dec 2023 16:20:33 +0800 +Subject: [PATCH] SUNRPC: fix a memleak in gss_import_v2_context +Git-commit: e67b652d8e8591d3b1e569dbcdfcee15993e91fa +Patch-mainline: v6.9-rc1 +References: git-fixes + +The ctx->mech_used.data allocated by kmemdup is not freed in neither +gss_import_v2_context nor it only caller gss_krb5_import_sec_context, +which frees ctx on error. + +Thus, this patch reform the last call of gss_import_v2_context to the +gss_krb5_import_ctx_v2, preventing the memleak while keepping the return +formation. + +Fixes: 47d848077629 ("gss_krb5: handle new context format from gssd") +Signed-off-by: Zhipeng Lu +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Acked-by: NeilBrown + +--- + net/sunrpc/auth_gss/gss_krb5_mech.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +--- a/net/sunrpc/auth_gss/gss_krb5_mech.c ++++ b/net/sunrpc/auth_gss/gss_krb5_mech.c +@@ -584,6 +584,7 @@ gss_import_v2_context(const void *p, con + gfp_t gfp_mask) + { + int keylen; ++ int ret; + + p = simple_get_bytes(p, end, &ctx->flags, sizeof(ctx->flags)); + if (IS_ERR(p)) +@@ -638,16 +639,22 @@ gss_import_v2_context(const void *p, con + + switch (ctx->enctype) { + case ENCTYPE_DES3_CBC_RAW: +- return context_derive_keys_des3(ctx, gfp_mask); ++ ret = context_derive_keys_des3(ctx, gfp_mask); ++ break; + case ENCTYPE_ARCFOUR_HMAC: +- return context_derive_keys_rc4(ctx); ++ ret = context_derive_keys_rc4(ctx); ++ break; + case ENCTYPE_AES128_CTS_HMAC_SHA1_96: + case ENCTYPE_AES256_CTS_HMAC_SHA1_96: +- return context_derive_keys_new(ctx, gfp_mask); ++ ret = context_derive_keys_new(ctx, gfp_mask); ++ break; + default: +- return -EINVAL; ++ ret = -EINVAL; + } + ++ if (ret) ++ kfree(ctx->mech_used.data); ++ return ret; + out_err: + return PTR_ERR(p); + } diff --git a/patches.suse/SUNRPC-fix-some-memleaks-in-gssx_dec_option_array.patch b/patches.suse/SUNRPC-fix-some-memleaks-in-gssx_dec_option_array.patch new file mode 100644 index 0000000..bfc6670 --- /dev/null +++ b/patches.suse/SUNRPC-fix-some-memleaks-in-gssx_dec_option_array.patch @@ -0,0 +1,80 @@ +From: Zhipeng Lu +Date: Tue, 2 Jan 2024 13:38:13 +0800 +Subject: [PATCH] SUNRPC: fix some memleaks in gssx_dec_option_array +Git-commit: 3cfcfc102a5e57b021b786a755a38935e357797d +Patch-mainline: v6.9-rc1 +References: git-fixes + +The creds and oa->data need to be freed in the error-handling paths after +their allocation. So this patch add these deallocations in the +corresponding paths. + +Fixes: 1d658336b05f ("SUNRPC: Add RPC based upcall mechanism for RPCGSS auth") +Signed-off-by: Zhipeng Lu +Signed-off-by: Chuck Lever +Acked-by: NeilBrown + +--- + net/sunrpc/auth_gss/gss_rpc_xdr.c | 27 +++++++++++++++++++-------- + 1 file changed, 19 insertions(+), 8 deletions(-) + +--- a/net/sunrpc/auth_gss/gss_rpc_xdr.c ++++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c +@@ -263,8 +263,8 @@ static int gssx_dec_option_array(struct + + creds = kzalloc(sizeof(struct svc_cred), GFP_KERNEL); + if (!creds) { +- kfree(oa->data); +- return -ENOMEM; ++ err = -ENOMEM; ++ goto free_oa; + } + + oa->data[0].option.data = CREDS_VALUE; +@@ -278,29 +278,40 @@ static int gssx_dec_option_array(struct + + /* option buffer */ + p = xdr_inline_decode(xdr, 4); +- if (unlikely(p == NULL)) +- return -ENOSPC; ++ if (unlikely(p == NULL)) { ++ err = -ENOSPC; ++ goto free_creds; ++ } + + length = be32_to_cpup(p); + p = xdr_inline_decode(xdr, length); +- if (unlikely(p == NULL)) +- return -ENOSPC; ++ if (unlikely(p == NULL)) { ++ err = -ENOSPC; ++ goto free_creds; ++ } + + if (length == sizeof(CREDS_VALUE) && + memcmp(p, CREDS_VALUE, sizeof(CREDS_VALUE)) == 0) { + /* We have creds here. parse them */ + err = gssx_dec_linux_creds(xdr, creds); + if (err) +- return err; ++ goto free_creds; + oa->data[0].value.len = 1; /* presence */ + } else { + /* consume uninteresting buffer */ + err = gssx_dec_buffer(xdr, &dummy); + if (err) +- return err; ++ goto free_creds; + } + } + return 0; ++ ++free_creds: ++ kfree(creds); ++free_oa: ++ kfree(oa->data); ++ oa->data = NULL; ++ return err; + } + + static int gssx_dec_status(struct xdr_stream *xdr, diff --git a/patches.suse/USB-dwc3-fix-runtime-pm-imbalance-on-probe-errors.patch b/patches.suse/USB-dwc3-fix-runtime-pm-imbalance-on-probe-errors.patch index 1a8f16d..f41d876 100644 --- a/patches.suse/USB-dwc3-fix-runtime-pm-imbalance-on-probe-errors.patch +++ b/patches.suse/USB-dwc3-fix-runtime-pm-imbalance-on-probe-errors.patch @@ -23,9 +23,9 @@ Signed-off-by: Oliver Neukum --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c -@@ -1239,13 +1239,11 @@ static int dwc3_probe(struct platform_de - +@@ -1271,13 +1271,11 @@ static int dwc3_probe(struct platform_de spin_lock_init(&dwc->lock); + mutex_init(&dwc->mutex); + pm_runtime_get_noresume(dev); pm_runtime_set_active(dev); @@ -38,7 +38,7 @@ Signed-off-by: Oliver Neukum pm_runtime_forbid(dev); -@@ -1304,11 +1302,10 @@ err3: +@@ -1336,11 +1334,10 @@ err3: dwc3_free_event_buffers(dwc); err2: diff --git a/patches.suse/USB-serial-option-add-Fibocom-L7xx-modules.patch b/patches.suse/USB-serial-option-add-Fibocom-L7xx-modules.patch new file mode 100644 index 0000000..62bb257 --- /dev/null +++ b/patches.suse/USB-serial-option-add-Fibocom-L7xx-modules.patch @@ -0,0 +1,94 @@ +From e389fe8b68137344562fb6e4d53d8a89ef6212dd Mon Sep 17 00:00:00 2001 +From: Victor Fragoso +Date: Tue, 21 Nov 2023 21:05:56 +0000 +Subject: [PATCH] USB: serial: option: add Fibocom L7xx modules +Git-commit: e389fe8b68137344562fb6e4d53d8a89ef6212dd +References: git-fixes +Patch-mainline: v6.7-rc3 + +Add support for Fibocom L716-EU module series. + +L716-EU is a Fibocom module based on ZTE's V3E/V3T chipset. + +Device creates multiple interfaces when connected to PC as follows: + - Network Interface: ECM or RNDIS (set by FW or AT Command) + - ttyUSB0: AT port + - ttyUSB1: Modem port + - ttyUSB2: AT2 port + - ttyUSB3: Trace port for log information + - ADB: ADB port for debugging. ("Driver=usbfs" when ADB server enabled) + +Here are the outputs of lsusb and usb-devices: +$ ls /dev/ttyUSB* +/dev/ttyUSB0 /dev/ttyUSB1 /dev/ttyUSB2 /dev/ttyUSB3 + +Usb-devices: +L716-EU (ECM mode): +T: Bus=03 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 51 Spd=480 MxCh= 0 +D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=2cb7 ProdID=0001 Rev= 1.00 +S: Manufacturer=Fibocom,Incorporated +S: Product=Fibocom Mobile Boardband +S: SerialNumber=1234567890ABCDEF +C:* #Ifs= 7 Cfg#= 1 Atr=e0 MxPwr=500mA +A: FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=06 Prot=00 +I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=06 Prot=00 Driver=cdc_ether +E: Ad=87(I) Atr=03(Int.) MxPS= 16 Ivl=32ms +I: If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether +I:* If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option +E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option +E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option +E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option +E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=usbfs +E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +L716-EU (RNDIS mode): +T: Bus=03 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 49 Spd=480 MxCh= 0 +C:* #Ifs= 7 Cfg#= 1 Atr=e0 MxPwr=500mA +A: FirstIf#= 0 IfCount= 2 Cls=e0(wlcon) Sub=01 Prot=03 +I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=ff Driver=rndis_host +E: Ad=87(I) Atr=03(Int.) MxPS= 8 Ivl=32ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host +I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option +I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option +I:* If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option +I:* If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option +I:* If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=usbfs + +Signed-off-by: Victor Fragoso +Reviewed-by: Lars Melin +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Oliver Neukum + +--- + drivers/usb/serial/option.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 9c76095ebfe1..06b9b04c022a 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -2250,6 +2250,7 @@ static const struct usb_device_id option_ids[] = { + .driver_info = RSVD(4) | RSVD(5) | RSVD(6) }, + { USB_DEVICE(0x1782, 0x4d10) }, /* Fibocom L610 (AT mode) */ + { USB_DEVICE_INTERFACE_CLASS(0x1782, 0x4d11, 0xff) }, /* Fibocom L610 (ECM/RNDIS mode) */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x0001, 0xff, 0xff, 0xff) }, /* Fibocom L716-EU (ECM/RNDIS mode) */ + { USB_DEVICE(0x2cb7, 0x0104), /* Fibocom NL678 series */ + .driver_info = RSVD(4) | RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */ +-- +2.44.0 + diff --git a/patches.suse/USB-serial-option-don-t-claim-interface-4-for-ZTE-MF.patch b/patches.suse/USB-serial-option-don-t-claim-interface-4-for-ZTE-MF.patch new file mode 100644 index 0000000..5584793 --- /dev/null +++ b/patches.suse/USB-serial-option-don-t-claim-interface-4-for-ZTE-MF.patch @@ -0,0 +1,70 @@ +From 8771127e25d6c20d458ad27cf32f7fcfc1755e05 Mon Sep 17 00:00:00 2001 +From: Lech Perczak +Date: Sat, 18 Nov 2023 00:19:17 +0100 +Subject: [PATCH] USB: serial: option: don't claim interface 4 for ZTE MF290 +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 8771127e25d6c20d458ad27cf32f7fcfc1755e05 +References: git-fixes +Patch-mainline: v6.7-rc3 + +Interface 4 is used by for QMI interface in stock firmware of MF28D, the +router which uses MF290 modem. Free the interface up, to rebind it to +qmi_wwan driver. +The proper configuration is: + +Interface mapping is: +0: QCDM, 1: (unknown), 2: AT (PCUI), 2: AT (Modem), 4: QMI + +T: Bus=01 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 4 Spd=480 MxCh= 0 +D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=19d2 ProdID=0189 Rev= 0.00 +S: Manufacturer=ZTE, Incorporated +S: Product=ZTE LTE Technologies MSM +C:* #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA +I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option +E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms +I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option +E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms +I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option +E: Ad=84(I) Atr=03(Int.) MxPS= 64 Ivl=2ms +E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms +I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan +E: Ad=86(I) Atr=03(Int.) MxPS= 64 Ivl=2ms +E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms + +Cc: Bjørn Mork +Signed-off-by: Lech Perczak +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Oliver Neukum + +--- + drivers/usb/serial/option.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 45dcfaadaf98..ff9049db6e65 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1546,7 +1546,8 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff), + .driver_info = RSVD(4) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0189, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0189, 0xff, 0xff, 0xff), ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0191, 0xff, 0xff, 0xff), /* ZTE EuFi890 */ + .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0196, 0xff, 0xff, 0xff) }, +-- +2.44.0 + diff --git a/patches.suse/USB-usbfs-Don-t-WARN-about-excessively-large-memory-.patch b/patches.suse/USB-usbfs-Don-t-WARN-about-excessively-large-memory-.patch new file mode 100644 index 0000000..5e02725 --- /dev/null +++ b/patches.suse/USB-usbfs-Don-t-WARN-about-excessively-large-memory-.patch @@ -0,0 +1,76 @@ +From 4f2629ea67e7225c3fd292c7fe4f5b3c9d6392de Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 18 May 2021 16:18:35 -0400 +Subject: [PATCH] USB: usbfs: Don't WARN about excessively large memory + allocations +Git-commit: 4f2629ea67e7225c3fd292c7fe4f5b3c9d6392de +REferences: bsc#1222004 CVE-2021-47170 +Patch-mainline: v5.13-rc4 + +Syzbot found that the kernel generates a WARNing if the user tries to +submit a bulk transfer through usbfs with a buffer that is way too +large. This isn't a bug in the kernel; it's merely an invalid request +from the user and the usbfs code does handle it correctly. + +In theory the same thing can happen with async transfers, or with the +packet descriptor table for isochronous transfers. + +To prevent the MM subsystem from complaining about these bad +allocation requests, add the __GFP_NOWARN flag to the kmalloc calls +for these buffers. + +Cc: Andrew Morton +Cc: +Reported-and-tested-by: syzbot+882a85c0c8ec4a3e2281@syzkaller.appspotmail.com +Signed-off-by: Alan Stern +Link: https://lore.kernel.org/r/20210518201835.GA1140918@rowland.harvard.edu +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum + +--- + drivers/usb/core/devio.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -1206,7 +1206,12 @@ static int proc_bulk(struct usb_dev_stat + ret = usbfs_increase_memory_usage(len1 + sizeof(struct urb)); + if (ret) + return ret; +- tbuf = kmalloc(len1, GFP_KERNEL); ++ ++ /* ++ * len1 can be almost arbitrarily large. Don't WARN if it's ++ * too big, just fail the request. ++ */ ++ tbuf = kmalloc(len1, GFP_KERNEL | __GFP_NOWARN); + if (!tbuf) { + ret = -ENOMEM; + goto done; +@@ -1634,7 +1639,7 @@ static int proc_do_submiturb(struct usb_ + + if (num_sgs) { + as->urb->sg = kmalloc(num_sgs * sizeof(struct scatterlist), +- GFP_KERNEL); ++ GFP_KERNEL | __GFP_NOWARN); + if (!as->urb->sg) { + ret = -ENOMEM; + goto error; +@@ -1645,7 +1650,7 @@ static int proc_do_submiturb(struct usb_ + totlen = uurb->buffer_length; + for (i = 0; i < as->urb->num_sgs; i++) { + u = (totlen > USB_SG_SIZE) ? USB_SG_SIZE : totlen; +- buf = kmalloc(u, GFP_KERNEL); ++ buf = kmalloc(u, GFP_KERNEL | __GFP_NOWARN); + if (!buf) { + ret = -ENOMEM; + goto error; +@@ -1669,7 +1674,7 @@ static int proc_do_submiturb(struct usb_ + (uurb_start - as->usbm->vm_start); + } else { + as->urb->transfer_buffer = kmalloc(uurb->buffer_length, +- GFP_KERNEL); ++ GFP_KERNEL | __GFP_NOWARN); + if (!as->urb->transfer_buffer) { + ret = -ENOMEM; + goto error; diff --git a/patches.suse/aoe-fix-the-potential-use-after-free-problem-in-aoec.patch b/patches.suse/aoe-fix-the-potential-use-after-free-problem-in-aoec.patch new file mode 100644 index 0000000..89b1b46 --- /dev/null +++ b/patches.suse/aoe-fix-the-potential-use-after-free-problem-in-aoec.patch @@ -0,0 +1,79 @@ +From: Chun-Yi Lee +Date: Tue, 5 Mar 2024 16:20:48 +0800 +Subject: aoe: fix the potential use-after-free problem in aoecmd_cfg_pkts +Patch-mainline: Queued in subsystem maintainer repository +Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git +Git-commit: f98364e926626c678fb4b9004b75cacf92ff0662 +References: bsc#1218562 CVE-2023-6270 + +This patch is against CVE-2023-6270. The description of cve is: + + A flaw was found in the ATA over Ethernet (AoE) driver in the Linux + kernel. The aoecmd_cfg_pkts() function improperly updates the refcnt on + `struct net_device`, and a use-after-free can be triggered by racing + between the free on the struct and the access through the `skbtxq` + global queue. This could lead to a denial of service condition or + potential code execution. + +In aoecmd_cfg_pkts(), it always calls dev_put(ifp) when skb initial +code is finished. But the net_device ifp will still be used in +later tx()->dev_queue_xmit() in kthread. Which means that the +dev_put(ifp) should NOT be called in the success path of skb +initial code in aoecmd_cfg_pkts(). Otherwise tx() may run into +use-after-free because the net_device is freed. + +This patch removed the dev_put(ifp) in the success path in +aoecmd_cfg_pkts(), and added dev_put() after skb xmit in tx(). + +Link: https://nvd.nist.gov/vuln/detail/CVE-2023-6270 +Fixes: 7562f876cd93 ("[NET]: Rework dev_base via list_head (v3)") +Signed-off-by: Chun-Yi Lee +Link: https://lore.kernel.org/r/20240305082048.25526-1-jlee@suse.com +Signed-off-by: Jens Axboe +--- + drivers/block/aoe/aoecmd.c | 12 ++++++------ + drivers/block/aoe/aoenet.c | 1 + + 2 files changed, 7 insertions(+), 6 deletions(-) + +--- a/drivers/block/aoe/aoecmd.c ++++ b/drivers/block/aoe/aoecmd.c +@@ -421,13 +421,16 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigne + rcu_read_lock(); + for_each_netdev_rcu(&init_net, ifp) { + dev_hold(ifp); +- if (!is_aoe_netif(ifp)) +- goto cont; ++ if (!is_aoe_netif(ifp)) { ++ dev_put(ifp); ++ continue; ++ } + + skb = new_skb(sizeof *h + sizeof *ch); + if (skb == NULL) { + printk(KERN_INFO "aoe: skb alloc failure\n"); +- goto cont; ++ dev_put(ifp); ++ continue; + } + skb_put(skb, sizeof *h + sizeof *ch); + skb->dev = ifp; +@@ -442,9 +445,6 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigne + h->major = cpu_to_be16(aoemajor); + h->minor = aoeminor; + h->cmd = AOECMD_CFG; +- +-cont: +- dev_put(ifp); + } + rcu_read_unlock(); + } +--- a/drivers/block/aoe/aoenet.c ++++ b/drivers/block/aoe/aoenet.c +@@ -64,6 +64,7 @@ tx(int id) __must_hold(&txlock) + pr_warn("aoe: packet could not be sent on %s. %s\n", + ifp ? ifp->name : "netif", + "consider increasing tx_queue_len"); ++ dev_put(ifp); + spin_lock_irq(&txlock); + } + return 0; diff --git a/patches.suse/asix-fix-uninit-value-in-asix_mdio_read.patch b/patches.suse/asix-fix-uninit-value-in-asix_mdio_read.patch index c7979f2..f0f9727 100644 --- a/patches.suse/asix-fix-uninit-value-in-asix_mdio_read.patch +++ b/patches.suse/asix-fix-uninit-value-in-asix_mdio_read.patch @@ -3,7 +3,7 @@ From: Pavel Skripkin Date: Tue, 21 Dec 2021 23:10:36 +0300 Subject: [PATCH] asix: fix uninit-value in asix_mdio_read() Git-commit: 8035b1a2a37a29d8c717ef84fca8fe7278bc9f03 -References: git-fixes +References: git-fixes CVE-2021-47101 bsc#1220987 Patch-mainline: v5.16-rc7 asix_read_cmd() may read less than sizeof(smsr) bytes and in this case diff --git a/patches.suse/atl1c-fix-error-return-code-in-atl1c_probe.patch b/patches.suse/atl1c-fix-error-return-code-in-atl1c_probe.patch new file mode 100644 index 0000000..8f5519e --- /dev/null +++ b/patches.suse/atl1c-fix-error-return-code-in-atl1c_probe.patch @@ -0,0 +1,39 @@ +From 9b9a609bf7439e682ac3639f1e9b44423682ae20 Mon Sep 17 00:00:00 2001 +From: Zhang Changzhong +Date: Tue, 17 Nov 2020 10:55:21 +0800 +Subject: [PATCH 3/8] atl1c: fix error return code in atl1c_probe() +Git-commit: 537a14726582c4e7bfe4dff9cb7fca19dc912cf6 +References: git-fixes +Patch-mainline: v5.10-rc5 + +Fix to return a negative error code from the error handling +case instead of 0, as done elsewhere in this function. + +Fixes: 43250ddd75a3 ("atl1c: Atheros L1C Gigabit Ethernet driver") +Reported-by: Hulk Robot +Signed-off-by: Zhang Changzhong +Link: https://lore.kernel.org/r/1605581721-36028-1-git-send-email-zhangchangzhong@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +index 7ef0d35c931f..d18314148f81 100644 +--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c ++++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +@@ -2567,8 +2567,8 @@ static int atl1c_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + * various kernel subsystems to support the mechanics required by a + * fixed-high-32-bit system. + */ +- if ((dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)) != 0) || +- (dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)) != 0)) { ++ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); ++ if (err) { + dev_err(&pdev->dev, "No usable DMA configuration,aborting\n"); + goto err_dma; + } +-- +2.16.4 + diff --git a/patches.suse/atl1e-fix-error-return-code-in-atl1e_probe.patch b/patches.suse/atl1e-fix-error-return-code-in-atl1e_probe.patch new file mode 100644 index 0000000..37f70fc --- /dev/null +++ b/patches.suse/atl1e-fix-error-return-code-in-atl1e_probe.patch @@ -0,0 +1,39 @@ +From f36e6cea52f7ac4ab98aa9d84257dc90293d11ec Mon Sep 17 00:00:00 2001 +From: Zhang Changzhong +Date: Tue, 17 Nov 2020 10:57:55 +0800 +Subject: [PATCH 4/8] atl1e: fix error return code in atl1e_probe() +Git-commit: 3a36060bf294e7b7e33c5dddcc4f5d2c1c834e56 +References: git-fixes +Patch-mainline: v5.10-rc5 + +Fix to return a negative error code from the error handling +case instead of 0, as done elsewhere in this function. + +Fixes: a6a5325239c2 ("atl1e: Atheros L1E Gigabit Ethernet driver") +Reported-by: Hulk Robot +Signed-off-by: Zhang Changzhong +Link: https://lore.kernel.org/r/1605581875-36281-1-git-send-email-zhangchangzhong@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +index 189535f6b22c..ca3f54324dd8 100644 +--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c ++++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +@@ -2328,8 +2328,8 @@ static int atl1e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + * various kernel subsystems to support the mechanics required by a + * fixed-high-32-bit system. + */ +- if ((dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)) != 0) || +- (dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)) != 0)) { ++ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); ++ if (err) { + dev_err(&pdev->dev, "No usable DMA configuration,aborting\n"); + goto err_dma; + } +-- +2.16.4 + diff --git a/patches.suse/bnx2x-Fix-enabling-network-interfaces-without-VFs.patch b/patches.suse/bnx2x-Fix-enabling-network-interfaces-without-VFs.patch new file mode 100644 index 0000000..57ef560 --- /dev/null +++ b/patches.suse/bnx2x-Fix-enabling-network-interfaces-without-VFs.patch @@ -0,0 +1,40 @@ +From f5f4bf3ae2fe60140ee74c5591604f0eaa9cf069 Mon Sep 17 00:00:00 2001 +From: Adrian Bunk +Date: Sun, 12 Sep 2021 22:05:23 +0300 +Subject: [PATCH] bnx2x: Fix enabling network interfaces without VFs +Git-commit: 52ce14c134a003fee03d8fc57442c05a55b53715 +References: git-fixes +Patch-mainline: v5.15-rc2 + +This function is called to enable SR-IOV when available, +not enabling interfaces without VFs was a regression. + +Fixes: 65161c35554f ("bnx2x: Fix missing error code in bnx2x_iov_init_one()") +Signed-off-by: Adrian Bunk +Reported-by: YunQiang Su +Tested-by: YunQiang Su +Cc: stable@vger.kernel.org +Acked-by: Shai Malin +Link: https://lore.kernel.org/r/20210912190523.27991-1-bunk@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +index 959de068fc5f..92f477544c8f 100644 +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +@@ -1248,7 +1248,7 @@ int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, + + /* SR-IOV capability was enabled but there are no VFs*/ + if (iov->total == 0) { +- err = -EINVAL; ++ err = 0; + goto failed; + } + +-- +2.16.4 + diff --git a/patches.suse/bnx2x-Fix-missing-error-code-in-bnx2x_iov_init_one.patch b/patches.suse/bnx2x-Fix-missing-error-code-in-bnx2x_iov_init_one.patch new file mode 100644 index 0000000..ea44f27 --- /dev/null +++ b/patches.suse/bnx2x-Fix-missing-error-code-in-bnx2x_iov_init_one.patch @@ -0,0 +1,40 @@ +From 91781b604e98ebabfe73b2c612d4ac0232e31ccf Mon Sep 17 00:00:00 2001 +From: Jiapeng Chong +Date: Tue, 25 May 2021 19:00:12 +0800 +Subject: [PATCH 3/4] bnx2x: Fix missing error code in bnx2x_iov_init_one() +Git-commit: 65161c35554f7135e6656b3df1ce2c500ca0bdcf +References: git-fixes +Patch-mainline: v5.13-rc4 + +Eliminate the follow smatch warning: + +drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c:1227 +bnx2x_iov_init_one() warn: missing error code 'err'. + +Reported-by: Abaci Robot +Signed-off-by: Jiapeng Chong +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +index b3693b48e24f..959de068fc5f 100644 +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +@@ -1247,8 +1247,10 @@ int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, + goto failed; + + /* SR-IOV capability was enabled but there are no VFs*/ +- if (iov->total == 0) ++ if (iov->total == 0) { ++ err = -EINVAL; + goto failed; ++ } + + iov->nr_virtfn = min_t(u16, iov->total, num_vfs_param); + +-- +2.16.4 + diff --git a/patches.suse/bnxt_en-Fix-RX-consumer-index-logic-in-the-error-pat.patch b/patches.suse/bnxt_en-Fix-RX-consumer-index-logic-in-the-error-pat.patch index 9172381..ad60f66 100644 --- a/patches.suse/bnxt_en-Fix-RX-consumer-index-logic-in-the-error-pat.patch +++ b/patches.suse/bnxt_en-Fix-RX-consumer-index-logic-in-the-error-pat.patch @@ -4,7 +4,7 @@ Date: Fri, 23 Apr 2021 18:13:19 -0400 Subject: [PATCH 13/19] bnxt_en: Fix RX consumer index logic in the error path. Git-commit: bbd6f0a948139970f4a615dff189d9a503681a39 Patch-mainline: v5.13-rc1 -References: git-fixes +References: git-fixes CVE-2021-47015 bsc#1220794 In bnxt_rx_pkt(), the RX buffers are expected to complete in order. If the RX consumer index indicates an out of order buffer completion, diff --git a/patches.suse/bpf-sockmap-Fix-preempt_rt-splat-when-using-raw_spin.patch b/patches.suse/bpf-sockmap-Fix-preempt_rt-splat-when-using-raw_spin.patch new file mode 100644 index 0000000..3f8ec12 --- /dev/null +++ b/patches.suse/bpf-sockmap-Fix-preempt_rt-splat-when-using-raw_spin.patch @@ -0,0 +1,252 @@ +From: John Fastabend +Date: Tue, 29 Aug 2023 22:35:17 -0700 +Subject: bpf, sockmap: Fix preempt_rt splat when using raw_spin_lock_t +Patch-mainline: v6.6-rc1 +Git-commit: 35d2b7ffffc1d9b3dc6c761010aa3338da49165b +References: git-fixes +X-Info: additional change in sock_map_free() due to commit 90db6d772f74 "bpf, sockmap: Remove bucket->lock from sock_{hash|map}_free" not backported + +Sockmap and sockhash maps are a collection of psocks that are +objects representing a socket plus a set of metadata needed +to manage the BPF programs associated with the socket. These +maps use the stab->lock to protect from concurrent operations +on the maps, e.g. trying to insert to objects into the array +at the same time in the same slot. Additionally, a sockhash map +has a bucket lock to protect iteration and insert/delete into +the hash entry. + +Each psock has a psock->link which is a linked list of all the +maps that a psock is attached to. This allows a psock (socket) +to be included in multiple sockmap and sockhash maps. This +linked list is protected the psock->link_lock. + +They _must_ be nested correctly to avoid deadlock: + + lock(stab->lock) + : do BPF map operations and psock insert/delete + lock(psock->link_lock) + : add map to psock linked list of maps + unlock(psock->link_lock) + unlock(stab->lock) + +For non PREEMPT_RT kernels both raw_spin_lock_t and spin_lock_t +are guaranteed to not sleep. But, with PREEMPT_RT kernels the +spin_lock_t variants may sleep. In the current code we have +many patterns like this: + + rcu_critical_section: + raw_spin_lock(stab->lock) + spin_lock(psock->link_lock) <- may sleep ouch + spin_unlock(psock->link_lock) + raw_spin_unlock(stab->lock) + rcu_critical_section + +Nesting spin_lock() inside a raw_spin_lock() violates locking +rules for PREEMPT_RT kernels. And additionally we do alloc(GFP_ATOMICS) +inside the stab->lock, but those might sleep on PREEMPT_RT kernels. +The result is splats like this: + +./test_progs -t sockmap_basic +[ 33.344330] bpf_testmod: loading out-of-tree module taints kernel. +[ 33.441933] +[ 33.442089] ============================= +[ 33.442421] [ BUG: Invalid wait context ] +[ 33.442763] 6.5.0-rc5-01731-gec0ded2e0282 #4958 Tainted: G O +[ 33.443320] ----------------------------- +[ 33.443624] test_progs/2073 is trying to lock: +[ 33.443960] ffff888102a1c290 (&psock->link_lock){....}-{3:3}, at: sock_map_update_common+0x2c2/0x3d0 +[ 33.444636] other info that might help us debug this: +[ 33.444991] context-{5:5} +[ 33.445183] 3 locks held by test_progs/2073: +[ 33.445498] #0: ffff88811a208d30 (sk_lock-AF_INET){+.+.}-{0:0}, at: sock_map_update_elem_sys+0xff/0x330 +[ 33.446159] #1: ffffffff842539e0 (rcu_read_lock){....}-{1:3}, at: sock_map_update_elem_sys+0xf5/0x330 +[ 33.446809] #2: ffff88810d687240 (&stab->lock){+...}-{2:2}, at: sock_map_update_common+0x177/0x3d0 +[ 33.447445] stack backtrace: +[ 33.447655] CPU: 10 PID + +To fix observe we can't readily remove the allocations (for that +we would need to use/create something similar to bpf_map_alloc). So +convert raw_spin_lock_t to spin_lock_t. We note that sock_map_update +that would trigger the allocate and potential sleep is only allowed +through sys_bpf ops and via sock_ops which precludes hw interrupts +and low level atomic sections in RT preempt kernel. On non RT +preempt kernel there are no changes here and spin locks sections +and alloc(GFP_ATOMIC) are still not sleepable. + +Signed-off-by: John Fastabend +Signed-off-by: Daniel Borkmann +Link: https://lore.kernel.org/bpf/20230830053517.166611-1-john.fastabend@gmail.com +Acked-by: Shung-Hsi Yu +--- + net/core/sock_map.c | 40 ++++++++++++++++++++-------------------- + 1 file changed, 20 insertions(+), 20 deletions(-) + +--- a/net/core/sock_map.c ++++ b/net/core/sock_map.c +@@ -15,7 +15,7 @@ struct bpf_stab { + struct bpf_map map; + struct sock **sks; + struct sk_psock_progs progs; +- raw_spinlock_t lock; ++ spinlock_t lock; + }; + + #define SOCK_CREATE_FLAG_MASK \ +@@ -40,7 +40,7 @@ static struct bpf_map *sock_map_alloc(un + return ERR_PTR(-ENOMEM); + + bpf_map_init_from_attr(&stab->map, attr); +- raw_spin_lock_init(&stab->lock); ++ spin_lock_init(&stab->lock); + + /* Make sure page count doesn't overflow. */ + cost = (u64) stab->map.max_entries * sizeof(struct sock *); +@@ -240,7 +240,7 @@ static void sock_map_free(struct bpf_map + + synchronize_rcu(); + rcu_read_lock(); +- raw_spin_lock_bh(&stab->lock); ++ spin_lock_bh(&stab->lock); + for (i = 0; i < stab->map.max_entries; i++) { + struct sock **psk = &stab->sks[i]; + struct sock *sk; +@@ -249,7 +249,7 @@ static void sock_map_free(struct bpf_map + if (sk) + sock_map_unref(sk, psk); + } +- raw_spin_unlock_bh(&stab->lock); ++ spin_unlock_bh(&stab->lock); + rcu_read_unlock(); + + synchronize_rcu(); +@@ -285,7 +285,7 @@ static int __sock_map_delete(struct bpf_ + struct sock *sk; + int err = 0; + +- raw_spin_lock_bh(&stab->lock); ++ spin_lock_bh(&stab->lock); + sk = *psk; + if (!sk_test || sk_test == sk) + sk = xchg(psk, NULL); +@@ -295,7 +295,7 @@ static int __sock_map_delete(struct bpf_ + else + err = -EINVAL; + +- raw_spin_unlock_bh(&stab->lock); ++ spin_unlock_bh(&stab->lock); + return err; + } + +@@ -364,7 +364,7 @@ static int sock_map_update_common(struct + psock = sk_psock(sk); + WARN_ON_ONCE(!psock); + +- raw_spin_lock_bh(&stab->lock); ++ spin_lock_bh(&stab->lock); + osk = stab->sks[idx]; + if (osk && flags == BPF_NOEXIST) { + ret = -EEXIST; +@@ -378,10 +378,10 @@ static int sock_map_update_common(struct + stab->sks[idx] = sk; + if (osk) + sock_map_unref(osk, &stab->sks[idx]); +- raw_spin_unlock_bh(&stab->lock); ++ spin_unlock_bh(&stab->lock); + return 0; + out_unlock: +- raw_spin_unlock_bh(&stab->lock); ++ spin_unlock_bh(&stab->lock); + if (psock) + sk_psock_put(sk, psock); + out_free: +@@ -521,7 +521,7 @@ struct bpf_htab_elem { + + struct bpf_htab_bucket { + struct hlist_head head; +- raw_spinlock_t lock; ++ spinlock_t lock; + }; + + struct bpf_htab { +@@ -596,7 +596,7 @@ static void sock_hash_delete_from_link(s + * is okay since it's going away only after RCU grace period. + * However, we need to check whether it's still present. + */ +- raw_spin_lock_bh(&bucket->lock); ++ spin_lock_bh(&bucket->lock); + elem_probe = sock_hash_lookup_elem_raw(&bucket->head, elem->hash, + elem->key, map->key_size); + if (elem_probe && elem_probe == elem) { +@@ -604,7 +604,7 @@ static void sock_hash_delete_from_link(s + sock_map_unref(elem->sk, elem); + sock_hash_free_elem(htab, elem); + } +- raw_spin_unlock_bh(&bucket->lock); ++ spin_unlock_bh(&bucket->lock); + } + + static int sock_hash_delete_elem(struct bpf_map *map, void *key) +@@ -618,7 +618,7 @@ static int sock_hash_delete_elem(struct + hash = sock_hash_bucket_hash(key, key_size); + bucket = sock_hash_select_bucket(htab, hash); + +- raw_spin_lock_bh(&bucket->lock); ++ spin_lock_bh(&bucket->lock); + elem = sock_hash_lookup_elem_raw(&bucket->head, hash, key, key_size); + if (elem) { + hlist_del_rcu(&elem->node); +@@ -626,7 +626,7 @@ static int sock_hash_delete_elem(struct + sock_hash_free_elem(htab, elem); + ret = 0; + } +- raw_spin_unlock_bh(&bucket->lock); ++ spin_unlock_bh(&bucket->lock); + return ret; + } + +@@ -688,7 +688,7 @@ static int sock_hash_update_common(struc + hash = sock_hash_bucket_hash(key, key_size); + bucket = sock_hash_select_bucket(htab, hash); + +- raw_spin_lock_bh(&bucket->lock); ++ spin_lock_bh(&bucket->lock); + elem = sock_hash_lookup_elem_raw(&bucket->head, hash, key, key_size); + if (elem && flags == BPF_NOEXIST) { + ret = -EEXIST; +@@ -714,10 +714,10 @@ static int sock_hash_update_common(struc + sock_map_unref(elem->sk, elem); + sock_hash_free_elem(htab, elem); + } +- raw_spin_unlock_bh(&bucket->lock); ++ spin_unlock_bh(&bucket->lock); + return 0; + out_unlock: +- raw_spin_unlock_bh(&bucket->lock); ++ spin_unlock_bh(&bucket->lock); + sk_psock_put(sk, psock); + out_free: + sk_psock_free_link(link); +@@ -842,7 +842,7 @@ static struct bpf_map *sock_hash_alloc(u + + for (i = 0; i < htab->buckets_num; i++) { + INIT_HLIST_HEAD(&htab->buckets[i].head); +- raw_spin_lock_init(&htab->buckets[i].lock); ++ spin_lock_init(&htab->buckets[i].lock); + } + + return &htab->map; +@@ -863,12 +863,12 @@ static void sock_hash_free(struct bpf_ma + rcu_read_lock(); + for (i = 0; i < htab->buckets_num; i++) { + bucket = sock_hash_select_bucket(htab, i); +- raw_spin_lock_bh(&bucket->lock); ++ spin_lock_bh(&bucket->lock); + hlist_for_each_entry_safe(elem, node, &bucket->head, node) { + hlist_del_rcu(&elem->node); + sock_map_unref(elem->sk, elem); + } +- raw_spin_unlock_bh(&bucket->lock); ++ spin_unlock_bh(&bucket->lock); + } + rcu_read_unlock(); + diff --git a/patches.suse/bpf-sockmap-Prevent-lock-inversion-deadlock-in-map-d.patch b/patches.suse/bpf-sockmap-Prevent-lock-inversion-deadlock-in-map-d.patch new file mode 100644 index 0000000..85b5489 --- /dev/null +++ b/patches.suse/bpf-sockmap-Prevent-lock-inversion-deadlock-in-map-d.patch @@ -0,0 +1,73 @@ +From: Jakub Sitnicki +Date: Tue, 2 Apr 2024 12:46:21 +0200 +Subject: bpf, sockmap: Prevent lock inversion deadlock in map delete elem +Patch-mainline: Queued in subsystem maintainer repository +Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git +Git-commit: ff91059932401894e6c86341915615c5eb0eca48 +References: bsc#1209657 CVE-2023-0160 + +syzkaller started using corpuses where a BPF tracing program deletes +elements from a sockmap/sockhash map. Because BPF tracing programs can be +invoked from any interrupt context, locks taken during a map_delete_elem +operation must be hardirq-safe. Otherwise a deadlock due to lock inversion +is possible, as reported by lockdep: + + CPU0 CPU1 + ---- ---- + lock(&htab->buckets[i].lock); + local_irq_disable(); + lock(&host->lock); + lock(&htab->buckets[i].lock); + + lock(&host->lock); + +Locks in sockmap are hardirq-unsafe by design. We expects elements to be +deleted from sockmap/sockhash only in task (normal) context with interrupts +enabled, or in softirq context. + +Detect when map_delete_elem operation is invoked from a context which is +_not_ hardirq-unsafe, that is interrupts are disabled, and bail out with an +error. + +Note that map updates are not affected by this issue. BPF verifier does not +allow updating sockmap/sockhash from a BPF tracing program today. + +Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface") +Reported-by: xingwei lee +Reported-by: yue sun +Reported-by: syzbot+bc922f476bd65abbd466@syzkaller.appspotmail.com +Reported-by: syzbot+d4066896495db380182e@syzkaller.appspotmail.com +Signed-off-by: Jakub Sitnicki +Signed-off-by: Daniel Borkmann +Tested-by: syzbot+d4066896495db380182e@syzkaller.appspotmail.com +Acked-by: John Fastabend +Closes: https://syzkaller.appspot.com/bug?extid=d4066896495db380182e +Closes: https://syzkaller.appspot.com/bug?extid=bc922f476bd65abbd466 +Link: https://lore.kernel.org/bpf/20240402104621.1050319-1-jakub@cloudflare.com +Acked-by: Shung-Hsi Yu +--- + net/core/sock_map.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/net/core/sock_map.c ++++ b/net/core/sock_map.c +@@ -285,6 +285,9 @@ static int __sock_map_delete(struct bpf_ + struct sock *sk; + int err = 0; + ++ if (irqs_disabled()) ++ return -EOPNOTSUPP; /* locks here are hardirq-unsafe */ ++ + spin_lock_bh(&stab->lock); + sk = *psk; + if (!sk_test || sk_test == sk) +@@ -615,6 +618,9 @@ static int sock_hash_delete_elem(struct + struct bpf_htab_elem *elem; + int ret = -ENOENT; + ++ if (irqs_disabled()) ++ return -EOPNOTSUPP; /* locks here are hardirq-unsafe */ ++ + hash = sock_hash_bucket_hash(key, key_size); + bucket = sock_hash_select_bucket(htab, hash); + diff --git a/patches.suse/bsc1084332-0003-lan78xx-Enable-LEDs-and-auto-negotiation.patch b/patches.suse/bsc1084332-0003-lan78xx-Enable-LEDs-and-auto-negotiation.patch index 3b39585..fbe59a6 100644 --- a/patches.suse/bsc1084332-0003-lan78xx-Enable-LEDs-and-auto-negotiation.patch +++ b/patches.suse/bsc1084332-0003-lan78xx-Enable-LEDs-and-auto-negotiation.patch @@ -13,14 +13,14 @@ Signed-off-by: Phil Elwell (cherry picked from commit 7c34b5c7793c40265af49880caea0a4a0caf202b) Signed-off-by: Alexander Graf --- - drivers/net/usb/lan78xx.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) + drivers/net/usb/lan78xx.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c -@@ -2349,6 +2349,11 @@ static int lan78xx_reset(struct lan78xx_ - int ret = 0; - unsigned long timeout; +@@ -2496,6 +2496,11 @@ static int lan78xx_reset(struct lan78xx_ + int ret; + u32 buf; u8 sig; + bool has_eeprom; + bool has_otp; @@ -29,18 +29,19 @@ Signed-off-by: Alexander Graf + has_otp = !lan78xx_read_otp(dev, 0, 0, NULL); ret = lan78xx_read_reg(dev, HW_CFG, &buf); - buf |= HW_CFG_LRST_; -@@ -2402,6 +2407,9 @@ static int lan78xx_reset(struct lan78xx_ + if (ret < 0) +@@ -2576,7 +2581,9 @@ static int lan78xx_reset(struct lan78xx_ + return ret; - ret = lan78xx_read_reg(dev, HW_CFG, &buf); buf |= HW_CFG_MEF_; +- + /* If no valid EEPROM and no valid OTP, enable the LEDs by default */ + if (!has_eeprom && !has_otp) -+ buf |= HW_CFG_LED0_EN_ | HW_CFG_LED1_EN_; ++ buf |= HW_CFG_LED0_EN_ | HW_CFG_LED1_EN_; ret = lan78xx_write_reg(dev, HW_CFG, buf); - - ret = lan78xx_read_reg(dev, USB_CFG0, &buf); -@@ -2457,6 +2465,10 @@ static int lan78xx_reset(struct lan78xx_ + if (ret < 0) + return ret; +@@ -2676,6 +2683,10 @@ static int lan78xx_reset(struct lan78xx_ buf |= MAC_CR_AUTO_DUPLEX_ | MAC_CR_AUTO_SPEED_; } } @@ -49,5 +50,5 @@ Signed-off-by: Alexander Graf + if (!has_eeprom && !has_otp) + buf |= MAC_CR_AUTO_DUPLEX_ | MAC_CR_AUTO_SPEED_; ret = lan78xx_write_reg(dev, MAC_CR, buf); - - ret = lan78xx_read_reg(dev, MAC_TX, &buf); + if (ret < 0) + return ret; diff --git a/patches.suse/btrfs-fix-race-between-transaction-aborts-and-fsyncs.patch b/patches.suse/btrfs-fix-race-between-transaction-aborts-and-fsyncs.patch index 5df8a4e..66a3e25 100644 --- a/patches.suse/btrfs-fix-race-between-transaction-aborts-and-fsyncs.patch +++ b/patches.suse/btrfs-fix-race-between-transaction-aborts-and-fsyncs.patch @@ -4,7 +4,7 @@ Git-commit: 061dde8245356d8864d29e25207aa4daa0be4d3c Patch-mainline: v5.13-rc1 Subject: [PATCH] btrfs: fix race between transaction aborts and fsyncs leading to use-after-free -References: bsc#1186441 +References: bsc#1186441 CVE-2021-46958 bsc#1220521 There is a race between a task aborting a transaction during a commit, a task doing an fsync and the transaction kthread, which leads to an diff --git a/patches.suse/ceph-fix-deadlock-or-deadcode-of-misusing-dget.patch b/patches.suse/ceph-fix-deadlock-or-deadcode-of-misusing-dget.patch new file mode 100644 index 0000000..4a45c17 --- /dev/null +++ b/patches.suse/ceph-fix-deadlock-or-deadcode-of-misusing-dget.patch @@ -0,0 +1,56 @@ +From: Xiubo Li +Date: Fri, 17 Nov 2023 13:26:18 +0800 +Subject: ceph: fix deadlock or deadcode of misusing dget() +Git-commit: b493ad718b1f0357394d2cdecbf00a44a36fa085 +Patch-mainline: v6.8-rc1 +References: bsc#1221058 CVE-2023-52583 + +The lock order is incorrect between denty and its parent, we should +always make sure that the parent get the lock first. + +But since this deadcode is never used and the parent dir will always +be set from the callers, let's just remove it. + +Link: https://lore.kernel.org/r/20231116081919.GZ1957730@ZenIV +Reported-by: Al Viro +Signed-off-by: Xiubo Li +Reviewed-by: Jeff Layton +Signed-off-by: Ilya Dryomov +Acked-by: Luis Henriques +--- + fs/ceph/caps.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +--- a/fs/ceph/caps.c ++++ b/fs/ceph/caps.c +@@ -4151,12 +4151,14 @@ int ceph_encode_dentry_release(void **p, + struct inode *dir, + int mds, int drop, int unless) + { +- struct dentry *parent = NULL; + struct ceph_mds_request_release *rel = *p; + struct ceph_dentry_info *di = ceph_dentry(dentry); + int force = 0; + int ret; + ++ /* This shouldn't happen */ ++ BUG_ON(!dir); ++ + /* + * force an record for the directory caps if we have a dentry lease. + * this is racy (can't take i_ceph_lock and d_lock together), but it +@@ -4166,14 +4168,9 @@ int ceph_encode_dentry_release(void **p, + spin_lock(&dentry->d_lock); + if (di->lease_session && di->lease_session->s_mds == mds) + force = 1; +- if (!dir) { +- parent = dget(dentry->d_parent); +- dir = d_inode(parent); +- } + spin_unlock(&dentry->d_lock); + + ret = ceph_encode_inode_release(p, dir, mds, drop, unless, force); +- dput(parent); + + spin_lock(&dentry->d_lock); + if (ret && di->lease_session && di->lease_session->s_mds == mds) { diff --git a/patches.suse/cifs-Return-correct-error-code-from-smb2_get_enc_key.patch b/patches.suse/cifs-Return-correct-error-code-from-smb2_get_enc_key.patch index 205e376..219d45c 100644 --- a/patches.suse/cifs-Return-correct-error-code-from-smb2_get_enc_key.patch +++ b/patches.suse/cifs-Return-correct-error-code-from-smb2_get_enc_key.patch @@ -2,7 +2,7 @@ From: Paul Aurich Date: Tue, 13 Apr 2021 14:25:27 -0700 Subject: [PATCH] cifs: Return correct error code from smb2_get_enc_key Git-commit: 83728cbf366e334301091d5b808add468ab46b27 -References: git-fixes +References: git-fixes CVE-2021-46960 bsc#1220528 Patch-mainline: v5.13-rc1 Avoid a warning if the error percolates back up: diff --git a/patches.suse/crypto-qat-ADF_STATUS_PF_RUNNING-should-be-set-after.patch b/patches.suse/crypto-qat-ADF_STATUS_PF_RUNNING-should-be-set-after.patch index dcd5557..41708e0 100644 --- a/patches.suse/crypto-qat-ADF_STATUS_PF_RUNNING-should-be-set-after.patch +++ b/patches.suse/crypto-qat-ADF_STATUS_PF_RUNNING-should-be-set-after.patch @@ -4,7 +4,7 @@ Date: Thu, 18 Mar 2021 23:40:00 -0400 Subject: [PATCH] crypto: qat - ADF_STATUS_PF_RUNNING should be set after adf_dev_init Git-commit: 8609f5cfdc872fc3a462efa6a3eca5cb1e2f6446 Patch-mainline: v5.13-rc1 -References: git-fixes +References: git-fixes CVE-2021-47056 bsc#1220769 ADF_STATUS_PF_RUNNING is (only) used and checked by adf_vf2pf_shutdown() before calling adf_iov_putmsg()->mutex_lock(vf2pf_lock), however the diff --git a/patches.suse/cxgb4-avoid-accessing-registers-when-clearing-filter.patch b/patches.suse/cxgb4-avoid-accessing-registers-when-clearing-filter.patch index cb2c037..9936e40 100644 --- a/patches.suse/cxgb4-avoid-accessing-registers-when-clearing-filter.patch +++ b/patches.suse/cxgb4-avoid-accessing-registers-when-clearing-filter.patch @@ -3,7 +3,7 @@ Date: Wed, 19 May 2021 16:48:31 +0530 Subject: cxgb4: avoid accessing registers when clearing filters Patch-mainline: v5.13-rc4 Git-commit: 88c380df84fbd03f9b137c2b9d0a44b9f2f553b0 -References: bsc#1136345 jsc#SLE-4681 +References: bsc#1136345 jsc#SLE-4681 CVE-2021-47138 bsc#1221934 Hardware register having the server TID base can contain invalid values when adapter is in bad state (for example, diff --git a/patches.suse/drivers-amd-pm-fix-a-use-after-free-in-kv_parse_powe.patch b/patches.suse/drivers-amd-pm-fix-a-use-after-free-in-kv_parse_powe.patch new file mode 100644 index 0000000..6128ee3 --- /dev/null +++ b/patches.suse/drivers-amd-pm-fix-a-use-after-free-in-kv_parse_powe.patch @@ -0,0 +1,47 @@ +From 28dd788382c43b330480f57cd34cde0840896743 Mon Sep 17 00:00:00 2001 +From: Zhipeng Lu +Date: Fri, 15 Dec 2023 00:24:58 +0800 +Subject: drivers/amd/pm: fix a use-after-free in kv_parse_power_table +Git-commit: 28dd788382c43b330480f57cd34cde0840896743 +Patch-mainline: v6.8-rc1 +References: bsc#1220411 CVE-2023-52469 + +When ps allocated by kzalloc equals to NULL, kv_parse_power_table +frees adev->pm.dpm.ps that allocated before. However, after the control +flow goes through the following call chains: + +kv_parse_power_table + |-> kv_dpm_init + |-> kv_dpm_sw_init + |-> kv_dpm_fini + +The adev->pm.dpm.ps is used in the for loop of kv_dpm_fini after its +first free in kv_parse_power_table and causes a use-after-free bug. + +Fixes: a2e73f56fa62 ("drm/amdgpu: Add support for CIK parts") +Signed-off-by: Zhipeng Lu +Signed-off-by: Alex Deucher +Acked-by: Patrik Jakobsson +--- + drivers/gpu/drm/amd/amdgpu/kv_dpm.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c +index 5d28c951a319..5cb4725c773f 100644 +--- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c ++++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c +@@ -2735,10 +2735,8 @@ static int kv_parse_power_table(struct amdgpu_device *adev) + non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) + &non_clock_info_array->nonClockInfo[non_clock_array_index]; + ps = kzalloc(sizeof(struct kv_ps), GFP_KERNEL); +- if (ps == NULL) { +- kfree(adev->pm.dpm.ps); ++ if (ps == NULL) + return -ENOMEM; +- } + adev->pm.dpm.ps[i].ps_priv = ps; + k = 0; + idx = (u8 *)&power_state->v2.clockInfoIndex[0]; +-- +2.44.0 + diff --git a/patches.suse/drm-amdgpu-Fix-a-use-after-free.patch b/patches.suse/drm-amdgpu-Fix-a-use-after-free.patch index cc71140..c7bbcc7 100644 --- a/patches.suse/drm-amdgpu-Fix-a-use-after-free.patch +++ b/patches.suse/drm-amdgpu-Fix-a-use-after-free.patch @@ -7,7 +7,7 @@ Content-type: text/plain; charset=UTF-8 Content-transfer-encoding: 8bit Git-commit: 1e5c37385097c35911b0f8a0c67ffd10ee1af9a2 Patch-mainline: v5.13-rc3 -References: git-fixes +References: git-fixes CVE-2021-47142 bsc#1221952 looks like we forget to set ttm->sg to NULL. Hit panic below diff --git a/patches.suse/drm-meson-fix-shutdown-crash-when-component-not-prob.patch b/patches.suse/drm-meson-fix-shutdown-crash-when-component-not-prob.patch index 472e909..901e6f8 100644 --- a/patches.suse/drm-meson-fix-shutdown-crash-when-component-not-prob.patch +++ b/patches.suse/drm-meson-fix-shutdown-crash-when-component-not-prob.patch @@ -4,7 +4,7 @@ Date: Fri, 30 Apr 2021 10:27:44 +0200 Subject: [PATCH] drm/meson: fix shutdown crash when component not probed Git-commit: 7cfc4ea78fc103ea51ecbacd9236abb5b1c490d2 Patch-mainline: v5.13-rc4 -References: git-fixes +References: git-fixes CVE-2021-47165 bsc#1221965 When main component is not probed, by example when the dw-hdmi module is not loaded yet or in probe defer, the following crash appears on shutdown: diff --git a/patches.suse/drm-radeon-check-the-alloc_workqueue-return-value-in.patch b/patches.suse/drm-radeon-check-the-alloc_workqueue-return-value-in.patch new file mode 100644 index 0000000..e4ea53d --- /dev/null +++ b/patches.suse/drm-radeon-check-the-alloc_workqueue-return-value-in.patch @@ -0,0 +1,45 @@ +From 7a2464fac80d42f6f8819fed97a553e9c2f43310 Mon Sep 17 00:00:00 2001 +From: Yang Yingliang +Date: Thu, 30 Nov 2023 15:50:16 +0800 +Subject: drm/radeon: check the alloc_workqueue return value in + radeon_crtc_init() +Git-commit: 7a2464fac80d42f6f8819fed97a553e9c2f43310 +Patch-mainline: v6.8-rc1 +References: bsc#1220413 CVE-2023-52470 + +check the alloc_workqueue return value in radeon_crtc_init() +to avoid null-ptr-deref. + +Fixes: fa7f517cb26e ("drm/radeon: rework page flip handling v4") +Signed-off-by: Yang Yingliang +Signed-off-by: Alex Deucher +Acked-by: Patrik Jakobsson +--- + drivers/gpu/drm/radeon/radeon_display.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c +index 901e75ec70ff..efd18c8d84c8 100644 +--- a/drivers/gpu/drm/radeon/radeon_display.c ++++ b/drivers/gpu/drm/radeon/radeon_display.c +@@ -687,11 +687,16 @@ static void radeon_crtc_init(struct drm_device *dev, int index) + if (radeon_crtc == NULL) + return; + ++ radeon_crtc->flip_queue = alloc_workqueue("radeon-crtc", WQ_HIGHPRI, 0); ++ if (!radeon_crtc->flip_queue) { ++ kfree(radeon_crtc); ++ return; ++ } ++ + drm_crtc_init(dev, &radeon_crtc->base, &radeon_crtc_funcs); + + drm_mode_crtc_set_gamma_size(&radeon_crtc->base, 256); + radeon_crtc->crtc_id = index; +- radeon_crtc->flip_queue = alloc_workqueue("radeon-crtc", WQ_HIGHPRI, 0); + rdev->mode_info.crtcs[index] = radeon_crtc; + + if (rdev->family >= CHIP_BONAIRE) { +-- +2.44.0 + diff --git a/patches.suse/ethernet-enic-Fix-a-use-after-free-bug-in-enic_hard_.patch b/patches.suse/ethernet-enic-Fix-a-use-after-free-bug-in-enic_hard_.patch index 303acad..a764cea 100644 --- a/patches.suse/ethernet-enic-Fix-a-use-after-free-bug-in-enic_hard_.patch +++ b/patches.suse/ethernet-enic-Fix-a-use-after-free-bug-in-enic_hard_.patch @@ -3,7 +3,7 @@ Date: Sun, 2 May 2021 04:58:18 -0700 Subject: ethernet:enic: Fix a use after free bug in enic_hard_start_xmit Patch-mainline: v5.13-rc1 Git-commit: 643001b47adc844ae33510c4bb93c236667008a3 -References: bsc#1113431 +References: bsc#1113431 CVE-2021-46998 bsc#1220625 In enic_hard_start_xmit, it calls enic_queue_wq_skb(). Inside enic_queue_wq_skb, if some error happens, the skb will be freed diff --git a/patches.suse/ethernet-myri10ge-Fix-missing-error-code-in-myri10ge.patch b/patches.suse/ethernet-myri10ge-Fix-missing-error-code-in-myri10ge.patch new file mode 100644 index 0000000..a60c247 --- /dev/null +++ b/patches.suse/ethernet-myri10ge-Fix-missing-error-code-in-myri10ge.patch @@ -0,0 +1,40 @@ +From 6db4b36136ced5936f12d1a616ef68b1c838a43a Mon Sep 17 00:00:00 2001 +From: Jiapeng Chong +Date: Tue, 1 Jun 2021 19:04:51 +0800 +Subject: [PATCH 4/4] ethernet: myri10ge: Fix missing error code in + myri10ge_probe() +Git-commit: f336d0b93ae978f12c5e27199f828da89b91e56a +References: git-fixes +Patch-mainline: v5.13-rc5 + +The error code is missing in this code scenario, add the error code +'-EINVAL' to the return value 'status'. + +Eliminate the follow smatch warning: + +drivers/net/ethernet/myricom/myri10ge/myri10ge.c:3818 myri10ge_probe() +warn: missing error code 'status'. + +Reported-by: Abaci Robot +Signed-off-by: Jiapeng Chong +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +index 98f881fe8be6..a81a7135de91 100644 +--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c ++++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +@@ -3852,6 +3852,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + dev_err(&pdev->dev, + "invalid sram_size %dB or board span %ldB\n", + mgp->sram_size, mgp->board_span); ++ status = -EINVAL; + goto abort_with_ioremap; + } + memcpy_fromio(mgp->eeprom_strings, +-- +2.16.4 + diff --git a/patches.suse/ethernet-ucc_geth-fix-definition-and-size-of-ucc_get.patch b/patches.suse/ethernet-ucc_geth-fix-definition-and-size-of-ucc_get.patch new file mode 100644 index 0000000..8dbf9be --- /dev/null +++ b/patches.suse/ethernet-ucc_geth-fix-definition-and-size-of-ucc_get.patch @@ -0,0 +1,63 @@ +From a999997633a8059cd08220ddc31dfb95bc7d648f Mon Sep 17 00:00:00 2001 +From: Rasmus Villemoes +Date: Fri, 18 Dec 2020 11:55:37 +0100 +Subject: [PATCH 1/2] ethernet: ucc_geth: fix definition and size of + ucc_geth_tx_global_pram +Git-commit: 887078de2a23689e29d6fa1b75d7cbc544c280be +References: git-fixes +Patch-mainline: v5.11-rc3 + +Table 8-53 in the QUICC Engine Reference manual shows definitions of +fields up to a size of 192 bytes, not just 128. But in table 8-111, +one does find the text + + Base Address of the Global Transmitter Parameter RAM Page. [...] + The user needs to allocate 128 bytes for this page. The address must + be aligned to the page size. + +I've checked both rev. 7 (11/2015) and rev. 9 (05/2018) of the manual; +they both have this inconsistency (and the table numbers are the +same). + +Adding a bit of debug printing, on my board the struct +ucc_geth_tx_global_pram is allocated at offset 0x880, while +the (opaque) ucc_geth_thread_data_tx gets allocated immediately +afterwards, at 0x900. So whatever the engine writes into the thread +data overlaps with the tail of the global tx pram (and devmem says +that something does get written during a simple ping). + +I haven't observed any failure that could be attributed to this, but +it seems to be the kind of thing that would be extremely hard to +debug. So extend the struct definition so that we do allocate 192 +bytes. + +Signed-off-by: Rasmus Villemoes +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/freescale/ucc_geth.h | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h +index 5da19b440a6a..bf25e49d4fe3 100644 +--- a/drivers/net/ethernet/freescale/ucc_geth.h ++++ b/drivers/net/ethernet/freescale/ucc_geth.h +@@ -580,7 +580,14 @@ struct ucc_geth_tx_global_pram { + u32 vtagtable[0x8]; /* 8 4-byte VLAN tags */ + u32 tqptr; /* a base pointer to the Tx Queues Memory + Region */ +- u8 res2[0x80 - 0x74]; ++ u8 res2[0x78 - 0x74]; ++ u64 snums_en; ++ u32 l2l3baseptr; /* top byte consists of a few other bit fields */ ++ ++ u16 mtu[8]; ++ u8 res3[0xa8 - 0x94]; ++ u32 wrrtablebase; /* top byte is reserved */ ++ u8 res4[0xc0 - 0xac]; + } __packed; + + /* structure representing Extended Filtering Global Parameters in PRAM */ +-- +2.16.4 + diff --git a/patches.suse/ext2-Avoid-reading-renamed-directory-if-parent-does-.patch b/patches.suse/ext2-Avoid-reading-renamed-directory-if-parent-does-.patch new file mode 100644 index 0000000..3b201d0 --- /dev/null +++ b/patches.suse/ext2-Avoid-reading-renamed-directory-if-parent-does-.patch @@ -0,0 +1,82 @@ +From 7307b73fa5a82661808b5541972176c344978789 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 12 Oct 2023 23:14:22 +0200 +Subject: [PATCH] ext2: Avoid reading renamed directory if parent does not + change +Git-commit: 7307b73fa5a82661808b5541972176c344978789 +Patch-mainline: v6.8-rc1 +References: bsc#1221044 CVE-2023-52591 + +The VFS will not be locking moved directory if its parent does not +change. Change ext2 rename code to avoid reading renamed directory if +its parent does not change. Although it is currently harmless it is a +bad practice to read directory contents without inode->i_rwsem. + +Signed-off-by: Jan Kara +Signed-off-by: Al Viro +Acked-by: Jan Kara + +--- + fs/ext2/namei.c | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +--- a/fs/ext2/namei.c ++++ b/fs/ext2/namei.c +@@ -321,6 +321,7 @@ static int ext2_rename (struct inode * o + struct ext2_dir_entry_2 * dir_de = NULL; + struct page * old_page; + struct ext2_dir_entry_2 * old_de; ++ bool old_is_dir = S_ISDIR(old_inode->i_mode); + int err; + + if (flags & ~RENAME_NOREPLACE) +@@ -340,7 +341,7 @@ static int ext2_rename (struct inode * o + goto out; + } + +- if (S_ISDIR(old_inode->i_mode)) { ++ if (old_is_dir && old_dir != new_dir) { + err = -EIO; + dir_de = ext2_dotdot(old_inode, &dir_page); + if (!dir_de) +@@ -352,7 +353,7 @@ static int ext2_rename (struct inode * o + struct ext2_dir_entry_2 *new_de; + + err = -ENOTEMPTY; +- if (dir_de && !ext2_empty_dir (new_inode)) ++ if (old_is_dir && !ext2_empty_dir(new_inode)) + goto out_dir; + + err = -ENOENT; +@@ -361,14 +362,14 @@ static int ext2_rename (struct inode * o + goto out_dir; + ext2_set_link(new_dir, new_de, new_page, old_inode, 1); + new_inode->i_ctime = current_time(new_inode); +- if (dir_de) ++ if (old_is_dir) + drop_nlink(new_inode); + inode_dec_link_count(new_inode); + } else { + err = ext2_add_link(new_dentry, old_inode); + if (err) + goto out_dir; +- if (dir_de) ++ if (old_is_dir) + inode_inc_link_count(new_dir); + } + +@@ -381,13 +382,9 @@ static int ext2_rename (struct inode * o + + ext2_delete_entry (old_de, old_page); + +- if (dir_de) { ++ if (old_is_dir) { + if (old_dir != new_dir) + ext2_set_link(old_inode, dir_de, dir_page, new_dir, 0); +- else { +- kunmap(dir_page); +- put_page(dir_page); +- } + inode_dec_link_count(old_dir); + } + return 0; diff --git a/patches.suse/ext4-don-t-access-the-source-subdirectory-content-on.patch b/patches.suse/ext4-don-t-access-the-source-subdirectory-content-on.patch new file mode 100644 index 0000000..9e97d91 --- /dev/null +++ b/patches.suse/ext4-don-t-access-the-source-subdirectory-content-on.patch @@ -0,0 +1,87 @@ +From 40dbd071f4b19d9630353c3cd45c2d6adb6799d4 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Tue, 17 Oct 2023 14:55:42 -0400 +Subject: [PATCH] ext4: don't access the source subdirectory content on + same-directory rename +Git-commit: 40dbd071f4b19d9630353c3cd45c2d6adb6799d4 +Patch-mainline: v6.8-rc1 +References: bsc#1221044 CVE-2023-52591 + +We can't really afford locking the source on same-directory rename; +currently vfs_rename() tries to do that, but it will have to be changed. +The logics in ext4 is lazy and goes looking for ".." in source even in +same-directory case. It's not hard to get rid of that, leaving that +behaviour only for cross-directory case; that VFS can get locks safely +(and will keep doing that after the coming changes). + +Reviewed-by: Jan Kara +Signed-off-by: Al Viro +Acked-by: Jan Kara + +--- + fs/ext4/namei.c | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -3527,10 +3527,14 @@ struct ext4_renament { + int dir_inlined; + }; + +-static int ext4_rename_dir_prepare(handle_t *handle, struct ext4_renament *ent) ++static int ext4_rename_dir_prepare(handle_t *handle, struct ext4_renament *ent, bool is_cross) + { + int retval; + ++ ent->is_dir = true; ++ if (!is_cross) ++ return 0; ++ + ent->dir_bh = ext4_get_first_dir_block(handle, ent->inode, + &retval, &ent->parent_de, + &ent->dir_inlined); +@@ -3547,6 +3551,9 @@ static int ext4_rename_dir_finish(handle + { + int retval; + ++ if (!ent->dir_bh) ++ return 0; ++ + ent->parent_de->inode = cpu_to_le32(dir_ino); + BUFFER_TRACE(ent->dir_bh, "call ext4_handle_dirty_metadata"); + if (!ent->dir_inlined) { +@@ -3829,7 +3836,7 @@ static int ext4_rename(struct inode *old + if (new.dir != old.dir && EXT4_DIR_LINK_MAX(new.dir)) + goto end_rename; + } +- retval = ext4_rename_dir_prepare(handle, &old); ++ retval = ext4_rename_dir_prepare(handle, &old, new.dir != old.dir); + if (retval) + goto end_rename; + } +@@ -3888,7 +3895,7 @@ static int ext4_rename(struct inode *old + } + old.dir->i_ctime = old.dir->i_mtime = current_time(old.dir); + ext4_update_dx_flag(old.dir); +- if (old.dir_bh) { ++ if (old.is_dir) { + retval = ext4_rename_dir_finish(handle, &old, new.dir->i_ino); + if (retval) + goto end_rename; +@@ -4004,14 +4011,12 @@ static int ext4_cross_rename(struct inod + ext4_handle_sync(handle); + + if (S_ISDIR(old.inode->i_mode)) { +- old.is_dir = true; +- retval = ext4_rename_dir_prepare(handle, &old); ++ retval = ext4_rename_dir_prepare(handle, &old, new.dir != old.dir); + if (retval) + goto end_rename; + } + if (S_ISDIR(new.inode->i_mode)) { +- new.is_dir = true; +- retval = ext4_rename_dir_prepare(handle, &new); ++ retval = ext4_rename_dir_prepare(handle, &new, new.dir != old.dir); + if (retval) + goto end_rename; + } diff --git a/patches.suse/ext4-fix-bug-on-in-ext4_es_cache_extent-as-ext4_spli.patch b/patches.suse/ext4-fix-bug-on-in-ext4_es_cache_extent-as-ext4_spli.patch index c21ce77..32307a1 100644 --- a/patches.suse/ext4-fix-bug-on-in-ext4_es_cache_extent-as-ext4_spli.patch +++ b/patches.suse/ext4-fix-bug-on-in-ext4_es_cache_extent-as-ext4_spli.patch @@ -5,7 +5,7 @@ Subject: [PATCH] ext4: fix bug on in ext4_es_cache_extent as ext4_split_extent_at failed Git-commit: 082cd4ec240b8734a82a89ffb890216ac98fec68 Patch-mainline: v5.13-rc5 -References: bsc#1187408 +References: bsc#1187408 CVE-2021-47117 bsc#1221575 We got follow bug_on when run fsstress with injecting IO fault: [130747.323114] kernel BUG at fs/ext4/extents_status.c:762! diff --git a/patches.suse/ext4-fix-memory-leak-in-ext4_fill_super.patch b/patches.suse/ext4-fix-memory-leak-in-ext4_fill_super.patch index f0a58cb..75580ec 100644 --- a/patches.suse/ext4-fix-memory-leak-in-ext4_fill_super.patch +++ b/patches.suse/ext4-fix-memory-leak-in-ext4_fill_super.patch @@ -4,7 +4,7 @@ Date: Fri, 21 May 2021 07:55:33 +0000 Subject: [PATCH] ext4: fix memory leak in ext4_fill_super Git-commit: afd09b617db3786b6ef3dc43e28fe728cfea84df Patch-mainline: v5.13-rc5 -References: bsc#1187409 +References: bsc#1187409 CVE-2021-47119 bsc#1221608 Buffer head references must be released before calling kill_bdev(); otherwise the buffer head (and its page referenced by b_data) will not diff --git a/patches.suse/f2fs-Avoid-reading-renamed-directory-if-parent-does-.patch b/patches.suse/f2fs-Avoid-reading-renamed-directory-if-parent-does-.patch new file mode 100644 index 0000000..fd55517 --- /dev/null +++ b/patches.suse/f2fs-Avoid-reading-renamed-directory-if-parent-does-.patch @@ -0,0 +1,80 @@ +From 7deee77b993a2234acb123b8ec477bd56f2e3be3 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 12 Oct 2023 23:14:23 +0200 +Subject: [PATCH] f2fs: Avoid reading renamed directory if parent does not + change +Git-commit: 7deee77b993a2234acb123b8ec477bd56f2e3be3 +Patch-mainline: v6.8-rc1 +References: bsc#1221044 CVE-2023-52591 + +The VFS will not be locking moved directory if its parent does not +change. Change f2fs rename code to avoid reading renamed directory if +its parent does not change. Having it uninlined while we are reading +it would cause trouble and we won't be able to rely upon ->i_rwsem +on the directory being renamed in cases that do not alter its parent. + +Signed-off-by: Jan Kara +Signed-off-by: Al Viro +Acked-by: Jan Kara + +--- + fs/f2fs/namei.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +--- a/fs/f2fs/namei.c ++++ b/fs/f2fs/namei.c +@@ -657,6 +657,7 @@ static int f2fs_rename(struct inode *old + struct f2fs_dir_entry *old_dir_entry = NULL; + struct f2fs_dir_entry *old_entry; + struct f2fs_dir_entry *new_entry; ++ bool old_is_dir = S_ISDIR(old_inode->i_mode); + bool is_old_inline = f2fs_has_inline_dentry(old_dir); + int err = -ENOENT; + +@@ -679,7 +680,7 @@ static int f2fs_rename(struct inode *old + goto out; + } + +- if (S_ISDIR(old_inode->i_mode)) { ++ if (old_is_dir && old_dir != new_dir) { + old_dir_entry = f2fs_parent_dir(old_inode, &old_dir_page); + if (!old_dir_entry) { + if (IS_ERR(old_dir_page)) +@@ -697,7 +698,7 @@ static int f2fs_rename(struct inode *old + if (new_inode) { + + err = -ENOTEMPTY; +- if (old_dir_entry && !f2fs_empty_dir(new_inode)) ++ if (old_is_dir && !f2fs_empty_dir(new_inode)) + goto out_whiteout; + + err = -ENOENT; +@@ -721,7 +722,7 @@ static int f2fs_rename(struct inode *old + + new_inode->i_ctime = current_time(new_inode); + down_write(&F2FS_I(new_inode)->i_sem); +- if (old_dir_entry) ++ if (old_is_dir) + f2fs_i_links_write(new_inode, false); + f2fs_i_links_write(new_inode, false); + up_write(&F2FS_I(new_inode)->i_sem); +@@ -741,7 +742,7 @@ static int f2fs_rename(struct inode *old + goto out_whiteout; + } + +- if (old_dir_entry) ++ if (old_is_dir) + f2fs_i_links_write(new_dir, true); + + /* +@@ -786,8 +787,8 @@ static int f2fs_rename(struct inode *old + iput(whiteout); + } + +- if (old_dir_entry) { +- if (old_dir != new_dir && !whiteout) { ++ if (old_is_dir) { ++ if (old_dir_entry && !whiteout) { + f2fs_set_link(old_inode, old_dir_entry, + old_dir_page, new_dir); + } else { diff --git a/patches.suse/fs-Establish-locking-order-for-unrelated-directories.patch b/patches.suse/fs-Establish-locking-order-for-unrelated-directories.patch new file mode 100644 index 0000000..96dde09 --- /dev/null +++ b/patches.suse/fs-Establish-locking-order-for-unrelated-directories.patch @@ -0,0 +1,104 @@ +From f23ce757185319886ca80c4864ce5f81ac6cc9e9 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 1 Jun 2023 12:58:24 +0200 +Subject: [PATCH] fs: Establish locking order for unrelated directories +Git-commit: f23ce757185319886ca80c4864ce5f81ac6cc9e9 +Patch-mainline: v6.5-rc1 +References: bsc#1221044 CVE-2023-52591 + +Currently the locking order of inode locks for directories that are not +in ancestor relationship is not defined because all operations that +needed to lock two directories like this were serialized by +sb->s_vfs_rename_mutex. However some filesystems need to lock two +subdirectories for RENAME_EXCHANGE operations and for this we need the +locking order established even for two tree-unrelated directories. +Provide a helper function lock_two_inodes() that establishes lock +ordering for any two inodes and use it in lock_two_directories(). + +Cc: stable@vger.kernel.org +Signed-off-by: Jan Kara +Message-id: <20230601105830.13168-4-jack@suse.cz> +Signed-off-by: Christian Brauner +Acked-by: Jan Kara + +--- + fs/inode.c | 42 ++++++++++++++++++++++++++++++++++++++++++ + fs/internal.h | 2 ++ + fs/namei.c | 4 ++-- + 3 files changed, 46 insertions(+), 2 deletions(-) + +--- a/fs/inode.c ++++ b/fs/inode.c +@@ -973,6 +973,48 @@ void unlock_new_inode(struct inode *inod + EXPORT_SYMBOL(unlock_new_inode); + + /** ++ * lock_two_inodes - lock two inodes (may be regular files but also dirs) ++ * ++ * Lock any non-NULL argument. The caller must make sure that if he is passing ++ * in two directories, one is not ancestor of the other. Zero, one or two ++ * objects may be locked by this function. ++ * ++ * @inode1: first inode to lock ++ * @inode2: second inode to lock ++ * @subclass1: inode lock subclass for the first lock obtained ++ * @subclass2: inode lock subclass for the second lock obtained ++ */ ++void lock_two_inodes(struct inode *inode1, struct inode *inode2, ++ unsigned subclass1, unsigned subclass2) ++{ ++ if (!inode1 || !inode2) { ++ /* ++ * Make sure @subclass1 will be used for the acquired lock. ++ * This is not strictly necessary (no current caller cares) but ++ * let's keep things consistent. ++ */ ++ if (!inode1) ++ swap(inode1, inode2); ++ goto lock; ++ } ++ ++ /* ++ * If one object is directory and the other is not, we must make sure ++ * to lock directory first as the other object may be its child. ++ */ ++ if (S_ISDIR(inode2->i_mode) == S_ISDIR(inode1->i_mode)) { ++ if (inode1 > inode2) ++ swap(inode1, inode2); ++ } else if (!S_ISDIR(inode1->i_mode)) ++ swap(inode1, inode2); ++lock: ++ if (inode1) ++ inode_lock_nested(inode1, subclass1); ++ if (inode2 && inode2 != inode1) ++ inode_lock_nested(inode2, subclass2); ++} ++ ++/** + * lock_two_nondirectories - take two i_mutexes on non-directory objects + * + * Lock any non-NULL argument that is not a directory. +--- a/fs/internal.h ++++ b/fs/internal.h +@@ -117,6 +117,8 @@ extern int vfs_open(const struct path *, + extern long prune_icache_sb(struct super_block *sb, struct shrink_control *sc); + extern void inode_add_lru(struct inode *inode); + extern int dentry_needs_remove_privs(struct dentry *dentry); ++void lock_two_inodes(struct inode *inode1, struct inode *inode2, ++ unsigned subclass1, unsigned subclass2); + + extern bool __atime_needs_update(const struct path *, struct inode *, bool); + static inline bool atime_needs_update_rcu(const struct path *path, +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -2906,8 +2906,8 @@ static struct dentry *lock_two_directori + return p; + } + +- inode_lock_nested(p1->d_inode, I_MUTEX_PARENT); +- inode_lock_nested(p2->d_inode, I_MUTEX_PARENT2); ++ lock_two_inodes(p1->d_inode, p2->d_inode, ++ I_MUTEX_PARENT, I_MUTEX_PARENT2); + return NULL; + } + diff --git a/patches.suse/fs-Lock-moved-directories.patch b/patches.suse/fs-Lock-moved-directories.patch new file mode 100644 index 0000000..62ee874 --- /dev/null +++ b/patches.suse/fs-Lock-moved-directories.patch @@ -0,0 +1,126 @@ +From 28eceeda130f5058074dd007d9c59d2e8bc5af2e Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 1 Jun 2023 12:58:25 +0200 +Subject: [PATCH] fs: Lock moved directories +Git-commit: 28eceeda130f5058074dd007d9c59d2e8bc5af2e +Patch-mainline: v6.5-rc1 +References: bsc#1221044 CVE-2023-52591 + +When a directory is moved to a different directory, some filesystems +(udf, ext4, ocfs2, f2fs, and likely gfs2, reiserfs, and others) need to +update their pointer to the parent and this must not race with other +operations on the directory. Lock the directories when they are moved. +Although not all filesystems need this locking, we perform it in +vfs_rename() because getting the lock ordering right is really difficult +and we don't want to expose these locking details to filesystems. + +Cc: stable@vger.kernel.org +Signed-off-by: Jan Kara +Message-id: <20230601105830.13168-5-jack@suse.cz> +Signed-off-by: Christian Brauner +Acked-by: Jan Kara + +--- + Documentation/filesystems/directory-locking | 26 ++++++++++++++------------ + fs/namei.c | 22 ++++++++++++++-------- + 2 files changed, 28 insertions(+), 20 deletions(-) + +--- a/Documentation/filesystems/directory-locking ++++ b/Documentation/filesystems/directory-locking +@@ -17,12 +17,11 @@ exclusive. + 3) object removal. Locking rules: caller locks parent, finds victim, + locks victim and calls the method. Locks are exclusive. + +-4) rename() that is _not_ cross-directory. Locking rules: caller locks +-the parent and finds source and target. In case of exchange (with +-RENAME_EXCHANGE in flags argument) lock both. In any case, +-if the target already exists, lock it. If the source is a non-directory, +-lock it. If we need to lock both, lock them in inode pointer order. +-Then call the method. All locks are exclusive. ++4) rename() that is _not_ cross-directory. Locking rules: caller locks the ++parent and finds source and target. We lock both (provided they exist). If we ++need to lock two inodes of different type (dir vs non-dir), we lock directory ++first. If we need to lock two inodes of the same type, lock them in inode ++pointer order. Then call the method. All locks are exclusive. + NB: we might get away with locking the the source (and target in exchange + case) shared. + +@@ -36,15 +35,17 @@ All locks are exclusive. + 6) cross-directory rename. The trickiest in the whole bunch. Locking + rules: + * lock the filesystem +- * lock parents in "ancestors first" order. ++ * lock parents in "ancestors first" order. If one is not ancestor of ++ the other, lock them in inode pointer order. + * find source and target. + * if old parent is equal to or is a descendent of target + fail with -ENOTEMPTY + * if new parent is equal to or is a descendent of source + fail with -ELOOP +- * If it's an exchange, lock both the source and the target. +- * If the target exists, lock it. If the source is a non-directory, +- lock it. If we need to lock both, do so in inode pointer order. ++ * Lock both the source and the target provided they exist. If we ++ need to lock two inodes of different type (dir vs non-dir), we lock ++ the directory first. If we need to lock two inodes of the same type, ++ lock them in inode pointer order. + * call the method. + All ->i_rwsem are taken exclusive. Again, we might get away with locking + the the source (and target in exchange case) shared. +@@ -56,8 +57,9 @@ read, modified or removed by method will + If no directory is its own ancestor, the scheme above is deadlock-free. + Proof: + +- First of all, at any moment we have a partial ordering of the +-objects - A < B iff A is an ancestor of B. ++ First of all, at any moment we have a linear ordering of the ++ objects - A < B iff (A is an ancestor of B) or (B is not an ancestor ++ of A and ptr(A) < ptr(B)). + + That ordering can change. However, the following is true: + +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -4501,7 +4501,7 @@ SYSCALL_DEFINE2(link, const char __user + * sb->s_vfs_rename_mutex. We might be more accurate, but that's another + * story. + * c) we have to lock _four_ objects - parents and victim (if it exists), +- * and source (if it is not a directory). ++ * and source. + * And that - after we got ->i_mutex on parents (until then we don't know + * whether the target exists). Solution: try to be smart with locking + * order for inodes. We rely on the fact that tree topology may change +@@ -4578,10 +4578,16 @@ int vfs_rename(struct inode *old_dir, st + + take_dentry_name_snapshot(&old_name, old_dentry); + dget(new_dentry); +- if (!is_dir || (flags & RENAME_EXCHANGE)) +- lock_two_nondirectories(source, target); +- else if (target) +- inode_lock(target); ++ /* ++ * Lock all moved children. Moved directories may need to change parent ++ * pointer so they need the lock to prevent against concurrent ++ * directory changes moving parent pointer. For regular files we've ++ * historically always done this. The lockdep locking subclasses are ++ * somewhat arbitrary but RENAME_EXCHANGE in particular can swap ++ * regular files and directories so it's difficult to tell which ++ * subclasses to use. ++ */ ++ lock_two_inodes(source, target, I_MUTEX_NORMAL, I_MUTEX_NONDIR2); + + error = -EPERM; + if (IS_SWAPFILE(source) || (target && IS_SWAPFILE(target))) +@@ -4629,9 +4635,9 @@ int vfs_rename(struct inode *old_dir, st + d_exchange(old_dentry, new_dentry); + } + out: +- if (!is_dir || (flags & RENAME_EXCHANGE)) +- unlock_two_nondirectories(source, target); +- else if (target) ++ if (source) ++ inode_unlock(source); ++ if (target) + inode_unlock(target); + dput(new_dentry); + if (!error) { diff --git a/patches.suse/fs-Restrict-lock_two_nondirectories-to-non-directory.patch b/patches.suse/fs-Restrict-lock_two_nondirectories-to-non-directory.patch new file mode 100644 index 0000000..eec2e9e --- /dev/null +++ b/patches.suse/fs-Restrict-lock_two_nondirectories-to-non-directory.patch @@ -0,0 +1,76 @@ +From 2454ad83b90afbc6ed2c22ec1310b624c40bf0d3 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 1 Jun 2023 12:58:26 +0200 +Subject: [PATCH] fs: Restrict lock_two_nondirectories() to non-directory + inodes +Git-commit: 2454ad83b90afbc6ed2c22ec1310b624c40bf0d3 +Patch-mainline: v6.5-rc1 +References: bsc#1221044 CVE-2023-52591 + +Currently lock_two_nondirectories() is skipping any passed directories. +After vfs_rename() uses lock_two_inodes(), all the remaining four users +of this function pass only regular files to it. So drop the somewhat +unusual "skip directory" logic and instead warn if anybody passes +directory to it. This also allows us to use lock_two_inodes() in +lock_two_nondirectories() to concentrate the lock ordering logic in less +places. + +Signed-off-by: Jan Kara +Message-id: <20230601105830.13168-6-jack@suse.cz> +Signed-off-by: Christian Brauner +Acked-by: Jan Kara + +--- + fs/inode.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/fs/inode.c b/fs/inode.c +index b9d498032270..53ae3b76d232 100644 +--- a/fs/inode.c ++++ b/fs/inode.c +@@ -1148,7 +1148,7 @@ void lock_two_inodes(struct inode *inode1, struct inode *inode2, + /** + * lock_two_nondirectories - take two i_mutexes on non-directory objects + * +- * Lock any non-NULL argument that is not a directory. ++ * Lock any non-NULL argument. Passed objects must not be directories. + * Zero, one or two objects may be locked by this function. + * + * @inode1: first inode to lock +@@ -1156,13 +1156,9 @@ void lock_two_inodes(struct inode *inode1, struct inode *inode2, + */ + void lock_two_nondirectories(struct inode *inode1, struct inode *inode2) + { +- if (inode1 > inode2) +- swap(inode1, inode2); +- +- if (inode1 && !S_ISDIR(inode1->i_mode)) +- inode_lock(inode1); +- if (inode2 && !S_ISDIR(inode2->i_mode) && inode2 != inode1) +- inode_lock_nested(inode2, I_MUTEX_NONDIR2); ++ WARN_ON_ONCE(S_ISDIR(inode1->i_mode)); ++ WARN_ON_ONCE(S_ISDIR(inode2->i_mode)); ++ lock_two_inodes(inode1, inode2, I_MUTEX_NORMAL, I_MUTEX_NONDIR2); + } + EXPORT_SYMBOL(lock_two_nondirectories); + +@@ -1173,10 +1169,14 @@ EXPORT_SYMBOL(lock_two_nondirectories); + */ + void unlock_two_nondirectories(struct inode *inode1, struct inode *inode2) + { +- if (inode1 && !S_ISDIR(inode1->i_mode)) ++ if (inode1) { ++ WARN_ON_ONCE(S_ISDIR(inode1->i_mode)); + inode_unlock(inode1); +- if (inode2 && !S_ISDIR(inode2->i_mode) && inode2 != inode1) ++ } ++ if (inode2 && inode2 != inode1) { ++ WARN_ON_ONCE(S_ISDIR(inode2->i_mode)); + inode_unlock(inode2); ++ } + } + EXPORT_SYMBOL(unlock_two_nondirectories); + +-- +2.35.3 + diff --git a/patches.suse/fs-don-t-assume-arguments-are-non-NULL.patch b/patches.suse/fs-don-t-assume-arguments-are-non-NULL.patch new file mode 100644 index 0000000..f5607d4 --- /dev/null +++ b/patches.suse/fs-don-t-assume-arguments-are-non-NULL.patch @@ -0,0 +1,45 @@ +From 33ab231f83cc12d0157711bbf84e180c3be7d7bc Mon Sep 17 00:00:00 2001 +From: Christian Brauner +Date: Mon, 3 Jul 2023 16:49:12 +0200 +Subject: [PATCH] fs: don't assume arguments are non-NULL +Git-commit: 33ab231f83cc12d0157711bbf84e180c3be7d7bc +Patch-mainline: v6.5-rc1 +References: bsc#1221044 CVE-2023-52591 + +The helper is explicitly documented as locking zero, one, or two +arguments. While all current callers do pass non-NULL arguments there's +no need or requirement for them to do so according to the code and the +unlock_two_nondirectories() helper is pretty clear about it as well. So +only call WARN_ON_ONCE() if the checked inode is valid. + +Fixes: 2454ad83b90a ("fs: Restrict lock_two_nondirectories() to non-directory inodes") +Reviewed-by: Jan Kara +Cc: Jan Kara +Message-id: <20230703-vfs-rename-source-v1-2-37eebb29b65b@kernel.org> +Signed-off-by: Christian Brauner +Acked-by: Jan Kara + +--- + fs/inode.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/fs/inode.c b/fs/inode.c +index d37fad91c8da..8fefb69e1f84 100644 +--- a/fs/inode.c ++++ b/fs/inode.c +@@ -1156,8 +1156,10 @@ void lock_two_inodes(struct inode *inode1, struct inode *inode2, + */ + void lock_two_nondirectories(struct inode *inode1, struct inode *inode2) + { +- WARN_ON_ONCE(S_ISDIR(inode1->i_mode)); +- WARN_ON_ONCE(S_ISDIR(inode2->i_mode)); ++ if (inode1) ++ WARN_ON_ONCE(S_ISDIR(inode1->i_mode)); ++ if (inode2) ++ WARN_ON_ONCE(S_ISDIR(inode2->i_mode)); + lock_two_inodes(inode1, inode2, I_MUTEX_NORMAL, I_MUTEX_NONDIR2); + } + EXPORT_SYMBOL(lock_two_nondirectories); +-- +2.35.3 + diff --git a/patches.suse/fs-introduce-lock_rename_child-helper.patch b/patches.suse/fs-introduce-lock_rename_child-helper.patch new file mode 100644 index 0000000..f3604dd --- /dev/null +++ b/patches.suse/fs-introduce-lock_rename_child-helper.patch @@ -0,0 +1,123 @@ +From 9bc37e04823b5280dd0f22b6680fc23fe81ca325 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Thu, 16 Mar 2023 07:34:34 +0900 +Subject: [PATCH] fs: introduce lock_rename_child() helper +Git-commit: 9bc37e04823b5280dd0f22b6680fc23fe81ca325 +Patch-mainline: v6.4-rc1 +References: bsc#1221044 CVE-2023-52591 + +Pass the dentry of a source file and the dentry of a destination directory +to lock parent inodes for rename. As soon as this function returns, +->d_parent of the source file dentry is stable and inodes are properly +locked for calling vfs-rename. This helper is needed for ksmbd server. +rename request of SMB protocol has to rename an opened file, no matter +which directory it's in. + +Signed-off-by: Al Viro +Signed-off-by: Namjae Jeon +Acked-by: Jan Kara + +--- + fs/namei.c | 68 +++++++++++++++++++++++++++++++++++++++++--------- + include/linux/namei.h | 1 + 2 files changed, 58 insertions(+), 11 deletions(-) + +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -2864,20 +2864,10 @@ static inline int may_create(struct inod + return inode_permission(dir, MAY_WRITE | MAY_EXEC); + } + +-/* +- * p1 and p2 should be directories on the same fs. +- */ +-struct dentry *lock_rename(struct dentry *p1, struct dentry *p2) ++static struct dentry *lock_two_directories(struct dentry *p1, struct dentry *p2) + { + struct dentry *p; + +- if (p1 == p2) { +- inode_lock_nested(p1->d_inode, I_MUTEX_PARENT); +- return NULL; +- } +- +- mutex_lock(&p1->d_sb->s_vfs_rename_mutex); +- + p = d_ancestor(p2, p1); + if (p) { + inode_lock_nested(p2->d_inode, I_MUTEX_PARENT); +@@ -2896,8 +2886,64 @@ struct dentry *lock_rename(struct dentry + inode_lock_nested(p2->d_inode, I_MUTEX_PARENT2); + return NULL; + } ++ ++/* ++ * p1 and p2 should be directories on the same fs. ++ */ ++struct dentry *lock_rename(struct dentry *p1, struct dentry *p2) ++{ ++ if (p1 == p2) { ++ inode_lock_nested(p1->d_inode, I_MUTEX_PARENT); ++ return NULL; ++ } ++ ++ mutex_lock(&p1->d_sb->s_vfs_rename_mutex); ++ return lock_two_directories(p1, p2); ++} + EXPORT_SYMBOL(lock_rename); + ++/* ++ * c1 and p2 should be on the same fs. ++ */ ++struct dentry *lock_rename_child(struct dentry *c1, struct dentry *p2) ++{ ++ if (READ_ONCE(c1->d_parent) == p2) { ++ /* ++ * hopefully won't need to touch ->s_vfs_rename_mutex at all. ++ */ ++ inode_lock_nested(p2->d_inode, I_MUTEX_PARENT); ++ /* ++ * now that p2 is locked, nobody can move in or out of it, ++ * so the test below is safe. ++ */ ++ if (likely(c1->d_parent == p2)) ++ return NULL; ++ ++ /* ++ * c1 got moved out of p2 while we'd been taking locks; ++ * unlock and fall back to slow case. ++ */ ++ inode_unlock(p2->d_inode); ++ } ++ ++ mutex_lock(&c1->d_sb->s_vfs_rename_mutex); ++ /* ++ * nobody can move out of any directories on this fs. ++ */ ++ if (likely(c1->d_parent != p2)) ++ return lock_two_directories(c1->d_parent, p2); ++ ++ /* ++ * c1 got moved into p2 while we were taking locks; ++ * we need p2 locked and ->s_vfs_rename_mutex unlocked, ++ * for consistency with lock_rename(). ++ */ ++ inode_lock_nested(p2->d_inode, I_MUTEX_PARENT); ++ mutex_unlock(&c1->d_sb->s_vfs_rename_mutex); ++ return NULL; ++} ++EXPORT_SYMBOL(lock_rename_child); ++ + void unlock_rename(struct dentry *p1, struct dentry *p2) + { + inode_unlock(p1->d_inode); +--- a/include/linux/namei.h ++++ b/include/linux/namei.h +@@ -94,6 +94,7 @@ extern int follow_down(struct path *); + extern int follow_up(struct path *); + + extern struct dentry *lock_rename(struct dentry *, struct dentry *); ++extern struct dentry *lock_rename_child(struct dentry *, struct dentry *); + extern void unlock_rename(struct dentry *, struct dentry *); + + extern void nd_jump_link(struct path *path); diff --git a/patches.suse/fs-no-need-to-check-source.patch b/patches.suse/fs-no-need-to-check-source.patch new file mode 100644 index 0000000..e96a0c2 --- /dev/null +++ b/patches.suse/fs-no-need-to-check-source.patch @@ -0,0 +1,50 @@ +From 66d8fc0539b0d49941f313c9509a8384e4245ac1 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Mon, 3 Jul 2023 16:49:11 +0200 +Subject: [PATCH] fs: no need to check source +Git-commit: 66d8fc0539b0d49941f313c9509a8384e4245ac1 +Patch-mainline: v6.5-rc1 +References: bsc#1221044 CVE-2023-52591 + +The @source inode must be valid. It is even checked via IS_SWAPFILE() +above making it pretty clear. So no need to check it when we unlock. + +What doesn't need to exist is the @target inode. The lock_two_inodes() +helper currently swaps the @inode1 and @inode2 arguments if @inode1 is +NULL to have consistent lock class usage. However, we know that at least +for vfs_rename() that @inode1 is @source and thus is never NULL as per +above. We also know that @source is a different inode than @target as +that is checked right at the beginning of vfs_rename(). So we know that +@source is valid and locked and that @target is locked. So drop the +check whether @source is non-NULL. + +Fixes: 28eceeda130f ("fs: Lock moved directories") +Reported-by: kernel test robot +Reported-by: Dan Carpenter +Closes: https://lore.kernel.org/r/202307030026.9sE2pk2x-lkp@intel.com +Message-id: <20230703-vfs-rename-source-v1-1-37eebb29b65b@kernel.org> +[brauner: use commit message from patch I sent concurrently] +Signed-off-by: Christian Brauner +Acked-by: Jan Kara + +--- + fs/namei.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/fs/namei.c b/fs/namei.c +index 91171da719c5..e56ff39a79bc 100644 +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -4874,8 +4874,7 @@ int vfs_rename(struct renamedata *rd) + d_exchange(old_dentry, new_dentry); + } + out: +- if (source) +- inode_unlock(source); ++ inode_unlock(source); + if (target) + inode_unlock(target); + dput(new_dentry); +-- +2.35.3 + diff --git a/patches.suse/fs-ocfs2-check-status-values.patch b/patches.suse/fs-ocfs2-check-status-values.patch new file mode 100644 index 0000000..27317a7 --- /dev/null +++ b/patches.suse/fs-ocfs2-check-status-values.patch @@ -0,0 +1,73 @@ +From 1b13a7030504da9d379270675166342e7039817c Mon Sep 17 00:00:00 2001 +From: Artem Chernyshev +Date: Mon, 9 Oct 2023 17:11:11 +0300 +Subject: [PATCH] fs: ocfs2: check status values +Git-commit: 1b13a7030504da9d379270675166342e7039817c +Patch-mainline: v6.7-rc1 +References: bsc#1221044 CVE-2023-52591 + +Test return values before overwriting. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Link: https://lkml.kernel.org/r/20231009141111.149858-1-artem.chernyshev@red-soft.ru +Signed-off-by: Artem Chernyshev +Reviewed-by: Joseph Qi +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Junxiao Bi +Cc: Changwei Ge +Cc: Gang He +Cc: Jun Piao +Signed-off-by: Andrew Morton +Acked-by: Jan Kara + +--- + fs/ocfs2/namei.c | 8 ++++++++ + fs/ocfs2/quota_local.c | 4 ++++ + 2 files changed, 12 insertions(+) + +diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c +index 5cd6d7771cea..836c4279a979 100644 +--- a/fs/ocfs2/namei.c ++++ b/fs/ocfs2/namei.c +@@ -1597,6 +1597,10 @@ static int ocfs2_rename(struct mnt_idmap *idmap, + if (update_dot_dot) { + status = ocfs2_update_entry(old_inode, handle, + &old_inode_dot_dot_res, new_dir); ++ if (status < 0) { ++ mlog_errno(status); ++ goto bail; ++ } + drop_nlink(old_dir); + if (new_inode) { + drop_nlink(new_inode); +@@ -1636,6 +1640,10 @@ static int ocfs2_rename(struct mnt_idmap *idmap, + INODE_CACHE(old_dir), + old_dir_bh, + OCFS2_JOURNAL_ACCESS_WRITE); ++ if (status < 0) { ++ mlog_errno(status); ++ goto bail; ++ } + fe = (struct ocfs2_dinode *) old_dir_bh->b_data; + ocfs2_set_links_count(fe, old_dir->i_nlink); + ocfs2_journal_dirty(handle, old_dir_bh); +diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c +index dfaae1e52412..e09842fc9d4d 100644 +--- a/fs/ocfs2/quota_local.c ++++ b/fs/ocfs2/quota_local.c +@@ -1240,6 +1240,10 @@ int ocfs2_create_local_dquot(struct dquot *dquot) + &od->dq_local_phys_blk, + &pcount, + NULL); ++ if (status < 0) { ++ mlog_errno(status); ++ goto out; ++ } + + /* Initialize dquot structure on disk */ + status = ocfs2_local_write_dquot(dquot); +-- +2.35.3 + diff --git a/patches.suse/gve-Add-NULL-pointer-checks-when-freeing-irqs.patch b/patches.suse/gve-Add-NULL-pointer-checks-when-freeing-irqs.patch index 8c34796..18bac7a 100644 --- a/patches.suse/gve-Add-NULL-pointer-checks-when-freeing-irqs.patch +++ b/patches.suse/gve-Add-NULL-pointer-checks-when-freeing-irqs.patch @@ -3,7 +3,7 @@ Date: Mon, 17 May 2021 14:08:13 -0700 Subject: gve: Add NULL pointer checks when freeing irqs. Patch-mainline: v5.13-rc4 Git-commit: 5218e919c8d06279884aa0baf76778a6817d5b93 -References: bsc#1176940 +References: bsc#1176940 CVE-2021-47141 bsc#1221949 When freeing notification blocks, we index priv->msix_vectors. If we failed to allocate priv->msix_vectors (see abort_with_msix_vectors) diff --git a/patches.suse/i2c-i801-Don-t-generate-an-interrupt-on-bus-reset.patch b/patches.suse/i2c-i801-Don-t-generate-an-interrupt-on-bus-reset.patch index 79dea11..5a69e4a 100644 --- a/patches.suse/i2c-i801-Don-t-generate-an-interrupt-on-bus-reset.patch +++ b/patches.suse/i2c-i801-Don-t-generate-an-interrupt-on-bus-reset.patch @@ -4,7 +4,7 @@ Date: Tue, 25 May 2021 17:03:36 +0200 Subject: [PATCH] i2c: i801: Don't generate an interrupt on bus reset Git-commit: e4d8716c3dcec47f1557024add24e1f3c09eb24b Patch-mainline: v5.13-rc4 -References: git-fixes +References: git-fixes CVE-2021-47153 bsc#1221969 Now that the i2c-i801 driver supports interrupts, setting the KILL bit in a attempt to recover from a timed out transaction triggers an diff --git a/patches.suse/iommu-vt-d-fix-sysfs-leak-in-alloc_iommu b/patches.suse/iommu-vt-d-fix-sysfs-leak-in-alloc_iommu index 80432bf..4b52ddf 100644 --- a/patches.suse/iommu-vt-d-fix-sysfs-leak-in-alloc_iommu +++ b/patches.suse/iommu-vt-d-fix-sysfs-leak-in-alloc_iommu @@ -3,7 +3,7 @@ Date: Tue, 25 May 2021 15:08:02 +0800 Subject: iommu/vt-d: Fix sysfs leak in alloc_iommu() Git-commit: 0ee74d5a48635c848c20f152d0d488bf84641304 Patch-mainline: v5.13-rc4 -References: bsc#1189272 +References: bsc#1189272 CVE-2021-47177 bsc#1221997 iommu_device_sysfs_add() is called before, so is has to be cleaned on subsequent errors. diff --git a/patches.suse/ipmi-Fix-UAF-when-uninstall-ipmi_si-and-ipmi_msghand.patch b/patches.suse/ipmi-Fix-UAF-when-uninstall-ipmi_si-and-ipmi_msghand.patch index 441bfc7..aa881d3 100644 --- a/patches.suse/ipmi-Fix-UAF-when-uninstall-ipmi_si-and-ipmi_msghand.patch +++ b/patches.suse/ipmi-Fix-UAF-when-uninstall-ipmi_si-and-ipmi_msghand.patch @@ -4,7 +4,7 @@ Date: Tue, 21 Dec 2021 15:00:34 +0800 Subject: [PATCH] ipmi: Fix UAF when uninstall ipmi_si and ipmi_msghandler module Git-commit: ffb76a86f8096a8206be03b14adda6092e18e275 -References: git-fixes +References: git-fixes CVE-2021-47100 bsc#1220985 Patch-mainline: v5.16-rc7 Hi, diff --git a/patches.suse/ipv6-init-the-accept_queue-s-spinlocks-in-inet6_crea.patch b/patches.suse/ipv6-init-the-accept_queue-s-spinlocks-in-inet6_crea.patch new file mode 100644 index 0000000..6c8870c --- /dev/null +++ b/patches.suse/ipv6-init-the-accept_queue-s-spinlocks-in-inet6_crea.patch @@ -0,0 +1,63 @@ +From: Zhengchao Shao +Date: Mon, 22 Jan 2024 18:20:01 +0800 +Subject: ipv6: init the accept_queue's spinlocks in inet6_create +Patch-mainline: v6.8-rc2 +Git-commit: 435e202d645c197dcfd39d7372eb2a56529b6640 +References: bsc#1221293 CVE-2024-26614 + +In commit 198bc90e0e73("tcp: make sure init the accept_queue's spinlocks +once"), the spinlocks of accept_queue are initialized only when socket is +created in the inet4 scenario. The locks are not initialized when socket +is created in the inet6 scenario. The kernel reports the following error: +INFO: trying to register non-static key. +The code is fine but needs lockdep annotation, or maybe +you didn't initialize this object before use? +turning off the locking correctness validator. +Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 +Call Trace: + + dump_stack_lvl (lib/dump_stack.c:107) + register_lock_class (kernel/locking/lockdep.c:1289) + __lock_acquire (kernel/locking/lockdep.c:5015) + lock_acquire.part.0 (kernel/locking/lockdep.c:5756) + _raw_spin_lock_bh (kernel/locking/spinlock.c:178) + inet_csk_listen_stop (net/ipv4/inet_connection_sock.c:1386) + tcp_disconnect (net/ipv4/tcp.c:2981) + inet_shutdown (net/ipv4/af_inet.c:935) + __sys_shutdown (./include/linux/file.h:32 net/socket.c:2438) + __x64_sys_shutdown (net/socket.c:2445) + do_syscall_64 (arch/x86/entry/common.c:52) + entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:129) +RIP: 0033:0x7f52ecd05a3d +Code: 5b 41 5c c3 66 0f 1f 84 00 00 00 00 00 f3 0f 1e fa 48 89 f8 48 89 f7 +48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff +ff 73 01 c3 48 8b 0d ab a3 0e 00 f7 d8 64 89 01 48 +RSP: 002b:00007f52ecf5dde8 EFLAGS: 00000293 ORIG_RAX: 0000000000000030 +RAX: ffffffffffffffda RBX: 00007f52ecf5e640 RCX: 00007f52ecd05a3d +RDX: 00007f52ecc8b188 RSI: 0000000000000000 RDI: 0000000000000004 +RBP: 00007f52ecf5de20 R08: 00007ffdae45c69f R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000293 R12: 00007f52ecf5e640 +R13: 0000000000000000 R14: 00007f52ecc8b060 R15: 00007ffdae45c6e0 + +Fixes: 198bc90e0e73 ("tcp: make sure init the accept_queue's spinlocks once") +Signed-off-by: Zhengchao Shao +Reviewed-by: Eric Dumazet +Link: https://lore.kernel.org/r/20240122102001.2851701-1-shaozhengchao@huawei.com +Signed-off-by: Paolo Abeni +Acked-by: Thomas Bogendoerfer +--- + net/ipv6/af_inet6.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/ipv6/af_inet6.c ++++ b/net/ipv6/af_inet6.c +@@ -190,6 +190,9 @@ lookup_protocol: + if (INET_PROTOSW_REUSE & answer_flags) + sk->sk_reuse = SK_CAN_REUSE; + ++ if (INET_PROTOSW_ICSK & answer_flags) ++ inet_init_csk_locks(sk); ++ + inet = inet_sk(sk); + inet->is_icsk = (INET_PROTOSW_ICSK & answer_flags) != 0; + diff --git a/patches.suse/kill-lock_two_inodes.patch b/patches.suse/kill-lock_two_inodes.patch new file mode 100644 index 0000000..05cf050 --- /dev/null +++ b/patches.suse/kill-lock_two_inodes.patch @@ -0,0 +1,97 @@ +From dbd4540df2b2857a91593754275c02f3e415fc30 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Sun, 19 Nov 2023 22:21:00 -0500 +Subject: [PATCH] kill lock_two_inodes() +Git-commit: dbd4540df2b2857a91593754275c02f3e415fc30 +Patch-mainline: v6.8-rc1 +References: bsc#1221044 CVE-2023-52591 + +There's only one caller left (lock_two_nondirectories()), and it +needs less complexity. Fold lock_two_inodes() in there and +simplify. + +Reviewed-by: Jan Kara +Signed-off-by: Al Viro +Acked-by: Jan Kara + +--- + fs/inode.c | 49 ++++++------------------------------------------- + fs/internal.h | 2 -- + 2 files changed, 6 insertions(+), 45 deletions(-) + +--- a/fs/inode.c ++++ b/fs/inode.c +@@ -973,48 +973,6 @@ void unlock_new_inode(struct inode *inod + EXPORT_SYMBOL(unlock_new_inode); + + /** +- * lock_two_inodes - lock two inodes (may be regular files but also dirs) +- * +- * Lock any non-NULL argument. The caller must make sure that if he is passing +- * in two directories, one is not ancestor of the other. Zero, one or two +- * objects may be locked by this function. +- * +- * @inode1: first inode to lock +- * @inode2: second inode to lock +- * @subclass1: inode lock subclass for the first lock obtained +- * @subclass2: inode lock subclass for the second lock obtained +- */ +-void lock_two_inodes(struct inode *inode1, struct inode *inode2, +- unsigned subclass1, unsigned subclass2) +-{ +- if (!inode1 || !inode2) { +- /* +- * Make sure @subclass1 will be used for the acquired lock. +- * This is not strictly necessary (no current caller cares) but +- * let's keep things consistent. +- */ +- if (!inode1) +- swap(inode1, inode2); +- goto lock; +- } +- +- /* +- * If one object is directory and the other is not, we must make sure +- * to lock directory first as the other object may be its child. +- */ +- if (S_ISDIR(inode2->i_mode) == S_ISDIR(inode1->i_mode)) { +- if (inode1 > inode2) +- swap(inode1, inode2); +- } else if (!S_ISDIR(inode1->i_mode)) +- swap(inode1, inode2); +-lock: +- if (inode1) +- inode_lock_nested(inode1, subclass1); +- if (inode2 && inode2 != inode1) +- inode_lock_nested(inode2, subclass2); +-} +- +-/** + * lock_two_nondirectories - take two i_mutexes on non-directory objects + * + * Lock any non-NULL argument. Passed objects must not be directories. +@@ -1029,7 +987,12 @@ void lock_two_nondirectories(struct inod + WARN_ON_ONCE(S_ISDIR(inode1->i_mode)); + if (inode2) + WARN_ON_ONCE(S_ISDIR(inode2->i_mode)); +- lock_two_inodes(inode1, inode2, I_MUTEX_NORMAL, I_MUTEX_NONDIR2); ++ if (inode1 > inode2) ++ swap(inode1, inode2); ++ if (inode1) ++ inode_lock(inode1); ++ if (inode2 && inode2 != inode1) ++ inode_lock_nested(inode2, I_MUTEX_NONDIR2); + } + EXPORT_SYMBOL(lock_two_nondirectories); + +--- a/fs/internal.h ++++ b/fs/internal.h +@@ -117,8 +117,6 @@ extern int vfs_open(const struct path *, + extern long prune_icache_sb(struct super_block *sb, struct shrink_control *sc); + extern void inode_add_lru(struct inode *inode); + extern int dentry_needs_remove_privs(struct dentry *dentry); +-void lock_two_inodes(struct inode *inode1, struct inode *inode2, +- unsigned subclass1, unsigned subclass2); + + extern bool __atime_needs_update(const struct path *, struct inode *, bool); + static inline bool atime_needs_update_rcu(const struct path *path, diff --git a/patches.suse/kvm-destroy-i-o-bus-devices-on-unregister-failure-after_-sync-ing-srcu b/patches.suse/kvm-destroy-i-o-bus-devices-on-unregister-failure-after_-sync-ing-srcu index a593e10..edf5dbb 100644 --- a/patches.suse/kvm-destroy-i-o-bus-devices-on-unregister-failure-after_-sync-ing-srcu +++ b/patches.suse/kvm-destroy-i-o-bus-devices-on-unregister-failure-after_-sync-ing-srcu @@ -4,7 +4,7 @@ Subject: KVM: Destroy I/O bus devices on unregister failure _after_ sync'ing SRCU Git-commit: 2ee3757424be7c1cd1d0bbfa6db29a7edd82a250 Patch-mainline: v5.13-rc1 -References: CVE-2020-36312 bsc#1184509 +References: CVE-2020-36312 bsc#1184509 CVE-2021-47061 bsc#1220745 If allocating a new instance of an I/O bus fails when unregistering a device, wait to destroy the device until after all readers are guaranteed diff --git a/patches.suse/kvm-stop-looking-for-coalesced-mmio-zones-if-the-bus-is-destroyed b/patches.suse/kvm-stop-looking-for-coalesced-mmio-zones-if-the-bus-is-destroyed index 927c70f..9143604 100644 --- a/patches.suse/kvm-stop-looking-for-coalesced-mmio-zones-if-the-bus-is-destroyed +++ b/patches.suse/kvm-stop-looking-for-coalesced-mmio-zones-if-the-bus-is-destroyed @@ -3,7 +3,7 @@ Date: Mon, 12 Apr 2021 15:20:49 -0700 Subject: KVM: Stop looking for coalesced MMIO zones if the bus is destroyed Git-commit: 5d3c4c79384af06e3c8e25b7770b6247496b4417 Patch-mainline: v5.13-rc1 -References: CVE-2020-36312 bsc#1184509 +References: CVE-2020-36312 bsc#1184509 CVE-2021-47060 bsc#1220742 Abort the walk of coalesced MMIO zones if kvm_io_bus_unregister_dev() fails to allocate memory for the new instance of the bus. If it can't diff --git a/patches.suse/lan78xx-Add-missing-return-code-checks.patch b/patches.suse/lan78xx-Add-missing-return-code-checks.patch new file mode 100644 index 0000000..d995d1f --- /dev/null +++ b/patches.suse/lan78xx-Add-missing-return-code-checks.patch @@ -0,0 +1,775 @@ +From 3415f6baaddb9b39d7112247ab39ef3c700f882e Mon Sep 17 00:00:00 2001 +From: John Efstathiades +Date: Tue, 24 Aug 2021 19:56:08 +0100 +Subject: [PATCH] lan78xx: Add missing return code checks +Git-commit: 3415f6baaddb9b39d7112247ab39ef3c700f882e +References: git-fixes +Patch-mainline: v5.15-rc1 + +There are many places in the driver where the return code from a +function call is captured but without a subsequent test of the +return code and appropriate action taken. + +This patch adds the missing return code tests and action. In most +cases the action is an early exit from the calling function. + +The function lan78xx_set_suspend() was also updated to make it +consistent with lan78xx_suspend(). + +Signed-off-by: John Efstathiades +Signed-off-by: David S. Miller +Signed-off-by: Oliver Neukum + +--- + drivers/net/usb/lan78xx.c | 399 +++++++++++++++++++++++++++++++------- + 1 file changed, 333 insertions(+), 66 deletions(-) + +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index 746aeeaa9d6e..1909d6003453 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -1173,7 +1173,7 @@ static int lan78xx_link_reset(struct lan78xx_net *dev) + /* clear LAN78xx interrupt status */ + ret = lan78xx_write_reg(dev, INT_STS, INT_STS_PHY_INT_); + if (unlikely(ret < 0)) +- return -EIO; ++ return ret; + + mutex_lock(&phydev->lock); + phy_read_status(phydev); +@@ -1186,11 +1186,11 @@ static int lan78xx_link_reset(struct lan78xx_net *dev) + /* reset MAC */ + ret = lan78xx_read_reg(dev, MAC_CR, &buf); + if (unlikely(ret < 0)) +- return -EIO; ++ return ret; + buf |= MAC_CR_RST_; + ret = lan78xx_write_reg(dev, MAC_CR, buf); + if (unlikely(ret < 0)) +- return -EIO; ++ return ret; + + del_timer(&dev->stat_monitor); + } else if (link && !dev->link_on) { +@@ -1202,18 +1202,30 @@ static int lan78xx_link_reset(struct lan78xx_net *dev) + if (ecmd.base.speed == 1000) { + /* disable U2 */ + ret = lan78xx_read_reg(dev, USB_CFG1, &buf); ++ if (ret < 0) ++ return ret; + buf &= ~USB_CFG1_DEV_U2_INIT_EN_; + ret = lan78xx_write_reg(dev, USB_CFG1, buf); ++ if (ret < 0) ++ return ret; + /* enable U1 */ + ret = lan78xx_read_reg(dev, USB_CFG1, &buf); ++ if (ret < 0) ++ return ret; + buf |= USB_CFG1_DEV_U1_INIT_EN_; + ret = lan78xx_write_reg(dev, USB_CFG1, buf); ++ if (ret < 0) ++ return ret; + } else { + /* enable U1 & U2 */ + ret = lan78xx_read_reg(dev, USB_CFG1, &buf); ++ if (ret < 0) ++ return ret; + buf |= USB_CFG1_DEV_U2_INIT_EN_; + buf |= USB_CFG1_DEV_U1_INIT_EN_; + ret = lan78xx_write_reg(dev, USB_CFG1, buf); ++ if (ret < 0) ++ return ret; + } + } + +@@ -1231,6 +1243,8 @@ static int lan78xx_link_reset(struct lan78xx_net *dev) + + ret = lan78xx_update_flowcontrol(dev, ecmd.base.duplex, ladv, + radv); ++ if (ret < 0) ++ return ret; + + if (!timer_pending(&dev->stat_monitor)) { + dev->delta = 1; +@@ -1241,7 +1255,7 @@ static int lan78xx_link_reset(struct lan78xx_net *dev) + tasklet_schedule(&dev->bh); + } + +- return ret; ++ return 0; + } + + /* some work can't be done in tasklets, so we use keventd +@@ -2460,23 +2474,33 @@ static void lan78xx_init_ltm(struct lan78xx_net *dev) + static int lan78xx_reset(struct lan78xx_net *dev) + { + struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]); +- u32 buf; +- int ret = 0; + unsigned long timeout; ++ int ret; ++ u32 buf; + u8 sig; + + ret = lan78xx_read_reg(dev, HW_CFG, &buf); ++ if (ret < 0) ++ return ret; ++ + buf |= HW_CFG_LRST_; ++ + ret = lan78xx_write_reg(dev, HW_CFG, buf); ++ if (ret < 0) ++ return ret; + + timeout = jiffies + HZ; + do { + mdelay(1); + ret = lan78xx_read_reg(dev, HW_CFG, &buf); ++ if (ret < 0) ++ return ret; ++ + if (time_after(jiffies, timeout)) { + netdev_warn(dev->net, + "timeout on completion of LiteReset"); +- return -EIO; ++ ret = -ETIMEDOUT; ++ return ret; + } + } while (buf & HW_CFG_LRST_); + +@@ -2484,13 +2508,22 @@ static int lan78xx_reset(struct lan78xx_net *dev) + + /* save DEVID for later usage */ + ret = lan78xx_read_reg(dev, ID_REV, &buf); ++ if (ret < 0) ++ return ret; ++ + dev->chipid = (buf & ID_REV_CHIP_ID_MASK_) >> 16; + dev->chiprev = buf & ID_REV_CHIP_REV_MASK_; + + /* Respond to the IN token with a NAK */ + ret = lan78xx_read_reg(dev, USB_CFG0, &buf); ++ if (ret < 0) ++ return ret; ++ + buf |= USB_CFG_BIR_; ++ + ret = lan78xx_write_reg(dev, USB_CFG0, buf); ++ if (ret < 0) ++ return ret; + + /* Init LTM */ + lan78xx_init_ltm(dev); +@@ -2513,53 +2546,105 @@ static int lan78xx_reset(struct lan78xx_net *dev) + } + + ret = lan78xx_write_reg(dev, BURST_CAP, buf); ++ if (ret < 0) ++ return ret; ++ + ret = lan78xx_write_reg(dev, BULK_IN_DLY, DEFAULT_BULK_IN_DELAY); ++ if (ret < 0) ++ return ret; + + ret = lan78xx_read_reg(dev, HW_CFG, &buf); ++ if (ret < 0) ++ return ret; ++ + buf |= HW_CFG_MEF_; ++ + ret = lan78xx_write_reg(dev, HW_CFG, buf); ++ if (ret < 0) ++ return ret; + + ret = lan78xx_read_reg(dev, USB_CFG0, &buf); ++ if (ret < 0) ++ return ret; ++ + buf |= USB_CFG_BCE_; ++ + ret = lan78xx_write_reg(dev, USB_CFG0, buf); ++ if (ret < 0) ++ return ret; + + /* set FIFO sizes */ + buf = (MAX_RX_FIFO_SIZE - 512) / 512; ++ + ret = lan78xx_write_reg(dev, FCT_RX_FIFO_END, buf); ++ if (ret < 0) ++ return ret; + + buf = (MAX_TX_FIFO_SIZE - 512) / 512; ++ + ret = lan78xx_write_reg(dev, FCT_TX_FIFO_END, buf); ++ if (ret < 0) ++ return ret; + + ret = lan78xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL_); ++ if (ret < 0) ++ return ret; ++ + ret = lan78xx_write_reg(dev, FLOW, 0); ++ if (ret < 0) ++ return ret; ++ + ret = lan78xx_write_reg(dev, FCT_FLOW, 0); ++ if (ret < 0) ++ return ret; + + /* Don't need rfe_ctl_lock during initialisation */ + ret = lan78xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl); ++ if (ret < 0) ++ return ret; ++ + pdata->rfe_ctl |= RFE_CTL_BCAST_EN_ | RFE_CTL_DA_PERFECT_; ++ + ret = lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); ++ if (ret < 0) ++ return ret; + + /* Enable or disable checksum offload engines */ +- lan78xx_set_features(dev->net, dev->net->features); ++ ret = lan78xx_set_features(dev->net, dev->net->features); ++ if (ret < 0) ++ return ret; + + lan78xx_set_multicast(dev->net); + + /* reset PHY */ + ret = lan78xx_read_reg(dev, PMT_CTL, &buf); ++ if (ret < 0) ++ return ret; ++ + buf |= PMT_CTL_PHY_RST_; ++ + ret = lan78xx_write_reg(dev, PMT_CTL, buf); ++ if (ret < 0) ++ return ret; + + timeout = jiffies + HZ; + do { + mdelay(1); + ret = lan78xx_read_reg(dev, PMT_CTL, &buf); ++ if (ret < 0) ++ return ret; ++ + if (time_after(jiffies, timeout)) { + netdev_warn(dev->net, "timeout waiting for PHY Reset"); +- return -EIO; ++ ret = -ETIMEDOUT; ++ return ret; + } + } while ((buf & PMT_CTL_PHY_RST_) || !(buf & PMT_CTL_READY_)); + + ret = lan78xx_read_reg(dev, MAC_CR, &buf); ++ if (ret < 0) ++ return ret; ++ + /* LAN7801 only has RGMII mode */ + if (dev->chipid == ID_REV_CHIP_ID_7801_) + buf &= ~MAC_CR_GMII_EN_; +@@ -2573,25 +2658,53 @@ static int lan78xx_reset(struct lan78xx_net *dev) + } + } + ret = lan78xx_write_reg(dev, MAC_CR, buf); ++ if (ret < 0) ++ return ret; + + ret = lan78xx_read_reg(dev, MAC_TX, &buf); ++ if (ret < 0) ++ return ret; ++ + buf |= MAC_TX_TXEN_; ++ + ret = lan78xx_write_reg(dev, MAC_TX, buf); ++ if (ret < 0) ++ return ret; + + ret = lan78xx_read_reg(dev, FCT_TX_CTL, &buf); ++ if (ret < 0) ++ return ret; ++ + buf |= FCT_TX_CTL_EN_; ++ + ret = lan78xx_write_reg(dev, FCT_TX_CTL, buf); ++ if (ret < 0) ++ return ret; + + ret = lan78xx_set_rx_max_frame_length(dev, + dev->net->mtu + VLAN_ETH_HLEN); ++ if (ret < 0) ++ return ret; + + ret = lan78xx_read_reg(dev, MAC_RX, &buf); ++ if (ret < 0) ++ return ret; ++ + buf |= MAC_RX_RXEN_; ++ + ret = lan78xx_write_reg(dev, MAC_RX, buf); ++ if (ret < 0) ++ return ret; + + ret = lan78xx_read_reg(dev, FCT_RX_CTL, &buf); ++ if (ret < 0) ++ return ret; ++ + buf |= FCT_RX_CTL_EN_; ++ + ret = lan78xx_write_reg(dev, FCT_RX_CTL, buf); ++ if (ret < 0) ++ return ret; + + return 0; + } +@@ -2629,7 +2742,7 @@ static int lan78xx_open(struct net_device *net) + + ret = usb_autopm_get_interface(dev->intf); + if (ret < 0) +- goto out; ++ return ret; + + phy_start(net->phydev); + +@@ -2657,7 +2770,6 @@ static int lan78xx_open(struct net_device *net) + done: + usb_autopm_put_interface(dev->intf); + +-out: + return ret; + } + +@@ -3806,35 +3918,62 @@ static u16 lan78xx_wakeframe_crc16(const u8 *buf, int len) + + static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) + { +- u32 buf; +- int mask_index; +- u16 crc; +- u32 temp_wucsr; +- u32 temp_pmt_ctl; + const u8 ipv4_multicast[3] = { 0x01, 0x00, 0x5E }; + const u8 ipv6_multicast[3] = { 0x33, 0x33 }; + const u8 arp_type[2] = { 0x08, 0x06 }; ++ u32 temp_pmt_ctl; ++ int mask_index; ++ u32 temp_wucsr; ++ u32 buf; ++ u16 crc; ++ int ret; ++ ++ ret = lan78xx_read_reg(dev, MAC_TX, &buf); ++ if (ret < 0) ++ return ret; + +- lan78xx_read_reg(dev, MAC_TX, &buf); + buf &= ~MAC_TX_TXEN_; +- lan78xx_write_reg(dev, MAC_TX, buf); +- lan78xx_read_reg(dev, MAC_RX, &buf); ++ ++ ret = lan78xx_write_reg(dev, MAC_TX, buf); ++ if (ret < 0) ++ return ret; ++ ++ ret = lan78xx_read_reg(dev, MAC_RX, &buf); ++ if (ret < 0) ++ return ret; ++ + buf &= ~MAC_RX_RXEN_; +- lan78xx_write_reg(dev, MAC_RX, buf); + +- lan78xx_write_reg(dev, WUCSR, 0); +- lan78xx_write_reg(dev, WUCSR2, 0); +- lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL); ++ ret = lan78xx_write_reg(dev, MAC_RX, buf); ++ if (ret < 0) ++ return ret; ++ ++ ret = lan78xx_write_reg(dev, WUCSR, 0); ++ if (ret < 0) ++ return ret; ++ ret = lan78xx_write_reg(dev, WUCSR2, 0); ++ if (ret < 0) ++ return ret; ++ ret = lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL); ++ if (ret < 0) ++ return ret; + + temp_wucsr = 0; + + temp_pmt_ctl = 0; +- lan78xx_read_reg(dev, PMT_CTL, &temp_pmt_ctl); ++ ++ ret = lan78xx_read_reg(dev, PMT_CTL, &temp_pmt_ctl); ++ if (ret < 0) ++ return ret; ++ + temp_pmt_ctl &= ~PMT_CTL_RES_CLR_WKP_EN_; + temp_pmt_ctl |= PMT_CTL_RES_CLR_WKP_STS_; + +- for (mask_index = 0; mask_index < NUM_OF_WUF_CFG; mask_index++) +- lan78xx_write_reg(dev, WUF_CFG(mask_index), 0); ++ for (mask_index = 0; mask_index < NUM_OF_WUF_CFG; mask_index++) { ++ ret = lan78xx_write_reg(dev, WUF_CFG(mask_index), 0); ++ if (ret < 0) ++ return ret; ++ } + + mask_index = 0; + if (wol & WAKE_PHY) { +@@ -3863,30 +4002,52 @@ static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) + + /* set WUF_CFG & WUF_MASK for IPv4 Multicast */ + crc = lan78xx_wakeframe_crc16(ipv4_multicast, 3); +- lan78xx_write_reg(dev, WUF_CFG(mask_index), +- WUF_CFGX_EN_ | +- WUF_CFGX_TYPE_MCAST_ | +- (0 << WUF_CFGX_OFFSET_SHIFT_) | +- (crc & WUF_CFGX_CRC16_MASK_)); +- +- lan78xx_write_reg(dev, WUF_MASK0(mask_index), 7); +- lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); +- lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); +- lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); ++ ret = lan78xx_write_reg(dev, WUF_CFG(mask_index), ++ WUF_CFGX_EN_ | ++ WUF_CFGX_TYPE_MCAST_ | ++ (0 << WUF_CFGX_OFFSET_SHIFT_) | ++ (crc & WUF_CFGX_CRC16_MASK_)); ++ if (ret < 0) ++ return ret; ++ ++ ret = lan78xx_write_reg(dev, WUF_MASK0(mask_index), 7); ++ if (ret < 0) ++ return ret; ++ ret = lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); ++ if (ret < 0) ++ return ret; ++ ret = lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); ++ if (ret < 0) ++ return ret; ++ ret = lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); ++ if (ret < 0) ++ return ret; ++ + mask_index++; + + /* for IPv6 Multicast */ + crc = lan78xx_wakeframe_crc16(ipv6_multicast, 2); +- lan78xx_write_reg(dev, WUF_CFG(mask_index), +- WUF_CFGX_EN_ | +- WUF_CFGX_TYPE_MCAST_ | +- (0 << WUF_CFGX_OFFSET_SHIFT_) | +- (crc & WUF_CFGX_CRC16_MASK_)); +- +- lan78xx_write_reg(dev, WUF_MASK0(mask_index), 3); +- lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); +- lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); +- lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); ++ ret = lan78xx_write_reg(dev, WUF_CFG(mask_index), ++ WUF_CFGX_EN_ | ++ WUF_CFGX_TYPE_MCAST_ | ++ (0 << WUF_CFGX_OFFSET_SHIFT_) | ++ (crc & WUF_CFGX_CRC16_MASK_)); ++ if (ret < 0) ++ return ret; ++ ++ ret = lan78xx_write_reg(dev, WUF_MASK0(mask_index), 3); ++ if (ret < 0) ++ return ret; ++ ret = lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); ++ if (ret < 0) ++ return ret; ++ ret = lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); ++ if (ret < 0) ++ return ret; ++ ret = lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); ++ if (ret < 0) ++ return ret; ++ + mask_index++; + + temp_pmt_ctl |= PMT_CTL_WOL_EN_; +@@ -3907,16 +4068,27 @@ static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) + * for packettype (offset 12,13) = ARP (0x0806) + */ + crc = lan78xx_wakeframe_crc16(arp_type, 2); +- lan78xx_write_reg(dev, WUF_CFG(mask_index), +- WUF_CFGX_EN_ | +- WUF_CFGX_TYPE_ALL_ | +- (0 << WUF_CFGX_OFFSET_SHIFT_) | +- (crc & WUF_CFGX_CRC16_MASK_)); +- +- lan78xx_write_reg(dev, WUF_MASK0(mask_index), 0x3000); +- lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); +- lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); +- lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); ++ ret = lan78xx_write_reg(dev, WUF_CFG(mask_index), ++ WUF_CFGX_EN_ | ++ WUF_CFGX_TYPE_ALL_ | ++ (0 << WUF_CFGX_OFFSET_SHIFT_) | ++ (crc & WUF_CFGX_CRC16_MASK_)); ++ if (ret < 0) ++ return ret; ++ ++ ret = lan78xx_write_reg(dev, WUF_MASK0(mask_index), 0x3000); ++ if (ret < 0) ++ return ret; ++ ret = lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); ++ if (ret < 0) ++ return ret; ++ ret = lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); ++ if (ret < 0) ++ return ret; ++ ret = lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); ++ if (ret < 0) ++ return ret; ++ + mask_index++; + + temp_pmt_ctl |= PMT_CTL_WOL_EN_; +@@ -3924,7 +4096,9 @@ static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) + temp_pmt_ctl |= PMT_CTL_SUS_MODE_0_; + } + +- lan78xx_write_reg(dev, WUCSR, temp_wucsr); ++ ret = lan78xx_write_reg(dev, WUCSR, temp_wucsr); ++ if (ret < 0) ++ return ret; + + /* when multiple WOL bits are set */ + if (hweight_long((unsigned long)wol) > 1) { +@@ -3932,16 +4106,30 @@ static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) + temp_pmt_ctl &= ~PMT_CTL_SUS_MODE_MASK_; + temp_pmt_ctl |= PMT_CTL_SUS_MODE_0_; + } +- lan78xx_write_reg(dev, PMT_CTL, temp_pmt_ctl); ++ ret = lan78xx_write_reg(dev, PMT_CTL, temp_pmt_ctl); ++ if (ret < 0) ++ return ret; + + /* clear WUPS */ +- lan78xx_read_reg(dev, PMT_CTL, &buf); ++ ret = lan78xx_read_reg(dev, PMT_CTL, &buf); ++ if (ret < 0) ++ return ret; ++ + buf |= PMT_CTL_WUPS_MASK_; +- lan78xx_write_reg(dev, PMT_CTL, buf); ++ ++ ret = lan78xx_write_reg(dev, PMT_CTL, buf); ++ if (ret < 0) ++ return ret; + + lan78xx_read_reg(dev, MAC_RX, &buf); ++ if (ret < 0) ++ return ret; ++ + buf |= MAC_RX_RXEN_; ++ + lan78xx_write_reg(dev, MAC_RX, buf); ++ if (ret < 0) ++ return ret; + + return 0; + } +@@ -3949,7 +4137,6 @@ static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) + static int lan78xx_suspend(struct usb_interface *intf, pm_message_t message) + { + struct lan78xx_net *dev = usb_get_intfdata(intf); +- struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]); + u32 buf; + int ret; + +@@ -3969,11 +4156,24 @@ static int lan78xx_suspend(struct usb_interface *intf, pm_message_t message) + + /* stop TX & RX */ + ret = lan78xx_read_reg(dev, MAC_TX, &buf); ++ if (ret < 0) ++ return ret; ++ + buf &= ~MAC_TX_TXEN_; ++ + ret = lan78xx_write_reg(dev, MAC_TX, buf); ++ if (ret < 0) ++ return ret; ++ + ret = lan78xx_read_reg(dev, MAC_RX, &buf); ++ if (ret < 0) ++ return ret; ++ + buf &= ~MAC_RX_RXEN_; ++ + ret = lan78xx_write_reg(dev, MAC_RX, buf); ++ if (ret < 0) ++ return ret; + + /* empty out the rx and queues */ + netif_device_detach(dev->net); +@@ -3990,25 +4190,50 @@ static int lan78xx_suspend(struct usb_interface *intf, pm_message_t message) + if (PMSG_IS_AUTO(message)) { + /* auto suspend (selective suspend) */ + ret = lan78xx_read_reg(dev, MAC_TX, &buf); ++ if (ret < 0) ++ return ret; ++ + buf &= ~MAC_TX_TXEN_; ++ + ret = lan78xx_write_reg(dev, MAC_TX, buf); ++ if (ret < 0) ++ return ret; ++ + ret = lan78xx_read_reg(dev, MAC_RX, &buf); ++ if (ret < 0) ++ return ret; ++ + buf &= ~MAC_RX_RXEN_; ++ + ret = lan78xx_write_reg(dev, MAC_RX, buf); ++ if (ret < 0) ++ return ret; + + ret = lan78xx_write_reg(dev, WUCSR, 0); ++ if (ret < 0) ++ return ret; + ret = lan78xx_write_reg(dev, WUCSR2, 0); ++ if (ret < 0) ++ return ret; + ret = lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL); ++ if (ret < 0) ++ return ret; + + /* set goodframe wakeup */ + ret = lan78xx_read_reg(dev, WUCSR, &buf); ++ if (ret < 0) ++ return ret; + + buf |= WUCSR_RFE_WAKE_EN_; + buf |= WUCSR_STORE_WAKE_; + + ret = lan78xx_write_reg(dev, WUCSR, buf); ++ if (ret < 0) ++ return ret; + + ret = lan78xx_read_reg(dev, PMT_CTL, &buf); ++ if (ret < 0) ++ return ret; + + buf &= ~PMT_CTL_RES_CLR_WKP_EN_; + buf |= PMT_CTL_RES_CLR_WKP_STS_; +@@ -4019,18 +4244,36 @@ static int lan78xx_suspend(struct usb_interface *intf, pm_message_t message) + buf |= PMT_CTL_SUS_MODE_3_; + + ret = lan78xx_write_reg(dev, PMT_CTL, buf); ++ if (ret < 0) ++ return ret; + + ret = lan78xx_read_reg(dev, PMT_CTL, &buf); ++ if (ret < 0) ++ return ret; + + buf |= PMT_CTL_WUPS_MASK_; + + ret = lan78xx_write_reg(dev, PMT_CTL, buf); ++ if (ret < 0) ++ return ret; + + ret = lan78xx_read_reg(dev, MAC_RX, &buf); ++ if (ret < 0) ++ return ret; ++ + buf |= MAC_RX_RXEN_; ++ + ret = lan78xx_write_reg(dev, MAC_RX, buf); ++ if (ret < 0) ++ return ret; + } else { +- lan78xx_set_suspend(dev, pdata->wol); ++ struct lan78xx_priv *pdata; ++ ++ pdata = (struct lan78xx_priv *)(dev->data[0]); ++ ++ ret = lan78xx_set_suspend(dev, pdata->wol); ++ if (ret < 0) ++ return ret; + } + } + +@@ -4055,8 +4298,11 @@ static int lan78xx_resume(struct usb_interface *intf) + + if (!--dev->suspend_count) { + /* resume interrupt URBs */ +- if (dev->urb_intr && test_bit(EVENT_DEV_OPEN, &dev->flags)) +- usb_submit_urb(dev->urb_intr, GFP_NOIO); ++ if (dev->urb_intr && test_bit(EVENT_DEV_OPEN, &dev->flags)) { ++ ret = usb_submit_urb(dev->urb_intr, GFP_NOIO); ++ if (ret < 0) ++ return ret; ++ } + + spin_lock_irq(&dev->txq.lock); + while ((res = usb_get_from_anchor(&dev->deferred))) { +@@ -4083,13 +4329,21 @@ static int lan78xx_resume(struct usb_interface *intf) + } + + ret = lan78xx_write_reg(dev, WUCSR2, 0); ++ if (ret < 0) ++ return ret; + ret = lan78xx_write_reg(dev, WUCSR, 0); ++ if (ret < 0) ++ return ret; + ret = lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL); ++ if (ret < 0) ++ return ret; + + ret = lan78xx_write_reg(dev, WUCSR2, WUCSR2_NS_RCD_ | + WUCSR2_ARP_RCD_ | + WUCSR2_IPV6_TCPSYN_RCD_ | + WUCSR2_IPV4_TCPSYN_RCD_); ++ if (ret < 0) ++ return ret; + + ret = lan78xx_write_reg(dev, WUCSR, WUCSR_EEE_TX_WAKE_ | + WUCSR_EEE_RX_WAKE_ | +@@ -4098,10 +4352,18 @@ static int lan78xx_resume(struct usb_interface *intf) + WUCSR_WUFR_ | + WUCSR_MPR_ | + WUCSR_BCST_FR_); ++ if (ret < 0) ++ return ret; + + ret = lan78xx_read_reg(dev, MAC_TX, &buf); ++ if (ret < 0) ++ return ret; ++ + buf |= MAC_TX_TXEN_; ++ + ret = lan78xx_write_reg(dev, MAC_TX, buf); ++ if (ret < 0) ++ return ret; + + return 0; + } +@@ -4109,12 +4371,17 @@ static int lan78xx_resume(struct usb_interface *intf) + static int lan78xx_reset_resume(struct usb_interface *intf) + { + struct lan78xx_net *dev = usb_get_intfdata(intf); ++ int ret; + +- lan78xx_reset(dev); ++ ret = lan78xx_reset(dev); ++ if (ret < 0) ++ return ret; + + phy_start(dev->net->phydev); + +- return lan78xx_resume(intf); ++ ret = lan78xx_resume(intf); ++ ++ return ret; + } + + static const struct usb_device_id products[] = { +-- +2.44.0 + diff --git a/patches.suse/lan78xx-Add-support-to-dump-lan78xx-registers.patch b/patches.suse/lan78xx-Add-support-to-dump-lan78xx-registers.patch new file mode 100644 index 0000000..3e511ae --- /dev/null +++ b/patches.suse/lan78xx-Add-support-to-dump-lan78xx-registers.patch @@ -0,0 +1,101 @@ +From 496218656f9857d801512efdec1d609ebbe8a83b Mon Sep 17 00:00:00 2001 +From: Raghuram Chary J +Date: Fri, 20 Apr 2018 11:43:50 +0530 +Subject: [PATCH] lan78xx: Add support to dump lan78xx registers +Git-commit: 496218656f9857d801512efdec1d609ebbe8a83b +References: git-fixes +Patch-mainline: v4.18-rc1 + +In order to dump lan78xx family registers using ethtool, add +support at lan78xx driver level. + +Signed-off-by: Raghuram Chary J +Signed-off-by: David S. Miller +Signed-off-by: Oliver Neukum + +--- + drivers/net/usb/lan78xx.c | 54 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 54 insertions(+) + +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index 6b03b973083e..c59f8afd0d73 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -280,6 +280,30 @@ struct lan78xx_statstage64 { + u64 eee_tx_lpi_time; + }; + ++static u32 lan78xx_regs[] = { ++ ID_REV, ++ INT_STS, ++ HW_CFG, ++ PMT_CTL, ++ E2P_CMD, ++ E2P_DATA, ++ USB_STATUS, ++ VLAN_TYPE, ++ MAC_CR, ++ MAC_RX, ++ MAC_TX, ++ FLOW, ++ ERR_STS, ++ MII_ACC, ++ MII_DATA, ++ EEE_TX_LPI_REQ_DLY, ++ EEE_TW_TX_SYS, ++ EEE_TX_LPI_REM_DLY, ++ WUCSR ++}; ++ ++#define PHY_REG_SIZE (32 * sizeof(u32)) ++ + struct lan78xx_net; + + struct lan78xx_priv { +@@ -1607,6 +1631,34 @@ static int lan78xx_set_pause(struct net_device *net, + return ret; + } + ++static int lan78xx_get_regs_len(struct net_device *netdev) ++{ ++ if (!netdev->phydev) ++ return (sizeof(lan78xx_regs)); ++ else ++ return (sizeof(lan78xx_regs) + PHY_REG_SIZE); ++} ++ ++static void ++lan78xx_get_regs(struct net_device *netdev, struct ethtool_regs *regs, ++ void *buf) ++{ ++ u32 *data = buf; ++ int i, j; ++ struct lan78xx_net *dev = netdev_priv(netdev); ++ ++ /* Read Device/MAC registers */ ++ for (i = 0; i < (sizeof(lan78xx_regs) / sizeof(u32)); i++) ++ lan78xx_read_reg(dev, lan78xx_regs[i], &data[i]); ++ ++ if (!netdev->phydev) ++ return; ++ ++ /* Read PHY registers */ ++ for (j = 0; j < 32; i++, j++) ++ data[i] = phy_read(netdev->phydev, j); ++} ++ + static const struct ethtool_ops lan78xx_ethtool_ops = { + .get_link = lan78xx_get_link, + .nway_reset = phy_ethtool_nway_reset, +@@ -1627,6 +1679,8 @@ static const struct ethtool_ops lan78xx_ethtool_ops = { + .set_pauseparam = lan78xx_set_pause, + .get_link_ksettings = lan78xx_get_link_ksettings, + .set_link_ksettings = lan78xx_set_link_ksettings, ++ .get_regs_len = lan78xx_get_regs_len, ++ .get_regs = lan78xx_get_regs, + }; + + static int lan78xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) +-- +2.44.0 + diff --git a/patches.suse/lan78xx-Do-not-access-skb_queue_head-list-pointers-d.patch b/patches.suse/lan78xx-Do-not-access-skb_queue_head-list-pointers-d.patch new file mode 100644 index 0000000..2f0f190 --- /dev/null +++ b/patches.suse/lan78xx-Do-not-access-skb_queue_head-list-pointers-d.patch @@ -0,0 +1,40 @@ +From e42a43a5cab2e019b5ab82bedb1340854709154d Mon Sep 17 00:00:00 2001 +From: "David S. Miller" +Date: Mon, 6 Aug 2018 23:12:17 -0700 +Subject: [PATCH] lan78xx: Do not access skb_queue_head list pointers directly. +Git-commit: e42a43a5cab2e019b5ab82bedb1340854709154d +References: git-fixes +Patch-mainline: v4.20-rc1 + +Use skb_queue_walk() instead. + +Adjust inner loop test to utilize and skb_queue_is_first(). +Unfortunately we have to keep pkt_cnt around because it is +used by a latter loop in this function. + +Signed-off-by: David S. Miller +Signed-off-by: Oliver Neukum + +--- + drivers/net/usb/lan78xx.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index 331bc99d55e7..3ce3c66559e4 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -3340,9 +3340,9 @@ static void lan78xx_tx_bh(struct lan78xx_net *dev) + count = 0; + length = 0; + spin_lock_irqsave(&tqp->lock, flags); +- for (skb = tqp->next; pkt_cnt < tqp->qlen; skb = skb->next) { ++ skb_queue_walk(tqp, skb) { + if (skb_is_gso(skb)) { +- if (pkt_cnt) { ++ if (!skb_queue_is_first(tqp, skb)) { + /* handle previous packets first */ + break; + } +-- +2.44.0 + diff --git a/patches.suse/lan78xx-Fix-exception-on-link-speed-change.patch b/patches.suse/lan78xx-Fix-exception-on-link-speed-change.patch new file mode 100644 index 0000000..164268c --- /dev/null +++ b/patches.suse/lan78xx-Fix-exception-on-link-speed-change.patch @@ -0,0 +1,96 @@ +From b1f6696daafebea243ed59ed18a8b10cfd33b474 Mon Sep 17 00:00:00 2001 +From: John Efstathiades +Date: Tue, 24 Aug 2021 19:56:09 +0100 +Subject: [PATCH] lan78xx: Fix exception on link speed change +Git-commit: b1f6696daafebea243ed59ed18a8b10cfd33b474 +References: git-fixes +Patch-mainline: v5.15-rc1 + +An exception is sometimes seen when the link speed is changed +from auto-negotiation to a fixed speed, or vice versa. The +exception occurs when the MAC is reset (due to the link speed +change) at the same time as the PHY state machine is accessing +a PHY register. The following changes fix this problem. + +Rework the MAC reset to ensure there is no outstanding MDIO +register transaction before the reset and then wait until the +reset is complete before allowing any further MAC register access. + +Signed-off-by: John Efstathiades +Signed-off-by: David S. Miller +Signed-off-by: Oliver Neukum + +--- + drivers/net/usb/lan78xx.c | 54 ++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 48 insertions(+), 6 deletions(-) + +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -1165,6 +1165,52 @@ static int lan78xx_update_flowcontrol(st + return 0; + } + ++static int lan78xx_mac_reset(struct lan78xx_net *dev) ++{ ++ unsigned long start_time = jiffies; ++ u32 val; ++ int ret; ++ ++ mutex_lock(&dev->phy_mutex); ++ ++ /* Resetting the device while there is activity on the MDIO ++ * bus can result in the MAC interface locking up and not ++ * completing register access transactions. ++ */ ++ ret = lan78xx_phy_wait_not_busy(dev); ++ if (ret < 0) ++ goto done; ++ ++ ret = lan78xx_read_reg(dev, MAC_CR, &val); ++ if (ret < 0) ++ goto done; ++ ++ val |= MAC_CR_RST_; ++ ret = lan78xx_write_reg(dev, MAC_CR, val); ++ if (ret < 0) ++ goto done; ++ ++ /* Wait for the reset to complete before allowing any further ++ * MAC register accesses otherwise the MAC may lock up. ++ */ ++ do { ++ ret = lan78xx_read_reg(dev, MAC_CR, &val); ++ if (ret < 0) ++ goto done; ++ ++ if (!(val & MAC_CR_RST_)) { ++ ret = 0; ++ goto done; ++ } ++ } while (!time_after(jiffies, start_time + HZ)); ++ ++ ret = -ETIMEDOUT; ++done: ++ mutex_unlock(&dev->phy_mutex); ++ ++ return ret; ++} ++ + static int lan78xx_link_reset(struct lan78xx_net *dev) + { + struct phy_device *phydev = dev->net->phydev; +@@ -1186,12 +1232,8 @@ static int lan78xx_link_reset(struct lan + dev->link_on = false; + + /* reset MAC */ +- ret = lan78xx_read_reg(dev, MAC_CR, &buf); +- if (unlikely(ret < 0)) +- return ret; +- buf |= MAC_CR_RST_; +- ret = lan78xx_write_reg(dev, MAC_CR, buf); +- if (unlikely(ret < 0)) ++ ret = lan78xx_mac_reset(dev); ++ if (ret < 0) + return ret; + + del_timer(&dev->stat_monitor); diff --git a/patches.suse/lan78xx-Fix-partial-packet-errors-on-suspend-resume.patch b/patches.suse/lan78xx-Fix-partial-packet-errors-on-suspend-resume.patch new file mode 100644 index 0000000..6447fa8 --- /dev/null +++ b/patches.suse/lan78xx-Fix-partial-packet-errors-on-suspend-resume.patch @@ -0,0 +1,454 @@ +From e1210fe63bf8b080edd0805240e90b81b6b069c1 Mon Sep 17 00:00:00 2001 +From: John Efstathiades +Date: Tue, 24 Aug 2021 19:56:10 +0100 +Subject: [PATCH] lan78xx: Fix partial packet errors on suspend/resume +Git-commit: e1210fe63bf8b080edd0805240e90b81b6b069c1 +References: git-fixes +Patch-mainline: v5.15-rc1 + +The MAC can get out of step with the internal packet FIFOs if the +system goes to sleep when the link is active, especially at high +data rates. This can result in partial frames in the packet FIFOs +that in result in malformed frames being delivered to the host. +This occurs because the driver does not enable/disable the internal +packet FIFOs in step with the corresponding MAC data path. The +following changes fix this problem. + +Update code that enables/disables the MAC receiver and transmitter +to the more general Rx and Tx data path, where the data path in each +direction consists of both the MAC function (Tx or Rx) and the +corresponding packet FIFO. + +In the receive path the packet FIFO must be enabled before the MAC +receiver but disabled after the MAC receiver. + +In the transmit path the opposite is true: the packet FIFO must be +enabled after the MAC transmitter but disabled before the MAC +transmitter. + +The packet FIFOs can be flushed safely once the corresponding data +path is stopped. + +Signed-off-by: John Efstathiades +Signed-off-by: David S. Miller +Signed-off-by: Oliver Neukum + +--- + drivers/net/usb/lan78xx.c | 303 +++++++++++++++++++++++++------------- + 1 file changed, 197 insertions(+), 106 deletions(-) + +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index 2eb853b13c2a..9170a786a24c 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -100,6 +100,12 @@ + /* statistic update interval (mSec) */ + #define STAT_UPDATE_TIMER (1 * 1000) + ++/* time to wait for MAC or FCT to stop (jiffies) */ ++#define HW_DISABLE_TIMEOUT (HZ / 10) ++ ++/* time to wait between polling MAC or FCT state (ms) */ ++#define HW_DISABLE_DELAY_MS 1 ++ + /* defines interrupts from interrupt EP */ + #define MAX_INT_EP (32) + #define INT_EP_INTEP (31) +@@ -487,6 +493,26 @@ static int lan78xx_write_reg(struct lan78xx_net *dev, u32 index, u32 data) + return ret; + } + ++static int lan78xx_update_reg(struct lan78xx_net *dev, u32 reg, u32 mask, ++ u32 data) ++{ ++ int ret; ++ u32 buf; ++ ++ ret = lan78xx_read_reg(dev, reg, &buf); ++ if (ret < 0) ++ return ret; ++ ++ buf &= ~mask; ++ buf |= (mask & data); ++ ++ ret = lan78xx_write_reg(dev, reg, buf); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ + static int lan78xx_read_stats(struct lan78xx_net *dev, + struct lan78xx_statstage *data) + { +@@ -2513,6 +2539,156 @@ static void lan78xx_init_ltm(struct lan78xx_net *dev) + lan78xx_write_reg(dev, LTM_INACTIVE1, regs[5]); + } + ++static int lan78xx_start_hw(struct lan78xx_net *dev, u32 reg, u32 hw_enable) ++{ ++ return lan78xx_update_reg(dev, reg, hw_enable, hw_enable); ++} ++ ++static int lan78xx_stop_hw(struct lan78xx_net *dev, u32 reg, u32 hw_enabled, ++ u32 hw_disabled) ++{ ++ unsigned long timeout; ++ bool stopped = true; ++ int ret; ++ u32 buf; ++ ++ /* Stop the h/w block (if not already stopped) */ ++ ++ ret = lan78xx_read_reg(dev, reg, &buf); ++ if (ret < 0) ++ return ret; ++ ++ if (buf & hw_enabled) { ++ buf &= ~hw_enabled; ++ ++ ret = lan78xx_write_reg(dev, reg, buf); ++ if (ret < 0) ++ return ret; ++ ++ stopped = false; ++ timeout = jiffies + HW_DISABLE_TIMEOUT; ++ do { ++ ret = lan78xx_read_reg(dev, reg, &buf); ++ if (ret < 0) ++ return ret; ++ ++ if (buf & hw_disabled) ++ stopped = true; ++ else ++ msleep(HW_DISABLE_DELAY_MS); ++ } while (!stopped && !time_after(jiffies, timeout)); ++ } ++ ++ ret = stopped ? 0 : -ETIME; ++ ++ return ret; ++} ++ ++static int lan78xx_flush_fifo(struct lan78xx_net *dev, u32 reg, u32 fifo_flush) ++{ ++ return lan78xx_update_reg(dev, reg, fifo_flush, fifo_flush); ++} ++ ++static int lan78xx_start_tx_path(struct lan78xx_net *dev) ++{ ++ int ret; ++ ++ netif_dbg(dev, drv, dev->net, "start tx path"); ++ ++ /* Start the MAC transmitter */ ++ ++ ret = lan78xx_start_hw(dev, MAC_TX, MAC_TX_TXEN_); ++ if (ret < 0) ++ return ret; ++ ++ /* Start the Tx FIFO */ ++ ++ ret = lan78xx_start_hw(dev, FCT_TX_CTL, FCT_TX_CTL_EN_); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++static int lan78xx_stop_tx_path(struct lan78xx_net *dev) ++{ ++ int ret; ++ ++ netif_dbg(dev, drv, dev->net, "stop tx path"); ++ ++ /* Stop the Tx FIFO */ ++ ++ ret = lan78xx_stop_hw(dev, FCT_TX_CTL, FCT_TX_CTL_EN_, FCT_TX_CTL_DIS_); ++ if (ret < 0) ++ return ret; ++ ++ /* Stop the MAC transmitter */ ++ ++ ret = lan78xx_stop_hw(dev, MAC_TX, MAC_TX_TXEN_, MAC_TX_TXD_); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++/* The caller must ensure the Tx path is stopped before calling ++ * lan78xx_flush_tx_fifo(). ++ */ ++static int lan78xx_flush_tx_fifo(struct lan78xx_net *dev) ++{ ++ return lan78xx_flush_fifo(dev, FCT_TX_CTL, FCT_TX_CTL_RST_); ++} ++ ++static int lan78xx_start_rx_path(struct lan78xx_net *dev) ++{ ++ int ret; ++ ++ netif_dbg(dev, drv, dev->net, "start rx path"); ++ ++ /* Start the Rx FIFO */ ++ ++ ret = lan78xx_start_hw(dev, FCT_RX_CTL, FCT_RX_CTL_EN_); ++ if (ret < 0) ++ return ret; ++ ++ /* Start the MAC receiver*/ ++ ++ ret = lan78xx_start_hw(dev, MAC_RX, MAC_RX_RXEN_); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++static int lan78xx_stop_rx_path(struct lan78xx_net *dev) ++{ ++ int ret; ++ ++ netif_dbg(dev, drv, dev->net, "stop rx path"); ++ ++ /* Stop the MAC receiver */ ++ ++ ret = lan78xx_stop_hw(dev, MAC_RX, MAC_RX_RXEN_, MAC_RX_RXD_); ++ if (ret < 0) ++ return ret; ++ ++ /* Stop the Rx FIFO */ ++ ++ ret = lan78xx_stop_hw(dev, FCT_RX_CTL, FCT_RX_CTL_EN_, FCT_RX_CTL_DIS_); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++/* The caller must ensure the Rx path is stopped before calling ++ * lan78xx_flush_rx_fifo(). ++ */ ++static int lan78xx_flush_rx_fifo(struct lan78xx_net *dev) ++{ ++ return lan78xx_flush_fifo(dev, FCT_RX_CTL, FCT_RX_CTL_RST_); ++} ++ + static int lan78xx_reset(struct lan78xx_net *dev) + { + struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]); +@@ -2703,23 +2879,7 @@ static int lan78xx_reset(struct lan78xx_net *dev) + if (ret < 0) + return ret; + +- ret = lan78xx_read_reg(dev, MAC_TX, &buf); +- if (ret < 0) +- return ret; +- +- buf |= MAC_TX_TXEN_; +- +- ret = lan78xx_write_reg(dev, MAC_TX, buf); +- if (ret < 0) +- return ret; +- +- ret = lan78xx_read_reg(dev, FCT_TX_CTL, &buf); +- if (ret < 0) +- return ret; +- +- buf |= FCT_TX_CTL_EN_; +- +- ret = lan78xx_write_reg(dev, FCT_TX_CTL, buf); ++ ret = lan78xx_start_tx_path(dev); + if (ret < 0) + return ret; + +@@ -2728,27 +2888,9 @@ static int lan78xx_reset(struct lan78xx_net *dev) + if (ret < 0) + return ret; + +- ret = lan78xx_read_reg(dev, MAC_RX, &buf); +- if (ret < 0) +- return ret; +- +- buf |= MAC_RX_RXEN_; +- +- ret = lan78xx_write_reg(dev, MAC_RX, buf); +- if (ret < 0) +- return ret; ++ ret = lan78xx_start_rx_path(dev); + +- ret = lan78xx_read_reg(dev, FCT_RX_CTL, &buf); +- if (ret < 0) +- return ret; +- +- buf |= FCT_RX_CTL_EN_; +- +- ret = lan78xx_write_reg(dev, FCT_RX_CTL, buf); +- if (ret < 0) +- return ret; +- +- return 0; ++ return ret; + } + + static void lan78xx_init_stats(struct lan78xx_net *dev) +@@ -3970,23 +4112,10 @@ static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) + u16 crc; + int ret; + +- ret = lan78xx_read_reg(dev, MAC_TX, &buf); ++ ret = lan78xx_stop_tx_path(dev); + if (ret < 0) + return ret; +- +- buf &= ~MAC_TX_TXEN_; +- +- ret = lan78xx_write_reg(dev, MAC_TX, buf); +- if (ret < 0) +- return ret; +- +- ret = lan78xx_read_reg(dev, MAC_RX, &buf); +- if (ret < 0) +- return ret; +- +- buf &= ~MAC_RX_RXEN_; +- +- ret = lan78xx_write_reg(dev, MAC_RX, buf); ++ ret = lan78xx_stop_rx_path(dev); + if (ret < 0) + return ret; + +@@ -4163,17 +4292,9 @@ static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) + if (ret < 0) + return ret; + +- lan78xx_read_reg(dev, MAC_RX, &buf); +- if (ret < 0) +- return ret; ++ ret = lan78xx_start_rx_path(dev); + +- buf |= MAC_RX_RXEN_; +- +- lan78xx_write_reg(dev, MAC_RX, buf); +- if (ret < 0) +- return ret; +- +- return 0; ++ return ret; + } + + static int lan78xx_suspend(struct usb_interface *intf, pm_message_t message) +@@ -4196,24 +4317,17 @@ static int lan78xx_suspend(struct usb_interface *intf, pm_message_t message) + spin_unlock_irq(&dev->txq.lock); + } + +- /* stop TX & RX */ +- ret = lan78xx_read_reg(dev, MAC_TX, &buf); ++ /* stop RX */ ++ ret = lan78xx_stop_rx_path(dev); + if (ret < 0) + return ret; + +- buf &= ~MAC_TX_TXEN_; +- +- ret = lan78xx_write_reg(dev, MAC_TX, buf); ++ ret = lan78xx_flush_rx_fifo(dev); + if (ret < 0) + return ret; + +- ret = lan78xx_read_reg(dev, MAC_RX, &buf); +- if (ret < 0) +- return ret; +- +- buf &= ~MAC_RX_RXEN_; +- +- ret = lan78xx_write_reg(dev, MAC_RX, buf); ++ /* stop Tx */ ++ ret = lan78xx_stop_tx_path(dev); + if (ret < 0) + return ret; + +@@ -4231,23 +4345,11 @@ static int lan78xx_suspend(struct usb_interface *intf, pm_message_t message) + + if (PMSG_IS_AUTO(message)) { + /* auto suspend (selective suspend) */ +- ret = lan78xx_read_reg(dev, MAC_TX, &buf); +- if (ret < 0) +- return ret; +- +- buf &= ~MAC_TX_TXEN_; +- +- ret = lan78xx_write_reg(dev, MAC_TX, buf); +- if (ret < 0) +- return ret; +- +- ret = lan78xx_read_reg(dev, MAC_RX, &buf); ++ ret = lan78xx_stop_tx_path(dev); + if (ret < 0) + return ret; + +- buf &= ~MAC_RX_RXEN_; +- +- ret = lan78xx_write_reg(dev, MAC_RX, buf); ++ ret = lan78xx_stop_rx_path(dev); + if (ret < 0) + return ret; + +@@ -4299,13 +4401,7 @@ static int lan78xx_suspend(struct usb_interface *intf, pm_message_t message) + if (ret < 0) + return ret; + +- ret = lan78xx_read_reg(dev, MAC_RX, &buf); +- if (ret < 0) +- return ret; +- +- buf |= MAC_RX_RXEN_; +- +- ret = lan78xx_write_reg(dev, MAC_RX, buf); ++ ret = lan78xx_start_rx_path(dev); + if (ret < 0) + return ret; + } else { +@@ -4330,7 +4426,6 @@ static int lan78xx_resume(struct usb_interface *intf) + struct sk_buff *skb; + struct urb *res; + int ret; +- u32 buf; + + if (!timer_pending(&dev->stat_monitor)) { + dev->delta = 1; +@@ -4338,6 +4433,10 @@ static int lan78xx_resume(struct usb_interface *intf) + jiffies + STAT_UPDATE_TIMER); + } + ++ ret = lan78xx_flush_tx_fifo(dev); ++ if (ret < 0) ++ return ret; ++ + if (!--dev->suspend_count) { + /* resume interrupt URBs */ + if (dev->urb_intr && test_bit(EVENT_DEV_OPEN, &dev->flags)) { +@@ -4397,17 +4496,9 @@ static int lan78xx_resume(struct usb_interface *intf) + if (ret < 0) + return ret; + +- ret = lan78xx_read_reg(dev, MAC_TX, &buf); +- if (ret < 0) +- return ret; +- +- buf |= MAC_TX_TXEN_; ++ ret = lan78xx_start_tx_path(dev); + +- ret = lan78xx_write_reg(dev, MAC_TX, buf); +- if (ret < 0) +- return ret; +- +- return 0; ++ return ret; + } + + static int lan78xx_reset_resume(struct usb_interface *intf) +-- +2.44.0 + diff --git a/patches.suse/lan78xx-Fix-race-conditions-in-suspend-resume-handli.patch b/patches.suse/lan78xx-Fix-race-conditions-in-suspend-resume-handli.patch new file mode 100644 index 0000000..4c9bd42 --- /dev/null +++ b/patches.suse/lan78xx-Fix-race-conditions-in-suspend-resume-handli.patch @@ -0,0 +1,740 @@ +From 5f4cc6e25148cc141f97afb41b4dfe9eb1cce613 Mon Sep 17 00:00:00 2001 +From: John Efstathiades +Date: Tue, 24 Aug 2021 19:56:11 +0100 +Subject: [PATCH] lan78xx: Fix race conditions in suspend/resume handling +Git-commit: 5f4cc6e25148cc141f97afb41b4dfe9eb1cce613 +References: git-fixes +Patch-mainline: v5.15-rc1 + +If the interface is given an IP address while the device is +suspended (as a result of an auto-suspend event) there is a race +between lan78xx_resume() and lan78xx_open() that can result in an +exception or failure to handle incoming packets. The following +changes fix this problem. + +Introduce a mutex to serialise operations in the network interface +open and stop entry points with respect to the USB driver suspend +and resume entry points. + +Move Tx and Rx data path start/stop to lan78xx_start() and +lan78xx_stop() respectively and flush the packet FIFOs before +starting the Tx and Rx data paths. This prevents the MAC and FIFOs +getting out of step and delivery of malformed packets to the network +stack. + +Stop processing of received packets before disconnecting the +PHY from the MAC to prevent a kernel exception caused by handling +packets after the PHY device has been removed. + +Refactor device auto-suspend code to make it consistent with the +the system suspend code and make the suspend handler easier to read. + +Add new code to stop wake-on-lan packets or PHY events resuming the +host or device from suspend if the device has not been opened +(typically after an IP address is assigned). + +This patch is dependent on changes to lan78xx_suspend() and +lan78xx_resume() introduced in the previous patch of this patch set. + +Signed-off-by: John Efstathiades +Signed-off-by: David S. Miller +Signed-off-by: Oliver Neukum + +--- + drivers/net/usb/lan78xx.c | 419 +++++++++++++++++++++++++++++++--------------- + 1 file changed, 284 insertions(+), 135 deletions(-) + +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -398,6 +398,7 @@ struct lan78xx_net { + struct urb *urb_intr; + struct usb_anchor deferred; + ++ struct mutex dev_mutex; /* serialise open/stop wrt suspend/resume */ + struct mutex phy_mutex; /* for phy access */ + unsigned int pipe_in, pipe_out, pipe_intr; + +@@ -2342,11 +2343,16 @@ static int lan78xx_change_mtu(struct net + int ll_mtu = new_mtu + netdev->hard_header_len; + int old_hard_mtu = dev->hard_mtu; + int old_rx_urb_size = dev->rx_urb_size; ++ int ret; + + /* no second zero-length packet read wanted after mtu-sized packets */ + if ((ll_mtu % dev->maxpacket) == 0) + return -EDOM; + ++ ret = usb_autopm_get_interface(dev->intf); ++ if (ret < 0) ++ return ret; ++ + lan78xx_set_rx_max_frame_length(dev, new_mtu + VLAN_ETH_HLEN); + + netdev->mtu = new_mtu; +@@ -2362,6 +2368,8 @@ static int lan78xx_change_mtu(struct net + } + } + ++ usb_autopm_put_interface(dev->intf); ++ + return 0; + } + +@@ -2853,16 +2861,8 @@ static int lan78xx_reset(struct lan78xx_ + if (ret < 0) + return ret; + +- ret = lan78xx_start_tx_path(dev); +- if (ret < 0) +- return ret; +- + ret = lan78xx_set_rx_max_frame_length(dev, + dev->net->mtu + VLAN_ETH_HLEN); +- if (ret < 0) +- return ret; +- +- ret = lan78xx_start_rx_path(dev); + + return ret; + } +@@ -2898,10 +2898,14 @@ static int lan78xx_open(struct net_devic + struct lan78xx_net *dev = netdev_priv(net); + int ret; + ++ netif_dbg(dev, ifup, dev->net, "open device"); ++ + ret = usb_autopm_get_interface(dev->intf); + if (ret < 0) + return ret; + ++ mutex_lock(&dev->dev_mutex); ++ + phy_start(net->phydev); + + netif_dbg(dev, ifup, dev->net, "phy initialised successfully"); +@@ -2916,6 +2920,20 @@ static int lan78xx_open(struct net_devic + } + } + ++ ret = lan78xx_flush_rx_fifo(dev); ++ if (ret < 0) ++ goto done; ++ ret = lan78xx_flush_tx_fifo(dev); ++ if (ret < 0) ++ goto done; ++ ++ ret = lan78xx_start_tx_path(dev); ++ if (ret < 0) ++ goto done; ++ ret = lan78xx_start_rx_path(dev); ++ if (ret < 0) ++ goto done; ++ + lan78xx_init_stats(dev); + + set_bit(EVENT_DEV_OPEN, &dev->flags); +@@ -2926,6 +2944,8 @@ static int lan78xx_open(struct net_devic + + lan78xx_defer_kevent(dev, EVENT_LINK_RESET); + done: ++ mutex_unlock(&dev->dev_mutex); ++ + usb_autopm_put_interface(dev->intf); + + return ret; +@@ -2944,38 +2964,56 @@ static void lan78xx_terminate_urbs(struc + temp = unlink_urbs(dev, &dev->txq) + unlink_urbs(dev, &dev->rxq); + + /* maybe wait for deletions to finish. */ +- while (!skb_queue_empty(&dev->rxq) && +- !skb_queue_empty(&dev->txq) && +- !skb_queue_empty(&dev->done)) { ++ while (!skb_queue_empty(&dev->rxq) || ++ !skb_queue_empty(&dev->txq)) { + schedule_timeout(msecs_to_jiffies(UNLINK_TIMEOUT_MS)); + set_current_state(TASK_UNINTERRUPTIBLE); + netif_dbg(dev, ifdown, dev->net, +- "waited for %d urb completions\n", temp); ++ "waited for %d urb completions", temp); + } + set_current_state(TASK_RUNNING); + dev->wait = NULL; + remove_wait_queue(&unlink_wakeup, &wait); ++ ++ while (!skb_queue_empty(&dev->done)) { ++ struct skb_data *entry; ++ struct sk_buff *skb; ++ ++ skb = skb_dequeue(&dev->done); ++ entry = (struct skb_data *)(skb->cb); ++ usb_free_urb(entry->urb); ++ dev_kfree_skb(skb); ++ } + } + + static int lan78xx_stop(struct net_device *net) + { + struct lan78xx_net *dev = netdev_priv(net); + ++ netif_dbg(dev, ifup, dev->net, "stop device"); ++ ++ mutex_lock(&dev->dev_mutex); ++ + if (timer_pending(&dev->stat_monitor)) + del_timer_sync(&dev->stat_monitor); + +- if (net->phydev) +- phy_stop(net->phydev); +- + clear_bit(EVENT_DEV_OPEN, &dev->flags); + netif_stop_queue(net); ++ tasklet_kill(&dev->bh); ++ ++ lan78xx_terminate_urbs(dev); + + netif_info(dev, ifdown, dev->net, + "stop stats: rx/tx %lu/%lu, errs %lu/%lu\n", + net->stats.rx_packets, net->stats.tx_packets, + net->stats.rx_errors, net->stats.tx_errors); + +- lan78xx_terminate_urbs(dev); ++ /* ignore errors that occur stopping the Tx and Rx data paths */ ++ lan78xx_stop_tx_path(dev); ++ lan78xx_stop_rx_path(dev); ++ ++ if (net->phydev) ++ phy_stop(net->phydev); + + usb_kill_urb(dev->urb_intr); + +@@ -2985,12 +3023,17 @@ static int lan78xx_stop(struct net_devic + * can't flush_scheduled_work() until we drop rtnl (later), + * else workers could deadlock; so make workers a NOP. + */ +- dev->flags = 0; ++ clear_bit(EVENT_TX_HALT, &dev->flags); ++ clear_bit(EVENT_RX_HALT, &dev->flags); ++ clear_bit(EVENT_LINK_RESET, &dev->flags); ++ clear_bit(EVENT_STAT_UPDATE, &dev->flags); ++ + cancel_delayed_work_sync(&dev->wq); +- tasklet_kill(&dev->bh); + + usb_autopm_put_interface(dev->intf); + ++ mutex_unlock(&dev->dev_mutex); ++ + return 0; + } + +@@ -3113,6 +3156,9 @@ lan78xx_start_xmit(struct sk_buff *skb, + struct lan78xx_net *dev = netdev_priv(net); + struct sk_buff *skb2 = NULL; + ++ if (test_bit(EVENT_DEV_ASLEEP, &dev->flags)) ++ schedule_delayed_work(&dev->wq, 0); ++ + if (skb) { + skb_tx_timestamp(skb); + skb2 = lan78xx_tx_prep(dev, skb, GFP_ATOMIC); +@@ -3695,18 +3741,17 @@ static void lan78xx_delayedwork(struct w + + dev = container_of(work, struct lan78xx_net, wq.work); + ++ if (usb_autopm_get_interface(dev->intf) < 0) ++ return; ++ + if (test_bit(EVENT_TX_HALT, &dev->flags)) { + unlink_urbs(dev, &dev->txq); +- status = usb_autopm_get_interface(dev->intf); +- if (status < 0) +- goto fail_pipe; ++ + status = usb_clear_halt(dev->udev, dev->pipe_out); +- usb_autopm_put_interface(dev->intf); + if (status < 0 && + status != -EPIPE && + status != -ESHUTDOWN) { + if (netif_msg_tx_err(dev)) +-fail_pipe: + netdev_err(dev->net, + "can't clear tx halt, status %d\n", + status); +@@ -3716,18 +3761,14 @@ fail_pipe: + netif_wake_queue(dev->net); + } + } ++ + if (test_bit(EVENT_RX_HALT, &dev->flags)) { + unlink_urbs(dev, &dev->rxq); +- status = usb_autopm_get_interface(dev->intf); +- if (status < 0) +- goto fail_halt; + status = usb_clear_halt(dev->udev, dev->pipe_in); +- usb_autopm_put_interface(dev->intf); + if (status < 0 && + status != -EPIPE && + status != -ESHUTDOWN) { + if (netif_msg_rx_err(dev)) +-fail_halt: + netdev_err(dev->net, + "can't clear rx halt, status %d\n", + status); +@@ -3741,16 +3782,9 @@ fail_halt: + int ret = 0; + + clear_bit(EVENT_LINK_RESET, &dev->flags); +- status = usb_autopm_get_interface(dev->intf); +- if (status < 0) +- goto skip_reset; + if (lan78xx_link_reset(dev) < 0) { +- usb_autopm_put_interface(dev->intf); +-skip_reset: + netdev_info(dev->net, "link reset failed (%d)\n", + ret); +- } else { +- usb_autopm_put_interface(dev->intf); + } + } + +@@ -3764,6 +3798,8 @@ skip_reset: + + dev->delta = min((dev->delta * 2), 50); + } ++ ++ usb_autopm_put_interface(dev->intf); + } + + static void intr_complete(struct urb *urb) +@@ -3925,6 +3961,7 @@ static int lan78xx_probe(struct usb_inte + skb_queue_head_init(&dev->rxq_pause); + skb_queue_head_init(&dev->txq_pend); + mutex_init(&dev->phy_mutex); ++ mutex_init(&dev->dev_mutex); + + tasklet_init(&dev->bh, lan78xx_bh, (unsigned long)dev); + INIT_DELAYED_WORK(&dev->wq, lan78xx_delayedwork); +@@ -4064,6 +4101,74 @@ static u16 lan78xx_wakeframe_crc16(const + return crc; + } + ++static int lan78xx_set_auto_suspend(struct lan78xx_net *dev) ++{ ++ u32 buf; ++ int ret; ++ ++ ret = lan78xx_stop_tx_path(dev); ++ if (ret < 0) ++ return ret; ++ ++ ret = lan78xx_stop_rx_path(dev); ++ if (ret < 0) ++ return ret; ++ ++ /* auto suspend (selective suspend) */ ++ ++ ret = lan78xx_write_reg(dev, WUCSR, 0); ++ if (ret < 0) ++ return ret; ++ ret = lan78xx_write_reg(dev, WUCSR2, 0); ++ if (ret < 0) ++ return ret; ++ ret = lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL); ++ if (ret < 0) ++ return ret; ++ ++ /* set goodframe wakeup */ ++ ++ ret = lan78xx_read_reg(dev, WUCSR, &buf); ++ if (ret < 0) ++ return ret; ++ ++ buf |= WUCSR_RFE_WAKE_EN_; ++ buf |= WUCSR_STORE_WAKE_; ++ ++ ret = lan78xx_write_reg(dev, WUCSR, buf); ++ if (ret < 0) ++ return ret; ++ ++ ret = lan78xx_read_reg(dev, PMT_CTL, &buf); ++ if (ret < 0) ++ return ret; ++ ++ buf &= ~PMT_CTL_RES_CLR_WKP_EN_; ++ buf |= PMT_CTL_RES_CLR_WKP_STS_; ++ buf |= PMT_CTL_PHY_WAKE_EN_; ++ buf |= PMT_CTL_WOL_EN_; ++ buf &= ~PMT_CTL_SUS_MODE_MASK_; ++ buf |= PMT_CTL_SUS_MODE_3_; ++ ++ ret = lan78xx_write_reg(dev, PMT_CTL, buf); ++ if (ret < 0) ++ return ret; ++ ++ ret = lan78xx_read_reg(dev, PMT_CTL, &buf); ++ if (ret < 0) ++ return ret; ++ ++ buf |= PMT_CTL_WUPS_MASK_; ++ ++ ret = lan78xx_write_reg(dev, PMT_CTL, buf); ++ if (ret < 0) ++ return ret; ++ ++ ret = lan78xx_start_rx_path(dev); ++ ++ return ret; ++} ++ + static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) + { + const u8 ipv4_multicast[3] = { 0x01, 0x00, 0x5E }; +@@ -4264,15 +4369,22 @@ static int lan78xx_set_suspend(struct la + static int lan78xx_suspend(struct usb_interface *intf, pm_message_t message) + { + struct lan78xx_net *dev = usb_get_intfdata(intf); +- u32 buf; ++ bool dev_open; + int ret; + +- if (!dev->suspend_count++) { ++ mutex_lock(&dev->dev_mutex); ++ ++ netif_dbg(dev, ifdown, dev->net, ++ "suspending: pm event %#x", message.event); ++ ++ dev_open = test_bit(EVENT_DEV_OPEN, &dev->flags); ++ ++ if (dev_open) { + spin_lock_irq(&dev->txq.lock); + /* don't autosuspend while transmitting */ + if ((skb_queue_len(&dev->txq) || + skb_queue_len(&dev->txq_pend)) && +- PMSG_IS_AUTO(message)) { ++ PMSG_IS_AUTO(message)) { + spin_unlock_irq(&dev->txq.lock); + ret = -EBUSY; + goto out; +@@ -4284,171 +4396,204 @@ static int lan78xx_suspend(struct usb_in + /* stop RX */ + ret = lan78xx_stop_rx_path(dev); + if (ret < 0) +- return ret; ++ goto out; + + ret = lan78xx_flush_rx_fifo(dev); + if (ret < 0) +- return ret; ++ goto out; + + /* stop Tx */ + ret = lan78xx_stop_tx_path(dev); + if (ret < 0) +- return ret; ++ goto out; + +- /* empty out the rx and queues */ ++ /* empty out the Rx and Tx queues */ + netif_device_detach(dev->net); + lan78xx_terminate_urbs(dev); + usb_kill_urb(dev->urb_intr); + + /* reattach */ + netif_device_attach(dev->net); +- } + +- if (test_bit(EVENT_DEV_ASLEEP, &dev->flags)) { + del_timer(&dev->stat_monitor); + + if (PMSG_IS_AUTO(message)) { +- /* auto suspend (selective suspend) */ +- ret = lan78xx_stop_tx_path(dev); ++ ret = lan78xx_set_auto_suspend(dev); + if (ret < 0) +- return ret; ++ goto out; ++ } else { ++ struct lan78xx_priv *pdata; + +- ret = lan78xx_stop_rx_path(dev); ++ pdata = (struct lan78xx_priv *)(dev->data[0]); ++ netif_carrier_off(dev->net); ++ ret = lan78xx_set_suspend(dev, pdata->wol); + if (ret < 0) +- return ret; ++ goto out; ++ } ++ } else { ++ /* Interface is down; don't allow WOL and PHY ++ * events to wake up the host ++ */ ++ u32 buf; + +- ret = lan78xx_write_reg(dev, WUCSR, 0); +- if (ret < 0) +- return ret; +- ret = lan78xx_write_reg(dev, WUCSR2, 0); +- if (ret < 0) +- return ret; +- ret = lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL); +- if (ret < 0) +- return ret; ++ set_bit(EVENT_DEV_ASLEEP, &dev->flags); + +- /* set goodframe wakeup */ +- ret = lan78xx_read_reg(dev, WUCSR, &buf); +- if (ret < 0) +- return ret; ++ ret = lan78xx_write_reg(dev, WUCSR, 0); ++ if (ret < 0) ++ goto out; ++ ret = lan78xx_write_reg(dev, WUCSR2, 0); ++ if (ret < 0) ++ goto out; + +- buf |= WUCSR_RFE_WAKE_EN_; +- buf |= WUCSR_STORE_WAKE_; ++ ret = lan78xx_read_reg(dev, PMT_CTL, &buf); ++ if (ret < 0) ++ goto out; + +- ret = lan78xx_write_reg(dev, WUCSR, buf); +- if (ret < 0) +- return ret; ++ buf &= ~PMT_CTL_RES_CLR_WKP_EN_; ++ buf |= PMT_CTL_RES_CLR_WKP_STS_; ++ buf &= ~PMT_CTL_SUS_MODE_MASK_; ++ buf |= PMT_CTL_SUS_MODE_3_; + +- ret = lan78xx_read_reg(dev, PMT_CTL, &buf); +- if (ret < 0) +- return ret; ++ ret = lan78xx_write_reg(dev, PMT_CTL, buf); ++ if (ret < 0) ++ goto out; + +- buf &= ~PMT_CTL_RES_CLR_WKP_EN_; +- buf |= PMT_CTL_RES_CLR_WKP_STS_; ++ ret = lan78xx_read_reg(dev, PMT_CTL, &buf); ++ if (ret < 0) ++ goto out; + +- buf |= PMT_CTL_PHY_WAKE_EN_; +- buf |= PMT_CTL_WOL_EN_; +- buf &= ~PMT_CTL_SUS_MODE_MASK_; +- buf |= PMT_CTL_SUS_MODE_3_; ++ buf |= PMT_CTL_WUPS_MASK_; + +- ret = lan78xx_write_reg(dev, PMT_CTL, buf); +- if (ret < 0) +- return ret; ++ ret = lan78xx_write_reg(dev, PMT_CTL, buf); ++ if (ret < 0) ++ goto out; ++ } + +- ret = lan78xx_read_reg(dev, PMT_CTL, &buf); +- if (ret < 0) +- return ret; ++ ret = 0; ++out: ++ mutex_unlock(&dev->dev_mutex); + +- buf |= PMT_CTL_WUPS_MASK_; ++ return ret; ++} + +- ret = lan78xx_write_reg(dev, PMT_CTL, buf); +- if (ret < 0) +- return ret; ++static bool lan78xx_submit_deferred_urbs(struct lan78xx_net *dev) ++{ ++ bool pipe_halted = false; ++ struct urb *urb; + +- ret = lan78xx_start_rx_path(dev); +- if (ret < 0) +- return ret; +- } else { +- struct lan78xx_priv *pdata; ++ while ((urb = usb_get_from_anchor(&dev->deferred))) { ++ struct sk_buff *skb = urb->context; ++ int ret; + +- pdata = (struct lan78xx_priv *)(dev->data[0]); ++ if (!netif_device_present(dev->net) || ++ !netif_carrier_ok(dev->net) || ++ pipe_halted) { ++ usb_free_urb(urb); ++ dev_kfree_skb(skb); ++ continue; ++ } + +- ret = lan78xx_set_suspend(dev, pdata->wol); +- if (ret < 0) +- return ret; ++ ret = usb_submit_urb(urb, GFP_ATOMIC); ++ ++ if (ret == 0) { ++ netif_trans_update(dev->net); ++ lan78xx_queue_skb(&dev->txq, skb, tx_start); ++ } else { ++ usb_free_urb(urb); ++ dev_kfree_skb(skb); ++ ++ if (ret == -EPIPE) { ++ netif_stop_queue(dev->net); ++ pipe_halted = true; ++ } else if (ret == -ENODEV) { ++ netif_device_detach(dev->net); ++ } + } + } + +- ret = 0; +-out: +- return ret; ++ return pipe_halted; + } + + static int lan78xx_resume(struct usb_interface *intf) + { + struct lan78xx_net *dev = usb_get_intfdata(intf); +- struct sk_buff *skb; +- struct urb *res; ++ bool dev_open; + int ret; + +- if (!timer_pending(&dev->stat_monitor)) { +- dev->delta = 1; +- mod_timer(&dev->stat_monitor, +- jiffies + STAT_UPDATE_TIMER); +- } ++ mutex_lock(&dev->dev_mutex); + +- ret = lan78xx_flush_tx_fifo(dev); +- if (ret < 0) +- return ret; ++ netif_dbg(dev, ifup, dev->net, "resuming device"); + +- if (!--dev->suspend_count) { +- /* resume interrupt URBs */ +- if (dev->urb_intr && test_bit(EVENT_DEV_OPEN, &dev->flags)) { +- ret = usb_submit_urb(dev->urb_intr, GFP_NOIO); +- if (ret < 0) +- return ret; +- } ++ dev_open = test_bit(EVENT_DEV_OPEN, &dev->flags); ++ ++ if (dev_open) { ++ bool pipe_halted = false; ++ ++ ret = lan78xx_flush_tx_fifo(dev); ++ if (ret < 0) ++ goto out; ++ ++ if (dev->urb_intr) { ++ int ret = usb_submit_urb(dev->urb_intr, GFP_KERNEL); + +- spin_lock_irq(&dev->txq.lock); +- while ((res = usb_get_from_anchor(&dev->deferred))) { +- skb = (struct sk_buff *)res->context; +- ret = usb_submit_urb(res, GFP_ATOMIC); + if (ret < 0) { +- dev_kfree_skb_any(skb); +- usb_free_urb(res); +- usb_autopm_put_interface_async(dev->intf); +- } else { +- netif_trans_update(dev->net); +- lan78xx_queue_skb(&dev->txq, skb, tx_start); ++ if (ret == -ENODEV) ++ netif_device_detach(dev->net); ++ ++ netdev_warn(dev->net, "Failed to submit intr URB"); + } + } + ++ spin_lock_irq(&dev->txq.lock); ++ ++ if (netif_device_present(dev->net)) { ++ pipe_halted = lan78xx_submit_deferred_urbs(dev); ++ ++ if (pipe_halted) ++ lan78xx_defer_kevent(dev, EVENT_TX_HALT); ++ } ++ + clear_bit(EVENT_DEV_ASLEEP, &dev->flags); ++ + spin_unlock_irq(&dev->txq.lock); + +- if (test_bit(EVENT_DEV_OPEN, &dev->flags)) { +- if (!(skb_queue_len(&dev->txq) >= dev->tx_qlen)) +- netif_start_queue(dev->net); +- tasklet_schedule(&dev->bh); ++ if (!pipe_halted && ++ netif_device_present(dev->net) && ++ (skb_queue_len(&dev->txq) < dev->tx_qlen)) ++ netif_start_queue(dev->net); ++ ++ ret = lan78xx_start_tx_path(dev); ++ if (ret < 0) ++ goto out; ++ ++ tasklet_schedule(&dev->bh); ++ ++ if (!timer_pending(&dev->stat_monitor)) { ++ dev->delta = 1; ++ mod_timer(&dev->stat_monitor, ++ jiffies + STAT_UPDATE_TIMER); + } ++ ++ } else { ++ clear_bit(EVENT_DEV_ASLEEP, &dev->flags); + } + + ret = lan78xx_write_reg(dev, WUCSR2, 0); + if (ret < 0) +- return ret; ++ goto out; + ret = lan78xx_write_reg(dev, WUCSR, 0); + if (ret < 0) +- return ret; ++ goto out; + ret = lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL); + if (ret < 0) +- return ret; ++ goto out; + + ret = lan78xx_write_reg(dev, WUCSR2, WUCSR2_NS_RCD_ | + WUCSR2_ARP_RCD_ | + WUCSR2_IPV6_TCPSYN_RCD_ | + WUCSR2_IPV4_TCPSYN_RCD_); + if (ret < 0) +- return ret; ++ goto out; + + ret = lan78xx_write_reg(dev, WUCSR, WUCSR_EEE_TX_WAKE_ | + WUCSR_EEE_RX_WAKE_ | +@@ -4458,9 +4603,11 @@ static int lan78xx_resume(struct usb_int + WUCSR_MPR_ | + WUCSR_BCST_FR_); + if (ret < 0) +- return ret; ++ goto out; + +- ret = lan78xx_start_tx_path(dev); ++ ret = 0; ++out: ++ mutex_unlock(&dev->dev_mutex); + + return ret; + } +@@ -4470,6 +4617,8 @@ static int lan78xx_reset_resume(struct u + struct lan78xx_net *dev = usb_get_intfdata(intf); + int ret; + ++ netif_dbg(dev, ifup, dev->net, "(reset) resuming device"); ++ + ret = lan78xx_reset(dev); + if (ret < 0) + return ret; diff --git a/patches.suse/lan78xx-Fix-white-space-and-style-issues.patch b/patches.suse/lan78xx-Fix-white-space-and-style-issues.patch new file mode 100644 index 0000000..744f18a --- /dev/null +++ b/patches.suse/lan78xx-Fix-white-space-and-style-issues.patch @@ -0,0 +1,249 @@ +From 9ceec7d33adf9647293f24d2fd9a055b89c63864 Mon Sep 17 00:00:00 2001 +From: John Efstathiades +Date: Tue, 24 Aug 2021 19:56:04 +0100 +Subject: [PATCH] lan78xx: Fix white space and style issues +Git-commit: 9ceec7d33adf9647293f24d2fd9a055b89c63864 +References: git-fixes +Patch-mainline: v5.15-rc1 + +Fix white space and code style issues identified by checkpatch. + +Signed-off-by: John Efstathiades +Signed-off-by: David S. Miller +Signed-off-by: Oliver Neukum + +--- + drivers/net/usb/lan78xx.c | 80 ++++++++++++++++++++++++---------------------- + 1 file changed, 42 insertions(+), 38 deletions(-) + +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -393,7 +393,7 @@ struct lan78xx_net { + struct usb_anchor deferred; + + struct mutex phy_mutex; /* for phy access */ +- unsigned pipe_in, pipe_out, pipe_intr; ++ unsigned int pipe_in, pipe_out, pipe_intr; + + u32 hard_mtu; /* count any extra framing */ + size_t rx_urb_size; /* size for rx urbs */ +@@ -403,7 +403,7 @@ struct lan78xx_net { + wait_queue_head_t *wait; + unsigned char suspend_count; + +- unsigned maxpacket; ++ unsigned int maxpacket; + struct timer_list delay; + struct timer_list stat_monitor; + +@@ -512,7 +512,7 @@ static int lan78xx_read_stats(struct lan + if (likely(ret >= 0)) { + src = (u32 *)stats; + dst = (u32 *)data; +- for (i = 0; i < sizeof(*stats)/sizeof(u32); i++) { ++ for (i = 0; i < sizeof(*stats) / sizeof(u32); i++) { + le32_to_cpus(&src[i]); + dst[i] = src[i]; + } +@@ -526,10 +526,11 @@ static int lan78xx_read_stats(struct lan + return ret; + } + +-#define check_counter_rollover(struct1, dev_stats, member) { \ +- if (struct1->member < dev_stats.saved.member) \ +- dev_stats.rollover_count.member++; \ +- } ++#define check_counter_rollover(struct1, dev_stats, member) \ ++ do { \ ++ if ((struct1)->member < (dev_stats).saved.member) \ ++ (dev_stats).rollover_count.member++; \ ++ } while (0) + + static void lan78xx_check_stat_rollover(struct lan78xx_net *dev, + struct lan78xx_statstage *stats) +@@ -855,9 +856,9 @@ static int lan78xx_read_raw_otp(struct l + + for (i = 0; i < length; i++) { + lan78xx_write_reg(dev, OTP_ADDR1, +- ((offset + i) >> 8) & OTP_ADDR1_15_11); ++ ((offset + i) >> 8) & OTP_ADDR1_15_11); + lan78xx_write_reg(dev, OTP_ADDR2, +- ((offset + i) & OTP_ADDR2_10_3)); ++ ((offset + i) & OTP_ADDR2_10_3)); + + lan78xx_write_reg(dev, OTP_FUNC_CMD, OTP_FUNC_CMD_READ_); + lan78xx_write_reg(dev, OTP_CMD_GO, OTP_CMD_GO_GO_); +@@ -911,9 +912,9 @@ static int lan78xx_write_raw_otp(struct + + for (i = 0; i < length; i++) { + lan78xx_write_reg(dev, OTP_ADDR1, +- ((offset + i) >> 8) & OTP_ADDR1_15_11); ++ ((offset + i) >> 8) & OTP_ADDR1_15_11); + lan78xx_write_reg(dev, OTP_ADDR2, +- ((offset + i) & OTP_ADDR2_10_3)); ++ ((offset + i) & OTP_ADDR2_10_3)); + lan78xx_write_reg(dev, OTP_PRGM_DATA, data[i]); + lan78xx_write_reg(dev, OTP_TST_CMD, OTP_TST_CMD_PRGVRFY_); + lan78xx_write_reg(dev, OTP_CMD_GO, OTP_CMD_GO_GO_); +@@ -972,7 +973,7 @@ static int lan78xx_dataport_wait_not_bus + usleep_range(40, 100); + } + +- netdev_warn(dev->net, "lan78xx_dataport_wait_not_busy timed out"); ++ netdev_warn(dev->net, "%s timed out", __func__); + + return -EIO; + } +@@ -985,7 +986,7 @@ static int lan78xx_dataport_write(struct + int i, ret; + + if (usb_autopm_get_interface(dev->intf) < 0) +- return 0; ++ return 0; + + mutex_lock(&pdata->dataport_mutex); + +@@ -1058,9 +1059,9 @@ static void lan78xx_deferred_multicast_w + for (i = 1; i < NUM_OF_MAF; i++) { + lan78xx_write_reg(dev, MAF_HI(i), 0); + lan78xx_write_reg(dev, MAF_LO(i), +- pdata->pfilter_table[i][1]); ++ pdata->pfilter_table[i][1]); + lan78xx_write_reg(dev, MAF_HI(i), +- pdata->pfilter_table[i][0]); ++ pdata->pfilter_table[i][0]); + } + + lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); +@@ -1079,11 +1080,12 @@ static void lan78xx_set_multicast(struct + RFE_CTL_DA_PERFECT_ | RFE_CTL_MCAST_HASH_); + + for (i = 0; i < DP_SEL_VHF_HASH_LEN; i++) +- pdata->mchash_table[i] = 0; ++ pdata->mchash_table[i] = 0; ++ + /* pfilter_table[0] has own HW address */ + for (i = 1; i < NUM_OF_MAF; i++) { +- pdata->pfilter_table[i][0] = +- pdata->pfilter_table[i][1] = 0; ++ pdata->pfilter_table[i][0] = 0; ++ pdata->pfilter_table[i][1] = 0; + } + + pdata->rfe_ctl |= RFE_CTL_BCAST_EN_; +@@ -1274,9 +1276,10 @@ static void lan78xx_status(struct lan78x + + if (dev->domain_data.phyirq > 0) + generic_handle_irq(dev->domain_data.phyirq); +- } else ++ } else { + netdev_warn(dev->net, + "unexpected interrupt: 0x%08x\n", intdata); ++ } + } + + static int lan78xx_ethtool_get_eeprom_len(struct net_device *netdev) +@@ -1365,7 +1368,7 @@ static void lan78xx_get_wol(struct net_d + struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]); + + if (usb_autopm_get_interface(dev->intf) < 0) +- return; ++ return; + + ret = lan78xx_read_reg(dev, USB_CFG0, &buf); + if (unlikely(ret < 0)) { +@@ -2019,7 +2022,7 @@ static int lan8835_fixup(struct phy_devi + + /* RGMII MAC TXC Delay Enable */ + lan78xx_write_reg(dev, MAC_RGMII_ID, +- MAC_RGMII_ID_TXC_DELAY_EN_); ++ MAC_RGMII_ID_TXC_DELAY_EN_); + + /* RGMII TX DLL Tune Adjust */ + lan78xx_write_reg(dev, RGMII_TX_BYP_DLL, 0x3D00); +@@ -3317,9 +3320,10 @@ drop: + if (skb) + dev_kfree_skb_any(skb); + usb_free_urb(urb); +- } else ++ } else { + netif_dbg(dev, tx_queued, dev->net, + "> tx, len %d, type 0x%x\n", length, skb->protocol); ++ } + } + + static void lan78xx_rx_bh(struct lan78xx_net *dev) +@@ -3420,7 +3424,7 @@ fail_pipe: + unlink_urbs(dev, &dev->rxq); + status = usb_autopm_get_interface(dev->intf); + if (status < 0) +- goto fail_halt; ++ goto fail_halt; + status = usb_clear_halt(dev->udev, dev->pipe_in); + usb_autopm_put_interface(dev->intf); + if (status < 0 && +@@ -3595,8 +3599,8 @@ static int lan78xx_probe(struct usb_inte + struct net_device *netdev; + struct usb_device *udev; + int ret; +- unsigned maxp; +- unsigned period; ++ unsigned int maxp; ++ unsigned int period; + u8 *buf = NULL; + + udev = interface_to_usbdev(intf); +@@ -3824,10 +3828,10 @@ static int lan78xx_set_suspend(struct la + /* set WUF_CFG & WUF_MASK for IPv4 Multicast */ + crc = lan78xx_wakeframe_crc16(ipv4_multicast, 3); + lan78xx_write_reg(dev, WUF_CFG(mask_index), +- WUF_CFGX_EN_ | +- WUF_CFGX_TYPE_MCAST_ | +- (0 << WUF_CFGX_OFFSET_SHIFT_) | +- (crc & WUF_CFGX_CRC16_MASK_)); ++ WUF_CFGX_EN_ | ++ WUF_CFGX_TYPE_MCAST_ | ++ (0 << WUF_CFGX_OFFSET_SHIFT_) | ++ (crc & WUF_CFGX_CRC16_MASK_)); + + lan78xx_write_reg(dev, WUF_MASK0(mask_index), 7); + lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); +@@ -3838,10 +3842,10 @@ static int lan78xx_set_suspend(struct la + /* for IPv6 Multicast */ + crc = lan78xx_wakeframe_crc16(ipv6_multicast, 2); + lan78xx_write_reg(dev, WUF_CFG(mask_index), +- WUF_CFGX_EN_ | +- WUF_CFGX_TYPE_MCAST_ | +- (0 << WUF_CFGX_OFFSET_SHIFT_) | +- (crc & WUF_CFGX_CRC16_MASK_)); ++ WUF_CFGX_EN_ | ++ WUF_CFGX_TYPE_MCAST_ | ++ (0 << WUF_CFGX_OFFSET_SHIFT_) | ++ (crc & WUF_CFGX_CRC16_MASK_)); + + lan78xx_write_reg(dev, WUF_MASK0(mask_index), 3); + lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); +@@ -3868,10 +3872,10 @@ static int lan78xx_set_suspend(struct la + */ + crc = lan78xx_wakeframe_crc16(arp_type, 2); + lan78xx_write_reg(dev, WUF_CFG(mask_index), +- WUF_CFGX_EN_ | +- WUF_CFGX_TYPE_ALL_ | +- (0 << WUF_CFGX_OFFSET_SHIFT_) | +- (crc & WUF_CFGX_CRC16_MASK_)); ++ WUF_CFGX_EN_ | ++ WUF_CFGX_TYPE_ALL_ | ++ (0 << WUF_CFGX_OFFSET_SHIFT_) | ++ (crc & WUF_CFGX_CRC16_MASK_)); + + lan78xx_write_reg(dev, WUF_MASK0(mask_index), 0x3000); + lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); +@@ -4016,7 +4020,7 @@ static int lan78xx_resume(struct usb_int + if (!--dev->suspend_count) { + /* resume interrupt URBs */ + if (dev->urb_intr && test_bit(EVENT_DEV_OPEN, &dev->flags)) +- usb_submit_urb(dev->urb_intr, GFP_NOIO); ++ usb_submit_urb(dev->urb_intr, GFP_NOIO); + + spin_lock_irq(&dev->txq.lock); + while ((res = usb_get_from_anchor(&dev->deferred))) { diff --git a/patches.suse/lan78xx-Modify-error-messages.patch b/patches.suse/lan78xx-Modify-error-messages.patch new file mode 100644 index 0000000..56741d5 --- /dev/null +++ b/patches.suse/lan78xx-Modify-error-messages.patch @@ -0,0 +1,42 @@ +From 7670ed7a25943a77af64ec4a7247a504e98fe812 Mon Sep 17 00:00:00 2001 +From: Raghuram Chary J +Date: Sat, 28 Apr 2018 11:33:16 +0530 +Subject: [PATCH] lan78xx: Modify error messages +Git-commit: 7670ed7a25943a77af64ec4a7247a504e98fe812 +References: git-fixes +Patch-mainline: v4.18-rc1 + +Modify the error messages when phy registration fails. + +Signed-off-by: Raghuram Chary J +Signed-off-by: David S. Miller +Signed-off-by: Oliver Neukum + +--- + drivers/net/usb/lan78xx.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index 54f8db887e3d..91761436709a 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -2100,14 +2100,14 @@ static struct phy_device *lan7801_phy_init(struct lan78xx_net *dev) + ret = phy_register_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0, + ksz9031rnx_fixup); + if (ret < 0) { +- netdev_err(dev->net, "fail to register fixup\n"); ++ netdev_err(dev->net, "Failed to register fixup for PHY_KSZ9031RNX\n"); + return NULL; + } + /* external PHY fixup for LAN8835 */ + ret = phy_register_fixup_for_uid(PHY_LAN8835, 0xfffffff0, + lan8835_fixup); + if (ret < 0) { +- netdev_err(dev->net, "fail to register fixup\n"); ++ netdev_err(dev->net, "Failed to register fixup for PHY_LAN8835\n"); + return NULL; + } + /* add more external PHY fixup here if needed */ +-- +2.44.0 + diff --git a/patches.suse/lan78xx-enable-auto-speed-configuration-for-LAN7850-.patch b/patches.suse/lan78xx-enable-auto-speed-configuration-for-LAN7850-.patch new file mode 100644 index 0000000..f4c9ad5 --- /dev/null +++ b/patches.suse/lan78xx-enable-auto-speed-configuration-for-LAN7850-.patch @@ -0,0 +1,45 @@ +From 0e67899abfbfdea0c3c0ed3fd263ffc601c5c157 Mon Sep 17 00:00:00 2001 +From: Oleksij Rempel +Date: Thu, 22 Feb 2024 13:38:38 +0100 +Subject: [PATCH] lan78xx: enable auto speed configuration for LAN7850 if no + EEPROM is detected +Git-commit: 0e67899abfbfdea0c3c0ed3fd263ffc601c5c157 +References: git-fixes +Patch-mainline: v6.8-rc7 + +Same as LAN7800, LAN7850 can be used without EEPROM. If EEPROM is not +present or not flashed, LAN7850 will fail to sync the speed detected by the PHY +with the MAC. In case link speed is 100Mbit, it will accidentally work, +otherwise no data can be transferred. + +Better way would be to implement link_up callback, or set auto speed +configuration unconditionally. But this changes would be more intrusive. +So, for now, set it only if no EEPROM is found. + +Fixes: e69647a19c87 ("lan78xx: Set ASD in MAC_CR when EEE is enabled.") +Signed-off-by: Oleksij Rempel +Link: https://lore.kernel.org/r/20240222123839.2816561-1-o.rempel@pengutronix.de +Signed-off-by: Jakub Kicinski +Signed-off-by: Oliver Neukum + +--- + drivers/net/usb/lan78xx.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index a6d653ff552a..e06193e831a5 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -3033,7 +3033,8 @@ static int lan78xx_reset(struct lan78xx_net *dev) + if (dev->chipid == ID_REV_CHIP_ID_7801_) + buf &= ~MAC_CR_GMII_EN_; + +- if (dev->chipid == ID_REV_CHIP_ID_7800_) { ++ if (dev->chipid == ID_REV_CHIP_ID_7800_ || ++ dev->chipid == ID_REV_CHIP_ID_7850_) { + ret = lan78xx_read_raw_eeprom(dev, 0, 1, &sig); + if (!ret && sig != EEPROM_INDICATOR) { + /* Implies there is no external eeprom. Set mac speed */ +-- +2.44.0 + diff --git a/patches.suse/md-raid1-properly-indicate-failure-when-ending-a-fai.patch b/patches.suse/md-raid1-properly-indicate-failure-when-ending-a-fai.patch index d1b331c..4097c67 100644 --- a/patches.suse/md-raid1-properly-indicate-failure-when-ending-a-fai.patch +++ b/patches.suse/md-raid1-properly-indicate-failure-when-ending-a-fai.patch @@ -5,7 +5,7 @@ Patch-mainline: v5.13-rc1 Git-commit: 2417b9869b81882ab90fd5ed1081a1cb2d4db1dd Subject: [PATCH] md/raid1: properly indicate failure when ending a failed write request -References: bsc#1185680 +References: bsc#1185680 CVE-2021-46950 bsc#1220662 This patch addresses a data corruption bug in raid1 arrays using bitmaps. Without this fix, the bitmap bits for the failed I/O end up being cleared. diff --git a/patches.suse/misc-uss720-fix-memory-leak-in-uss720_probe.patch b/patches.suse/misc-uss720-fix-memory-leak-in-uss720_probe.patch index 54e7d8c..673b671 100644 --- a/patches.suse/misc-uss720-fix-memory-leak-in-uss720_probe.patch +++ b/patches.suse/misc-uss720-fix-memory-leak-in-uss720_probe.patch @@ -4,7 +4,7 @@ Date: Fri, 14 May 2021 20:43:48 +0800 Subject: [PATCH] misc/uss720: fix memory leak in uss720_probe Git-commit: dcb4b8ad6a448532d8b681b5d1a7036210b622de Patch-mainline: v5.13-rc4 -References: git-fixes +References: git-fixes CVE-2021-47173 bsc#1221993 uss720_probe forgets to decrease the refcount of usbdev in uss720_probe. Fix this by decreasing the refcount of usbdev by usb_put_dev. diff --git a/patches.suse/mmc-moxart_remove-Fix-UAF.patch b/patches.suse/mmc-moxart_remove-Fix-UAF.patch index 8ae9313..aa5da5e 100644 --- a/patches.suse/mmc-moxart_remove-Fix-UAF.patch +++ b/patches.suse/mmc-moxart_remove-Fix-UAF.patch @@ -4,7 +4,7 @@ Date: Thu, 27 Jan 2022 08:16:38 +0100 Subject: [PATCH] moxart: fix potential use-after-free on remove path Git-commit: bd2db32e7c3e35bd4d9b8bbff689434a50893546 Patch-mainline: v5.17-rc4 -References: bsc#1194516 CVE-2022-0487 +References: bsc#1194516 CVE-2022-0487 CVE-2022-48626 bsc#1220366 It was reported that the mmc host structure could be accessed after it was freed in moxart_remove(), so fix this by saving the base register of diff --git a/patches.suse/msft-hv-2305-Drivers-hv-vmbus-Use-after-free-in-__vmbus_open.patch b/patches.suse/msft-hv-2305-Drivers-hv-vmbus-Use-after-free-in-__vmbus_open.patch index 90dfcd6..adacf14 100644 --- a/patches.suse/msft-hv-2305-Drivers-hv-vmbus-Use-after-free-in-__vmbus_open.patch +++ b/patches.suse/msft-hv-2305-Drivers-hv-vmbus-Use-after-free-in-__vmbus_open.patch @@ -3,7 +3,7 @@ Date: Tue, 13 Apr 2021 13:50:04 +0300 Patch-mainline: v5.13-rc1 Subject: Drivers: hv: vmbus: Use after free in __vmbus_open() Git-commit: 3e9bf43f7f7a46f21ec071cb47be92d0874c48da -References: git-fixes +References: git-fixes CVE-2021-47049 bsc#1220692 The "open_info" variable is added to the &vmbus_connection.chn_msg_list, but the error handling frees "open_info" without removing it from the diff --git a/patches.suse/msft-hv-2316-uio_hv_generic-Fix-a-memory-leak-in-error-handling-p.patch b/patches.suse/msft-hv-2316-uio_hv_generic-Fix-a-memory-leak-in-error-handling-p.patch index 76ee174..387a3a8 100644 --- a/patches.suse/msft-hv-2316-uio_hv_generic-Fix-a-memory-leak-in-error-handling-p.patch +++ b/patches.suse/msft-hv-2316-uio_hv_generic-Fix-a-memory-leak-in-error-handling-p.patch @@ -1,7 +1,7 @@ From: Christophe JAILLET Date: Sun, 9 May 2021 09:13:03 +0200 Patch-mainline: v5.13-rc3 -References: git-fixes +References: git-fixes CVE-2021-47071 bsc#1220846 Subject: uio_hv_generic: Fix a memory leak in error handling paths Git-commit: 3ee098f96b8b6c1a98f7f97915f8873164e6af9d diff --git a/patches.suse/msft-hv-2317-uio_hv_generic-Fix-another-memory-leak-in-error-hand.patch b/patches.suse/msft-hv-2317-uio_hv_generic-Fix-another-memory-leak-in-error-hand.patch index e141e38..0f6d57c 100644 --- a/patches.suse/msft-hv-2317-uio_hv_generic-Fix-another-memory-leak-in-error-hand.patch +++ b/patches.suse/msft-hv-2317-uio_hv_generic-Fix-another-memory-leak-in-error-hand.patch @@ -1,7 +1,7 @@ From: Christophe JAILLET Date: Sun, 9 May 2021 09:13:12 +0200 Patch-mainline: v5.13-rc3 -References: git-fixes +References: git-fixes CVE-2021-47070 bsc#1220829 Subject: uio_hv_generic: Fix another memory leak in error handling paths Git-commit: 0b0226be3a52dadd965644bc52a807961c2c26df diff --git a/patches.suse/mtd-require-write-permissions-for-locking-and-badblo.patch b/patches.suse/mtd-require-write-permissions-for-locking-and-badblo.patch index bc8c2ef..6b65ebf 100644 --- a/patches.suse/mtd-require-write-permissions-for-locking-and-badblo.patch +++ b/patches.suse/mtd-require-write-permissions-for-locking-and-badblo.patch @@ -7,7 +7,7 @@ Content-type: text/plain; charset=UTF-8 Content-transfer-encoding: 8bit Git-commit: 1e97743fd180981bef5f01402342bb54bf1c6366 Patch-mainline: v5.13-rc1 -References: git-fixes +References: git-fixes CVE-2021-47055 bsc#1220768 MEMLOCK, MEMUNLOCK and OTPLOCK modify protection bits. Thus require write permission. Depending on the hardware MEMLOCK might even be diff --git a/patches.suse/nbd-Fix-NULL-pointer-in-flush_workqueue-79eb.patch b/patches.suse/nbd-Fix-NULL-pointer-in-flush_workqueue-79eb.patch index 76d6bec..7f5b004 100644 --- a/patches.suse/nbd-Fix-NULL-pointer-in-flush_workqueue-79eb.patch +++ b/patches.suse/nbd-Fix-NULL-pointer-in-flush_workqueue-79eb.patch @@ -4,7 +4,7 @@ Date: Wed, 12 May 2021 19:43:30 +0800 Subject: [PATCH] nbd: Fix NULL pointer in flush_workqueue Git-commit: 79ebe9110fa458d58f1fceb078e2068d7ad37390 Patch-mainline: v5.13-rc2 -References: git-fixes +References: git-fixes CVE-2021-46981 bsc#1220611 Open /dev/nbdX first, the config_refs will be 1 and the pointers in nbd_device are still null. Disconnect diff --git a/patches.suse/net-Fix-features-skip-in-for_each_netdev_feature.patch b/patches.suse/net-Fix-features-skip-in-for_each_netdev_feature.patch new file mode 100644 index 0000000..544dcea --- /dev/null +++ b/patches.suse/net-Fix-features-skip-in-for_each_netdev_feature.patch @@ -0,0 +1,42 @@ +From: Tariq Toukan +Date: Wed, 4 May 2022 11:09:14 +0300 +Subject: net: Fix features skip in for_each_netdev_feature() +Git-commit: 85db6352fc8a158a893151baa1716463d34a20d0 +Patch-mainline: 5.18-rc7 +References: git-fixes + +The find_next_netdev_feature() macro gets the "remaining length", +not bit index. +Passing "bit - 1" for the following iteration is wrong as it skips +the adjacent bit. Pass "bit" instead. + +Fixes: 3b89ea9c5902 ("net: Fix for_each_netdev_feature on Big endian") +Signed-off-by: Tariq Toukan +Reviewed-by: Gal Pressman +Link: https://lore.kernel.org/r/20220504080914.1918-1-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Jiri Slaby +--- + include/linux/netdev_features.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/include/linux/netdev_features.h ++++ b/include/linux/netdev_features.h +@@ -156,7 +156,7 @@ enum { + #define NETIF_F_HW_TLS_TX __NETIF_F(HW_TLS_TX) + #define NETIF_F_HW_TLS_RX __NETIF_F(HW_TLS_RX) + +-/* Finds the next feature with the highest number of the range of start till 0. ++/* Finds the next feature with the highest number of the range of start-1 till 0. + */ + static inline int find_next_netdev_feature(u64 feature, unsigned long start) + { +@@ -175,7 +175,7 @@ static inline int find_next_netdev_featu + for ((bit) = find_next_netdev_feature((mask_addr), \ + NETDEV_FEATURE_COUNT); \ + (bit) >= 0; \ +- (bit) = find_next_netdev_feature((mask_addr), (bit) - 1)) ++ (bit) = find_next_netdev_feature((mask_addr), (bit))) + + /* Features valid for ethtool to change */ + /* = all defined minus driver/device-class-related */ diff --git a/patches.suse/net-allwinner-Fix-some-resources-leak-in-the-error-h.patch b/patches.suse/net-allwinner-Fix-some-resources-leak-in-the-error-h.patch new file mode 100644 index 0000000..375092d --- /dev/null +++ b/patches.suse/net-allwinner-Fix-some-resources-leak-in-the-error-h.patch @@ -0,0 +1,64 @@ +From acecc240618b73e6e53b516218e3896b79d961dc Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Mon, 14 Dec 2020 21:21:17 +0100 +Subject: [PATCH 2/2] net: allwinner: Fix some resources leak in the error + handling path of the probe and in the remove function +Git-commit: 322e53d1e2529ae9d501f5e0f20604a79b873aef +References: git-fixes +Patch-mainline: v5.11-rc1 + +'irq_of_parse_and_map()' should be balanced by a corresponding +'irq_dispose_mapping()' call. Otherwise, there is some resources leaks. + +Add such a call in the error handling path of the probe function and in the +remove function. + +Fixes: 492205050d77 ("net: Add EMAC ethernet driver found on Allwinner A10 SoC's") +Signed-off-by: Christophe JAILLET +Link: https://lore.kernel.org/r/20201214202117.146293-1-christophe.jaillet@wanadoo.fr +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/allwinner/sun4i-emac.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c +index c458b81ba63a..d249a4309da2 100644 +--- a/drivers/net/ethernet/allwinner/sun4i-emac.c ++++ b/drivers/net/ethernet/allwinner/sun4i-emac.c +@@ -847,13 +847,13 @@ static int emac_probe(struct platform_device *pdev) + db->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(db->clk)) { + ret = PTR_ERR(db->clk); +- goto out_iounmap; ++ goto out_dispose_mapping; + } + + ret = clk_prepare_enable(db->clk); + if (ret) { + dev_err(&pdev->dev, "Error couldn't enable clock (%d)\n", ret); +- goto out_iounmap; ++ goto out_dispose_mapping; + } + + ret = sunxi_sram_claim(&pdev->dev); +@@ -910,6 +910,8 @@ static int emac_probe(struct platform_device *pdev) + sunxi_sram_release(&pdev->dev); + out_clk_disable_unprepare: + clk_disable_unprepare(db->clk); ++out_dispose_mapping: ++ irq_dispose_mapping(ndev->irq); + out_iounmap: + iounmap(db->membase); + out: +@@ -928,6 +930,7 @@ static int emac_remove(struct platform_device *pdev) + unregister_netdev(ndev); + sunxi_sram_release(&pdev->dev); + clk_disable_unprepare(db->clk); ++ irq_dispose_mapping(ndev->irq); + iounmap(db->membase); + free_netdev(ndev); + +-- +2.16.4 + diff --git a/patches.suse/net-atheros-switch-from-pci_-to-dma_-API.patch b/patches.suse/net-atheros-switch-from-pci_-to-dma_-API.patch new file mode 100644 index 0000000..46649c7 --- /dev/null +++ b/patches.suse/net-atheros-switch-from-pci_-to-dma_-API.patch @@ -0,0 +1,556 @@ +From dcd843e68d046933b6aa7dadc82894b77d8ec7de Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Sun, 23 Aug 2020 10:03:53 +0200 +Subject: [PATCH 2/8] net: atheros: switch from 'pci_' to 'dma_' API +Git-commit: 85eb5bc33717eea3642148632f3ecbefb7ae6a02 +References: git-fixes +Patch-mainline: v5.10-rc1 + +The wrappers in include/linux/pci-dma-compat.h should go away. + +The patch has been generated with the coccinelle script below and has been +hand modified to replace GFP_ with a correct flag. +It has been compile tested. + +When memory is allocated in 'atl1e_setup_ring_resources()' (atl1e_main.c), +'atl1_setup_ring_resources()' (atl1.c) and 'atl2_setup_ring_resources()' +(atl2.c) GFP_KERNEL can be used because it can be called from a .ndo_open. + +'atl1_setup_ring_resources()' (atl1.c) can also be called from a +'.set_ringparam' (see struct ethtool_ops) where sleep is also allowed. + +Both cases are protected by 'rtnl_lock()' which is a mutex. So these +function can sleep. + +@@ +@@ +- PCI_DMA_BIDIRECTIONAL ++ DMA_BIDIRECTIONAL + +@@ +@@ +- PCI_DMA_TODEVICE ++ DMA_TO_DEVICE + +@@ +@@ +- PCI_DMA_FROMDEVICE ++ DMA_FROM_DEVICE + +@@ +@@ +- PCI_DMA_NONE ++ DMA_NONE + +@@ +expression e1, e2, e3; +@@ +- pci_alloc_consistent(e1, e2, e3) ++ dma_alloc_coherent(&e1->dev, e2, e3, GFP_) + +@@ +expression e1, e2, e3; +@@ +- pci_zalloc_consistent(e1, e2, e3) ++ dma_alloc_coherent(&e1->dev, e2, e3, GFP_) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_free_consistent(e1, e2, e3, e4) ++ dma_free_coherent(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_map_single(e1, e2, e3, e4) ++ dma_map_single(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_unmap_single(e1, e2, e3, e4) ++ dma_unmap_single(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4, e5; +@@ +- pci_map_page(e1, e2, e3, e4, e5) ++ dma_map_page(&e1->dev, e2, e3, e4, e5) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_unmap_page(e1, e2, e3, e4) ++ dma_unmap_page(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_map_sg(e1, e2, e3, e4) ++ dma_map_sg(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_unmap_sg(e1, e2, e3, e4) ++ dma_unmap_sg(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_dma_sync_single_for_cpu(e1, e2, e3, e4) ++ dma_sync_single_for_cpu(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_dma_sync_single_for_device(e1, e2, e3, e4) ++ dma_sync_single_for_device(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_dma_sync_sg_for_cpu(e1, e2, e3, e4) ++ dma_sync_sg_for_cpu(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2, e3, e4; +@@ +- pci_dma_sync_sg_for_device(e1, e2, e3, e4) ++ dma_sync_sg_for_device(&e1->dev, e2, e3, e4) + +@@ +expression e1, e2; +@@ +- pci_dma_mapping_error(e1, e2) ++ dma_mapping_error(&e1->dev, e2) + +@@ +expression e1, e2; +@@ +- pci_set_dma_mask(e1, e2) ++ dma_set_mask(&e1->dev, e2) + +@@ +expression e1, e2; +@@ +- pci_set_consistent_dma_mask(e1, e2) ++ dma_set_coherent_mask(&e1->dev, e2) + +Signed-off-by: Christophe JAILLET +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 48 ++++++++++----------- + drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 57 +++++++++++++++---------- + drivers/net/ethernet/atheros/atlx/atl1.c | 48 +++++++++++---------- + drivers/net/ethernet/atheros/atlx/atl2.c | 12 +++--- + 4 files changed, 88 insertions(+), 77 deletions(-) + +diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +index 21507548c104..7ef0d35c931f 100644 +--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c ++++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +@@ -841,16 +841,16 @@ static inline void atl1c_clean_buffer(struct pci_dev *pdev, + return; + if (buffer_info->dma) { + if (buffer_info->flags & ATL1C_PCIMAP_FROMDEVICE) +- pci_driection = PCI_DMA_FROMDEVICE; ++ pci_driection = DMA_FROM_DEVICE; + else +- pci_driection = PCI_DMA_TODEVICE; ++ pci_driection = DMA_TO_DEVICE; + + if (buffer_info->flags & ATL1C_PCIMAP_SINGLE) +- pci_unmap_single(pdev, buffer_info->dma, +- buffer_info->length, pci_driection); ++ dma_unmap_single(&pdev->dev, buffer_info->dma, ++ buffer_info->length, pci_driection); + else if (buffer_info->flags & ATL1C_PCIMAP_PAGE) +- pci_unmap_page(pdev, buffer_info->dma, +- buffer_info->length, pci_driection); ++ dma_unmap_page(&pdev->dev, buffer_info->dma, ++ buffer_info->length, pci_driection); + } + if (buffer_info->skb) + dev_consume_skb_any(buffer_info->skb); +@@ -948,9 +948,8 @@ static void atl1c_free_ring_resources(struct atl1c_adapter *adapter) + { + struct pci_dev *pdev = adapter->pdev; + +- pci_free_consistent(pdev, adapter->ring_header.size, +- adapter->ring_header.desc, +- adapter->ring_header.dma); ++ dma_free_coherent(&pdev->dev, adapter->ring_header.size, ++ adapter->ring_header.desc, adapter->ring_header.dma); + adapter->ring_header.desc = NULL; + + /* Note: just free tdp_ring.buffer_info, +@@ -1732,10 +1731,9 @@ static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter) + ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY); + buffer_info->skb = skb; + buffer_info->length = adapter->rx_buffer_len; +- mapping = pci_map_single(pdev, vir_addr, +- buffer_info->length, +- PCI_DMA_FROMDEVICE); +- if (unlikely(pci_dma_mapping_error(pdev, mapping))) { ++ mapping = dma_map_single(&pdev->dev, vir_addr, ++ buffer_info->length, DMA_FROM_DEVICE); ++ if (unlikely(dma_mapping_error(&pdev->dev, mapping))) { + dev_kfree_skb(skb); + buffer_info->skb = NULL; + buffer_info->length = 0; +@@ -1846,8 +1844,8 @@ static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter, + rfd_index = (rrs->word0 >> RRS_RX_RFD_INDEX_SHIFT) & + RRS_RX_RFD_INDEX_MASK; + buffer_info = &rfd_ring->buffer_info[rfd_index]; +- pci_unmap_single(pdev, buffer_info->dma, +- buffer_info->length, PCI_DMA_FROMDEVICE); ++ dma_unmap_single(&pdev->dev, buffer_info->dma, ++ buffer_info->length, DMA_FROM_DEVICE); + skb = buffer_info->skb; + } else { + /* TODO */ +@@ -2123,10 +2121,10 @@ static int atl1c_tx_map(struct atl1c_adapter *adapter, + + buffer_info = atl1c_get_tx_buffer(adapter, use_tpd); + buffer_info->length = map_len; +- buffer_info->dma = pci_map_single(adapter->pdev, +- skb->data, hdr_len, PCI_DMA_TODEVICE); +- if (unlikely(pci_dma_mapping_error(adapter->pdev, +- buffer_info->dma))) ++ buffer_info->dma = dma_map_single(&adapter->pdev->dev, ++ skb->data, hdr_len, ++ DMA_TO_DEVICE); ++ if (unlikely(dma_mapping_error(&adapter->pdev->dev, buffer_info->dma))) + goto err_dma; + ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY); + ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE, +@@ -2148,10 +2146,10 @@ static int atl1c_tx_map(struct atl1c_adapter *adapter, + buffer_info = atl1c_get_tx_buffer(adapter, use_tpd); + buffer_info->length = buf_len - mapped_len; + buffer_info->dma = +- pci_map_single(adapter->pdev, skb->data + mapped_len, +- buffer_info->length, PCI_DMA_TODEVICE); +- if (unlikely(pci_dma_mapping_error(adapter->pdev, +- buffer_info->dma))) ++ dma_map_single(&adapter->pdev->dev, ++ skb->data + mapped_len, ++ buffer_info->length, DMA_TO_DEVICE); ++ if (unlikely(dma_mapping_error(&adapter->pdev->dev, buffer_info->dma))) + goto err_dma; + + ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY); +@@ -2569,8 +2567,8 @@ static int atl1c_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + * various kernel subsystems to support the mechanics required by a + * fixed-high-32-bit system. + */ +- if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) || +- (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) { ++ if ((dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)) != 0) || ++ (dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)) != 0)) { + dev_err(&pdev->dev, "No usable DMA configuration,aborting\n"); + goto err_dma; + } +diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +index 0d08039981b5..189535f6b22c 100644 +--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c ++++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +@@ -670,11 +670,13 @@ static void atl1e_clean_tx_ring(struct atl1e_adapter *adapter) + tx_buffer = &tx_ring->tx_buffer[index]; + if (tx_buffer->dma) { + if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE) +- pci_unmap_single(pdev, tx_buffer->dma, +- tx_buffer->length, PCI_DMA_TODEVICE); ++ dma_unmap_single(&pdev->dev, tx_buffer->dma, ++ tx_buffer->length, ++ DMA_TO_DEVICE); + else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE) +- pci_unmap_page(pdev, tx_buffer->dma, +- tx_buffer->length, PCI_DMA_TODEVICE); ++ dma_unmap_page(&pdev->dev, tx_buffer->dma, ++ tx_buffer->length, ++ DMA_TO_DEVICE); + tx_buffer->dma = 0; + } + } +@@ -790,8 +792,8 @@ static void atl1e_free_ring_resources(struct atl1e_adapter *adapter) + atl1e_clean_rx_ring(adapter); + + if (adapter->ring_vir_addr) { +- pci_free_consistent(pdev, adapter->ring_size, +- adapter->ring_vir_addr, adapter->ring_dma); ++ dma_free_coherent(&pdev->dev, adapter->ring_size, ++ adapter->ring_vir_addr, adapter->ring_dma); + adapter->ring_vir_addr = NULL; + } + +@@ -826,11 +828,12 @@ static int atl1e_setup_ring_resources(struct atl1e_adapter *adapter) + /* real ring DMA buffer */ + + size = adapter->ring_size; +- adapter->ring_vir_addr = pci_zalloc_consistent(pdev, adapter->ring_size, +- &adapter->ring_dma); ++ adapter->ring_vir_addr = dma_alloc_coherent(&pdev->dev, ++ adapter->ring_size, ++ &adapter->ring_dma, GFP_KERNEL); + if (adapter->ring_vir_addr == NULL) { + netdev_err(adapter->netdev, +- "pci_alloc_consistent failed, size = D%d\n", size); ++ "dma_alloc_coherent failed, size = D%d\n", size); + return -ENOMEM; + } + +@@ -886,8 +889,8 @@ static int atl1e_setup_ring_resources(struct atl1e_adapter *adapter) + return 0; + failed: + if (adapter->ring_vir_addr != NULL) { +- pci_free_consistent(pdev, adapter->ring_size, +- adapter->ring_vir_addr, adapter->ring_dma); ++ dma_free_coherent(&pdev->dev, adapter->ring_size, ++ adapter->ring_vir_addr, adapter->ring_dma); + adapter->ring_vir_addr = NULL; + } + return err; +@@ -1249,11 +1252,15 @@ static bool atl1e_clean_tx_irq(struct atl1e_adapter *adapter) + tx_buffer = &tx_ring->tx_buffer[next_to_clean]; + if (tx_buffer->dma) { + if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE) +- pci_unmap_single(adapter->pdev, tx_buffer->dma, +- tx_buffer->length, PCI_DMA_TODEVICE); ++ dma_unmap_single(&adapter->pdev->dev, ++ tx_buffer->dma, ++ tx_buffer->length, ++ DMA_TO_DEVICE); + else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE) +- pci_unmap_page(adapter->pdev, tx_buffer->dma, +- tx_buffer->length, PCI_DMA_TODEVICE); ++ dma_unmap_page(&adapter->pdev->dev, ++ tx_buffer->dma, ++ tx_buffer->length, ++ DMA_TO_DEVICE); + tx_buffer->dma = 0; + } + +@@ -1726,8 +1733,9 @@ static int atl1e_tx_map(struct atl1e_adapter *adapter, + + tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd); + tx_buffer->length = map_len; +- tx_buffer->dma = pci_map_single(adapter->pdev, +- skb->data, hdr_len, PCI_DMA_TODEVICE); ++ tx_buffer->dma = dma_map_single(&adapter->pdev->dev, ++ skb->data, hdr_len, ++ DMA_TO_DEVICE); + if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) + return -ENOSPC; + +@@ -1755,8 +1763,9 @@ static int atl1e_tx_map(struct atl1e_adapter *adapter, + ((buf_len - mapped_len) >= MAX_TX_BUF_LEN) ? + MAX_TX_BUF_LEN : (buf_len - mapped_len); + tx_buffer->dma = +- pci_map_single(adapter->pdev, skb->data + mapped_len, +- map_len, PCI_DMA_TODEVICE); ++ dma_map_single(&adapter->pdev->dev, ++ skb->data + mapped_len, map_len, ++ DMA_TO_DEVICE); + + if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) { + /* We need to unwind the mappings we've done */ +@@ -1765,8 +1774,10 @@ static int atl1e_tx_map(struct atl1e_adapter *adapter, + while (adapter->tx_ring.next_to_use != ring_end) { + tpd = atl1e_get_tpd(adapter); + tx_buffer = atl1e_get_tx_buffer(adapter, tpd); +- pci_unmap_single(adapter->pdev, tx_buffer->dma, +- tx_buffer->length, PCI_DMA_TODEVICE); ++ dma_unmap_single(&adapter->pdev->dev, ++ tx_buffer->dma, ++ tx_buffer->length, ++ DMA_TO_DEVICE); + } + /* Reset the tx rings next pointer */ + adapter->tx_ring.next_to_use = ring_start; +@@ -2317,8 +2328,8 @@ static int atl1e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + * various kernel subsystems to support the mechanics required by a + * fixed-high-32-bit system. + */ +- if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) || +- (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) { ++ if ((dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)) != 0) || ++ (dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)) != 0)) { + dev_err(&pdev->dev, "No usable DMA configuration,aborting\n"); + goto err_dma; + } +diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c +index 83d2db2abb45..78b559adca1c 100644 +--- a/drivers/net/ethernet/atheros/atlx/atl1.c ++++ b/drivers/net/ethernet/atheros/atlx/atl1.c +@@ -1069,11 +1069,11 @@ static s32 atl1_setup_ring_resources(struct atl1_adapter *adapter) + + sizeof(struct stats_msg_block) + + 40; + +- ring_header->desc = pci_alloc_consistent(pdev, ring_header->size, +- &ring_header->dma); ++ ring_header->desc = dma_alloc_coherent(&pdev->dev, ring_header->size, ++ &ring_header->dma, GFP_KERNEL); + if (unlikely(!ring_header->desc)) { + if (netif_msg_drv(adapter)) +- dev_err(&pdev->dev, "pci_alloc_consistent failed\n"); ++ dev_err(&pdev->dev, "dma_alloc_coherent failed\n"); + goto err_nomem; + } + +@@ -1157,8 +1157,8 @@ static void atl1_clean_rx_ring(struct atl1_adapter *adapter) + for (i = 0; i < rfd_ring->count; i++) { + buffer_info = &rfd_ring->buffer_info[i]; + if (buffer_info->dma) { +- pci_unmap_page(pdev, buffer_info->dma, +- buffer_info->length, PCI_DMA_FROMDEVICE); ++ dma_unmap_page(&pdev->dev, buffer_info->dma, ++ buffer_info->length, DMA_FROM_DEVICE); + buffer_info->dma = 0; + } + if (buffer_info->skb) { +@@ -1196,8 +1196,8 @@ static void atl1_clean_tx_ring(struct atl1_adapter *adapter) + for (i = 0; i < tpd_ring->count; i++) { + buffer_info = &tpd_ring->buffer_info[i]; + if (buffer_info->dma) { +- pci_unmap_page(pdev, buffer_info->dma, +- buffer_info->length, PCI_DMA_TODEVICE); ++ dma_unmap_page(&pdev->dev, buffer_info->dma, ++ buffer_info->length, DMA_TO_DEVICE); + buffer_info->dma = 0; + } + } +@@ -1238,8 +1238,8 @@ static void atl1_free_ring_resources(struct atl1_adapter *adapter) + atl1_clean_rx_ring(adapter); + + kfree(tpd_ring->buffer_info); +- pci_free_consistent(pdev, ring_header->size, ring_header->desc, +- ring_header->dma); ++ dma_free_coherent(&pdev->dev, ring_header->size, ring_header->desc, ++ ring_header->dma); + + tpd_ring->buffer_info = NULL; + tpd_ring->desc = NULL; +@@ -1887,9 +1887,9 @@ static u16 atl1_alloc_rx_buffers(struct atl1_adapter *adapter) + buffer_info->length = (u16) adapter->rx_buffer_len; + page = virt_to_page(skb->data); + offset = offset_in_page(skb->data); +- buffer_info->dma = pci_map_page(pdev, page, offset, ++ buffer_info->dma = dma_map_page(&pdev->dev, page, offset, + adapter->rx_buffer_len, +- PCI_DMA_FROMDEVICE); ++ DMA_FROM_DEVICE); + rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma); + rfd_desc->buf_len = cpu_to_le16(adapter->rx_buffer_len); + rfd_desc->coalese = 0; +@@ -2013,8 +2013,8 @@ static int atl1_intr_rx(struct atl1_adapter *adapter, int budget) + } + + /* Good Receive */ +- pci_unmap_page(adapter->pdev, buffer_info->dma, +- buffer_info->length, PCI_DMA_FROMDEVICE); ++ dma_unmap_page(&adapter->pdev->dev, buffer_info->dma, ++ buffer_info->length, DMA_FROM_DEVICE); + buffer_info->dma = 0; + skb = buffer_info->skb; + length = le16_to_cpu(rrd->xsz.xsum_sz.pkt_size); +@@ -2083,8 +2083,8 @@ static int atl1_intr_tx(struct atl1_adapter *adapter) + while (cmb_tpd_next_to_clean != sw_tpd_next_to_clean) { + buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean]; + if (buffer_info->dma) { +- pci_unmap_page(adapter->pdev, buffer_info->dma, +- buffer_info->length, PCI_DMA_TODEVICE); ++ dma_unmap_page(&adapter->pdev->dev, buffer_info->dma, ++ buffer_info->length, DMA_TO_DEVICE); + buffer_info->dma = 0; + } + +@@ -2231,9 +2231,9 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb, + buffer_info->length = hdr_len; + page = virt_to_page(skb->data); + offset = offset_in_page(skb->data); +- buffer_info->dma = pci_map_page(adapter->pdev, page, ++ buffer_info->dma = dma_map_page(&adapter->pdev->dev, page, + offset, hdr_len, +- PCI_DMA_TODEVICE); ++ DMA_TO_DEVICE); + + if (++next_to_use == tpd_ring->count) + next_to_use = 0; +@@ -2256,9 +2256,10 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb, + (hdr_len + i * ATL1_MAX_TX_BUF_LEN)); + offset = offset_in_page(skb->data + + (hdr_len + i * ATL1_MAX_TX_BUF_LEN)); +- buffer_info->dma = pci_map_page(adapter->pdev, +- page, offset, buffer_info->length, +- PCI_DMA_TODEVICE); ++ buffer_info->dma = dma_map_page(&adapter->pdev->dev, ++ page, offset, ++ buffer_info->length, ++ DMA_TO_DEVICE); + if (++next_to_use == tpd_ring->count) + next_to_use = 0; + } +@@ -2268,8 +2269,9 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb, + buffer_info->length = buf_len; + page = virt_to_page(skb->data); + offset = offset_in_page(skb->data); +- buffer_info->dma = pci_map_page(adapter->pdev, page, +- offset, buf_len, PCI_DMA_TODEVICE); ++ buffer_info->dma = dma_map_page(&adapter->pdev->dev, page, ++ offset, buf_len, ++ DMA_TO_DEVICE); + if (++next_to_use == tpd_ring->count) + next_to_use = 0; + } +@@ -2946,7 +2948,7 @@ static int atl1_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + * various kernel subsystems to support the mechanics required by a + * fixed-high-32-bit system. + */ +- err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); ++ err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); + if (err) { + dev_err(&pdev->dev, "no usable DMA configuration\n"); + goto err_dma; +diff --git a/drivers/net/ethernet/atheros/atlx/atl2.c b/drivers/net/ethernet/atheros/atlx/atl2.c +index 225b4d452e0e..0a1b51f7ec90 100644 +--- a/drivers/net/ethernet/atheros/atlx/atl2.c ++++ b/drivers/net/ethernet/atheros/atlx/atl2.c +@@ -300,8 +300,8 @@ static s32 atl2_setup_ring_resources(struct atl2_adapter *adapter) + adapter->txs_ring_size * 4 + 7 + /* dword align */ + adapter->rxd_ring_size * 1536 + 127; /* 128bytes align */ + +- adapter->ring_vir_addr = pci_alloc_consistent(pdev, size, +- &adapter->ring_dma); ++ adapter->ring_vir_addr = dma_alloc_coherent(&pdev->dev, size, ++ &adapter->ring_dma, GFP_KERNEL); + if (!adapter->ring_vir_addr) + return -ENOMEM; + memset(adapter->ring_vir_addr, 0, adapter->ring_size); +@@ -683,8 +683,8 @@ static int atl2_request_irq(struct atl2_adapter *adapter) + static void atl2_free_ring_resources(struct atl2_adapter *adapter) + { + struct pci_dev *pdev = adapter->pdev; +- pci_free_consistent(pdev, adapter->ring_size, adapter->ring_vir_addr, +- adapter->ring_dma); ++ dma_free_coherent(&pdev->dev, adapter->ring_size, ++ adapter->ring_vir_addr, adapter->ring_dma); + } + + /** +@@ -1348,8 +1348,8 @@ static int atl2_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + * until the kernel has the proper infrastructure to support 64-bit DMA + * on these devices. + */ +- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) && +- pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { ++ if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)) && ++ dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32))) { + printk(KERN_ERR "atl2: No usable DMA configuration, aborting\n"); + err = -EIO; + goto err_dma; +-- +2.16.4 + diff --git a/patches.suse/net-fec-fix-the-potential-memory-leak-in-fec_enet_in.patch b/patches.suse/net-fec-fix-the-potential-memory-leak-in-fec_enet_in.patch index dee76a9..ac86628 100644 --- a/patches.suse/net-fec-fix-the-potential-memory-leak-in-fec_enet_in.patch +++ b/patches.suse/net-fec-fix-the-potential-memory-leak-in-fec_enet_in.patch @@ -5,7 +5,7 @@ Subject: [PATCH 04/16] net: fec: fix the potential memory leak in fec_enet_init() Git-commit: 619fee9eb13b5d29e4267cb394645608088c28a8 Patch-mainline: v5.13-rc4 -References: git-fixes +References: git-fixes CVE-2021-47150 bsc#1221973 If the memory allocated for cbd_base is failed, it should free the memory allocated for the queues, otherwise it causes diff --git a/patches.suse/net-hso-fix-NULL-deref-on-disconnect-regression.patch b/patches.suse/net-hso-fix-NULL-deref-on-disconnect-regression.patch index 8974dea..8e784f5 100644 --- a/patches.suse/net-hso-fix-NULL-deref-on-disconnect-regression.patch +++ b/patches.suse/net-hso-fix-NULL-deref-on-disconnect-regression.patch @@ -3,7 +3,7 @@ From: Johan Hovold Date: Mon, 26 Apr 2021 10:11:49 +0200 Subject: [PATCH] net: hso: fix NULL-deref on disconnect regression Git-commit: 2ad5692db72874f02b9ad551d26345437ea4f7f3 -References: git-fixes +References: bsc#1220416 bsc#1220418 CVE-2021-46905 CVE-2021-46904 Patch-mainline: v5.13-rc1 Commit 8a12f8836145 ("net: hso: fix null-ptr-deref during tty device diff --git a/patches.suse/net-hso-fix-null-ptr-deref-during-tty-device-unregis.patch b/patches.suse/net-hso-fix-null-ptr-deref-during-tty-device-unregis.patch index 6ae4003..6f2fa39 100644 --- a/patches.suse/net-hso-fix-null-ptr-deref-during-tty-device-unregis.patch +++ b/patches.suse/net-hso-fix-null-ptr-deref-during-tty-device-unregis.patch @@ -3,7 +3,7 @@ From: Anirudh Rayabharam Date: Wed, 7 Apr 2021 22:57:22 +0530 Subject: [PATCH] net: hso: fix null-ptr-deref during tty device unregistration Git-commit: 8a12f8836145ffe37e9c8733dce18c22fb668b66 -References: git-fixes +References: bsc#1220416 CVE-2021-46904 Patch-mainline: v5.12-rc7 Multiple ttys try to claim the same the minor number causing a double diff --git a/patches.suse/net-lan78xx-Allow-for-VLAN-headers-in-timeout-calcs.patch b/patches.suse/net-lan78xx-Allow-for-VLAN-headers-in-timeout-calcs.patch new file mode 100644 index 0000000..e3da707 --- /dev/null +++ b/patches.suse/net-lan78xx-Allow-for-VLAN-headers-in-timeout-calcs.patch @@ -0,0 +1,48 @@ +From 2259b7a64d71f27311a19fd7a5bed47413d75985 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Mon, 25 Jun 2018 15:07:12 +0100 +Subject: [PATCH] net: lan78xx: Allow for VLAN headers in timeout calcs +Git-commit: 2259b7a64d71f27311a19fd7a5bed47413d75985 +References: git-fixes +Patch-mainline: v4.18-rc4 + +The frame abort timeout being set by lan78xx_set_rx_max_frame_length +didn't account for any VLAN headers, resulting in very low +throughput if used with tagged VLANs. + +Use VLAN_ETH_HLEN instead of ETH_HLEN to correct for this. + +Signed-off-by: Dave Stevenson +Signed-off-by: David S. Miller +Signed-off-by: Oliver Neukum + +--- + drivers/net/usb/lan78xx.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index 8dff87ec6d99..1a1d3cc8e308 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -2298,7 +2298,7 @@ static int lan78xx_change_mtu(struct net_device *netdev, int new_mtu) + if ((ll_mtu % dev->maxpacket) == 0) + return -EDOM; + +- ret = lan78xx_set_rx_max_frame_length(dev, new_mtu + ETH_HLEN); ++ ret = lan78xx_set_rx_max_frame_length(dev, new_mtu + VLAN_ETH_HLEN); + + netdev->mtu = new_mtu; + +@@ -2587,7 +2587,8 @@ static int lan78xx_reset(struct lan78xx_net *dev) + buf |= FCT_TX_CTL_EN_; + ret = lan78xx_write_reg(dev, FCT_TX_CTL, buf); + +- ret = lan78xx_set_rx_max_frame_length(dev, dev->net->mtu + ETH_HLEN); ++ ret = lan78xx_set_rx_max_frame_length(dev, ++ dev->net->mtu + VLAN_ETH_HLEN); + + ret = lan78xx_read_reg(dev, MAC_RX, &buf); + buf |= MAC_RX_RXEN_; +-- +2.44.0 + diff --git a/patches.suse/net-lan78xx-Make-declaration-style-consistent.patch b/patches.suse/net-lan78xx-Make-declaration-style-consistent.patch new file mode 100644 index 0000000..2d45d72 --- /dev/null +++ b/patches.suse/net-lan78xx-Make-declaration-style-consistent.patch @@ -0,0 +1,68 @@ +From 51ceac9fb5886febc4116123012caa268277643b Mon Sep 17 00:00:00 2001 +From: Stefan Wahren +Date: Tue, 4 Sep 2018 19:29:12 +0200 +Subject: [PATCH] net: lan78xx: Make declaration style consistent +Git-commit: 51ceac9fb5886febc4116123012caa268277643b +References: git-fixes +Patch-mainline: v4.20-rc1 + +This patch makes some declaration more consistent. + +Signed-off-by: Stefan Wahren +Reviewed-by: Raghuram Chary Jallipalli +Signed-off-by: David S. Miller +Signed-off-by: Oliver Neukum + +--- + drivers/net/usb/lan78xx.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index e1c055d68d87..331bc99d55e7 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -1015,7 +1015,7 @@ static int lan78xx_dataport_write(struct lan78xx_net *dev, u32 ram_select, + static void lan78xx_set_addr_filter(struct lan78xx_priv *pdata, + int index, u8 addr[ETH_ALEN]) + { +- u32 temp; ++ u32 temp; + + if ((pdata) && (index > 0) && (index < NUM_OF_MAF)) { + temp = addr[3]; +@@ -2690,7 +2690,7 @@ static void lan78xx_terminate_urbs(struct lan78xx_net *dev) + + static int lan78xx_stop(struct net_device *net) + { +- struct lan78xx_net *dev = netdev_priv(net); ++ struct lan78xx_net *dev = netdev_priv(net); + + if (timer_pending(&dev->stat_monitor)) + del_timer_sync(&dev->stat_monitor); +@@ -3073,7 +3073,7 @@ static void lan78xx_rx_vlan_offload(struct lan78xx_net *dev, + + static void lan78xx_skb_return(struct lan78xx_net *dev, struct sk_buff *skb) + { +- int status; ++ int status; + + if (test_bit(EVENT_RX_PAUSED, &dev->flags)) { + skb_queue_tail(&dev->rxq_pause, skb); +@@ -3633,10 +3633,10 @@ static void intr_complete(struct urb *urb) + + static void lan78xx_disconnect(struct usb_interface *intf) + { +- struct lan78xx_net *dev; +- struct usb_device *udev; +- struct net_device *net; +- struct phy_device *phydev; ++ struct lan78xx_net *dev; ++ struct usb_device *udev; ++ struct net_device *net; ++ struct phy_device *phydev; + + dev = usb_get_intfdata(intf); + usb_set_intfdata(intf, NULL); +-- +2.44.0 + diff --git a/patches.suse/net-lan78xx-Merge-memcpy-lexx_to_cpus-to-get_unalign.patch b/patches.suse/net-lan78xx-Merge-memcpy-lexx_to_cpus-to-get_unalign.patch new file mode 100644 index 0000000..621dc5c --- /dev/null +++ b/patches.suse/net-lan78xx-Merge-memcpy-lexx_to_cpus-to-get_unalign.patch @@ -0,0 +1,59 @@ +From bb448f8a60ea93722edb28418448e0008d148b0c Mon Sep 17 00:00:00 2001 +From: Chuhong Yuan +Date: Fri, 19 Jul 2019 15:36:15 +0800 +Subject: [PATCH] net: lan78xx: Merge memcpy + lexx_to_cpus to + get_unaligned_lexx +Git-commit: bb448f8a60ea93722edb28418448e0008d148b0c +References: git-fixes +Patch-mainline: v5.4-rc1 + +Merge the combo use of memcpy and lexx_to_cpus. +Use get_unaligned_lexx instead. +This simplifies the code. + +Signed-off-by: Chuhong Yuan +Acked-by: Woojung Huh +Signed-off-by: David S. Miller +Signed-off-by: Oliver Neukum + +--- + drivers/net/usb/lan78xx.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index 3d92ea6fcc02..9c33b35bd155 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -1258,8 +1258,7 @@ static void lan78xx_status(struct lan78xx_net *dev, struct urb *urb) + return; + } + +- memcpy(&intdata, urb->transfer_buffer, 4); +- le32_to_cpus(&intdata); ++ intdata = get_unaligned_le32(urb->transfer_buffer); + + if (intdata & INT_ENP_PHY_INT) { + netif_dbg(dev, link, dev->net, "PHY INTR: 0x%08x\n", intdata); +@@ -3105,16 +3104,13 @@ static int lan78xx_rx(struct lan78xx_net *dev, struct sk_buff *skb) + struct sk_buff *skb2; + unsigned char *packet; + +- memcpy(&rx_cmd_a, skb->data, sizeof(rx_cmd_a)); +- le32_to_cpus(&rx_cmd_a); ++ rx_cmd_a = get_unaligned_le32(skb->data); + skb_pull(skb, sizeof(rx_cmd_a)); + +- memcpy(&rx_cmd_b, skb->data, sizeof(rx_cmd_b)); +- le32_to_cpus(&rx_cmd_b); ++ rx_cmd_b = get_unaligned_le32(skb->data); + skb_pull(skb, sizeof(rx_cmd_b)); + +- memcpy(&rx_cmd_c, skb->data, sizeof(rx_cmd_c)); +- le16_to_cpus(&rx_cmd_c); ++ rx_cmd_c = get_unaligned_le16(skb->data); + skb_pull(skb, sizeof(rx_cmd_c)); + + packet = skb->data; +-- +2.44.0 + diff --git a/patches.suse/net-lan78xx-fix-runtime-PM-count-underflow-on-link-s.patch b/patches.suse/net-lan78xx-fix-runtime-PM-count-underflow-on-link-s.patch new file mode 100644 index 0000000..fb75fb9 --- /dev/null +++ b/patches.suse/net-lan78xx-fix-runtime-PM-count-underflow-on-link-s.patch @@ -0,0 +1,40 @@ +From 1eecc7ab82c42133b748e1895275942a054a7f67 Mon Sep 17 00:00:00 2001 +From: Oleksij Rempel +Date: Wed, 28 Feb 2024 13:45:17 +0100 +Subject: [PATCH] net: lan78xx: fix runtime PM count underflow on link stop +Git-commit: 1eecc7ab82c42133b748e1895275942a054a7f67 +References: git-fixes +Patch-mainline: v6.8 + +Current driver has some asymmetry in the runtime PM calls. On lan78xx_open() +it will call usb_autopm_get() and unconditionally usb_autopm_put(). And +on lan78xx_stop() it will call only usb_autopm_put(). So far, it was +working only because this driver do not activate autosuspend by default, +so it was visible only by warning "Runtime PM usage count underflow!". + +Since, with current driver, we can't use runtime PM with active link, +execute lan78xx_open()->usb_autopm_put() only in error case. Otherwise, +keep ref counting high as long as interface is open. + +Fixes: 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to 10/100/1000 Ethernet device driver") +Signed-off-by: Oleksij Rempel +Reviewed-by: Jiri Pirko +Signed-off-by: David S. Miller +Signed-off-by: Oliver Neukum + +--- + drivers/net/usb/lan78xx.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -2370,7 +2370,8 @@ static int lan78xx_change_mtu(struct net + } + } + +- usb_autopm_put_interface(dev->intf); ++ if (ret < 0) ++ usb_autopm_put_interface(dev->intf); + + return 0; + } diff --git a/patches.suse/net-lan78xx-remove-set-but-not-used-variable-event.patch b/patches.suse/net-lan78xx-remove-set-but-not-used-variable-event.patch new file mode 100644 index 0000000..737a685 --- /dev/null +++ b/patches.suse/net-lan78xx-remove-set-but-not-used-variable-event.patch @@ -0,0 +1,40 @@ +From 337d866a8014987dd45cf138ddcb9eca1ae44d56 Mon Sep 17 00:00:00 2001 +From: YueHaibing +Date: Wed, 23 Oct 2019 15:36:26 +0800 +Subject: [PATCH] net: lan78xx: remove set but not used variable 'event' +Git-commit: 337d866a8014987dd45cf138ddcb9eca1ae44d56 +References: git-fixes +Patch-mainline: v5.5-rc1 + +Fixes gcc '-Wunused-but-set-variable' warning: + +drivers/net/usb/lan78xx.c:3995:6: warning: + variable event set but not used [-Wunused-but-set-variable] + +It is never used, so can be removed. + +Signed-off-by: YueHaibing +Signed-off-by: David S. Miller +Signed-off-by: Oliver Neukum + +--- + drivers/net/usb/lan78xx.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index 62948098191f..f8c0818e56c9 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -3992,9 +3992,6 @@ static int lan78xx_suspend(struct usb_interface *intf, pm_message_t message) + struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]); + u32 buf; + int ret; +- int event; +- +- event = message.event; + + if (!dev->suspend_count++) { + spin_lock_irq(&dev->txq.lock); +-- +2.44.0 + diff --git a/patches.suse/net-macb-ensure-the-device-is-available-before-acces.patch b/patches.suse/net-macb-ensure-the-device-is-available-before-acces.patch new file mode 100644 index 0000000..5c20968 --- /dev/null +++ b/patches.suse/net-macb-ensure-the-device-is-available-before-acces.patch @@ -0,0 +1,45 @@ +From 631ecb89ab98a82be25bac475b9ec761209c82de Mon Sep 17 00:00:00 2001 +From: Zong Li +Date: Sat, 22 May 2021 17:16:11 +0800 +Subject: [PATCH 2/4] net: macb: ensure the device is available before + accessing GEMGXL control registers +Git-commit: 5eff1461a6dec84f04fafa9128548bad51d96147 +References: git-fixes +Patch-mainline: v5.13-rc4 + +If runtime power menagement is enabled, the gigabit ethernet PLL would +be disabled after macb_probe(). During this period of time, the system +would hang up if we try to access GEMGXL control registers. + +We can't put runtime_pm_get/runtime_pm_put/ there due to the issue of +sleep inside atomic section (7fa2955ff70ce453 ("sh_eth: Fix sleeping +function called from invalid context"). Add netif_running checking to +ensure the device is available before accessing GEMGXL device. + +Changed in v2: + - Use netif_running instead of its own flag + +Signed-off-by: Zong Li +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/cadence/macb.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c +index b934435c4cbc..94bd999d02d0 100644 +--- a/drivers/net/ethernet/cadence/macb.c ++++ b/drivers/net/ethernet/cadence/macb.c +@@ -2256,6 +2256,9 @@ static struct net_device_stats *gem_get_stats(struct macb *bp) + struct gem_stats *hwstat = &bp->hw_stats.gem; + struct net_device_stats *nstat = &bp->dev->stats; + ++ if (!netif_running(bp->dev)) ++ return nstat; ++ + gem_update_stats(bp); + + nstat->rx_errors = (hwstat->rx_frame_check_sequence_errors + +-- +2.16.4 + diff --git a/patches.suse/net-mlx5-Properly-convey-driver-version-to-firmware.patch b/patches.suse/net-mlx5-Properly-convey-driver-version-to-firmware.patch new file mode 100644 index 0000000..011ed5e --- /dev/null +++ b/patches.suse/net-mlx5-Properly-convey-driver-version-to-firmware.patch @@ -0,0 +1,46 @@ +From 9584d5052f7d2f250b8bdc080e89859f2fdde1dd Mon Sep 17 00:00:00 2001 +From: Leon Romanovsky +Date: Thu, 15 Oct 2020 14:52:00 +0300 +Subject: [PATCH 7/8] net/mlx5: Properly convey driver version to firmware +Git-commit: 907af0f0cab4ee5d5604f182ecec2c5b5119d294 +References: git-fixes +Patch-mainline: v5.11-rc1 + +mlx5 firmware expects driver version in specific format X.X.X, so +make it always correct and based on real kernel version aligned with +the driver. + +Fixes: 012e50e109fd ("net/mlx5: Set driver version into firmware") +Signed-off-by: Leon Romanovsky +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/mellanox/mlx5/core/main.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c +index b1c4f12136b8..1f97230c678a 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c +@@ -51,6 +51,7 @@ + #ifdef CONFIG_RFS_ACCEL + #include + #endif ++#include + #include + #include "mlx5_core.h" + #include "fs_core.h" +@@ -211,7 +212,10 @@ static void mlx5_set_driver_version(struct mlx5_core_dev *dev) + strncat(string, ",", remaining_size); + + remaining_size = max_t(int, 0, driver_ver_sz - strlen(string)); +- strncat(string, DRIVER_VERSION, remaining_size); ++ ++ snprintf(string + strlen(string), remaining_size, "%u.%u.%u", ++ (u8)((LINUX_VERSION_CODE >> 16) & 0xff), (u8)((LINUX_VERSION_CODE >> 8) & 0xff), ++ (u16)(LINUX_VERSION_CODE & 0xffff)); + + /*Send the command*/ + MLX5_SET(set_driver_version_in, in, opcode, +-- +2.16.4 + diff --git a/patches.suse/net-nfc-fix-use-after-free-llcp_sock_bind-connect.patch b/patches.suse/net-nfc-fix-use-after-free-llcp_sock_bind-connect.patch index c50e2f4..ee655db 100644 --- a/patches.suse/net-nfc-fix-use-after-free-llcp_sock_bind-connect.patch +++ b/patches.suse/net-nfc-fix-use-after-free-llcp_sock_bind-connect.patch @@ -4,7 +4,7 @@ Date: Tue, 4 May 2021 10:16:46 +0300 Subject: [PATCH] net/nfc: fix use-after-free llcp_sock_bind/connect Git-commit: c61760e6940dd4039a7f5e84a6afc9cdbf4d82b6 Patch-mainline: v5.13-rc1 -References: CVE-2021-23134 bsc#1186060 +References: CVE-2021-23134 bsc#1186060 CVE-2021-47068 bsc#1220739 Commits 8a4cd82d ("nfc: fix refcount leak in llcp_sock_connect()") and c33b1cc62 ("nfc: fix refcount leak in llcp_sock_bind()") diff --git a/patches.suse/net-nfc-llcp-Add-lock-when-modifying-device-list.patch b/patches.suse/net-nfc-llcp-Add-lock-when-modifying-device-list.patch index c4c291e..e4d12d3 100644 --- a/patches.suse/net-nfc-llcp-Add-lock-when-modifying-device-list.patch +++ b/patches.suse/net-nfc-llcp-Add-lock-when-modifying-device-list.patch @@ -4,7 +4,7 @@ Date: Fri, 8 Sep 2023 19:58:53 -0400 Subject: [PATCH 12/12] net: nfc: llcp: Add lock when modifying device list Patch-mainline: v6.6-rc5 Git-commit: dfc7f7a988dad34c3bf4c053124fb26aa6c5f916 -References: git-fixes +References: git-fixes CVE-2023-52524 bsc#1220927 The device list needs its associated lock held when modifying it, or the list could become corrupted, as syzbot discovered. diff --git a/patches.suse/net-qla3xxx-fix-schedule-while-atomic-in-ql_sem_spin.patch b/patches.suse/net-qla3xxx-fix-schedule-while-atomic-in-ql_sem_spin.patch new file mode 100644 index 0000000..9f79383 --- /dev/null +++ b/patches.suse/net-qla3xxx-fix-schedule-while-atomic-in-ql_sem_spin.patch @@ -0,0 +1,107 @@ +From b07d4ceee844c384afb84bae46be3299eafa3edd Mon Sep 17 00:00:00 2001 +From: Zheyu Ma +Date: Thu, 20 May 2021 12:32:36 +0000 +Subject: [PATCH 1/4] net/qla3xxx: fix schedule while atomic in ql_sem_spinlock +Git-commit: 92766c4628ea349c8ddab0cd7bd0488f36e5c4ce +References: git-fixes +Patch-mainline: v5.14-rc4 + +When calling the 'ql_sem_spinlock', the driver has already acquired the +spin lock, so the driver should not call 'ssleep' in atomic context. + +This bug can be fixed by using 'mdelay' instead of 'ssleep'. + +The KASAN's log reveals it: + +[ 3.238124 ] BUG: scheduling while atomic: swapper/0/1/0x00000002 +[ 3.238748 ] 2 locks held by swapper/0/1: +[ 3.239151 ] #0: ffff88810177b240 (&dev->mutex){....}-{3:3}, at: +__device_driver_lock+0x41/0x60 +[ 3.240026 ] #1: ffff888107c60e28 (&qdev->hw_lock){....}-{2:2}, at: +ql3xxx_probe+0x2aa/0xea0 +[ 3.240873 ] Modules linked in: +[ 3.241187 ] irq event stamp: 460854 +[ 3.241541 ] hardirqs last enabled at (460853): [] +_raw_spin_unlock_irqrestore+0x4f/0x70 +[ 3.242245 ] hardirqs last disabled at (460854): [] +_raw_spin_lock_irqsave+0x2a/0x70 +[ 3.242245 ] softirqs last enabled at (446076): [] +__do_softirq+0x2e4/0x4b1 +[ 3.242245 ] softirqs last disabled at (446069): [] +irq_exit_rcu+0x100/0x110 +[ 3.242245 ] Preemption disabled at: +[ 3.242245 ] [] ql3xxx_probe+0x2aa/0xea0 +[ 3.242245 ] Kernel panic - not syncing: scheduling while atomic +[ 3.242245 ] CPU: 2 PID: 1 Comm: swapper/0 Not tainted +5.13.0-rc1-00145 +-gee7dc339169-dirty #16 +[ 3.242245 ] Call Trace: +[ 3.242245 ] dump_stack+0xba/0xf5 +[ 3.242245 ] ? ql3xxx_probe+0x1f0/0xea0 +[ 3.242245 ] panic+0x15a/0x3f2 +[ 3.242245 ] ? vprintk+0x76/0x150 +[ 3.242245 ] ? ql3xxx_probe+0x2aa/0xea0 +[ 3.242245 ] __schedule_bug+0xae/0xe0 +[ 3.242245 ] __schedule+0x72e/0xa00 +[ 3.242245 ] schedule+0x43/0xf0 +[ 3.242245 ] schedule_timeout+0x28b/0x500 +[ 3.242245 ] ? del_timer_sync+0xf0/0xf0 +[ 3.242245 ] ? msleep+0x2f/0x70 +[ 3.242245 ] msleep+0x59/0x70 +[ 3.242245 ] ql3xxx_probe+0x307/0xea0 +[ 3.242245 ] ? _raw_spin_unlock_irqrestore+0x3a/0x70 +[ 3.242245 ] ? pci_device_remove+0x110/0x110 +[ 3.242245 ] local_pci_probe+0x45/0xa0 +[ 3.242245 ] pci_device_probe+0x12b/0x1d0 +[ 3.242245 ] really_probe+0x2a9/0x610 +[ 3.242245 ] driver_probe_device+0x90/0x1d0 +[ 3.242245 ] ? mutex_lock_nested+0x1b/0x20 +[ 3.242245 ] device_driver_attach+0x68/0x70 +[ 3.242245 ] __driver_attach+0x124/0x1b0 +[ 3.242245 ] ? device_driver_attach+0x70/0x70 +[ 3.242245 ] bus_for_each_dev+0xbb/0x110 +[ 3.242245 ] ? rdinit_setup+0x45/0x45 +[ 3.242245 ] driver_attach+0x27/0x30 +[ 3.242245 ] bus_add_driver+0x1eb/0x2a0 +[ 3.242245 ] driver_register+0xa9/0x180 +[ 3.242245 ] __pci_register_driver+0x82/0x90 +[ 3.242245 ] ? yellowfin_init+0x25/0x25 +[ 3.242245 ] ql3xxx_driver_init+0x23/0x25 +[ 3.242245 ] do_one_initcall+0x7f/0x3d0 +[ 3.242245 ] ? rdinit_setup+0x45/0x45 +[ 3.242245 ] ? rcu_read_lock_sched_held+0x4f/0x80 +[ 3.242245 ] kernel_init_freeable+0x2aa/0x301 +[ 3.242245 ] ? rest_init+0x2c0/0x2c0 +[ 3.242245 ] kernel_init+0x18/0x190 +[ 3.242245 ] ? rest_init+0x2c0/0x2c0 +[ 3.242245 ] ? rest_init+0x2c0/0x2c0 +[ 3.242245 ] ret_from_fork+0x1f/0x30 +[ 3.242245 ] Dumping ftrace buffer: +[ 3.242245 ] (ftrace buffer empty) +[ 3.242245 ] Kernel Offset: disabled +[ 3.242245 ] Rebooting in 1 seconds. + +Reported-by: Zheyu Ma +Signed-off-by: Zheyu Ma +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/qlogic/qla3xxx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c +index cc53ee26bd3e..a8bb061e1a8a 100644 +--- a/drivers/net/ethernet/qlogic/qla3xxx.c ++++ b/drivers/net/ethernet/qlogic/qla3xxx.c +@@ -115,7 +115,7 @@ static int ql_sem_spinlock(struct ql3_adapter *qdev, + value = readl(&port_regs->CommonRegs.semaphoreReg); + if ((value & (sem_mask >> 16)) == sem_bits) + return 0; +- ssleep(1); ++ mdelay(1000); + } while (--seconds); + return -1; + } +-- +2.16.4 + diff --git a/patches.suse/net-smc-remove-device-from-smcd_dev_list-after-failed-device_add b/patches.suse/net-smc-remove-device-from-smcd_dev_list-after-failed-device_add index 32f7a57..1d80ee9 100644 --- a/patches.suse/net-smc-remove-device-from-smcd_dev_list-after-failed-device_add +++ b/patches.suse/net-smc-remove-device-from-smcd_dev_list-after-failed-device_add @@ -3,7 +3,7 @@ Date: Mon, 17 May 2021 10:47:06 +0200 Subject: net/smc: remove device from smcd_dev_list after failed device_add() Git-commit: 444d7be9532dcfda8e0385226c862fd7e986f607 Patch-mainline: v5.13-rc4 -References: git-fixes +References: git-fixes CVE-2021-47143 bsc#1221988 If the device_add() for a smcd_dev fails, there's no cleanup step that rolls back the earlier list_add(). The device subsequently gets freed, diff --git a/patches.suse/net-stmmac-free-tx-skb-buffer-in-stmmac_resume.patch b/patches.suse/net-stmmac-free-tx-skb-buffer-in-stmmac_resume.patch new file mode 100644 index 0000000..6575529 --- /dev/null +++ b/patches.suse/net-stmmac-free-tx-skb-buffer-in-stmmac_resume.patch @@ -0,0 +1,115 @@ +From c81f0c7a0b8d8345b42a60ed642022bdbebedebd Mon Sep 17 00:00:00 2001 +From: Fugang Duan +Date: Mon, 7 Dec 2020 18:51:39 +0800 +Subject: [PATCH 6/8] net: stmmac: free tx skb buffer in stmmac_resume() +Git-commit: 4ec236c7c51f89abb0224a4da4a6b77f9beb6600 +References: git-fixes +Patch-mainline: v5.10 + +When do suspend/resume test, there have WARN_ON() log dump from +stmmac_xmit() funciton, the code logic: + entry = tx_q->cur_tx; + first_entry = entry; + WARN_ON(tx_q->tx_skbuff[first_entry]); + +In normal case, tx_q->tx_skbuff[txq->cur_tx] should be NULL because +the skb should be handled and freed in stmmac_tx_clean(). + +But stmmac_resume() reset queue parameters like below, skb buffers +may not be freed. + tx_q->cur_tx = 0; + tx_q->dirty_tx = 0; + +So free tx skb buffer in stmmac_resume() to avoid warning and +memory leak. + +log: +[ 46.139824] ------------[ cut here ]------------ +[ 46.144453] WARNING: CPU: 0 PID: 0 at drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:3235 stmmac_xmit+0x7a0/0x9d0 +[ 46.154969] Modules linked in: crct10dif_ce vvcam(O) flexcan can_dev +[ 46.161328] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G O 5.4.24-2.1.0+g2ad925d15481 #1 +[ 46.170369] Hardware name: NXP i.MX8MPlus EVK board (DT) +[ 46.175677] pstate: 80000005 (Nzcv daif -PAN -UAO) +[ 46.180465] pc : stmmac_xmit+0x7a0/0x9d0 +[ 46.184387] lr : dev_hard_start_xmit+0x94/0x158 +[ 46.188913] sp : ffff800010003cc0 +[ 46.192224] x29: ffff800010003cc0 x28: ffff000177e2a100 +[ 46.197533] x27: ffff000176ef0840 x26: ffff000176ef0090 +[ 46.202842] x25: 0000000000000000 x24: 0000000000000000 +[ 46.208151] x23: 0000000000000003 x22: ffff8000119ddd30 +[ 46.213460] x21: ffff00017636f000 x20: ffff000176ef0cc0 +[ 46.218769] x19: 0000000000000003 x18: 0000000000000000 +[ 46.224078] x17: 0000000000000000 x16: 0000000000000000 +[ 46.229386] x15: 0000000000000079 x14: 0000000000000000 +[ 46.234695] x13: 0000000000000003 x12: 0000000000000003 +[ 46.240003] x11: 0000000000000010 x10: 0000000000000010 +[ 46.245312] x9 : ffff00017002b140 x8 : 0000000000000000 +[ 46.250621] x7 : ffff00017636f000 x6 : 0000000000000010 +[ 46.255930] x5 : 0000000000000001 x4 : ffff000176ef0000 +[ 46.261238] x3 : 0000000000000003 x2 : 00000000ffffffff +[ 46.266547] x1 : ffff000177e2a000 x0 : 0000000000000000 +[ 46.271856] Call trace: +[ 46.274302] stmmac_xmit+0x7a0/0x9d0 +[ 46.277874] dev_hard_start_xmit+0x94/0x158 +[ 46.282056] sch_direct_xmit+0x11c/0x338 +[ 46.285976] __qdisc_run+0x118/0x5f0 +[ 46.289549] net_tx_action+0x110/0x198 +[ 46.293297] __do_softirq+0x120/0x23c +[ 46.296958] irq_exit+0xb8/0xd8 +[ 46.300098] __handle_domain_irq+0x64/0xb8 +[ 46.304191] gic_handle_irq+0x5c/0x148 +[ 46.307936] el1_irq+0xb8/0x180 +[ 46.311076] cpuidle_enter_state+0x84/0x360 +[ 46.315256] cpuidle_enter+0x34/0x48 +[ 46.318829] call_cpuidle+0x18/0x38 +[ 46.322314] do_idle+0x1e0/0x280 +[ 46.325539] cpu_startup_entry+0x24/0x40 +[ 46.329460] rest_init+0xd4/0xe0 +[ 46.332687] arch_call_rest_init+0xc/0x14 +[ 46.336695] start_kernel+0x420/0x44c +[ 46.340353] ---[ end trace bc1ee695123cbacd ]--- + +Fixes: 47dd7a540b8a0 ("net: add support for STMicroelectronics Ethernet controllers.") +Signed-off-by: Fugang Duan +Signed-off-by: Joakim Zhang +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 3c0753e38fdc..821a9a0a5400 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -1404,6 +1404,19 @@ static void dma_free_tx_skbufs(struct stmmac_priv *priv, u32 queue) + stmmac_free_tx_buffer(priv, queue, i); + } + ++/** ++ * stmmac_free_tx_skbufs - free TX skb buffers ++ * @priv: private structure ++ */ ++static void stmmac_free_tx_skbufs(struct stmmac_priv *priv) ++{ ++ u32 tx_queue_cnt = priv->plat->tx_queues_to_use; ++ u32 queue; ++ ++ for (queue = 0; queue < tx_queue_cnt; queue++) ++ dma_free_tx_skbufs(priv, queue); ++} ++ + /** + * free_dma_rx_desc_resources - free RX dma desc resources + * @priv: private structure +@@ -4501,6 +4514,7 @@ int stmmac_resume(struct device *dev) + + stmmac_reset_queues_param(priv); + ++ stmmac_free_tx_skbufs(priv); + stmmac_clear_descriptors(priv); + + stmmac_hw_setup(ndev, false); +-- +2.16.4 + diff --git a/patches.suse/net-sunrpc-Fix-an-off-by-one-in-rpc_sockaddr2uaddr.patch b/patches.suse/net-sunrpc-Fix-an-off-by-one-in-rpc_sockaddr2uaddr.patch new file mode 100644 index 0000000..fddc8a9 --- /dev/null +++ b/patches.suse/net-sunrpc-Fix-an-off-by-one-in-rpc_sockaddr2uaddr.patch @@ -0,0 +1,36 @@ +From: Christophe JAILLET +Date: Tue, 24 Oct 2023 23:58:20 +0200 +Subject: [PATCH] net: sunrpc: Fix an off by one in rpc_sockaddr2uaddr() +Git-commit: d6f4de70f73a106986ee315d7d512539f2f3303a +Patch-mainline: v6.9-rc1 +References: git-fixes + +The intent is to check if the strings' are truncated or not. So, >= should +be used instead of >, because strlcat() and snprintf() return the length of +the output, excluding the trailing NULL. + +Fixes: a02d69261134 ("SUNRPC: Provide functions for managing universal addresses") +Signed-off-by: Christophe JAILLET +Reviewed-by: Benjamin Coddington +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + net/sunrpc/addr.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/sunrpc/addr.c ++++ b/net/sunrpc/addr.c +@@ -283,10 +283,10 @@ char *rpc_sockaddr2uaddr(const struct so + } + + if (snprintf(portbuf, sizeof(portbuf), +- ".%u.%u", port >> 8, port & 0xff) > (int)sizeof(portbuf)) ++ ".%u.%u", port >> 8, port & 0xff) >= (int)sizeof(portbuf)) + return NULL; + +- if (strlcat(addrbuf, portbuf, sizeof(addrbuf)) > sizeof(addrbuf)) ++ if (strlcat(addrbuf, portbuf, sizeof(addrbuf)) >= sizeof(addrbuf)) + return NULL; + + return kstrdup(addrbuf, gfp_flags); diff --git a/patches.suse/net-usb-Use-ARRAY_SIZE-instead-of-calculating-the-ar.patch b/patches.suse/net-usb-Use-ARRAY_SIZE-instead-of-calculating-the-ar.patch new file mode 100644 index 0000000..8273117 --- /dev/null +++ b/patches.suse/net-usb-Use-ARRAY_SIZE-instead-of-calculating-the-ar.patch @@ -0,0 +1,35 @@ +From bf37afceaf549ce9ef50e3042f64d257a3d4be80 Mon Sep 17 00:00:00 2001 +From: zhong jiang +Date: Fri, 3 Aug 2018 14:53:14 +0800 +Subject: [PATCH] net:usb: Use ARRAY_SIZE instead of calculating the array size +Git-commit: bf37afceaf549ce9ef50e3042f64d257a3d4be80 +References: git-fixes +Patch-mainline: v4.19-rc1 + +We use ARRAY_SIZE to replace open code sizeof(lan78xx_regs) / sizeof(u32). +It make the code concise. + +Signed-off-by: zhong jiang +Signed-off-by: David S. Miller +Signed-off-by: Oliver Neukum + +--- + drivers/net/usb/lan78xx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index 4662fa0381f9..a9991c5f4736 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -1649,7 +1649,7 @@ lan78xx_get_regs(struct net_device *netdev, struct ethtool_regs *regs, + struct lan78xx_net *dev = netdev_priv(netdev); + + /* Read Device/MAC registers */ +- for (i = 0; i < (sizeof(lan78xx_regs) / sizeof(u32)); i++) ++ for (i = 0; i < ARRAY_SIZE(lan78xx_regs); i++) + lan78xx_read_reg(dev, lan78xx_regs[i], &data[i]); + + if (!netdev->phydev) +-- +2.44.0 + diff --git a/patches.suse/net-usb-fix-memory-leak-in-smsc75xx_bind.patch b/patches.suse/net-usb-fix-memory-leak-in-smsc75xx_bind.patch index 5a28f26..73f12da 100644 --- a/patches.suse/net-usb-fix-memory-leak-in-smsc75xx_bind.patch +++ b/patches.suse/net-usb-fix-memory-leak-in-smsc75xx_bind.patch @@ -4,7 +4,7 @@ Date: Mon, 24 May 2021 23:02:08 +0300 Subject: [PATCH] net: usb: fix memory leak in smsc75xx_bind Git-commit: 46a8b29c6306d8bbfd92b614ef65a47c900d8e70 Patch-mainline: v5.13-rc4 -References: git-fixes +References: git-fixes CVE-2021-47171 bsc#1221994 Syzbot reported memory leak in smsc75xx_bind(). The problem was is non-freed memory in case of diff --git a/patches.suse/net-usb-lan78xx-Remove-lots-of-set-but-unused-ret-va.patch b/patches.suse/net-usb-lan78xx-Remove-lots-of-set-but-unused-ret-va.patch new file mode 100644 index 0000000..cdfc2de --- /dev/null +++ b/patches.suse/net-usb-lan78xx-Remove-lots-of-set-but-unused-ret-va.patch @@ -0,0 +1,540 @@ +From 06cd7c46b3ab3f2252c61bf85b191236cf0254e1 Mon Sep 17 00:00:00 2001 +From: Lee Jones +Date: Mon, 2 Nov 2020 11:45:06 +0000 +Subject: [PATCH] net: usb: lan78xx: Remove lots of set but unused 'ret' + variables +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: 06cd7c46b3ab3f2252c61bf85b191236cf0254e1 +References: git-fixes +Patch-mainline: v5.11-rc1 + +Fixes the following W=1 kernel build warning(s): + + drivers/net/usb/lan78xx.c: In function ‘lan78xx_read_raw_otp’: + drivers/net/usb/lan78xx.c:825:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] + drivers/net/usb/lan78xx.c: In function ‘lan78xx_write_raw_otp’: + drivers/net/usb/lan78xx.c:879:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] + drivers/net/usb/lan78xx.c: In function ‘lan78xx_deferred_multicast_write’: + drivers/net/usb/lan78xx.c:1041:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] + drivers/net/usb/lan78xx.c: In function ‘lan78xx_update_flowcontrol’: + drivers/net/usb/lan78xx.c:1127:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] + drivers/net/usb/lan78xx.c: In function ‘lan78xx_init_mac_address’: + drivers/net/usb/lan78xx.c:1666:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] + drivers/net/usb/lan78xx.c: In function ‘lan78xx_link_status_change’: + drivers/net/usb/lan78xx.c:1841:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] + drivers/net/usb/lan78xx.c: In function ‘lan78xx_irq_bus_sync_unlock’: + drivers/net/usb/lan78xx.c:1920:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] + drivers/net/usb/lan78xx.c: In function ‘lan8835_fixup’: + drivers/net/usb/lan78xx.c:1994:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] + drivers/net/usb/lan78xx.c: In function ‘lan78xx_set_rx_max_frame_length’: + drivers/net/usb/lan78xx.c:2192:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] + drivers/net/usb/lan78xx.c: In function ‘lan78xx_change_mtu’: + drivers/net/usb/lan78xx.c:2270:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] + drivers/net/usb/lan78xx.c: In function ‘lan78xx_set_mac_addr’: + drivers/net/usb/lan78xx.c:2299:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] + drivers/net/usb/lan78xx.c: In function ‘lan78xx_set_features’: + drivers/net/usb/lan78xx.c:2333:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] + drivers/net/usb/lan78xx.c: In function ‘lan78xx_set_suspend’: + drivers/net/usb/lan78xx.c:3807:6: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] + +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/20201102114512.1062724-25-lee.jones@linaro.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Oliver Neukum + +--- + drivers/net/usb/lan78xx.c | 168 ++++++++++++++++++-------------------- + 1 file changed, 78 insertions(+), 90 deletions(-) + +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index 65b315bc60ab..bf243edeb064 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -822,20 +822,19 @@ static int lan78xx_read_raw_otp(struct lan78xx_net *dev, u32 offset, + u32 length, u8 *data) + { + int i; +- int ret; + u32 buf; + unsigned long timeout; + +- ret = lan78xx_read_reg(dev, OTP_PWR_DN, &buf); ++ lan78xx_read_reg(dev, OTP_PWR_DN, &buf); + + if (buf & OTP_PWR_DN_PWRDN_N_) { + /* clear it and wait to be cleared */ +- ret = lan78xx_write_reg(dev, OTP_PWR_DN, 0); ++ lan78xx_write_reg(dev, OTP_PWR_DN, 0); + + timeout = jiffies + HZ; + do { + usleep_range(1, 10); +- ret = lan78xx_read_reg(dev, OTP_PWR_DN, &buf); ++ lan78xx_read_reg(dev, OTP_PWR_DN, &buf); + if (time_after(jiffies, timeout)) { + netdev_warn(dev->net, + "timeout on OTP_PWR_DN"); +@@ -845,18 +844,18 @@ static int lan78xx_read_raw_otp(struct lan78xx_net *dev, u32 offset, + } + + for (i = 0; i < length; i++) { +- ret = lan78xx_write_reg(dev, OTP_ADDR1, ++ lan78xx_write_reg(dev, OTP_ADDR1, + ((offset + i) >> 8) & OTP_ADDR1_15_11); +- ret = lan78xx_write_reg(dev, OTP_ADDR2, ++ lan78xx_write_reg(dev, OTP_ADDR2, + ((offset + i) & OTP_ADDR2_10_3)); + +- ret = lan78xx_write_reg(dev, OTP_FUNC_CMD, OTP_FUNC_CMD_READ_); +- ret = lan78xx_write_reg(dev, OTP_CMD_GO, OTP_CMD_GO_GO_); ++ lan78xx_write_reg(dev, OTP_FUNC_CMD, OTP_FUNC_CMD_READ_); ++ lan78xx_write_reg(dev, OTP_CMD_GO, OTP_CMD_GO_GO_); + + timeout = jiffies + HZ; + do { + udelay(1); +- ret = lan78xx_read_reg(dev, OTP_STATUS, &buf); ++ lan78xx_read_reg(dev, OTP_STATUS, &buf); + if (time_after(jiffies, timeout)) { + netdev_warn(dev->net, + "timeout on OTP_STATUS"); +@@ -864,7 +863,7 @@ static int lan78xx_read_raw_otp(struct lan78xx_net *dev, u32 offset, + } + } while (buf & OTP_STATUS_BUSY_); + +- ret = lan78xx_read_reg(dev, OTP_RD_DATA, &buf); ++ lan78xx_read_reg(dev, OTP_RD_DATA, &buf); + + data[i] = (u8)(buf & 0xFF); + } +@@ -876,20 +875,19 @@ static int lan78xx_write_raw_otp(struct lan78xx_net *dev, u32 offset, + u32 length, u8 *data) + { + int i; +- int ret; + u32 buf; + unsigned long timeout; + +- ret = lan78xx_read_reg(dev, OTP_PWR_DN, &buf); ++ lan78xx_read_reg(dev, OTP_PWR_DN, &buf); + + if (buf & OTP_PWR_DN_PWRDN_N_) { + /* clear it and wait to be cleared */ +- ret = lan78xx_write_reg(dev, OTP_PWR_DN, 0); ++ lan78xx_write_reg(dev, OTP_PWR_DN, 0); + + timeout = jiffies + HZ; + do { + udelay(1); +- ret = lan78xx_read_reg(dev, OTP_PWR_DN, &buf); ++ lan78xx_read_reg(dev, OTP_PWR_DN, &buf); + if (time_after(jiffies, timeout)) { + netdev_warn(dev->net, + "timeout on OTP_PWR_DN completion"); +@@ -899,21 +897,21 @@ static int lan78xx_write_raw_otp(struct lan78xx_net *dev, u32 offset, + } + + /* set to BYTE program mode */ +- ret = lan78xx_write_reg(dev, OTP_PRGM_MODE, OTP_PRGM_MODE_BYTE_); ++ lan78xx_write_reg(dev, OTP_PRGM_MODE, OTP_PRGM_MODE_BYTE_); + + for (i = 0; i < length; i++) { +- ret = lan78xx_write_reg(dev, OTP_ADDR1, ++ lan78xx_write_reg(dev, OTP_ADDR1, + ((offset + i) >> 8) & OTP_ADDR1_15_11); +- ret = lan78xx_write_reg(dev, OTP_ADDR2, ++ lan78xx_write_reg(dev, OTP_ADDR2, + ((offset + i) & OTP_ADDR2_10_3)); +- ret = lan78xx_write_reg(dev, OTP_PRGM_DATA, data[i]); +- ret = lan78xx_write_reg(dev, OTP_TST_CMD, OTP_TST_CMD_PRGVRFY_); +- ret = lan78xx_write_reg(dev, OTP_CMD_GO, OTP_CMD_GO_GO_); ++ lan78xx_write_reg(dev, OTP_PRGM_DATA, data[i]); ++ lan78xx_write_reg(dev, OTP_TST_CMD, OTP_TST_CMD_PRGVRFY_); ++ lan78xx_write_reg(dev, OTP_CMD_GO, OTP_CMD_GO_GO_); + + timeout = jiffies + HZ; + do { + udelay(1); +- ret = lan78xx_read_reg(dev, OTP_STATUS, &buf); ++ lan78xx_read_reg(dev, OTP_STATUS, &buf); + if (time_after(jiffies, timeout)) { + netdev_warn(dev->net, + "Timeout on OTP_STATUS completion"); +@@ -1038,7 +1036,6 @@ static void lan78xx_deferred_multicast_write(struct work_struct *param) + container_of(param, struct lan78xx_priv, set_multicast); + struct lan78xx_net *dev = pdata->dev; + int i; +- int ret; + + netif_dbg(dev, drv, dev->net, "deferred multicast write 0x%08x\n", + pdata->rfe_ctl); +@@ -1047,14 +1044,14 @@ static void lan78xx_deferred_multicast_write(struct work_struct *param) + DP_SEL_VHF_HASH_LEN, pdata->mchash_table); + + for (i = 1; i < NUM_OF_MAF; i++) { +- ret = lan78xx_write_reg(dev, MAF_HI(i), 0); +- ret = lan78xx_write_reg(dev, MAF_LO(i), ++ lan78xx_write_reg(dev, MAF_HI(i), 0); ++ lan78xx_write_reg(dev, MAF_LO(i), + pdata->pfilter_table[i][1]); +- ret = lan78xx_write_reg(dev, MAF_HI(i), ++ lan78xx_write_reg(dev, MAF_HI(i), + pdata->pfilter_table[i][0]); + } + +- ret = lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); ++ lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); + } + + static void lan78xx_set_multicast(struct net_device *netdev) +@@ -1124,7 +1121,6 @@ static int lan78xx_update_flowcontrol(struct lan78xx_net *dev, u8 duplex, + u16 lcladv, u16 rmtadv) + { + u32 flow = 0, fct_flow = 0; +- int ret; + u8 cap; + + if (dev->fc_autoneg) +@@ -1147,10 +1143,10 @@ static int lan78xx_update_flowcontrol(struct lan78xx_net *dev, u8 duplex, + (cap & FLOW_CTRL_RX ? "enabled" : "disabled"), + (cap & FLOW_CTRL_TX ? "enabled" : "disabled")); + +- ret = lan78xx_write_reg(dev, FCT_FLOW, fct_flow); ++ lan78xx_write_reg(dev, FCT_FLOW, fct_flow); + + /* threshold value should be set before enabling flow */ +- ret = lan78xx_write_reg(dev, FLOW, flow); ++ lan78xx_write_reg(dev, FLOW, flow); + + return 0; + } +@@ -1663,11 +1659,10 @@ static const struct ethtool_ops lan78xx_ethtool_ops = { + static void lan78xx_init_mac_address(struct lan78xx_net *dev) + { + u32 addr_lo, addr_hi; +- int ret; + u8 addr[6]; + +- ret = lan78xx_read_reg(dev, RX_ADDRL, &addr_lo); +- ret = lan78xx_read_reg(dev, RX_ADDRH, &addr_hi); ++ lan78xx_read_reg(dev, RX_ADDRL, &addr_lo); ++ lan78xx_read_reg(dev, RX_ADDRH, &addr_hi); + + addr[0] = addr_lo & 0xFF; + addr[1] = (addr_lo >> 8) & 0xFF; +@@ -1700,12 +1695,12 @@ static void lan78xx_init_mac_address(struct lan78xx_net *dev) + (addr[2] << 16) | (addr[3] << 24); + addr_hi = addr[4] | (addr[5] << 8); + +- ret = lan78xx_write_reg(dev, RX_ADDRL, addr_lo); +- ret = lan78xx_write_reg(dev, RX_ADDRH, addr_hi); ++ lan78xx_write_reg(dev, RX_ADDRL, addr_lo); ++ lan78xx_write_reg(dev, RX_ADDRH, addr_hi); + } + +- ret = lan78xx_write_reg(dev, MAF_LO(0), addr_lo); +- ret = lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_); ++ lan78xx_write_reg(dev, MAF_LO(0), addr_lo); ++ lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_); + + ether_addr_copy(dev->net->dev_addr, addr); + } +@@ -1838,7 +1833,7 @@ static void lan78xx_remove_mdio(struct lan78xx_net *dev) + static void lan78xx_link_status_change(struct net_device *net) + { + struct phy_device *phydev = net->phydev; +- int ret, temp; ++ int temp; + + /* At forced 100 F/H mode, chip may fail to set mode correctly + * when cable is switched between long(~50+m) and short one. +@@ -1849,7 +1844,7 @@ static void lan78xx_link_status_change(struct net_device *net) + /* disable phy interrupt */ + temp = phy_read(phydev, LAN88XX_INT_MASK); + temp &= ~LAN88XX_INT_MASK_MDINTPIN_EN_; +- ret = phy_write(phydev, LAN88XX_INT_MASK, temp); ++ phy_write(phydev, LAN88XX_INT_MASK, temp); + + temp = phy_read(phydev, MII_BMCR); + temp &= ~(BMCR_SPEED100 | BMCR_SPEED1000); +@@ -1863,7 +1858,7 @@ static void lan78xx_link_status_change(struct net_device *net) + /* enable phy interrupt back */ + temp = phy_read(phydev, LAN88XX_INT_MASK); + temp |= LAN88XX_INT_MASK_MDINTPIN_EN_; +- ret = phy_write(phydev, LAN88XX_INT_MASK, temp); ++ phy_write(phydev, LAN88XX_INT_MASK, temp); + } + } + +@@ -1917,14 +1912,13 @@ static void lan78xx_irq_bus_sync_unlock(struct irq_data *irqd) + struct lan78xx_net *dev = + container_of(data, struct lan78xx_net, domain_data); + u32 buf; +- int ret; + + /* call register access here because irq_bus_lock & irq_bus_sync_unlock + * are only two callbacks executed in non-atomic contex. + */ +- ret = lan78xx_read_reg(dev, INT_EP_CTL, &buf); ++ lan78xx_read_reg(dev, INT_EP_CTL, &buf); + if (buf != data->irqenable) +- ret = lan78xx_write_reg(dev, INT_EP_CTL, data->irqenable); ++ lan78xx_write_reg(dev, INT_EP_CTL, data->irqenable); + + mutex_unlock(&data->irq_lock); + } +@@ -1991,7 +1985,6 @@ static void lan78xx_remove_irq_domain(struct lan78xx_net *dev) + static int lan8835_fixup(struct phy_device *phydev) + { + int buf; +- int ret; + struct lan78xx_net *dev = netdev_priv(phydev->attached_dev); + + /* LED2/PME_N/IRQ_N/RGMII_ID pin to IRQ_N mode */ +@@ -2001,11 +1994,11 @@ static int lan8835_fixup(struct phy_device *phydev) + phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8010, buf); + + /* RGMII MAC TXC Delay Enable */ +- ret = lan78xx_write_reg(dev, MAC_RGMII_ID, ++ lan78xx_write_reg(dev, MAC_RGMII_ID, + MAC_RGMII_ID_TXC_DELAY_EN_); + + /* RGMII TX DLL Tune Adjust */ +- ret = lan78xx_write_reg(dev, RGMII_TX_BYP_DLL, 0x3D00); ++ lan78xx_write_reg(dev, RGMII_TX_BYP_DLL, 0x3D00); + + dev->interface = PHY_INTERFACE_MODE_RGMII_TXID; + +@@ -2189,28 +2182,27 @@ static int lan78xx_phy_init(struct lan78xx_net *dev) + + static int lan78xx_set_rx_max_frame_length(struct lan78xx_net *dev, int size) + { +- int ret = 0; + u32 buf; + bool rxenabled; + +- ret = lan78xx_read_reg(dev, MAC_RX, &buf); ++ lan78xx_read_reg(dev, MAC_RX, &buf); + + rxenabled = ((buf & MAC_RX_RXEN_) != 0); + + if (rxenabled) { + buf &= ~MAC_RX_RXEN_; +- ret = lan78xx_write_reg(dev, MAC_RX, buf); ++ lan78xx_write_reg(dev, MAC_RX, buf); + } + + /* add 4 to size for FCS */ + buf &= ~MAC_RX_MAX_SIZE_MASK_; + buf |= (((size + 4) << MAC_RX_MAX_SIZE_SHIFT_) & MAC_RX_MAX_SIZE_MASK_); + +- ret = lan78xx_write_reg(dev, MAC_RX, buf); ++ lan78xx_write_reg(dev, MAC_RX, buf); + + if (rxenabled) { + buf |= MAC_RX_RXEN_; +- ret = lan78xx_write_reg(dev, MAC_RX, buf); ++ lan78xx_write_reg(dev, MAC_RX, buf); + } + + return 0; +@@ -2267,13 +2259,12 @@ static int lan78xx_change_mtu(struct net_device *netdev, int new_mtu) + int ll_mtu = new_mtu + netdev->hard_header_len; + int old_hard_mtu = dev->hard_mtu; + int old_rx_urb_size = dev->rx_urb_size; +- int ret; + + /* no second zero-length packet read wanted after mtu-sized packets */ + if ((ll_mtu % dev->maxpacket) == 0) + return -EDOM; + +- ret = lan78xx_set_rx_max_frame_length(dev, new_mtu + VLAN_ETH_HLEN); ++ lan78xx_set_rx_max_frame_length(dev, new_mtu + VLAN_ETH_HLEN); + + netdev->mtu = new_mtu; + +@@ -2296,7 +2287,6 @@ static int lan78xx_set_mac_addr(struct net_device *netdev, void *p) + struct lan78xx_net *dev = netdev_priv(netdev); + struct sockaddr *addr = p; + u32 addr_lo, addr_hi; +- int ret; + + if (netif_running(netdev)) + return -EBUSY; +@@ -2313,12 +2303,12 @@ static int lan78xx_set_mac_addr(struct net_device *netdev, void *p) + addr_hi = netdev->dev_addr[4] | + netdev->dev_addr[5] << 8; + +- ret = lan78xx_write_reg(dev, RX_ADDRL, addr_lo); +- ret = lan78xx_write_reg(dev, RX_ADDRH, addr_hi); ++ lan78xx_write_reg(dev, RX_ADDRL, addr_lo); ++ lan78xx_write_reg(dev, RX_ADDRH, addr_hi); + + /* Added to support MAC address changes */ +- ret = lan78xx_write_reg(dev, MAF_LO(0), addr_lo); +- ret = lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_); ++ lan78xx_write_reg(dev, MAF_LO(0), addr_lo); ++ lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_); + + return 0; + } +@@ -2330,7 +2320,6 @@ static int lan78xx_set_features(struct net_device *netdev, + struct lan78xx_net *dev = netdev_priv(netdev); + struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]); + unsigned long flags; +- int ret; + + spin_lock_irqsave(&pdata->rfe_ctl_lock, flags); + +@@ -2354,7 +2343,7 @@ static int lan78xx_set_features(struct net_device *netdev, + + spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags); + +- ret = lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); ++ lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); + + return 0; + } +@@ -3804,7 +3793,6 @@ static u16 lan78xx_wakeframe_crc16(const u8 *buf, int len) + static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) + { + u32 buf; +- int ret; + int mask_index; + u16 crc; + u32 temp_wucsr; +@@ -3813,26 +3801,26 @@ static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) + const u8 ipv6_multicast[3] = { 0x33, 0x33 }; + const u8 arp_type[2] = { 0x08, 0x06 }; + +- ret = lan78xx_read_reg(dev, MAC_TX, &buf); ++ lan78xx_read_reg(dev, MAC_TX, &buf); + buf &= ~MAC_TX_TXEN_; +- ret = lan78xx_write_reg(dev, MAC_TX, buf); +- ret = lan78xx_read_reg(dev, MAC_RX, &buf); ++ lan78xx_write_reg(dev, MAC_TX, buf); ++ lan78xx_read_reg(dev, MAC_RX, &buf); + buf &= ~MAC_RX_RXEN_; +- ret = lan78xx_write_reg(dev, MAC_RX, buf); ++ lan78xx_write_reg(dev, MAC_RX, buf); + +- ret = lan78xx_write_reg(dev, WUCSR, 0); +- ret = lan78xx_write_reg(dev, WUCSR2, 0); +- ret = lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL); ++ lan78xx_write_reg(dev, WUCSR, 0); ++ lan78xx_write_reg(dev, WUCSR2, 0); ++ lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL); + + temp_wucsr = 0; + + temp_pmt_ctl = 0; +- ret = lan78xx_read_reg(dev, PMT_CTL, &temp_pmt_ctl); ++ lan78xx_read_reg(dev, PMT_CTL, &temp_pmt_ctl); + temp_pmt_ctl &= ~PMT_CTL_RES_CLR_WKP_EN_; + temp_pmt_ctl |= PMT_CTL_RES_CLR_WKP_STS_; + + for (mask_index = 0; mask_index < NUM_OF_WUF_CFG; mask_index++) +- ret = lan78xx_write_reg(dev, WUF_CFG(mask_index), 0); ++ lan78xx_write_reg(dev, WUF_CFG(mask_index), 0); + + mask_index = 0; + if (wol & WAKE_PHY) { +@@ -3861,30 +3849,30 @@ static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) + + /* set WUF_CFG & WUF_MASK for IPv4 Multicast */ + crc = lan78xx_wakeframe_crc16(ipv4_multicast, 3); +- ret = lan78xx_write_reg(dev, WUF_CFG(mask_index), ++ lan78xx_write_reg(dev, WUF_CFG(mask_index), + WUF_CFGX_EN_ | + WUF_CFGX_TYPE_MCAST_ | + (0 << WUF_CFGX_OFFSET_SHIFT_) | + (crc & WUF_CFGX_CRC16_MASK_)); + +- ret = lan78xx_write_reg(dev, WUF_MASK0(mask_index), 7); +- ret = lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); +- ret = lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); +- ret = lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); ++ lan78xx_write_reg(dev, WUF_MASK0(mask_index), 7); ++ lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); ++ lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); ++ lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); + mask_index++; + + /* for IPv6 Multicast */ + crc = lan78xx_wakeframe_crc16(ipv6_multicast, 2); +- ret = lan78xx_write_reg(dev, WUF_CFG(mask_index), ++ lan78xx_write_reg(dev, WUF_CFG(mask_index), + WUF_CFGX_EN_ | + WUF_CFGX_TYPE_MCAST_ | + (0 << WUF_CFGX_OFFSET_SHIFT_) | + (crc & WUF_CFGX_CRC16_MASK_)); + +- ret = lan78xx_write_reg(dev, WUF_MASK0(mask_index), 3); +- ret = lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); +- ret = lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); +- ret = lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); ++ lan78xx_write_reg(dev, WUF_MASK0(mask_index), 3); ++ lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); ++ lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); ++ lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); + mask_index++; + + temp_pmt_ctl |= PMT_CTL_WOL_EN_; +@@ -3905,16 +3893,16 @@ static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) + * for packettype (offset 12,13) = ARP (0x0806) + */ + crc = lan78xx_wakeframe_crc16(arp_type, 2); +- ret = lan78xx_write_reg(dev, WUF_CFG(mask_index), ++ lan78xx_write_reg(dev, WUF_CFG(mask_index), + WUF_CFGX_EN_ | + WUF_CFGX_TYPE_ALL_ | + (0 << WUF_CFGX_OFFSET_SHIFT_) | + (crc & WUF_CFGX_CRC16_MASK_)); + +- ret = lan78xx_write_reg(dev, WUF_MASK0(mask_index), 0x3000); +- ret = lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); +- ret = lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); +- ret = lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); ++ lan78xx_write_reg(dev, WUF_MASK0(mask_index), 0x3000); ++ lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); ++ lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); ++ lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); + mask_index++; + + temp_pmt_ctl |= PMT_CTL_WOL_EN_; +@@ -3922,7 +3910,7 @@ static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) + temp_pmt_ctl |= PMT_CTL_SUS_MODE_0_; + } + +- ret = lan78xx_write_reg(dev, WUCSR, temp_wucsr); ++ lan78xx_write_reg(dev, WUCSR, temp_wucsr); + + /* when multiple WOL bits are set */ + if (hweight_long((unsigned long)wol) > 1) { +@@ -3930,16 +3918,16 @@ static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) + temp_pmt_ctl &= ~PMT_CTL_SUS_MODE_MASK_; + temp_pmt_ctl |= PMT_CTL_SUS_MODE_0_; + } +- ret = lan78xx_write_reg(dev, PMT_CTL, temp_pmt_ctl); ++ lan78xx_write_reg(dev, PMT_CTL, temp_pmt_ctl); + + /* clear WUPS */ +- ret = lan78xx_read_reg(dev, PMT_CTL, &buf); ++ lan78xx_read_reg(dev, PMT_CTL, &buf); + buf |= PMT_CTL_WUPS_MASK_; +- ret = lan78xx_write_reg(dev, PMT_CTL, buf); ++ lan78xx_write_reg(dev, PMT_CTL, buf); + +- ret = lan78xx_read_reg(dev, MAC_RX, &buf); ++ lan78xx_read_reg(dev, MAC_RX, &buf); + buf |= MAC_RX_RXEN_; +- ret = lan78xx_write_reg(dev, MAC_RX, buf); ++ lan78xx_write_reg(dev, MAC_RX, buf); + + return 0; + } +-- +2.44.0 + diff --git a/patches.suse/net-usb-smsc75xx-Fix-uninit-value-access-in-__smsc75.patch b/patches.suse/net-usb-smsc75xx-Fix-uninit-value-access-in-__smsc75.patch index bc5f090..ab07f98 100644 --- a/patches.suse/net-usb-smsc75xx-Fix-uninit-value-access-in-__smsc75.patch +++ b/patches.suse/net-usb-smsc75xx-Fix-uninit-value-access-in-__smsc75.patch @@ -4,7 +4,7 @@ Date: Sun, 24 Sep 2023 02:35:49 +0900 Subject: [PATCH] net: usb: smsc75xx: Fix uninit-value access in __smsc75xx_read_reg Git-commit: e9c65989920f7c28775ec4e0c11b483910fb67b8 -References: git-fixes +References: git-fixes CVE-2023-52528 bsc#1220843 Patch-mainline: v6.6-rc5 syzbot reported the following uninit-value access issue: diff --git a/patches.suse/netfilter-ctnetlink-fix-possible-refcount-leak-in-ct.patch b/patches.suse/netfilter-ctnetlink-fix-possible-refcount-leak-in-ct.patch new file mode 100644 index 0000000..c4aac59 --- /dev/null +++ b/patches.suse/netfilter-ctnetlink-fix-possible-refcount-leak-in-ct.patch @@ -0,0 +1,40 @@ +From: Hangyu Hua +Date: Fri, 10 Feb 2023 15:17:30 +0800 +Subject: netfilter: ctnetlink: fix possible refcount leak in ctnetlink_create_conntrack() +Patch-mainline: v6.3-rc1 +Git-commit: ac4893980bbe79ce383daf9a0885666a30fe4c83 +References: CVE-2023-7192 bsc#1218479 + +nf_ct_put() needs to be called to put the refcount got by +nf_conntrack_find_get() to avoid refcount leak when +nf_conntrack_hash_check_insert() fails. + +Fixes: 7d367e06688d ("netfilter: ctnetlink: fix soft lockup when netlink adds new entries (v2)") +Signed-off-by: Hangyu Hua +Acked-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Acked-by: Michal Kubecek + +--- + net/netfilter/nf_conntrack_netlink.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/net/netfilter/nf_conntrack_netlink.c ++++ b/net/netfilter/nf_conntrack_netlink.c +@@ -1892,12 +1892,15 @@ ctnetlink_create_conntrack(struct net *net, + + err = nf_conntrack_hash_check_insert(ct); + if (err < 0) +- goto err2; ++ goto err3; + + rcu_read_unlock(); + + return ct; + ++err3: ++ if (ct->master) ++ nf_ct_put(ct->master); + err2: + rcu_read_unlock(); + err1: diff --git a/patches.suse/netfilter-nf_tables-disallow-anonymous-set-with-time.patch b/patches.suse/netfilter-nf_tables-disallow-anonymous-set-with-time.patch new file mode 100644 index 0000000..8a9cf9b --- /dev/null +++ b/patches.suse/netfilter-nf_tables-disallow-anonymous-set-with-time.patch @@ -0,0 +1,32 @@ +From: Pablo Neira Ayuso +Date: Fri, 1 Mar 2024 00:11:10 +0100 +Subject: netfilter: nf_tables: disallow anonymous set with timeout flag +Patch-mainline: v6.8 +Git-commit: 16603605b667b70da974bea8216c93e7db043bf1 +References: CVE-2024-26642 bsc#1221830 + +Anonymous sets are never used with timeout from userspace, reject this. +Exception to this rule is NFT_SET_EVAL to ensure legacy meters still work. + +Cc: stable@vger.kernel.org +Fixes: 761da2935d6e ("netfilter: nf_tables: add set timeout API support") +Reported-by: lonial con +Signed-off-by: Pablo Neira Ayuso +Acked-by: Michal Kubecek + +--- + net/netfilter/nf_tables_api.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -2986,6 +2986,9 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, + if ((flags & (NFT_SET_MAP | NFT_SET_EVAL | NFT_SET_OBJECT)) == + (NFT_SET_MAP | NFT_SET_EVAL | NFT_SET_OBJECT)) + return -EOPNOTSUPP; ++ if ((flags & (NFT_SET_ANONYMOUS | NFT_SET_TIMEOUT | NFT_SET_EVAL)) == ++ (NFT_SET_ANONYMOUS | NFT_SET_TIMEOUT)) ++ return -EOPNOTSUPP; + } + + dtype = 0; diff --git a/patches.suse/netlabel-fix-out-of-bounds-memory-accesses.patch b/patches.suse/netlabel-fix-out-of-bounds-memory-accesses.patch index 0aa2523..15bb8ec 100644 --- a/patches.suse/netlabel-fix-out-of-bounds-memory-accesses.patch +++ b/patches.suse/netlabel-fix-out-of-bounds-memory-accesses.patch @@ -3,7 +3,7 @@ Date: Mon, 25 Feb 2019 19:06:06 -0500 Subject: netlabel: fix out-of-bounds memory accesses Git-commit: 5578de4834fe0f2a34fedc7374be691443396d1f Patch-mainline: v5.0 -References: networking-stable-19_03_07 +References: networking-stable-19_03_07 CVE-2019-25160 bsc#1220394 There are two array out-of-bounds memory accesses, one in cipso_v4_map_lvl_valid(), the other in netlbl_bitmap_walk(). Both diff --git a/patches.suse/nfs-only-issue-commit-in-DIO-codepath-if-we-have-unc.patch b/patches.suse/nfs-only-issue-commit-in-DIO-codepath-if-we-have-unc.patch new file mode 100644 index 0000000..e993b82 --- /dev/null +++ b/patches.suse/nfs-only-issue-commit-in-DIO-codepath-if-we-have-unc.patch @@ -0,0 +1,107 @@ +From: Jeff Layton +Date: Fri, 22 Jul 2022 14:12:20 -0400 +Subject: [PATCH] nfs: only issue commit in DIO codepath if we have uncommitted + data +Git-commit: 69d966510d9f5de81588b37d23a9ee8ccc477b23 +Patch-mainline: v6.0 +References: git-fixes + +Currently, we try to determine whether to issue a commit based on +nfs_write_need_commit which looks at the current verifier. In the case +where we got a short write and then tried to follow it up with one that +failed, the verifier can't be trusted. + +What we really want to know is whether the pgio request had any +successful writes that came back as UNSTABLE. Add a new flag to the pgio +request, and use that to indicate that we've had a successful unstable +write. Only issue a commit if that flag is set. + +Signed-off-by: Jeff Layton +Signed-off-by: Trond Myklebust +Acked-by: NeilBrown + +--- + fs/nfs/direct.c | 2 +- + fs/nfs/write.c | 48 ++++++++++++++++++++++++++++++------------------ + include/linux/nfs_xdr.h | 1 + + 3 files changed, 32 insertions(+), 19 deletions(-) + +--- a/fs/nfs/direct.c ++++ b/fs/nfs/direct.c +@@ -737,7 +737,7 @@ static void nfs_direct_write_completion( + } + + nfs_direct_count_bytes(dreq, hdr); +- if (hdr->good_bytes != 0 && nfs_write_need_commit(hdr)) { ++ if (test_bit(NFS_IOHDR_UNSTABLE_WRITES, &hdr->flags)) { + switch (dreq->flags) { + case 0: + dreq->flags = NFS_ODIRECT_DO_COMMIT; +--- a/fs/nfs/write.c ++++ b/fs/nfs/write.c +@@ -1582,25 +1582,37 @@ static int nfs_writeback_done(struct rpc + return status; + nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, hdr->res.count); + +- if (hdr->res.verf->committed < hdr->args.stable && +- task->tk_status >= 0) { +- /* We tried a write call, but the server did not +- * commit data to stable storage even though we +- * requested it. +- * Note: There is a known bug in Tru64 < 5.0 in which +- * the server reports NFS_DATA_SYNC, but performs +- * NFS_FILE_SYNC. We therefore implement this checking +- * as a dprintk() in order to avoid filling syslog. +- */ +- static unsigned long complain; ++ if (task->tk_status >= 0) { ++ enum nfs3_stable_how committed = hdr->res.verf->committed; + +- /* Note this will print the MDS for a DS write */ +- if (time_before(complain, jiffies)) { +- dprintk("NFS: faulty NFS server %s:" +- " (committed = %d) != (stable = %d)\n", +- NFS_SERVER(inode)->nfs_client->cl_hostname, +- hdr->res.verf->committed, hdr->args.stable); +- complain = jiffies + 300 * HZ; ++ if (committed == NFS_UNSTABLE) { ++ /* ++ * We have some uncommitted data on the server at ++ * this point, so ensure that we keep track of that ++ * fact irrespective of what later writes do. ++ */ ++ set_bit(NFS_IOHDR_UNSTABLE_WRITES, &hdr->flags); ++ } ++ ++ if (committed < hdr->args.stable) { ++ /* We tried a write call, but the server did not ++ * commit data to stable storage even though we ++ * requested it. ++ * Note: There is a known bug in Tru64 < 5.0 in which ++ * the server reports NFS_DATA_SYNC, but performs ++ * NFS_FILE_SYNC. We therefore implement this checking ++ * as a dprintk() in order to avoid filling syslog. ++ */ ++ static unsigned long complain; ++ ++ /* Note this will print the MDS for a DS write */ ++ if (time_before(complain, jiffies)) { ++ dprintk("NFS: faulty NFS server %s:" ++ " (committed = %d) != (stable = %d)\n", ++ NFS_SERVER(inode)->nfs_client->cl_hostname, ++ committed, hdr->args.stable); ++ complain = jiffies + 300 * HZ; ++ } + } + } + +--- a/include/linux/nfs_xdr.h ++++ b/include/linux/nfs_xdr.h +@@ -1422,6 +1422,7 @@ enum { + NFS_IOHDR_EOF, + NFS_IOHDR_REDO, + NFS_IOHDR_STAT, ++ NFS_IOHDR_UNSTABLE_WRITES, + }; + + struct nfs_io_completion; diff --git a/patches.suse/nfsd-lock_rename-needs-both-directories-to-live-on-t.patch b/patches.suse/nfsd-lock_rename-needs-both-directories-to-live-on-t.patch new file mode 100644 index 0000000..1b14ec0 --- /dev/null +++ b/patches.suse/nfsd-lock_rename-needs-both-directories-to-live-on-t.patch @@ -0,0 +1,51 @@ +From: Al Viro +Date: Sat, 14 Oct 2023 21:34:40 -0400 +Subject: [PATCH] nfsd: lock_rename() needs both directories to live on the + same fs +Git-commit: 1aee9158bc978f91701c5992e395efbc6da2de3c +Patch-mainline: v6.6 +References: git-fixes + +... checking that after lock_rename() is too late. Incidentally, +NFSv2 had no nfserr_xdev... + +Fixes: aa387d6ce153 "nfsd: fix EXDEV checking in rename" +Cc: stable@vger.kernel.org # v3.9+ +Reviewed-by: Jeff Layton +Acked-by: Chuck Lever +Tested-by: Jeff Layton +Signed-off-by: Al Viro +Acked-by: NeilBrown + +--- + fs/nfsd/vfs.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/fs/nfsd/vfs.c ++++ b/fs/nfsd/vfs.c +@@ -1689,6 +1689,12 @@ nfsd_rename(struct svc_rqst *rqstp, stru + if (!flen || isdotent(fname, flen) || !tlen || isdotent(tname, tlen)) + goto out; + ++ err = (rqstp->rq_vers == 2) ? nfserr_acces : nfserr_xdev; ++ if (ffhp->fh_export->ex_path.mnt != tfhp->fh_export->ex_path.mnt) ++ goto out; ++ if (ffhp->fh_export->ex_path.dentry != tfhp->fh_export->ex_path.dentry) ++ goto out; ++ + host_err = fh_want_write(ffhp); + if (host_err) { + err = nfserrno(host_err); +@@ -1722,12 +1728,6 @@ nfsd_rename(struct svc_rqst *rqstp, stru + if (ndentry == trap) + goto out_dput_new; + +- host_err = -EXDEV; +- if (ffhp->fh_export->ex_path.mnt != tfhp->fh_export->ex_path.mnt) +- goto out_dput_new; +- if (ffhp->fh_export->ex_path.dentry != tfhp->fh_export->ex_path.dentry) +- goto out_dput_new; +- + host_err = vfs_rename(fdir, odentry, tdir, ndentry, NULL, 0); + if (!host_err) { + host_err = commit_metadata(tfhp); diff --git a/patches.suse/nvmet-tcp-Fix-a-kernel-panic-when-host-sends-an-inva.patch b/patches.suse/nvmet-tcp-Fix-a-kernel-panic-when-host-sends-an-inva.patch index 06a3788..deeef27 100644 --- a/patches.suse/nvmet-tcp-Fix-a-kernel-panic-when-host-sends-an-inva.patch +++ b/patches.suse/nvmet-tcp-Fix-a-kernel-panic-when-host-sends-an-inva.patch @@ -4,7 +4,7 @@ Subject: nvmet-tcp: Fix a kernel panic when host sends an invalid H2C PDU length Patch-mainline: v6.8-rc1 Git-commit: efa56305908ba20de2104f1b8508c6a7401833be -References: bsc#1217987 bsc#1217988 bsc#1217989 CVE-2023-6535 CVE-2023-6536 CVE-2023-6356 +References: bsc#1217987 bsc#1217988 bsc#1217989 CVE-2023-6535 CVE-2023-6536 CVE-2023-6356 CVE-2023-52454 bsc#1220320 If the host sends an H2CData command with an invalid DATAL, the kernel may crash in nvmet_tcp_build_pdu_iovec(). diff --git a/patches.suse/ocfs2-Avoid-touching-renamed-directory-if-parent-doe.patch b/patches.suse/ocfs2-Avoid-touching-renamed-directory-if-parent-doe.patch new file mode 100644 index 0000000..74325de --- /dev/null +++ b/patches.suse/ocfs2-Avoid-touching-renamed-directory-if-parent-doe.patch @@ -0,0 +1,58 @@ +From 9d618d19b29c2943527e3a43da0a35aea91062fc Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 12 Oct 2023 23:14:21 +0200 +Subject: [PATCH] ocfs2: Avoid touching renamed directory if parent does not + change +Git-commit: 9d618d19b29c2943527e3a43da0a35aea91062fc +Patch-mainline: v6.8-rc1 +References: bsc#1221044 CVE-2023-52591 CVE-2023-52590 bsc#1221088 + +The VFS will not be locking moved directory if its parent does not +change. Change ocfs2 rename code to avoid touching renamed directory if +its parent does not change as without locking that can corrupt the +filesystem. + +Signed-off-by: Jan Kara +Signed-off-by: Al Viro +Acked-by: Jan Kara + +--- + fs/ocfs2/namei.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c +index 814733ba2f4b..9221a33f917b 100644 +--- a/fs/ocfs2/namei.c ++++ b/fs/ocfs2/namei.c +@@ -1336,7 +1336,7 @@ static int ocfs2_rename(struct mnt_idmap *idmap, + goto bail; + } + +- if (S_ISDIR(old_inode->i_mode)) { ++ if (S_ISDIR(old_inode->i_mode) && new_dir != old_dir) { + u64 old_inode_parent; + + update_dot_dot = 1; +@@ -1353,8 +1353,7 @@ static int ocfs2_rename(struct mnt_idmap *idmap, + goto bail; + } + +- if (!new_inode && new_dir != old_dir && +- new_dir->i_nlink >= ocfs2_link_max(osb)) { ++ if (!new_inode && new_dir->i_nlink >= ocfs2_link_max(osb)) { + status = -EMLINK; + goto bail; + } +@@ -1601,6 +1600,9 @@ static int ocfs2_rename(struct mnt_idmap *idmap, + mlog_errno(status); + goto bail; + } ++ } ++ ++ if (S_ISDIR(old_inode->i_mode)) { + drop_nlink(old_dir); + if (new_inode) { + drop_nlink(new_inode); +-- +2.35.3 + diff --git a/patches.suse/ocfs2-fix-data-corruption-by-fallocate.patch b/patches.suse/ocfs2-fix-data-corruption-by-fallocate.patch index 2b07976..7282b3b 100644 --- a/patches.suse/ocfs2-fix-data-corruption-by-fallocate.patch +++ b/patches.suse/ocfs2-fix-data-corruption-by-fallocate.patch @@ -4,7 +4,7 @@ Date: Fri, 4 Jun 2021 20:01:42 -0700 Subject: [PATCH] ocfs2: fix data corruption by fallocate Git-commit: 6bba4471f0cc1296fe3c2089b9e52442d3074b2e Patch-mainline: v5.13-rc5 -References: bsc#1187412 +References: bsc#1187412 CVE-2021-47114 bsc#1221548 When fallocate punches holes out of inode size, if original isize is in the middle of last cluster, then the part from isize to the end of the diff --git a/patches.suse/pNFS-Fix-the-pnfs-block-driver-s-calculation-of-layo.patch b/patches.suse/pNFS-Fix-the-pnfs-block-driver-s-calculation-of-layo.patch new file mode 100644 index 0000000..4f869ed --- /dev/null +++ b/patches.suse/pNFS-Fix-the-pnfs-block-driver-s-calculation-of-layo.patch @@ -0,0 +1,81 @@ +From: Trond Myklebust +Date: Fri, 17 Nov 2023 06:25:13 -0500 +Subject: [PATCH] pNFS: Fix the pnfs block driver's calculation of layoutget + size +Git-commit: 8a6291bf3b0eae1bf26621e6419a91682f2d6227 +Patch-mainline: v6.8 +References: git-fixes + +Instead of relying on the value of the 'bytes_left' field, we should +calculate the layout size based on the offset of the request that is +being written out. + +Reported-by: Benjamin Coddington +Signed-off-by: Trond Myklebust +Fixes: 954998b60caa ("NFS: Fix error handling for O_DIRECT write scheduling") +Reviewed-by: Benjamin Coddington +Tested-by: Benjamin Coddington +Reviewed-by: Christoph Hellwig +Signed-off-by: Anna Schumaker +Acked-by: NeilBrown + +--- + fs/nfs/blocklayout/blocklayout.c | 5 ++--- + fs/nfs/direct.c | 5 +++-- + fs/nfs/internal.h | 2 +- + fs/nfs/pnfs.c | 3 ++- + 4 files changed, 8 insertions(+), 7 deletions(-) + +--- a/fs/nfs/blocklayout/blocklayout.c ++++ b/fs/nfs/blocklayout/blocklayout.c +@@ -847,10 +847,9 @@ bl_pg_init_write(struct nfs_pageio_descr + } + + if (pgio->pg_dreq == NULL) +- wb_size = pnfs_num_cont_bytes(pgio->pg_inode, +- req->wb_index); ++ wb_size = pnfs_num_cont_bytes(pgio->pg_inode, req->wb_index); + else +- wb_size = nfs_dreq_bytes_left(pgio->pg_dreq); ++ wb_size = nfs_dreq_bytes_left(pgio->pg_dreq, req_offset(req)); + + pnfs_generic_pg_init_write(pgio, req, wb_size); + } +--- a/fs/nfs/direct.c ++++ b/fs/nfs/direct.c +@@ -267,9 +267,10 @@ static void nfs_direct_req_release(struc + kref_put(&dreq->kref, nfs_direct_req_free); + } + +-ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq) ++ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq, loff_t offset) + { +- return dreq->bytes_left; ++ loff_t start = offset - dreq->io_start; ++ return dreq->max_count - start; + } + EXPORT_SYMBOL_GPL(nfs_dreq_bytes_left); + +--- a/fs/nfs/internal.h ++++ b/fs/nfs/internal.h +@@ -577,7 +577,7 @@ extern int nfs_sillyrename(struct inode + /* direct.c */ + void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo, + struct nfs_direct_req *dreq); +-extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq); ++extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq, loff_t offset); + + /* nfs4proc.c */ + extern struct nfs_client *nfs4_init_client(struct nfs_client *clp, +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -2173,7 +2173,8 @@ pnfs_generic_pg_init_read(struct nfs_pag + if (pgio->pg_dreq == NULL) + rd_size = i_size_read(pgio->pg_inode) - req_offset(req); + else +- rd_size = nfs_dreq_bytes_left(pgio->pg_dreq); ++ rd_size = nfs_dreq_bytes_left(pgio->pg_dreq, ++ req_offset(req)); + + pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, + req->wb_context, diff --git a/patches.suse/pNFS-flexfiles-Check-the-layout-validity-in-ff_layou.patch b/patches.suse/pNFS-flexfiles-Check-the-layout-validity-in-ff_layou.patch new file mode 100644 index 0000000..f89d158 --- /dev/null +++ b/patches.suse/pNFS-flexfiles-Check-the-layout-validity-in-ff_layou.patch @@ -0,0 +1,54 @@ +From: Trond Myklebust +Date: Sun, 8 Oct 2023 14:28:46 -0400 +Subject: [PATCH] pNFS/flexfiles: Check the layout validity in + ff_layout_mirror_prepare_stats +Git-commit: e1c6cfbb3bd1377e2ddcbe06cf8fb1ec323ea7d3 +Patch-mainline: v6.6 +References: git-fixes + +Ensure that we check the layout pointer and validity after dereferencing +it in ff_layout_mirror_prepare_stats. + +Fixes: 08e2e5bc6c9a ("pNFS/flexfiles: Clean up layoutstats") +Signed-off-by: Trond Myklebust +Signed-off-by: Anna Schumaker +Acked-by: NeilBrown + +--- + fs/nfs/flexfilelayout/flexfilelayout.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +--- a/fs/nfs/flexfilelayout/flexfilelayout.c ++++ b/fs/nfs/flexfilelayout/flexfilelayout.c +@@ -2348,9 +2348,9 @@ ff_layout_mirror_prepare_stats(struct pn + return i; + } + +-static int +-ff_layout_prepare_layoutstats(struct nfs42_layoutstat_args *args) ++static int ff_layout_prepare_layoutstats(struct nfs42_layoutstat_args *args) + { ++ struct pnfs_layout_hdr *lo; + struct nfs4_flexfile_layout *ff_layout; + const int dev_count = PNFS_LAYOUTSTATS_MAXDEV; + +@@ -2360,11 +2360,14 @@ ff_layout_prepare_layoutstats(struct nfs + return -ENOMEM; + + spin_lock(&args->inode->i_lock); +- ff_layout = FF_LAYOUT_FROM_HDR(NFS_I(args->inode)->layout); +- args->num_dev = ff_layout_mirror_prepare_stats(&ff_layout->generic_hdr, +- &args->devinfo[0], +- dev_count, +- NFS4_FF_OP_LAYOUTSTATS); ++ lo = NFS_I(args->inode)->layout; ++ if (lo && pnfs_layout_is_valid(lo)) { ++ ff_layout = FF_LAYOUT_FROM_HDR(lo); ++ args->num_dev = ff_layout_mirror_prepare_stats( ++ &ff_layout->generic_hdr, &args->devinfo[0], dev_count, ++ NFS4_FF_OP_LAYOUTSTATS); ++ } else ++ args->num_dev = 0; + spin_unlock(&args->inode->i_lock); + if (!args->num_dev) { + kfree(args->devinfo); diff --git a/patches.suse/perf-x86-lbr-Filter-vsyscall-addresses.patch b/patches.suse/perf-x86-lbr-Filter-vsyscall-addresses.patch new file mode 100644 index 0000000..9c7ec09 --- /dev/null +++ b/patches.suse/perf-x86-lbr-Filter-vsyscall-addresses.patch @@ -0,0 +1,71 @@ +From: JP Kobryn +Date: Fri, 6 Oct 2023 11:57:26 -0700 +Subject: perf/x86/lbr: Filter vsyscall addresses +Git-commit: e53899771a02f798d436655efbd9d4b46c0f9265 +Patch-mainline: v6.6-rc6 +References: bsc#1220703, CVE-2023-52476 + +We found that a panic can occur when a vsyscall is made while LBR sampling +is active. If the vsyscall is interrupted (NMI) for perf sampling, this +call sequence can occur (most recent at top): + + __insn_get_emulate_prefix() + insn_get_emulate_prefix() + insn_get_prefixes() + insn_get_opcode() + decode_branch_type() + get_branch_type() + intel_pmu_lbr_filter() + intel_pmu_handle_irq() + perf_event_nmi_handler() + +Within __insn_get_emulate_prefix() at frame 0, a macro is called: + + peek_nbyte_next(insn_byte_t, insn, i) + +Within this macro, this dereference occurs: + + (insn)->next_byte + +Inspecting registers at this point, the value of the next_byte field is the +address of the vsyscall made, for example the location of the vsyscall +version of gettimeofday() at 0xffffffffff600000. The access to an address +in the vsyscall region will trigger an oops due to an unhandled page fault. + +To fix the bug, filtering for vsyscalls can be done when +determining the branch type. This patch will return +a "none" branch if a kernel address if found to lie in the +vsyscall region. + +Suggested-by: Alexei Starovoitov +Signed-off-by: JP Kobryn +Signed-off-by: Ingo Molnar +Cc: stable@vger.kernel.org + +Signed-off-by: Tony Jones +--- + arch/x86/events/intel/lbr.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/arch/x86/events/intel/lbr.c ++++ b/arch/x86/events/intel/lbr.c +@@ -4,6 +4,7 @@ + #include + #include + #include ++#include + + #include "../perf_event.h" + +@@ -826,9 +827,9 @@ + * The LBR logs any address in the IP, even if the IP just + * faulted. This means userspace can control the from address. + * Ensure we don't blindy read any address by validating it is +- * a known text address. ++ * a known text address and not a vsyscall address. + */ +- if (kernel_text_address(from)) { ++ if (kernel_text_address(from) && !in_gate_area_no_mm(from)) { + addr = (void *)from; + /* + * Assume we can get the maximum possible size diff --git a/patches.suse/pid-take-a-reference-when-initializing-cad_pid.patch b/patches.suse/pid-take-a-reference-when-initializing-cad_pid.patch index daa4de4..5d19ee4 100644 --- a/patches.suse/pid-take-a-reference-when-initializing-cad_pid.patch +++ b/patches.suse/pid-take-a-reference-when-initializing-cad_pid.patch @@ -3,7 +3,7 @@ Date: Fri, 4 Jun 2021 20:01:14 -0700 Subject: pid: take a reference when initializing `cad_pid` Git-commit: 0711f0d7050b9e07c44bc159bbc64ac0a1022c7f Patch-mainline: v5.13-rc5 -References: bsc#1114648 +References: bsc#1114648 CVE-2021-47118 bsc#1221605 During boot, kernel_init_freeable() initializes `cad_pid` to the init task's struct pid. Later on, we may change `cad_pid` via a sysctl, and diff --git a/patches.suse/platform-x86-dell-smbios-wmi-Fix-oops-on-rmmod-dell_.patch b/patches.suse/platform-x86-dell-smbios-wmi-Fix-oops-on-rmmod-dell_.patch index 4475e25..562d9ab 100644 --- a/patches.suse/platform-x86-dell-smbios-wmi-Fix-oops-on-rmmod-dell_.patch +++ b/patches.suse/platform-x86-dell-smbios-wmi-Fix-oops-on-rmmod-dell_.patch @@ -3,7 +3,7 @@ From: Hans de Goede Date: Tue, 18 May 2021 14:50:27 +0200 Subject: [PATCH] platform/x86: dell-smbios-wmi: Fix oops on rmmod dell_smbios Git-commit: 3a53587423d25c87af4b4126a806a0575104b45e -References: git-fixes +References: git-fixes CVE-2021-47073 bsc#1220850 Patch-mainline: v5.13-rc3 init_dell_smbios_wmi() only registers the dell_smbios_wmi_driver on systems diff --git a/patches.suse/powerpc-64s-Fix-crashes-when-toggling-entry-flush-ba.patch b/patches.suse/powerpc-64s-Fix-crashes-when-toggling-entry-flush-ba.patch index f253b1c..af53bb1 100644 --- a/patches.suse/powerpc-64s-Fix-crashes-when-toggling-entry-flush-ba.patch +++ b/patches.suse/powerpc-64s-Fix-crashes-when-toggling-entry-flush-ba.patch @@ -3,7 +3,7 @@ From: Michael Ellerman Date: Thu, 6 May 2021 14:49:59 +1000 Subject: [PATCH] powerpc/64s: Fix crashes when toggling entry flush barrier -References: bsc#1177666 git-fixes bsc#1186460 ltc#192531 +References: bsc#1177666 git-fixes bsc#1186460 ltc#192531 CVE-2021-46990 bsc#1220743 Patch-mainline: v5.13-rc2 Git-commit: aec86b052df6541cc97c5fca44e5934cbea4963b diff --git a/patches.suse/powerpc-64s-Fix-pte-update-for-kernel-memory-on-radi.patch b/patches.suse/powerpc-64s-Fix-pte-update-for-kernel-memory-on-radi.patch index 8822470..b253687 100644 --- a/patches.suse/powerpc-64s-Fix-pte-update-for-kernel-memory-on-radi.patch +++ b/patches.suse/powerpc-64s-Fix-pte-update-for-kernel-memory-on-radi.patch @@ -3,7 +3,7 @@ From: Jordan Niethe Date: Mon, 8 Feb 2021 14:29:56 +1100 Subject: [PATCH] powerpc/64s: Fix pte update for kernel memory on radix -References: bsc#1055117 git-fixes +References: bsc#1055117 git-fixes CVE-2021-47034 bsc#1220687 Patch-mainline: v5.13-rc1 Git-commit: b8b2f37cf632434456182e9002d63cbc4cccc50c diff --git a/patches.suse/powerpc-mm-Fix-null-pointer-dereference-in-pgtable_c.patch b/patches.suse/powerpc-mm-Fix-null-pointer-dereference-in-pgtable_c.patch new file mode 100644 index 0000000..6913555 --- /dev/null +++ b/patches.suse/powerpc-mm-Fix-null-pointer-dereference-in-pgtable_c.patch @@ -0,0 +1,48 @@ +From f46c8a75263f97bda13c739ba1c90aced0d3b071 Mon Sep 17 00:00:00 2001 +From: Kunwu Chan +Date: Mon, 4 Dec 2023 10:32:23 +0800 +Subject: [PATCH] powerpc/mm: Fix null-pointer dereference in pgtable_cache_add + +References: CVE-2023-52607 bsc#1221061 +Patch-mainline: v6.8-rc1 +Git-commit: f46c8a75263f97bda13c739ba1c90aced0d3b071 + +kasprintf() returns a pointer to dynamically allocated memory +which can be NULL upon failure. Ensure the allocation was successful +by checking the pointer validity. + +Suggested-by: Christophe Leroy +Suggested-by: Michael Ellerman +Signed-off-by: Kunwu Chan +Signed-off-by: Michael Ellerman +Link: https://msgid.link/20231204023223.2447523-1-chentao@kylinos.cn +Acked-by: Michal Suchanek +--- + arch/powerpc/mm/init-common.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/arch/powerpc/mm/init-common.c b/arch/powerpc/mm/init-common.c +--- a/arch/powerpc/mm/init-common.c ++++ b/arch/powerpc/mm/init-common.c +@@ -126,7 +126,7 @@ void pgtable_cache_add(unsigned int shift) + * as to leave enough 0 bits in the address to contain it. */ + unsigned long minalign = max(MAX_PGTABLE_INDEX_SIZE + 1, + HUGEPD_SHIFT_MASK + 1); +- struct kmem_cache *new; ++ struct kmem_cache *new = NULL; + + /* It would be nice if this was a BUILD_BUG_ON(), but at the + * moment, gcc doesn't seem to recognize is_power_of_2 as a +@@ -139,7 +139,8 @@ void pgtable_cache_add(unsigned int shift) + + align = max_t(unsigned long, align, minalign); + name = kasprintf(GFP_KERNEL, "pgtable-2^%d", shift); +- new = kmem_cache_create(name, table_size, align, 0, ctor); ++ if (name) ++ new = kmem_cache_create(name, table_size, align, 0, ctor); + if (!new) + panic("Could not allocate pgtable cache for order %d", shift); + +-- +2.44.0 + diff --git a/patches.suse/ravb-Fix-use-after-free-issue-in-ravb_tx_timeout_wor.patch b/patches.suse/ravb-Fix-use-after-free-issue-in-ravb_tx_timeout_wor.patch index 27d1eda..fc48dcb 100644 --- a/patches.suse/ravb-Fix-use-after-free-issue-in-ravb_tx_timeout_wor.patch +++ b/patches.suse/ravb-Fix-use-after-free-issue-in-ravb_tx_timeout_wor.patch @@ -3,7 +3,7 @@ Date: Thu, 5 Oct 2023 10:12:01 +0900 Subject: ravb: Fix use-after-free issue in ravb_tx_timeout_work() Patch-mainline: v6.6-rc6 Git-commit: 3971442870713de527684398416970cf025b4f89 -References: bsc#1212514 CVE-2023-35827 +References: bsc#1212514 CVE-2023-35827 CVE-2023-52509 bsc#1220836 The ravb_stop() should call cancel_work_sync(). Otherwise, ravb_tx_timeout_work() is possible to use the freed priv after diff --git a/patches.suse/reiserfs-Avoid-touching-renamed-directory-if-parent-.patch b/patches.suse/reiserfs-Avoid-touching-renamed-directory-if-parent-.patch new file mode 100644 index 0000000..b3189d5 --- /dev/null +++ b/patches.suse/reiserfs-Avoid-touching-renamed-directory-if-parent-.patch @@ -0,0 +1,140 @@ +From 49db9b1b86a82448dfaf3fcfefcf678dee56c8ed Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 12 Oct 2023 23:14:20 +0200 +Subject: [PATCH] reiserfs: Avoid touching renamed directory if parent does not + change +Git-commit: 49db9b1b86a82448dfaf3fcfefcf678dee56c8ed +Patch-mainline: v6.8-rc1 +References: git-fixes bsc#1221044 CVE-2023-52591 + +The VFS will not be locking moved directory if its parent does not +change. Change reiserfs rename code to avoid touching renamed directory +if its parent does not change as without locking that can corrupt the +filesystem. + +Signed-off-by: Jan Kara +Signed-off-by: Al Viro +Acked-by: Anthony Iliopoulos + +--- + fs/reiserfs/namei.c | 54 +++++++++++++++++++++++++++------------------------- + 1 file changed, 29 insertions(+), 25 deletions(-) + +--- a/fs/reiserfs/namei.c ++++ b/fs/reiserfs/namei.c +@@ -1318,9 +1318,9 @@ static int reiserfs_rename(struct inode + struct inode *old_inode, *new_dentry_inode; + struct reiserfs_transaction_handle th; + int jbegin_count; +- umode_t old_inode_mode; + unsigned long savelink = 1; + struct timespec ctime; ++ bool update_dir_parent = false; + + if (flags & ~RENAME_NOREPLACE) + return -EINVAL; +@@ -1370,8 +1370,7 @@ static int reiserfs_rename(struct inode + return -ENOENT; + } + +- old_inode_mode = old_inode->i_mode; +- if (S_ISDIR(old_inode_mode)) { ++ if (S_ISDIR(old_inode->i_mode)) { + /* + * make sure that directory being renamed has correct ".." + * and that its new parent directory has not too many links +@@ -1384,24 +1383,28 @@ static int reiserfs_rename(struct inode + } + } + +- /* +- * directory is renamed, its parent directory will be changed, +- * so find ".." entry +- */ +- dot_dot_de.de_gen_number_bit_string = NULL; +- retval = +- reiserfs_find_entry(old_inode, "..", 2, &dot_dot_entry_path, ++ if (old_dir != new_dir) { ++ /* ++ * directory is renamed, its parent directory will be ++ * changed, so find ".." entry ++ */ ++ dot_dot_de.de_gen_number_bit_string = NULL; ++ retval = ++ reiserfs_find_entry(old_inode, "..", 2, ++ &dot_dot_entry_path, + &dot_dot_de); +- pathrelse(&dot_dot_entry_path); +- if (retval != NAME_FOUND) { +- reiserfs_write_unlock(old_dir->i_sb); +- return -EIO; +- } ++ pathrelse(&dot_dot_entry_path); ++ if (retval != NAME_FOUND) { ++ reiserfs_write_unlock(old_dir->i_sb); ++ return -EIO; ++ } + +- /* inode number of .. must equal old_dir->i_ino */ +- if (dot_dot_de.de_objectid != old_dir->i_ino) { +- reiserfs_write_unlock(old_dir->i_sb); +- return -EIO; ++ /* inode number of .. must equal old_dir->i_ino */ ++ if (dot_dot_de.de_objectid != old_dir->i_ino) { ++ reiserfs_write_unlock(old_dir->i_sb); ++ return -EIO; ++ } ++ update_dir_parent = true; + } + } + +@@ -1481,7 +1484,7 @@ static int reiserfs_rename(struct inode + + reiserfs_prepare_for_journal(old_inode->i_sb, new_de.de_bh, 1); + +- if (S_ISDIR(old_inode->i_mode)) { ++ if (update_dir_parent) { + if ((retval = + search_by_entry_key(new_dir->i_sb, + &dot_dot_de.de_entry_key, +@@ -1529,14 +1532,14 @@ static int reiserfs_rename(struct inode + new_de.de_bh); + reiserfs_restore_prepared_buffer(old_inode->i_sb, + old_de.de_bh); +- if (S_ISDIR(old_inode_mode)) ++ if (update_dir_parent) + reiserfs_restore_prepared_buffer(old_inode-> + i_sb, + dot_dot_de. + de_bh); + continue; + } +- if (S_ISDIR(old_inode_mode)) { ++ if (update_dir_parent) { + if (item_moved(&dot_dot_ih, &dot_dot_entry_path) || + !entry_points_to_object("..", 2, &dot_dot_de, + old_dir)) { +@@ -1554,7 +1557,7 @@ static int reiserfs_rename(struct inode + } + } + +- RFALSE(S_ISDIR(old_inode_mode) && ++ RFALSE(update_dir_parent && + !buffer_journal_prepared(dot_dot_de.de_bh), ""); + + break; +@@ -1591,11 +1594,12 @@ static int reiserfs_rename(struct inode + savelink = new_dentry_inode->i_nlink; + } + +- if (S_ISDIR(old_inode_mode)) { ++ if (update_dir_parent) { + /* adjust ".." of renamed directory */ + set_ino_in_dir_entry(&dot_dot_de, INODE_PKEY(new_dir)); + journal_mark_dirty(&th, dot_dot_de.de_bh); +- ++ } ++ if (S_ISDIR(old_inode->i_mode)) { + /* + * there (in new_dir) was no directory, so it got new link + * (".." of renamed directory) diff --git a/patches.suse/reiserfs-add-check-to-detect-corrupted-directory-entry.patch b/patches.suse/reiserfs-add-check-to-detect-corrupted-directory-entry.patch index 81d755f..f4aa8c5 100644 --- a/patches.suse/reiserfs-add-check-to-detect-corrupted-directory-entry.patch +++ b/patches.suse/reiserfs-add-check-to-detect-corrupted-directory-entry.patch @@ -16,14 +16,12 @@ so that if there is an error, we can return appropriately. Signed-off-by: Jeff Mahoney --- - fs/reiserfs/namei.c | 32 ++++++++++++++++++++++++++++++-- + fs/reiserfs/namei.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) -diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c -index 97f3fc4fdd79..5be509a9204f 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c -@@ -1282,7 +1282,7 @@ static int entry_points_to_object(const char *name, int len, +@@ -1285,7 +1285,7 @@ static int entry_points_to_object(const /* this must be added hidden entry */ if (de_visible(de->de_deh + de->de_entry_num)) @@ -32,20 +30,24 @@ index 97f3fc4fdd79..5be509a9204f 100644 return 1; } -@@ -1389,7 +1389,8 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry, - reiserfs_find_entry(old_inode, "..", 2, &dot_dot_entry_path, +@@ -1393,7 +1393,8 @@ static int reiserfs_rename(struct inode + &dot_dot_entry_path, &dot_dot_de); - pathrelse(&dot_dot_entry_path); -- if (retval != NAME_FOUND) { -+ if (retval != NAME_FOUND || -+ dot_dot_de.de_objectid != old_dir->i_ino) { - reiserfs_write_unlock(old_dir->i_sb); - return -EIO; - } -@@ -1473,6 +1474,33 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry, - return -EIO; - } - + pathrelse(&dot_dot_entry_path); +- if (retval != NAME_FOUND) { ++ if (retval != NAME_FOUND || ++ dot_dot_de.de_objectid != old_dir->i_ino) { + reiserfs_write_unlock(old_dir->i_sb); + return -EIO; + } +@@ -1475,6 +1476,33 @@ static int reiserfs_rename(struct inode + pathrelse(&new_entry_path); + pathrelse(&old_entry_path); + journal_end(&th); ++ reiserfs_write_unlock(old_dir->i_sb); ++ return -EIO; ++ } ++ + /* + * If this entry is corrupted and points somewhere else, + * we'll loop forever as we check to ensure it points to @@ -69,11 +71,6 @@ index 97f3fc4fdd79..5be509a9204f 100644 + pathrelse(&new_entry_path); + pathrelse(&old_entry_path); + journal_end(&th); -+ reiserfs_write_unlock(old_dir->i_sb); -+ return -EIO; -+ } -+ - copy_item_head(&new_entry_ih, tp_item_head(&new_entry_path)); - - reiserfs_prepare_for_journal(old_inode->i_sb, new_de.de_bh, 1); - + reiserfs_write_unlock(old_dir->i_sb); + return -EIO; + } diff --git a/patches.suse/reiserfs-don-t-panic-on-bad-directory-entries.patch b/patches.suse/reiserfs-don-t-panic-on-bad-directory-entries.patch index a6a81a0..61e9a5d 100644 --- a/patches.suse/reiserfs-don-t-panic-on-bad-directory-entries.patch +++ b/patches.suse/reiserfs-don-t-panic-on-bad-directory-entries.patch @@ -10,14 +10,12 @@ This patch instead returns -EIO and sets the file system read-only. Signed-off-by: Jeff Mahoney --- - fs/reiserfs/namei.c | 108 ++++++++++++++++++++++++++++++++-------------------- + fs/reiserfs/namei.c | 108 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 41 deletions(-) -diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c -index 5be509a9204f..01e788f91a1d 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c -@@ -1254,7 +1254,7 @@ static int reiserfs_link(struct dentry *old_dentry, struct inode *dir, +@@ -1257,7 +1257,7 @@ static int reiserfs_link(struct dentry * /* de contains information pointing to an entry which */ static int de_still_valid(const char *name, int len, @@ -26,7 +24,7 @@ index 5be509a9204f..01e788f91a1d 100644 { struct reiserfs_dir_entry tmp = *de; -@@ -1266,23 +1266,31 @@ static int de_still_valid(const char *name, int len, +@@ -1269,23 +1269,31 @@ static int de_still_valid(const char *na return 1; } @@ -66,7 +64,7 @@ index 5be509a9204f..01e788f91a1d 100644 return 1; } -@@ -1541,47 +1549,65 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry, +@@ -1547,47 +1555,65 @@ static int reiserfs_rename(struct inode * of the above checks could have scheduled. We have to be * sure our items haven't been shifted by another process. */ @@ -82,7 +80,7 @@ index 5be509a9204f..01e788f91a1d 100644 - new_de.de_bh); - reiserfs_restore_prepared_buffer(old_inode->i_sb, - old_de.de_bh); -- if (S_ISDIR(old_inode_mode)) +- if (update_dir_parent) - reiserfs_restore_prepared_buffer(old_inode-> - i_sb, - dot_dot_de. @@ -91,7 +89,7 @@ index 5be509a9204f..01e788f91a1d 100644 + if (item_moved(&new_entry_ih, &new_entry_path)) { + retval = 0; + goto restore; - } ++ } + + retval = entry_points_to_object(new_dir, + new_dentry->d_name.name, @@ -103,7 +101,7 @@ index 5be509a9204f..01e788f91a1d 100644 + if (item_moved(&old_entry_ih, &old_entry_path)) { + retval = 0; + goto restore; -+ } + } + + retval = entry_points_to_object(old_dir, + old_dentry->d_name.name, @@ -112,7 +110,7 @@ index 5be509a9204f..01e788f91a1d 100644 + if (retval != 1) + goto restore; + - if (S_ISDIR(old_inode_mode)) { + if (update_dir_parent) { - if (item_moved(&dot_dot_ih, &dot_dot_entry_path) || - !entry_points_to_object("..", 2, &dot_dot_de, - old_dir)) { @@ -140,7 +138,7 @@ index 5be509a9204f..01e788f91a1d 100644 + retval = 0; + - RFALSE(S_ISDIR(old_inode_mode) && + RFALSE(update_dir_parent && !buffer_journal_prepared(dot_dot_de.de_bh), ""); break; @@ -150,7 +148,7 @@ index 5be509a9204f..01e788f91a1d 100644 + new_de.de_bh); + reiserfs_restore_prepared_buffer(old_inode->i_sb, + old_de.de_bh); -+ if (S_ISDIR(old_inode_mode)) ++ if (update_dir_parent) + reiserfs_restore_prepared_buffer(old_inode->i_sb, + dot_dot_de.de_bh); + if (retval) { @@ -164,4 +162,3 @@ index 5be509a9204f..01e788f91a1d 100644 } /* - diff --git a/patches.suse/rename-avoid-a-deadlock-in-the-case-of-parents-havin.patch b/patches.suse/rename-avoid-a-deadlock-in-the-case-of-parents-havin.patch new file mode 100644 index 0000000..53c0c52 --- /dev/null +++ b/patches.suse/rename-avoid-a-deadlock-in-the-case-of-parents-havin.patch @@ -0,0 +1,611 @@ +From a8b0026847b8c43445c921ad2c85521c92eb175f Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Mon, 20 Nov 2023 20:02:11 -0500 +Subject: [PATCH] rename(): avoid a deadlock in the case of parents having no + common ancestor +Git-commit: a8b0026847b8c43445c921ad2c85521c92eb175f +Patch-mainline: v6.8-rc1 +References: bsc#1221044 CVE-2023-52591 + +... and fix the directory locking documentation and proof of correctness. +Holding ->s_vfs_rename_mutex *almost* prevents ->d_parent changes; the +case where we really don't want it is splicing the root of disconnected +tree to somewhere. + +In other words, ->s_vfs_rename_mutex is sufficient to stabilize "X is an +ancestor of Y" only if X and Y are already in the same tree. Otherwise +it can go from false to true, and one can construct a deadlock on that. + +Make lock_two_directories() report an error in such case and update the +callers of lock_rename()/lock_rename_child() to handle such errors. + +And yes, such conditions are not impossible to create ;-/ + +Reviewed-by: Jan Kara +Signed-off-by: Al Viro +Acked-by: Jan Kara + +--- + Documentation/filesystems/directory-locking | 353 +++++++++++++++++++--------- + Documentation/filesystems/porting | 7 + fs/cachefiles/namei.c | 2 + fs/ecryptfs/inode.c | 5 + fs/namei.c | 37 ++ + fs/nfsd/vfs.c | 4 + fs/overlayfs/copy_up.c | 8 + fs/overlayfs/dir.c | 11 + fs/overlayfs/super.c | 6 + 9 files changed, 315 insertions(+), 118 deletions(-) + +--- a/Documentation/filesystems/directory-locking ++++ b/Documentation/filesystems/directory-locking +@@ -6,126 +6,267 @@ kinds of locks - per-inode (->i_rwsem) a + always acquire the locks in order by increasing address. We'll call + that "inode pointer" order in the following. + +- For our purposes all operations fall in 5 classes: ++Primitives ++========== + +-1) read access. Locking rules: caller locks directory we are accessing. +-The lock is taken shared. ++For our purposes all operations fall in 6 classes: + +-2) object creation. Locking rules: same as above, but the lock is taken +-exclusive. ++1. read access. Locking rules: + +-3) object removal. Locking rules: caller locks parent, finds victim, +-locks victim and calls the method. Locks are exclusive. +- +-4) rename() that is _not_ cross-directory. Locking rules: caller locks +-the parent and finds source and target. Then we decide which of the +-source and target need to be locked. Source needs to be locked if it's a +-non-directory; target - if it's a non-directory or about to be removed. +-Take the locks that need to be taken, in inode pointer order if need +-to take both (that can happen only when both source and target are +-non-directories - the source because it wouldn't be locked otherwise +-and the target because mixing directory and non-directory is allowed +-only with RENAME_EXCHANGE, and that won't be removing the target). +-After the locks had been taken, call the method. All locks are exclusive. +- +-5) link creation. Locking rules: +- * lock parent +- * check that source is not a directory +- * lock source +- * call the method. +-All locks are exclusive. ++ * lock the directory we are accessing (shared) + +-6) cross-directory rename. The trickiest in the whole bunch. Locking +-rules: +- * lock the filesystem +- * lock parents in "ancestors first" order. If one is not ancestor of +- the other, lock the parent of source first. +- * find source and target. +- * if old parent is equal to or is a descendent of target +- fail with -ENOTEMPTY +- * if new parent is equal to or is a descendent of source +- fail with -ELOOP +- * Lock subdirectories involved (source before target). +- * Lock non-directories involved, in inode pointer order. +- * call the method. ++2. object creation. Locking rules: ++ ++ * lock the directory we are accessing (exclusive) ++ ++3. object removal. Locking rules: ++ ++ * lock the parent (exclusive) ++ * find the victim ++ * lock the victim (exclusive) ++ ++4. link creation. Locking rules: ++ ++ * lock the parent (exclusive) ++ * check that the source is not a directory ++ * lock the source (exclusive; probably could be weakened to shared) + +-All ->i_rwsem are taken exclusive. ++5. rename that is _not_ cross-directory. Locking rules: + +-The rules above obviously guarantee that all directories that are going to be +-read, modified or removed by method will be locked by caller. ++ * lock the parent (exclusive) ++ * find the source and target ++ * decide which of the source and target need to be locked. ++ The source needs to be locked if it's a non-directory, target - if it's ++ a non-directory or about to be removed. ++ * take the locks that need to be taken (exlusive), in inode pointer order ++ if need to take both (that can happen only when both source and target ++ are non-directories - the source because it wouldn't need to be locked ++ otherwise and the target because mixing directory and non-directory is ++ allowed only with RENAME_EXCHANGE, and that won't be removing the target). + ++6. cross-directory rename. The trickiest in the whole bunch. Locking rules: ++ ++ * lock the filesystem ++ * if the parents don't have a common ancestor, fail the operation. ++ * lock the parents in "ancestors first" order (exclusive). If neither is an ++ ancestor of the other, lock the parent of source first. ++ * find the source and target. ++ * verify that the source is not a descendent of the target and ++ target is not a descendent of source; fail the operation otherwise. ++ * lock the subdirectories involved (exclusive), source before target. ++ * lock the non-directories involved (exclusive), in inode pointer order. ++ ++The rules above obviously guarantee that all directories that are going ++to be read, modified or removed by method will be locked by the caller. ++ ++ ++Splicing ++======== ++ ++There is one more thing to consider - splicing. It's not an operation ++in its own right; it may happen as part of lookup. We speak of the ++operations on directory trees, but we obviously do not have the full ++picture of those - especially for network filesystems. What we have ++is a bunch of subtrees visible in dcache and locking happens on those. ++Trees grow as we do operations; memory pressure prunes them. Normally ++that's not a problem, but there is a nasty twist - what should we do ++when one growing tree reaches the root of another? That can happen in ++several scenarios, starting from "somebody mounted two nested subtrees ++from the same NFS4 server and doing lookups in one of them has reached ++the root of another"; there's also open-by-fhandle stuff, and there's a ++possibility that directory we see in one place gets moved by the server ++to another and we run into it when we do a lookup. ++ ++For a lot of reasons we want to have the same directory present in dcache ++only once. Multiple aliases are not allowed. So when lookup runs into ++a subdirectory that already has an alias, something needs to be done with ++dcache trees. Lookup is already holding the parent locked. If alias is ++a root of separate tree, it gets attached to the directory we are doing a ++lookup in, under the name we'd been looking for. If the alias is already ++a child of the directory we are looking in, it changes name to the one ++we'd been looking for. No extra locking is involved in these two cases. ++However, if it's a child of some other directory, the things get trickier. ++First of all, we verify that it is *not* an ancestor of our directory ++and fail the lookup if it is. Then we try to lock the filesystem and the ++current parent of the alias. If either trylock fails, we fail the lookup. ++If trylocks succeed, we detach the alias from its current parent and ++attach to our directory, under the name we are looking for. ++ ++Note that splicing does *not* involve any modification of the filesystem; ++all we change is the view in dcache. Moreover, holding a directory locked ++exclusive prevents such changes involving its children and holding the ++filesystem lock prevents any changes of tree topology, other than having a ++root of one tree becoming a child of directory in another. In particular, ++if two dentries have been found to have a common ancestor after taking ++the filesystem lock, their relationship will remain unchanged until ++the lock is dropped. So from the directory operations' point of view ++splicing is almost irrelevant - the only place where it matters is one ++step in cross-directory renames; we need to be careful when checking if ++parents have a common ancestor. ++ ++ ++Multiple-filesystem stuff ++========================= ++ ++For some filesystems a method can involve a directory operation on ++another filesystem; it may be ecryptfs doing operation in the underlying ++filesystem, overlayfs doing something to the layers, network filesystem ++using a local one as a cache, etc. In all such cases the operations ++on other filesystems must follow the same locking rules. Moreover, "a ++directory operation on this filesystem might involve directory operations ++on that filesystem" should be an asymmetric relation (or, if you will, ++it should be possible to rank the filesystems so that directory operation ++on a filesystem could trigger directory operations only on higher-ranked ++ones - in these terms overlayfs ranks lower than its layers, network ++filesystem ranks lower than whatever it caches on, etc.) ++ ++ ++Deadlock avoidance ++================== + + If no directory is its own ancestor, the scheme above is deadlock-free. ++ + Proof: + +-[XXX: will be updated once we are done massaging the lock_rename()] +- First of all, at any moment we have a linear ordering of the +- objects - A < B iff (A is an ancestor of B) or (B is not an ancestor +- of A and ptr(A) < ptr(B)). +- +- That ordering can change. However, the following is true: +- +-(1) if object removal or non-cross-directory rename holds lock on A and +- attempts to acquire lock on B, A will remain the parent of B until we +- acquire the lock on B. (Proof: only cross-directory rename can change +- the parent of object and it would have to lock the parent). +- +-(2) if cross-directory rename holds the lock on filesystem, order will not +- change until rename acquires all locks. (Proof: other cross-directory +- renames will be blocked on filesystem lock and we don't start changing +- the order until we had acquired all locks). +- +-(3) locks on non-directory objects are acquired only after locks on +- directory objects, and are acquired in inode pointer order. +- (Proof: all operations but renames take lock on at most one +- non-directory object, except renames, which take locks on source and +- target in inode pointer order in the case they are not directories.) +- +- Now consider the minimal deadlock. Each process is blocked on +-attempt to acquire some lock and already holds at least one lock. Let's +-consider the set of contended locks. First of all, filesystem lock is +-not contended, since any process blocked on it is not holding any locks. +-Thus all processes are blocked on ->i_rwsem. +- +- By (3), any process holding a non-directory lock can only be +-waiting on another non-directory lock with a larger address. Therefore +-the process holding the "largest" such lock can always make progress, and +-non-directory objects are not included in the set of contended locks. +- +- Thus link creation can't be a part of deadlock - it can't be +-blocked on source and it means that it doesn't hold any locks. +- +- Any contended object is either held by cross-directory rename or +-has a child that is also contended. Indeed, suppose that it is held by +-operation other than cross-directory rename. Then the lock this operation +-is blocked on belongs to child of that object due to (1). +- +- It means that one of the operations is cross-directory rename. +-Otherwise the set of contended objects would be infinite - each of them +-would have a contended child and we had assumed that no object is its +-own descendent. Moreover, there is exactly one cross-directory rename +-(see above). +- +- Consider the object blocking the cross-directory rename. One +-of its descendents is locked by cross-directory rename (otherwise we +-would again have an infinite set of contended objects). But that +-means that cross-directory rename is taking locks out of order. Due +-to (2) the order hadn't changed since we had acquired filesystem lock. +-But locking rules for cross-directory rename guarantee that we do not +-try to acquire lock on descendent before the lock on ancestor. +-Contradiction. I.e. deadlock is impossible. Q.E.D. ++There is a ranking on the locks, such that all primitives take ++them in order of non-decreasing rank. Namely, ++ ++ * rank ->i_rwsem of non-directories on given filesystem in inode pointer ++ order. ++ * put ->i_rwsem of all directories on a filesystem at the same rank, ++ lower than ->i_rwsem of any non-directory on the same filesystem. ++ * put ->s_vfs_rename_mutex at rank lower than that of any ->i_rwsem ++ on the same filesystem. ++ * among the locks on different filesystems use the relative ++ rank of those filesystems. ++ ++For example, if we have NFS filesystem caching on a local one, we have ++ ++ 1. ->s_vfs_rename_mutex of NFS filesystem ++ 2. ->i_rwsem of directories on that NFS filesystem, same rank for all ++ 3. ->i_rwsem of non-directories on that filesystem, in order of ++ increasing address of inode ++ 4. ->s_vfs_rename_mutex of local filesystem ++ 5. ->i_rwsem of directories on the local filesystem, same rank for all ++ 6. ->i_rwsem of non-directories on local filesystem, in order of ++ increasing address of inode. ++ ++It's easy to verify that operations never take a lock with rank ++lower than that of an already held lock. ++ ++Suppose deadlocks are possible. Consider the minimal deadlocked ++set of threads. It is a cycle of several threads, each blocked on a lock ++held by the next thread in the cycle. ++ ++Since the locking order is consistent with the ranking, all ++contended locks in the minimal deadlock will be of the same rank, ++i.e. they all will be ->i_rwsem of directories on the same filesystem. ++Moreover, without loss of generality we can assume that all operations ++are done directly to that filesystem and none of them has actually ++reached the method call. ++ ++In other words, we have a cycle of threads, T1,..., Tn, ++and the same number of directories (D1,...,Dn) such that ++ ++ T1 is blocked on D1 which is held by T2 ++ ++ T2 is blocked on D2 which is held by T3 ++ ++ ... ++ ++ Tn is blocked on Dn which is held by T1. ++ ++Each operation in the minimal cycle must have locked at least ++one directory and blocked on attempt to lock another. That leaves ++only 3 possible operations: directory removal (locks parent, then ++child), same-directory rename killing a subdirectory (ditto) and ++cross-directory rename of some sort. ++ ++There must be a cross-directory rename in the set; indeed, ++if all operations had been of the "lock parent, then child" sort ++we would have Dn a parent of D1, which is a parent of D2, which is ++a parent of D3, ..., which is a parent of Dn. Relationships couldn't ++have changed since the moment directory locks had been acquired, ++so they would all hold simultaneously at the deadlock time and ++we would have a loop. ++ ++Since all operations are on the same filesystem, there can't be ++more than one cross-directory rename among them. Without loss of ++generality we can assume that T1 is the one doing a cross-directory ++rename and everything else is of the "lock parent, then child" sort. ++ ++In other words, we have a cross-directory rename that locked ++Dn and blocked on attempt to lock D1, which is a parent of D2, which is ++a parent of D3, ..., which is a parent of Dn. Relationships between ++D1,...,Dn all hold simultaneously at the deadlock time. Moreover, ++cross-directory rename does not get to locking any directories until it ++has acquired filesystem lock and verified that directories involved have ++a common ancestor, which guarantees that ancestry relationships between ++all of them had been stable. ++ ++Consider the order in which directories are locked by the ++cross-directory rename; parents first, then possibly their children. ++Dn and D1 would have to be among those, with Dn locked before D1. ++Which pair could it be? ++ ++It can't be the parents - indeed, since D1 is an ancestor of Dn, ++it would be the first parent to be locked. Therefore at least one of the ++children must be involved and thus neither of them could be a descendent ++of another - otherwise the operation would not have progressed past ++locking the parents. ++ ++It can't be a parent and its child; otherwise we would've had ++a loop, since the parents are locked before the children, so the parent ++would have to be a descendent of its child. ++ ++It can't be a parent and a child of another parent either. ++Otherwise the child of the parent in question would've been a descendent ++of another child. ++ ++That leaves only one possibility - namely, both Dn and D1 are ++among the children, in some order. But that is also impossible, since ++neither of the children is a descendent of another. ++ ++That concludes the proof, since the set of operations with the ++properties requiered for a minimal deadlock can not exist. ++ ++Note that the check for having a common ancestor in cross-directory ++rename is crucial - without it a deadlock would be possible. Indeed, ++suppose the parents are initially in different trees; we would lock the ++parent of source, then try to lock the parent of target, only to have ++an unrelated lookup splice a distant ancestor of source to some distant ++descendent of the parent of target. At that point we have cross-directory ++rename holding the lock on parent of source and trying to lock its ++distant ancestor. Add a bunch of rmdir() attempts on all directories ++in between (all of those would fail with -ENOTEMPTY, had they ever gotten ++the locks) and voila - we have a deadlock. + ++Loop avoidance ++============== + +- These operations are guaranteed to avoid loop creation. Indeed, ++These operations are guaranteed to avoid loop creation. Indeed, + the only operation that could introduce loops is cross-directory rename. +-Since the only new (parent, child) pair added by rename() is (new parent, +-source), such loop would have to contain these objects and the rest of it +-would have to exist before rename(). I.e. at the moment of loop creation +-rename() responsible for that would be holding filesystem lock and new parent +-would have to be equal to or a descendent of source. But that means that +-new parent had been equal to or a descendent of source since the moment when +-we had acquired filesystem lock and rename() would fail with -ELOOP in that +-case. ++Suppose after the operation there is a loop; since there hadn't been such ++loops before the operation, at least on of the nodes in that loop must've ++had its parent changed. In other words, the loop must be passing through ++the source or, in case of exchange, possibly the target. ++ ++Since the operation has succeeded, neither source nor target could have ++been ancestors of each other. Therefore the chain of ancestors starting ++in the parent of source could not have passed through the target and ++vice versa. On the other hand, the chain of ancestors of any node could ++not have passed through the node itself, or we would've had a loop before ++the operation. But everything other than source and target has kept ++the parent after the operation, so the operation does not change the ++chains of ancestors of (ex-)parents of source and target. In particular, ++those chains must end after a finite number of steps. ++ ++Now consider the loop created by the operation. It passes through either ++source or target; the next node in the loop would be the ex-parent of ++target or source resp. After that the loop would follow the chain of ++ancestors of that parent. But as we have just shown, that chain must ++end after a finite number of steps, which means that it can't be a part ++of any loop. Q.E.D. + + While this locking scheme works for arbitrary DAGs, it relies on + ability to check that directory is a descendent of another object. Current +--- a/Documentation/filesystems/porting ++++ b/Documentation/filesystems/porting +@@ -619,3 +619,10 @@ in your dentry operations instead. + protected by any locks; just don't do it if the old parent is the same + as the new one. We really can't lock two subdirectories in + same-directory rename - not without deadlocks. ++ ++-- ++[mandatory] ++ lock_rename() and lock_rename_child() may fail in cross-directory case, ++ if their arguments do not have a common ancestor. In that case ++ ERR_PTR(-EXDEV) is returned, with no locks taken. In-tree users ++ updated; out-of-tree ones would need to do so. +--- a/fs/cachefiles/namei.c ++++ b/fs/cachefiles/namei.c +@@ -339,6 +339,8 @@ try_again: + + /* do the multiway lock magic */ + trap = lock_rename(cache->graveyard, dir); ++ if (IS_ERR(trap)) ++ return PTR_ERR(trap); + + /* do some checks before getting the grave dentry */ + if (rep->d_parent != dir || IS_DEADDIR(d_inode(rep))) { +--- a/fs/ecryptfs/inode.c ++++ b/fs/ecryptfs/inode.c +@@ -604,6 +604,10 @@ ecryptfs_rename(struct inode *old_dir, s + lower_new_dir_dentry = dget_parent(lower_new_dentry); + target_inode = d_inode(new_dentry); + trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); ++ if (IS_ERR(trap)) { ++ rc = PTR_ERR(trap); ++ goto out_put; ++ } + /* source should not be ancestor of target */ + if (trap == lower_old_dentry) { + rc = -EINVAL; +@@ -627,6 +631,7 @@ ecryptfs_rename(struct inode *old_dir, s + fsstack_copy_attr_all(old_dir, d_inode(lower_old_dir_dentry)); + out_lock: + unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); ++out_put: + dput(lower_new_dir_dentry); + dput(lower_old_dir_dentry); + dput(lower_new_dentry); +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -2888,21 +2888,37 @@ static inline int may_create(struct inod + return inode_permission(dir, MAY_WRITE | MAY_EXEC); + } + ++// p1 != p2, both are on the same filesystem, ->s_vfs_rename_mutex is held + static struct dentry *lock_two_directories(struct dentry *p1, struct dentry *p2) + { +- struct dentry *p; ++ struct dentry *p = p1, *q = p2, *r; + +- p = d_ancestor(p2, p1); +- if (p) { ++ while ((r = p->d_parent) != p2 && r != p) ++ p = r; ++ if (r == p2) { ++ // p is a child of p2 and an ancestor of p1 or p1 itself + inode_lock_nested(p2->d_inode, I_MUTEX_PARENT); + inode_lock_nested(p1->d_inode, I_MUTEX_PARENT2); + return p; + } +- +- p = d_ancestor(p1, p2); +- inode_lock_nested(p1->d_inode, I_MUTEX_PARENT); +- inode_lock_nested(p2->d_inode, I_MUTEX_PARENT2); +- return p; ++ // p is the root of connected component that contains p1 ++ // p2 does not occur on the path from p to p1 ++ while ((r = q->d_parent) != p1 && r != p && r != q) ++ q = r; ++ if (r == p1) { ++ // q is a child of p1 and an ancestor of p2 or p2 itself ++ inode_lock_nested(p1->d_inode, I_MUTEX_PARENT); ++ inode_lock_nested(p2->d_inode, I_MUTEX_PARENT2); ++ return q; ++ } else if (likely(r == p)) { ++ // both p2 and p1 are descendents of p ++ inode_lock_nested(p1->d_inode, I_MUTEX_PARENT); ++ inode_lock_nested(p2->d_inode, I_MUTEX_PARENT2); ++ return NULL; ++ } else { // no common ancestor at the time we'd been called ++ mutex_unlock(&p1->d_sb->s_vfs_rename_mutex); ++ return ERR_PTR(-EXDEV); ++ } + } + + /* +@@ -4743,6 +4759,10 @@ retry: + + retry_deleg: + trap = lock_rename(new_path.dentry, old_path.dentry); ++ if (IS_ERR(trap)) { ++ error = PTR_ERR(trap); ++ goto exit_lock_rename; ++ } + + old_dentry = __lookup_hash(&old_last, old_path.dentry, lookup_flags); + error = PTR_ERR(old_dentry); +@@ -4801,6 +4821,7 @@ exit4: + dput(old_dentry); + exit3: + unlock_rename(new_path.dentry, old_path.dentry); ++exit_lock_rename: + if (delegated_inode) { + error = break_deleg_wait(&delegated_inode); + if (!error) +--- a/fs/nfsd/vfs.c ++++ b/fs/nfsd/vfs.c +@@ -1697,6 +1697,10 @@ nfsd_rename(struct svc_rqst *rqstp, stru + /* cannot use fh_lock as we need deadlock protective ordering + * so do it by hand */ + trap = lock_rename(tdentry, fdentry); ++ if (IS_ERR(trap)) { ++ err = (rqstp->rq_vers == 2) ? nfserr_acces : nfserr_xdev; ++ goto out; ++ } + ffhp->fh_locked = tfhp->fh_locked = true; + fill_pre_wcc(ffhp); + fill_pre_wcc(tfhp); +--- a/fs/overlayfs/copy_up.c ++++ b/fs/overlayfs/copy_up.c +@@ -452,6 +452,7 @@ static int ovl_copy_up_one(struct dentry + struct path parentpath; + struct dentry *lowerdentry = lowerpath->dentry; + struct dentry *upperdir; ++ struct dentry *trap; + const char *link = NULL; + struct ovl_fs *ofs = dentry->d_sb->s_fs_info; + +@@ -499,7 +500,12 @@ static int ovl_copy_up_one(struct dentry + } + + err = -EIO; +- if (lock_rename(workdir, upperdir) != NULL) { ++ trap = lock_rename(workdir, upperdir); ++ if (IS_ERR(trap)) { ++ pr_err("overlayfs: failed to lock workdir+upperdir\n"); ++ goto out_done; ++ } ++ if (trap != NULL) { + pr_err("overlayfs: failed to lock workdir+upperdir\n"); + goto out_unlock; + } +--- a/fs/overlayfs/dir.c ++++ b/fs/overlayfs/dir.c +@@ -216,12 +216,17 @@ out_unlock: + static int ovl_lock_rename_workdir(struct dentry *workdir, + struct dentry *upperdir) + { ++ struct dentry *trap; ++ + /* Workdir should not be the same as upperdir */ + if (workdir == upperdir) + goto err; + + /* Workdir should not be subdir of upperdir and vice versa */ +- if (lock_rename(workdir, upperdir) != NULL) ++ trap = lock_rename(workdir, upperdir); ++ if (IS_ERR(trap)) ++ goto err; ++ if (trap) + goto err_unlock; + + return 0; +@@ -995,6 +1000,10 @@ static int ovl_rename(struct inode *oldd + } + + trap = lock_rename(new_upperdir, old_upperdir); ++ if (IS_ERR(trap)) { ++ err = PTR_ERR(trap); ++ goto out_revert_creds; ++ } + + olddentry = lookup_one_len(old->d_name.name, old_upperdir, + old->d_name.len); +--- a/fs/overlayfs/super.c ++++ b/fs/overlayfs/super.c +@@ -580,8 +580,10 @@ static bool ovl_workdir_ok(struct dentry + bool ok = false; + + if (workdir != upperdir) { +- ok = (lock_rename(workdir, upperdir) == NULL); +- unlock_rename(workdir, upperdir); ++ struct dentry *trap = lock_rename(workdir, upperdir); ++ if (!IS_ERR(trap)) ++ unlock_rename(workdir, upperdir); ++ ok = (trap == NULL); + } + return ok; + } diff --git a/patches.suse/rename-fix-the-locking-of-subdirectories.patch b/patches.suse/rename-fix-the-locking-of-subdirectories.patch new file mode 100644 index 0000000..7cf82af --- /dev/null +++ b/patches.suse/rename-fix-the-locking-of-subdirectories.patch @@ -0,0 +1,271 @@ +From 22e111ed6c83dcde3037fc81176012721bc34c0b Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Sun, 19 Nov 2023 20:25:58 -0500 +Subject: [PATCH] rename(): fix the locking of subdirectories +Git-commit: 22e111ed6c83dcde3037fc81176012721bc34c0b +Patch-mainline: v6.8-rc1 +References: bsc#1221044 CVE-2023-52591 + + We should never lock two subdirectories without having taken +->s_vfs_rename_mutex; inode pointer order or not, the "order" proposed +in 28eceeda130f "fs: Lock moved directories" is not transitive, with +the usual consequences. + + The rationale for locking renamed subdirectory in all cases was +the possibility of race between rename modifying .. in a subdirectory to +reflect the new parent and another thread modifying the same subdirectory. +For a lot of filesystems that's not a problem, but for some it can lead +to trouble (e.g. the case when short directory contents is kept in the +inode, but creating a file in it might push it across the size limit +and copy its contents into separate data block(s)). + + However, we need that only in case when the parent does change - +otherwise ->rename() doesn't need to do anything with .. entry in the +first place. Some instances are lazy and do a tautological update anyway, +but it's really not hard to avoid. + +Amended locking rules for rename(): + find the parent(s) of source and target + if source and target have the same parent + lock the common parent + else + lock ->s_vfs_rename_mutex + lock both parents, in ancestor-first order; if neither + is an ancestor of another, lock the parent of source + first. + find the source and target. + if source and target have the same parent + if operation is an overwriting rename of a subdirectory + lock the target subdirectory + else + if source is a subdirectory + lock the source + if target is a subdirectory + lock the target + lock non-directories involved, in inode pointer order if both + source and target are such. + +That way we are guaranteed that parents are locked (for obvious reasons), +that any renamed non-directory is locked (nfsd relies upon that), +that any victim is locked (emptiness check needs that, among other things) +and subdirectory that changes parent is locked (needed to protect the update +of .. entries). We are also guaranteed that any operation locking more +than one directory either takes ->s_vfs_rename_mutex or locks a parent +followed by its child. + +Cc: stable@vger.kernel.org +Fixes: 28eceeda130f "fs: Lock moved directories" +Reviewed-by: Jan Kara +Signed-off-by: Al Viro +Acked-by: Jan Kara + +--- + Documentation/filesystems/Locking | 5 +- + Documentation/filesystems/directory-locking | 30 +++++++------- + Documentation/filesystems/porting | 13 ++++++ + fs/namei.c | 60 +++++++++++++++++----------- + 4 files changed, 70 insertions(+), 38 deletions(-) + +--- a/Documentation/filesystems/Locking ++++ b/Documentation/filesystems/Locking +@@ -78,7 +78,7 @@ symlink: yes + mkdir: yes + unlink: yes (both) + rmdir: yes (both) (see below) +-rename: yes (all) (see below) ++rename: exclusive (both parents, some children) (see below) + readlink: no + get_link: no + setattr: yes +@@ -95,6 +95,9 @@ tmpfile: no + Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on + victim. + cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem. ++ ->unlink() and ->rename() have ->i_rwsem exclusive on all non-directories ++ involved. ++ ->rename() has ->i_rwsem exclusive on any subdirectory that changes parent. + + See Documentation/filesystems/directory-locking for more detailed discussion + of the locking scheme for directory operations. +--- a/Documentation/filesystems/directory-locking ++++ b/Documentation/filesystems/directory-locking +@@ -17,13 +17,16 @@ exclusive. + 3) object removal. Locking rules: caller locks parent, finds victim, + locks victim and calls the method. Locks are exclusive. + +-4) rename() that is _not_ cross-directory. Locking rules: caller locks the +-parent and finds source and target. We lock both (provided they exist). If we +-need to lock two inodes of different type (dir vs non-dir), we lock directory +-first. If we need to lock two inodes of the same type, lock them in inode +-pointer order. Then call the method. All locks are exclusive. +-NB: we might get away with locking the the source (and target in exchange +-case) shared. ++4) rename() that is _not_ cross-directory. Locking rules: caller locks ++the parent and finds source and target. Then we decide which of the ++source and target need to be locked. Source needs to be locked if it's a ++non-directory; target - if it's a non-directory or about to be removed. ++Take the locks that need to be taken, in inode pointer order if need ++to take both (that can happen only when both source and target are ++non-directories - the source because it wouldn't be locked otherwise ++and the target because mixing directory and non-directory is allowed ++only with RENAME_EXCHANGE, and that won't be removing the target). ++After the locks had been taken, call the method. All locks are exclusive. + + 5) link creation. Locking rules: + * lock parent +@@ -36,19 +39,17 @@ All locks are exclusive. + rules: + * lock the filesystem + * lock parents in "ancestors first" order. If one is not ancestor of +- the other, lock them in inode pointer order. ++ the other, lock the parent of source first. + * find source and target. + * if old parent is equal to or is a descendent of target + fail with -ENOTEMPTY + * if new parent is equal to or is a descendent of source + fail with -ELOOP +- * Lock both the source and the target provided they exist. If we +- need to lock two inodes of different type (dir vs non-dir), we lock +- the directory first. If we need to lock two inodes of the same type, +- lock them in inode pointer order. ++ * Lock subdirectories involved (source before target). ++ * Lock non-directories involved, in inode pointer order. + * call the method. +-All ->i_rwsem are taken exclusive. Again, we might get away with locking +-the the source (and target in exchange case) shared. ++ ++All ->i_rwsem are taken exclusive. + + The rules above obviously guarantee that all directories that are going to be + read, modified or removed by method will be locked by caller. +@@ -57,6 +58,7 @@ read, modified or removed by method will + If no directory is its own ancestor, the scheme above is deadlock-free. + Proof: + ++[XXX: will be updated once we are done massaging the lock_rename()] + First of all, at any moment we have a linear ordering of the + objects - A < B iff (A is an ancestor of B) or (B is not an ancestor + of A and ptr(A) < ptr(B)). +--- a/Documentation/filesystems/porting ++++ b/Documentation/filesystems/porting +@@ -606,3 +606,16 @@ in your dentry operations instead. + dentry separately, and it now has request_mask and query_flags arguments + to specify the fields and sync type requested by statx. Filesystems not + supporting any statx-specific features may ignore the new arguments. ++-- ++[mandatory] ++ If ->rename() update of .. on cross-directory move needs an exclusion ++ with directory modifications, do *not* lock the subdirectory in ++ question in your ->rename() - it's done by the caller now [that item ++ should've been added in 28eceeda130f "fs: Lock moved directories"]. ++ ++-- ++[mandatory] ++ On same-directory ->rename() the (tautological) update of .. is not ++ protected by any locks; just don't do it if the old parent is the same ++ as the new one. We really can't lock two subdirectories in ++ same-directory rename - not without deadlocks. +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -2895,20 +2895,14 @@ static struct dentry *lock_two_directori + p = d_ancestor(p2, p1); + if (p) { + inode_lock_nested(p2->d_inode, I_MUTEX_PARENT); +- inode_lock_nested(p1->d_inode, I_MUTEX_CHILD); ++ inode_lock_nested(p1->d_inode, I_MUTEX_PARENT2); + return p; + } + + p = d_ancestor(p1, p2); +- if (p) { +- inode_lock_nested(p1->d_inode, I_MUTEX_PARENT); +- inode_lock_nested(p2->d_inode, I_MUTEX_CHILD); +- return p; +- } +- +- lock_two_inodes(p1->d_inode, p2->d_inode, +- I_MUTEX_PARENT, I_MUTEX_PARENT2); +- return NULL; ++ inode_lock_nested(p1->d_inode, I_MUTEX_PARENT); ++ inode_lock_nested(p2->d_inode, I_MUTEX_PARENT2); ++ return p; + } + + /* +@@ -4511,11 +4505,12 @@ SYSCALL_DEFINE2(link, const char __user + * Problems: + * a) we can get into loop creation. + * b) race potential - two innocent renames can create a loop together. +- * That's where 4.4 screws up. Current fix: serialization on ++ * That's where 4.4BSD screws up. Current fix: serialization on + * sb->s_vfs_rename_mutex. We might be more accurate, but that's another + * story. +- * c) we have to lock _four_ objects - parents and victim (if it exists), +- * and source. ++ * c) we may have to lock up to _four_ objects - parents and victim (if it exists), ++ * and source (if it's a non-directory or a subdirectory that moves to ++ * different parent). + * And that - after we got ->i_mutex on parents (until then we don't know + * whether the target exists). Solution: try to be smart with locking + * order for inodes. We rely on the fact that tree topology may change +@@ -4544,6 +4539,7 @@ int vfs_rename(struct inode *old_dir, st + bool new_is_dir = false; + unsigned max_links = new_dir->i_sb->s_max_links; + struct name_snapshot old_name; ++ bool lock_old_subdir, lock_new_subdir; + + if (source == target) + return 0; +@@ -4593,15 +4589,32 @@ int vfs_rename(struct inode *old_dir, st + take_dentry_name_snapshot(&old_name, old_dentry); + dget(new_dentry); + /* +- * Lock all moved children. Moved directories may need to change parent +- * pointer so they need the lock to prevent against concurrent +- * directory changes moving parent pointer. For regular files we've +- * historically always done this. The lockdep locking subclasses are +- * somewhat arbitrary but RENAME_EXCHANGE in particular can swap +- * regular files and directories so it's difficult to tell which +- * subclasses to use. ++ * Lock children. ++ * The source subdirectory needs to be locked on cross-directory ++ * rename or cross-directory exchange since its parent changes. ++ * The target subdirectory needs to be locked on cross-directory ++ * exchange due to parent change and on any rename due to becoming ++ * a victim. ++ * Non-directories need locking in all cases (for NFS reasons); ++ * they get locked after any subdirectories (in inode address order). ++ * ++ * NOTE: WE ONLY LOCK UNRELATED DIRECTORIES IN CROSS-DIRECTORY CASE. ++ * NEVER, EVER DO THAT WITHOUT ->s_vfs_rename_mutex. + */ +- lock_two_inodes(source, target, I_MUTEX_NORMAL, I_MUTEX_NONDIR2); ++ lock_old_subdir = new_dir != old_dir; ++ lock_new_subdir = new_dir != old_dir || !(flags & RENAME_EXCHANGE); ++ if (is_dir) { ++ if (lock_old_subdir) ++ inode_lock_nested(source, I_MUTEX_CHILD); ++ if (target && (!new_is_dir || lock_new_subdir)) ++ inode_lock(target); ++ } else if (new_is_dir) { ++ if (lock_new_subdir) ++ inode_lock_nested(target, I_MUTEX_CHILD); ++ inode_lock(source); ++ } else { ++ lock_two_nondirectories(source, target); ++ } + + error = -EPERM; + if (IS_SWAPFILE(source) || (target && IS_SWAPFILE(target))) +@@ -4649,8 +4662,9 @@ int vfs_rename(struct inode *old_dir, st + d_exchange(old_dentry, new_dentry); + } + out: +- inode_unlock(source); +- if (target) ++ if (!is_dir || lock_old_subdir) ++ inode_unlock(source); ++ if (target && (!new_is_dir || lock_new_subdir)) + inode_unlock(target); + dput(new_dentry); + if (!error) { diff --git a/patches.suse/s390-ptrace-handle-setting-of-fpc-register-correctly.patch b/patches.suse/s390-ptrace-handle-setting-of-fpc-register-correctly.patch new file mode 100644 index 0000000..8487c11 --- /dev/null +++ b/patches.suse/s390-ptrace-handle-setting-of-fpc-register-correctly.patch @@ -0,0 +1,67 @@ +From: Heiko Carstens +Date: Thu, 30 Nov 2023 18:55:59 +0100 +Subject: s390/ptrace: handle setting of fpc register correctly +Git-commit: 8b13601d19c541158a6e18b278c00ba69ae37829 +Patch-mainline: v6.8-rc1 +References: CVE-2023-52598 bsc#1221060 git-fixes + +If the content of the floating point control (fpc) register of a traced +process is modified with the ptrace interface the new value is tested for +validity by temporarily loading it into the fpc register. + +This may lead to corruption of the fpc register of the tracing process: +if an interrupt happens while the value is temporarily loaded into the +fpc register, and within interrupt context floating point or vector +registers are used, the current fp/vx registers are saved with +save_fpu_regs() assuming they belong to user space and will be loaded into +fp/vx registers when returning to user space. + +test_fp_ctl() restores the original user space fpc register value, however +it will be discarded, when returning to user space. + +In result the tracer will incorrectly continue to run with the value that +was supposed to be used for the traced process. + +Fix this by saving fpu register contents with save_fpu_regs() before using +test_fp_ctl(). + +Reviewed-by: Claudio Imbrenda +Signed-off-by: Heiko Carstens +Signed-off-by: Alexander Gordeev +Acked-by: Miroslav Franc +--- + arch/s390/kernel/ptrace.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c +index 046403471c5d..c7ed302a6b59 100644 +--- a/arch/s390/kernel/ptrace.c ++++ b/arch/s390/kernel/ptrace.c +@@ -392,6 +392,7 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data) + /* + * floating point control reg. is in the thread structure + */ ++ save_fpu_regs(); + if ((unsigned int) data != 0 || + test_fp_ctl(data >> (BITS_PER_LONG - 32))) + return -EINVAL; +@@ -748,6 +749,7 @@ static int __poke_user_compat(struct task_struct *child, + /* + * floating point control reg. is in the thread structure + */ ++ save_fpu_regs(); + if (test_fp_ctl(tmp)) + return -EINVAL; + child->thread.fpu.fpc = data; +@@ -911,9 +913,7 @@ static int s390_fpregs_set(struct task_struct *target, + int rc = 0; + freg_t fprs[__NUM_FPRS]; + +- if (target == current) +- save_fpu_regs(); +- ++ save_fpu_regs(); + if (MACHINE_HAS_VX) + convert_vx_to_fp(fprs, target->thread.fpu.vxrs); + else + diff --git a/patches.suse/s390-vtime-fix-average-steal-time-calculation.patch b/patches.suse/s390-vtime-fix-average-steal-time-calculation.patch new file mode 100644 index 0000000..052522e --- /dev/null +++ b/patches.suse/s390-vtime-fix-average-steal-time-calculation.patch @@ -0,0 +1,60 @@ +From: Mete Durlu +Date: Wed, 6 Mar 2024 12:31:52 +0100 +Subject: s390/vtime: fix average steal time calculation +Git-commit: 367c50f78451d3bd7ad70bc5c89f9ba6dec46ca9 +Patch-mainline: v6.9-rc1 +References: git-fixes bsc#1221953 + +Current average steal timer calculation produces volatile and inflated +values. The only user of this value is KVM so far and it uses that to +decide whether or not to yield the vCPU which is seeing steal time. +KVM compares average steal timer to a threshold and if the threshold +is past then it does not allow CPU polling and yields it to host, else +it keeps the CPU by polling. +Since KVM's steal time threshold is very low by default (%10) it most +likely is not effected much by the bloated average steal timer values +because the operating region is pretty small. However there might be +new users in the future who might rely on this number. Fix average +steal timer calculation by changing the formula from: + + avg_steal_timer = avg_steal_timer / 2 + steal_timer; + +to the following: + + avg_steal_timer = (avg_steal_timer + steal_timer) / 2; + +This ensures that avg_steal_timer is actually a naive average of steal +timer values. It now closely follows steal timer values but of course +in a smoother manner. + +Fixes: 152e9b8676c6 ("s390/vtime: steal time exponential moving average") +Signed-off-by: Mete Durlu +Acked-by: Heiko Carstens +Acked-by: Christian Borntraeger +Signed-off-by: Heiko Carstens +Acked-by: Miroslav Franc +--- + arch/s390/kernel/vtime.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c +index e0a88dcaf5cb..24a18e5ef6e8 100644 +--- a/arch/s390/kernel/vtime.c ++++ b/arch/s390/kernel/vtime.c +@@ -210,13 +210,13 @@ void vtime_flush(struct task_struct *tsk) + virt_timer_expire(); + + steal = S390_lowcore.steal_timer; +- avg_steal = S390_lowcore.avg_steal_timer / 2; ++ avg_steal = S390_lowcore.avg_steal_timer; + if ((s64) steal > 0) { + S390_lowcore.steal_timer = 0; + account_steal_time(cputime_to_nsecs(steal)); + avg_steal += steal; + } +- S390_lowcore.avg_steal_timer = avg_steal; ++ S390_lowcore.avg_steal_timer = avg_steal / 2; + } + + /* + diff --git a/patches.suse/scsi-lpfc-Fix-null-pointer-dereference-in-lpfc_prep_.patch b/patches.suse/scsi-lpfc-Fix-null-pointer-dereference-in-lpfc_prep_.patch index b91d979..5fd6c1f 100644 --- a/patches.suse/scsi-lpfc-Fix-null-pointer-dereference-in-lpfc_prep_.patch +++ b/patches.suse/scsi-lpfc-Fix-null-pointer-dereference-in-lpfc_prep_.patch @@ -3,7 +3,7 @@ Date: Mon, 1 Mar 2021 09:18:08 -0800 Subject: scsi: lpfc: Fix null pointer dereference in lpfc_prep_els_iocb() Patch-mainline: v5.13-rc1 Git-commit: 8dd1c125f7f838abad009b64bff5f0a11afe3cb6 -References: bsc#1182574 +References: bsc#1182574 CVE-2021-47045 bsc#1220640 It is possible to call lpfc_issue_els_plogi() passing a did for which no matching ndlp is found. A call is then made to lpfc_prep_els_iocb() with a diff --git a/patches.suse/scsi-qla2xxx-Change-debug-message-during-driver-unlo.patch b/patches.suse/scsi-qla2xxx-Change-debug-message-during-driver-unlo.patch new file mode 100644 index 0000000..7d257dc --- /dev/null +++ b/patches.suse/scsi-qla2xxx-Change-debug-message-during-driver-unlo.patch @@ -0,0 +1,34 @@ +From: Saurav Kashyap +Date: Tue, 27 Feb 2024 22:11:25 +0530 +Subject: scsi: qla2xxx: Change debug message during driver unload +Patch-mainline: v6.9-rc2 +Git-commit: b5a30840727a3e41d12a336d19f6c0716b299161 +References: bsc1221816 + +Upon driver unload, purge_mbox flag is set and the heartbeat monitor thread +detects this flag and does not send the mailbox command down to FW with a +debug message "Error detected: purge[1] eeh[0] cmd=0x0, Exiting". This +being not a real error, change the debug message. + +Cc: stable@vger.kernel.org +Signed-off-by: Saurav Kashyap +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-10-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_mbx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/qla2xxx/qla_mbx.c ++++ b/drivers/scsi/qla2xxx/qla_mbx.c +@@ -195,7 +195,7 @@ qla2x00_mailbox_command(scsi_qla_host_t + if (ha->flags.purge_mbox || chip_reset != ha->chip_reset || + ha->flags.eeh_busy) { + ql_log(ql_log_warn, vha, 0xd035, +- "Error detected: purge[%d] eeh[%d] cmd=0x%x, Exiting.\n", ++ "Purge mbox: purge[%d] eeh[%d] cmd=0x%x, Exiting.\n", + ha->flags.purge_mbox, ha->flags.eeh_busy, mcp->mb[0]); + rval = QLA_ABORTED; + goto premature_exit; diff --git a/patches.suse/scsi-qla2xxx-Delay-I-O-Abort-on-PCI-error.patch b/patches.suse/scsi-qla2xxx-Delay-I-O-Abort-on-PCI-error.patch new file mode 100644 index 0000000..1a906f7 --- /dev/null +++ b/patches.suse/scsi-qla2xxx-Delay-I-O-Abort-on-PCI-error.patch @@ -0,0 +1,55 @@ +From: Quinn Tran +Date: Tue, 27 Feb 2024 22:11:26 +0530 +Subject: scsi: qla2xxx: Delay I/O Abort on PCI error +Patch-mainline: v6.9-rc2 +Git-commit: 591c1fdf2016d118b8fbde427b796fac13f3f070 +References: bsc1221816 + +Currently when PCI error is detected, I/O is aborted manually through the +ABORT IOCB mechanism which is not guaranteed to succeed. + +Instead, wait for the OS or system to notify driver to wind down I/O +through the pci_error_handlers api. Set eeh_busy flag to pause all traffic +and wait for I/O to drain. + +Cc: stable@vger.kernel.org +Signed-off-by: Quinn Tran +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-11-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_attr.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_attr.c ++++ b/drivers/scsi/qla2xxx/qla_attr.c +@@ -2737,7 +2737,13 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rp + return; + + if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { +- qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); ++ /* Will wait for wind down of adapter */ ++ ql_dbg(ql_dbg_aer, fcport->vha, 0x900c, ++ "%s pci offline detected (id %06x)\n", __func__, ++ fcport->d_id.b24); ++ qla_pci_set_eeh_busy(fcport->vha); ++ qla2x00_eh_wait_for_pending_commands(fcport->vha, fcport->d_id.b24, ++ 0, WAIT_TARGET); + return; + } + } +@@ -2759,7 +2765,11 @@ qla2x00_terminate_rport_io(struct fc_rpo + vha = fcport->vha; + + if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { +- qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); ++ /* Will wait for wind down of adapter */ ++ ql_dbg(ql_dbg_aer, fcport->vha, 0x900b, ++ "%s pci offline detected (id %06x)\n", __func__, ++ fcport->d_id.b24); ++ qla_pci_set_eeh_busy(vha); + qla2x00_eh_wait_for_pending_commands(fcport->vha, fcport->d_id.b24, + 0, WAIT_TARGET); + return; diff --git a/patches.suse/scsi-qla2xxx-Fix-N2N-stuck-connection.patch b/patches.suse/scsi-qla2xxx-Fix-N2N-stuck-connection.patch new file mode 100644 index 0000000..ef1d2f1 --- /dev/null +++ b/patches.suse/scsi-qla2xxx-Fix-N2N-stuck-connection.patch @@ -0,0 +1,143 @@ +From: Quinn Tran +Date: Tue, 27 Feb 2024 22:11:18 +0530 +Subject: scsi: qla2xxx: Fix N2N stuck connection +Patch-mainline: v6.9-rc2 +Git-commit: 881eb861ca3877300570db10abbf11494e48548d +References: bsc1221816 + +Disk failed to rediscover after chip reset error injection. The chip reset +happens at the time when a PLOGI is being sent. This causes a flag to be +left on which blocks the retry. Clear the blocking flag. + +Cc: stable@vger.kernel.org +Signed-off-by: Quinn Tran +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-3-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_gbl.h | 2 +- + drivers/scsi/qla2xxx/qla_iocb.c | 32 +++++++++++--------------------- + drivers/scsi/qla2xxx/qla_os.c | 2 +- + 3 files changed, 13 insertions(+), 23 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_gbl.h ++++ b/drivers/scsi/qla2xxx/qla_gbl.h +@@ -45,7 +45,7 @@ extern int qla2x00_fabric_login(scsi_qla + extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *); + + extern int qla24xx_els_dcmd_iocb(scsi_qla_host_t *, int, port_id_t); +-extern int qla24xx_els_dcmd2_iocb(scsi_qla_host_t *, int, fc_port_t *, bool); ++extern int qla24xx_els_dcmd2_iocb(scsi_qla_host_t *, int, fc_port_t *); + extern void qla2x00_els_dcmd2_free(scsi_qla_host_t *vha, + struct els_plogi *els_plogi); + +--- a/drivers/scsi/qla2xxx/qla_iocb.c ++++ b/drivers/scsi/qla2xxx/qla_iocb.c +@@ -3044,7 +3044,7 @@ static void qla2x00_els_dcmd2_sp_done(sr + + int + qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, +- fc_port_t *fcport, bool wait) ++ fc_port_t *fcport) + { + srb_t *sp; + struct srb_iocb *elsio = NULL; +@@ -3059,8 +3059,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t * + if (!sp) { + ql_log(ql_log_info, vha, 0x70e6, + "SRB allocation failed\n"); +- fcport->flags &= ~FCF_ASYNC_ACTIVE; +- return -ENOMEM; ++ goto done; + } + + fcport->flags |= FCF_ASYNC_SENT; +@@ -3069,9 +3068,6 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t * + ql_dbg(ql_dbg_io, vha, 0x3073, + "%s Enter: PLOGI portid=%06x\n", __func__, fcport->d_id.b24); + +- if (wait) +- sp->flags = SRB_WAKEUP_ON_COMP; +- + sp->type = SRB_ELS_DCMD; + sp->name = "ELS_DCMD"; + sp->fcport = fcport; +@@ -3087,7 +3083,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t * + + if (!elsio->u.els_plogi.els_plogi_pyld) { + rval = QLA_FUNCTION_FAILED; +- goto out; ++ goto done_free_sp; + } + + resp_ptr = elsio->u.els_plogi.els_resp_pyld = +@@ -3096,7 +3092,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t * + + if (!elsio->u.els_plogi.els_resp_pyld) { + rval = QLA_FUNCTION_FAILED; +- goto out; ++ goto done_free_sp; + } + + ql_dbg(ql_dbg_io, vha, 0x3073, "PLOGI %p %p\n", ptr, resp_ptr); +@@ -3112,7 +3108,6 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t * + + if (els_opcode == ELS_DCMD_PLOGI && DBELL_ACTIVE(vha)) { + struct fc_els_flogi *p = ptr; +- + p->fl_csp.sp_features |= cpu_to_be16(FC_SP_FT_SEC); + } + +@@ -3121,10 +3116,11 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t * + (uint8_t *)elsio->u.els_plogi.els_plogi_pyld, + sizeof(*elsio->u.els_plogi.els_plogi_pyld)); + +- init_completion(&elsio->u.els_plogi.comp); + rval = qla2x00_start_sp(sp); + if (rval != QLA_SUCCESS) { +- rval = QLA_FUNCTION_FAILED; ++ fcport->flags |= FCF_LOGIN_NEEDED; ++ set_bit(RELOGIN_NEEDED, &vha->dpc_flags); ++ goto done_free_sp; + } else { + ql_dbg(ql_dbg_disc, vha, 0x3074, + "%s PLOGI sent, hdl=%x, loopid=%x, to port_id %06x from port_id %06x\n", +@@ -3132,21 +3128,15 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t * + fcport->d_id.b24, vha->d_id.b24); + } + +- if (wait) { +- wait_for_completion(&elsio->u.els_plogi.comp); +- +- if (elsio->u.els_plogi.comp_status != CS_COMPLETE) +- rval = QLA_FUNCTION_FAILED; +- } else { +- goto done; +- } ++ return rval; + +-out: +- fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); ++done_free_sp: + qla2x00_els_dcmd2_free(vha, &elsio->u.els_plogi); + /* ref: INIT */ + kref_put(&sp->cmd_kref, qla2x00_sp_release); + done: ++ fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); ++ qla2x00_set_fcport_disc_state(fcport, DSC_DELETED); + return rval; + } + +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -5569,7 +5569,7 @@ qla2x00_do_work(struct scsi_qla_host *vh + break; + case QLA_EVT_ELS_PLOGI: + qla24xx_els_dcmd2_iocb(vha, ELS_DCMD_PLOGI, +- e->u.fcport.fcport, false); ++ e->u.fcport.fcport); + break; + case QLA_EVT_SA_REPLACE: + rc = qla24xx_issue_sa_replace_iocb(vha, e); diff --git a/patches.suse/scsi-qla2xxx-Fix-command-flush-on-cable-pull.patch b/patches.suse/scsi-qla2xxx-Fix-command-flush-on-cable-pull.patch new file mode 100644 index 0000000..6a58ec6 --- /dev/null +++ b/patches.suse/scsi-qla2xxx-Fix-command-flush-on-cable-pull.patch @@ -0,0 +1,92 @@ +From: Quinn Tran +Date: Tue, 27 Feb 2024 22:11:22 +0530 +Subject: scsi: qla2xxx: Fix command flush on cable pull +Patch-mainline: v6.9-rc2 +Git-commit: a27d4d0e7de305def8a5098a614053be208d1aa1 +References: bsc1221816 + +System crash due to command failed to flush back to SCSI layer. + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 + PGD 0 P4D 0 + Oops: 0000 [#1] SMP NOPTI + CPU: 27 PID: 793455 Comm: kworker/u130:6 Kdump: loaded Tainted: G OE --------- - - 4.18.0-372.9.1.el8.x86_64 #1 + Hardware name: HPE ProLiant DL360 Gen10/ProLiant DL360 Gen10, BIOS U32 09/03/2021 + Workqueue: nvme-wq nvme_fc_connect_ctrl_work [nvme_fc] + RIP: 0010:__wake_up_common+0x4c/0x190 + Code: 24 10 4d 85 c9 74 0a 41 f6 01 04 0f 85 9d 00 00 00 48 8b 43 08 48 83 c3 08 4c 8d 48 e8 49 8d 41 18 48 39 c3 0f 84 f0 00 00 00 <49> 8b 41 18 89 54 24 08 31 ed 4c 8d 70 e8 45 8b 29 41 f6 c5 04 75 + RSP: 0018:ffff95f3e0cb7cd0 EFLAGS: 00010086 + RAX: 0000000000000000 RBX: ffff8b08d3b26328 RCX: 0000000000000000 + RDX: 0000000000000001 RSI: 0000000000000003 RDI: ffff8b08d3b26320 + RBP: 0000000000000001 R08: 0000000000000000 R09: ffffffffffffffe8 + R10: 0000000000000000 R11: ffff95f3e0cb7a60 R12: ffff95f3e0cb7d20 + R13: 0000000000000003 R14: 0000000000000000 R15: 0000000000000000 + FS: 0000000000000000(0000) GS:ffff8b2fdf6c0000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000000 CR3: 0000002f1e410002 CR4: 00000000007706e0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + PKRU: 55555554 + Call Trace: + __wake_up_common_lock+0x7c/0xc0 + qla_nvme_ls_req+0x355/0x4c0 [qla2xxx] + qla2xxx [0000:12:00.1]-f084:3: qlt_free_session_done: se_sess 0000000000000000 / sess ffff8ae1407ca000 from port 21:32:00:02:ac:07:ee:b8 loop_id 0x02 s_id 01:02:00 logout 1 keep 0 els_logo 0 + ? __nvme_fc_send_ls_req+0x260/0x380 [nvme_fc] + qla2xxx [0000:12:00.1]-207d:3: FCPort 21:32:00:02:ac:07:ee:b8 state transitioned from ONLINE to LOST - portid=010200. + ? nvme_fc_send_ls_req.constprop.42+0x1a/0x45 [nvme_fc] + qla2xxx [0000:12:00.1]-2109:3: qla2x00_schedule_rport_del 21320002ac07eeb8. rport ffff8ae598122000 roles 1 + ? nvme_fc_connect_ctrl_work.cold.63+0x1e3/0xa7d [nvme_fc] + qla2xxx [0000:12:00.1]-f084:3: qlt_free_session_done: se_sess 0000000000000000 / sess ffff8ae14801e000 from port 21:32:01:02:ad:f7:ee:b8 loop_id 0x04 s_id 01:02:01 logout 1 keep 0 els_logo 0 + ? __switch_to+0x10c/0x450 + ? process_one_work+0x1a7/0x360 + qla2xxx [0000:12:00.1]-207d:3: FCPort 21:32:01:02:ad:f7:ee:b8 state transitioned from ONLINE to LOST - portid=010201. + ? worker_thread+0x1ce/0x390 + ? create_worker+0x1a0/0x1a0 + qla2xxx [0000:12:00.1]-2109:3: qla2x00_schedule_rport_del 21320102adf7eeb8. rport ffff8ae3b2312800 roles 70 + ? kthread+0x10a/0x120 + qla2xxx [0000:12:00.1]-2112:3: qla_nvme_unregister_remote_port: unregister remoteport on ffff8ae14801e000 21320102adf7eeb8 + ? set_kthread_struct+0x40/0x40 + qla2xxx [0000:12:00.1]-2110:3: remoteport_delete of ffff8ae14801e000 21320102adf7eeb8 completed. + ? ret_from_fork+0x1f/0x40 + qla2xxx [0000:12:00.1]-f086:3: qlt_free_session_done: waiting for sess ffff8ae14801e000 logout + +The system was under memory stress where driver was not able to allocate an +SRB to carry out error recovery of cable pull. The failure to flush causes +upper layer to start modifying scsi_cmnd. When the system frees up some +memory, the subsequent cable pull trigger another command flush. At this +point the driver access a null pointer when attempting to DMA unmap the +SGL. + +Add a check to make sure commands are flush back on session tear down to +prevent the null pointer access. + +Cc: stable@vger.kernel.org +Signed-off-by: Quinn Tran +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-7-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_target.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/scsi/qla2xxx/qla_target.c ++++ b/drivers/scsi/qla2xxx/qla_target.c +@@ -1071,6 +1071,16 @@ void qlt_free_session_done(struct work_s + "%s: sess %p logout completed\n", __func__, sess); + } + ++ /* check for any straggling io left behind */ ++ if (!(sess->flags & FCF_FCP2_DEVICE) && ++ qla2x00_eh_wait_for_pending_commands(sess->vha, sess->d_id.b24, 0, WAIT_TARGET)) { ++ ql_log(ql_log_warn, vha, 0x3027, ++ "IO not return. Resetting.\n"); ++ set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); ++ qla2xxx_wake_dpc(vha); ++ qla2x00_wait_for_chip_reset(vha); ++ } ++ + if (sess->logo_ack_needed) { + sess->logo_ack_needed = 0; + qla24xx_async_notify_ack(vha, sess, diff --git a/patches.suse/scsi-qla2xxx-Fix-crash-in-qla2xxx_mqueuecommand.patch b/patches.suse/scsi-qla2xxx-Fix-crash-in-qla2xxx_mqueuecommand.patch index bae200f..cba9718 100644 --- a/patches.suse/scsi-qla2xxx-Fix-crash-in-qla2xxx_mqueuecommand.patch +++ b/patches.suse/scsi-qla2xxx-Fix-crash-in-qla2xxx_mqueuecommand.patch @@ -3,7 +3,7 @@ Date: Mon, 29 Mar 2021 01:52:23 -0700 Subject: scsi: qla2xxx: Fix crash in qla2xxx_mqueuecommand() Patch-mainline: v5.13-rc1 Git-commit: 6641df81ab799f28a5d564f860233dd26cca0d93 -References: bsc#1185491 +References: bsc#1185491 CVE-2021-46963 bsc#1220536 RIP: 0010:kmem_cache_free+0xfa/0x1b0 Call Trace: diff --git a/patches.suse/scsi-qla2xxx-Fix-double-free-of-fcport.patch b/patches.suse/scsi-qla2xxx-Fix-double-free-of-fcport.patch new file mode 100644 index 0000000..4edbdd8 --- /dev/null +++ b/patches.suse/scsi-qla2xxx-Fix-double-free-of-fcport.patch @@ -0,0 +1,77 @@ +From: Saurav Kashyap +Date: Tue, 27 Feb 2024 22:11:24 +0530 +Subject: scsi: qla2xxx: Fix double free of fcport +Patch-mainline: v6.9-rc2 +Git-commit: 82f522ae0d97119a43da53e0f729275691b9c525 +References: bsc1221816 + +The server was crashing after LOGO because fcport was getting freed twice. + + -----------[ cut here ]----------- + kernel BUG at mm/slub.c:371! + invalid opcode: 0000 1 SMP PTI + CPU: 35 PID: 4610 Comm: bash Kdump: loaded Tainted: G OE --------- - - 4.18.0-425.3.1.el8.x86_64 #1 + Hardware name: HPE ProLiant DL360 Gen10/ProLiant DL360 Gen10, BIOS U32 09/03/2021 + RIP: 0010:set_freepointer.part.57+0x0/0x10 + RSP: 0018:ffffb07107027d90 EFLAGS: 00010246 + RAX: ffff9cb7e3150000 RBX: ffff9cb7e332b9c0 RCX: ffff9cb7e3150400 + RDX: 0000000000001f37 RSI: 0000000000000000 RDI: ffff9cb7c0005500 + RBP: fffff693448c5400 R08: 0000000080000000 R09: 0000000000000009 + R10: 0000000000000000 R11: 0000000000132af0 R12: ffff9cb7c0005500 + R13: ffff9cb7e3150000 R14: ffffffffc06990e0 R15: ffff9cb7ea85ea58 + FS: 00007ff6b79c2740(0000) GS:ffff9cb8f7ec0000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 000055b426b7d700 CR3: 0000000169c18002 CR4: 00000000007706e0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + PKRU: 55555554 + Call Trace: + kfree+0x238/0x250 + qla2x00_els_dcmd_sp_free+0x20/0x230 [qla2xxx] + ? qla24xx_els_dcmd_iocb+0x607/0x690 [qla2xxx] + qla2x00_issue_logo+0x28c/0x2a0 [qla2xxx] + ? qla2x00_issue_logo+0x28c/0x2a0 [qla2xxx] + ? kernfs_fop_write+0x11e/0x1a0 + +Remove one of the free calls and add check for valid fcport. Also use +function qla2x00_free_fcport() instead of kfree(). + +Cc: stable@vger.kernel.org +Signed-off-by: Saurav Kashyap +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-9-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_iocb.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_iocb.c ++++ b/drivers/scsi/qla2xxx/qla_iocb.c +@@ -2640,7 +2640,8 @@ static void qla2x00_els_dcmd_sp_free(srb + { + struct srb_iocb *elsio = &sp->u.iocb_cmd; + +- kfree(sp->fcport); ++ if (sp->fcport) ++ qla2x00_free_fcport(sp->fcport); + + if (elsio->u.els_logo.els_logo_pyld) + dma_free_coherent(&sp->vha->hw->pdev->dev, DMA_POOL_SIZE, +@@ -2753,6 +2754,7 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *v + if (!elsio->u.els_logo.els_logo_pyld) { + /* ref: INIT */ + kref_put(&sp->cmd_kref, qla2x00_sp_release); ++ qla2x00_free_fcport(fcport); + return QLA_FUNCTION_FAILED; + } + +@@ -2787,7 +2789,6 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *v + fcport->d_id.b.area, fcport->d_id.b.al_pa); + + wait_for_completion(&elsio->u.els_logo.comp); +- qla2x00_free_fcport(fcport); + + /* ref: INIT */ + kref_put(&sp->cmd_kref, qla2x00_sp_release); diff --git a/patches.suse/scsi-qla2xxx-Fix-double-free-of-the-ha-vp_map-pointe.patch b/patches.suse/scsi-qla2xxx-Fix-double-free-of-the-ha-vp_map-pointe.patch new file mode 100644 index 0000000..bdaf32e --- /dev/null +++ b/patches.suse/scsi-qla2xxx-Fix-double-free-of-the-ha-vp_map-pointe.patch @@ -0,0 +1,34 @@ +From: Saurav Kashyap +Date: Tue, 27 Feb 2024 22:11:23 +0530 +Subject: scsi: qla2xxx: Fix double free of the ha->vp_map pointer +Patch-mainline: v6.9-rc2 +Git-commit: e288285d47784fdcf7c81be56df7d65c6f10c58b +References: bsc1221816 + +Coverity scan reported potential risk of double free of the pointer +ha->vp_map. ha->vp_map was freed in qla2x00_mem_alloc(), and again freed +in function qla2x00_mem_free(ha). + +Assign NULL to vp_map and kfree take care of NULL. + +Cc: stable@vger.kernel.org +Signed-off-by: Saurav Kashyap +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-8-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_os.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -4594,6 +4594,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha + ha->init_cb_dma = 0; + fail_free_vp_map: + kfree(ha->vp_map); ++ ha->vp_map = NULL; + fail: + ql_log(ql_log_fatal, NULL, 0x0030, + "Memory allocation failure.\n"); diff --git a/patches.suse/scsi-qla2xxx-NVME-FCP-prefer-flag-not-being-honored.patch b/patches.suse/scsi-qla2xxx-NVME-FCP-prefer-flag-not-being-honored.patch new file mode 100644 index 0000000..0b5f76d --- /dev/null +++ b/patches.suse/scsi-qla2xxx-NVME-FCP-prefer-flag-not-being-honored.patch @@ -0,0 +1,67 @@ +From: Quinn Tran +Date: Tue, 27 Feb 2024 22:11:21 +0530 +Subject: scsi: qla2xxx: NVME|FCP prefer flag not being honored +Patch-mainline: v6.9-rc2 +Git-commit: 69aecdd410106dc3a8f543a4f7ec6379b995b8d0 +References: bsc1221816 + +Changing of [FCP|NVME] prefer flag in flash has no effect on driver. For +device that supports both FCP + NVMe over the same connection, driver +continues to connect to this device using the previous successful login +mode. + +On completion of flash update, adapter will be reset. Driver will +reset the prefer flag based on setting from flash. + +Cc: stable@vger.kernel.org +Signed-off-by: Quinn Tran +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-6-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_init.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -7511,6 +7511,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) + struct scsi_qla_host *vp, *tvp; + struct req_que *req = ha->req_q_map[0]; + unsigned long flags; ++ fc_port_t *fcport; + + if (vha->flags.online) { + qla2x00_abort_isp_cleanup(vha); +@@ -7579,6 +7580,15 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) + "ISP Abort - ISP reg disconnect post nvmram config, exiting.\n"); + return status; + } ++ ++ /* User may have updated [fcp|nvme] prefer in flash */ ++ list_for_each_entry(fcport, &vha->vp_fcports, list) { ++ if (NVME_PRIORITY(ha, fcport)) ++ fcport->do_prli_nvme = 1; ++ else ++ fcport->do_prli_nvme = 0; ++ } ++ + if (!qla2x00_restart_isp(vha)) { + clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags); + +@@ -7649,6 +7659,14 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) + atomic_inc(&vp->vref_count); + spin_unlock_irqrestore(&ha->vport_slock, flags); + ++ /* User may have updated [fcp|nvme] prefer in flash */ ++ list_for_each_entry(fcport, &vp->vp_fcports, list) { ++ if (NVME_PRIORITY(ha, fcport)) ++ fcport->do_prli_nvme = 1; ++ else ++ fcport->do_prli_nvme = 0; ++ } ++ + qla2x00_vp_abort_isp(vp); + + spin_lock_irqsave(&ha->vport_slock, flags); diff --git a/patches.suse/scsi-qla2xxx-Prevent-command-send-on-chip-reset.patch b/patches.suse/scsi-qla2xxx-Prevent-command-send-on-chip-reset.patch new file mode 100644 index 0000000..6c38d00 --- /dev/null +++ b/patches.suse/scsi-qla2xxx-Prevent-command-send-on-chip-reset.patch @@ -0,0 +1,113 @@ +From: Quinn Tran +Date: Tue, 27 Feb 2024 22:11:17 +0530 +Subject: scsi: qla2xxx: Prevent command send on chip reset +Patch-mainline: v6.9-rc2 +Git-commit: 4895009c4bb72f71f2e682f1e7d2c2d96e482087 +References: bsc1221816 + +Currently IOCBs are allowed to push through while chip reset could be in +progress. During chip reset the outstanding_cmds array is cleared +twice. Once when any command on this array is returned as failed and +secondly when the array is initialize to zero. If a command is inserted on +to the array between these intervals, then the command will be lost. Check +for chip reset before sending IOCB. + +Cc: stable@vger.kernel.org +Signed-off-by: Quinn Tran +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-2-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_init.c | 8 ++++++-- + drivers/scsi/qla2xxx/qla_iocb.c | 33 +++++++++++++++++++++++++++++++-- + 2 files changed, 37 insertions(+), 4 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -1206,8 +1206,12 @@ int qla24xx_async_gnl(struct scsi_qla_ho + return rval; + + done_free_sp: +- /* ref: INIT */ +- kref_put(&sp->cmd_kref, qla2x00_sp_release); ++ /* ++ * use qla24xx_async_gnl_sp_done to purge all pending gnl request. ++ * kref_put is call behind the scene. ++ */ ++ sp->u.iocb_cmd.u.mbx.in_mb[0] = MBS_COMMAND_ERROR; ++ qla24xx_async_gnl_sp_done(sp, QLA_COMMAND_ERROR); + fcport->flags &= ~(FCF_ASYNC_SENT); + done: + fcport->flags &= ~(FCF_ASYNC_ACTIVE); +--- a/drivers/scsi/qla2xxx/qla_iocb.c ++++ b/drivers/scsi/qla2xxx/qla_iocb.c +@@ -2588,6 +2588,33 @@ void + qla2x00_sp_release(struct kref *kref) + { + struct srb *sp = container_of(kref, struct srb, cmd_kref); ++ struct scsi_qla_host *vha = sp->vha; ++ ++ switch (sp->type) { ++ case SRB_CT_PTHRU_CMD: ++ /* GPSC & GFPNID use fcport->ct_desc.ct_sns for both req & rsp */ ++ if (sp->u.iocb_cmd.u.ctarg.req && ++ (!sp->fcport || ++ sp->u.iocb_cmd.u.ctarg.req != sp->fcport->ct_desc.ct_sns)) { ++ dma_free_coherent(&vha->hw->pdev->dev, ++ sp->u.iocb_cmd.u.ctarg.req_allocated_size, ++ sp->u.iocb_cmd.u.ctarg.req, ++ sp->u.iocb_cmd.u.ctarg.req_dma); ++ sp->u.iocb_cmd.u.ctarg.req = NULL; ++ } ++ if (sp->u.iocb_cmd.u.ctarg.rsp && ++ (!sp->fcport || ++ sp->u.iocb_cmd.u.ctarg.rsp != sp->fcport->ct_desc.ct_sns)) { ++ dma_free_coherent(&vha->hw->pdev->dev, ++ sp->u.iocb_cmd.u.ctarg.rsp_allocated_size, ++ sp->u.iocb_cmd.u.ctarg.rsp, ++ sp->u.iocb_cmd.u.ctarg.rsp_dma); ++ sp->u.iocb_cmd.u.ctarg.rsp = NULL; ++ } ++ break; ++ default: ++ break; ++ } + + sp->free(sp); + } +@@ -2695,7 +2722,7 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *v + */ + sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); + if (!sp) { +- kfree(fcport); ++ qla2x00_free_fcport(fcport); + ql_log(ql_log_info, vha, 0x70e6, + "SRB allocation failed\n"); + return -ENOMEM; +@@ -2750,6 +2777,7 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *v + if (rval != QLA_SUCCESS) { + /* ref: INIT */ + kref_put(&sp->cmd_kref, qla2x00_sp_release); ++ qla2x00_free_fcport(fcport); + return QLA_FUNCTION_FAILED; + } + +@@ -2759,6 +2787,7 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *v + fcport->d_id.b.area, fcport->d_id.b.al_pa); + + wait_for_completion(&elsio->u.els_logo.comp); ++ qla2x00_free_fcport(fcport); + + /* ref: INIT */ + kref_put(&sp->cmd_kref, qla2x00_sp_release); +@@ -3914,7 +3943,7 @@ qla2x00_start_sp(srb_t *sp) + return -EAGAIN; + } + +- pkt = __qla2x00_alloc_iocbs(sp->qpair, sp); ++ pkt = qla2x00_alloc_iocbs_ready(sp->qpair, sp); + if (!pkt) { + rval = -EAGAIN; + ql_log(ql_log_warn, vha, 0x700c, diff --git a/patches.suse/scsi-qla2xxx-Reserve-extra-IRQ-vectors.patch b/patches.suse/scsi-qla2xxx-Reserve-extra-IRQ-vectors.patch index 7aefa8c..13e0b24 100644 --- a/patches.suse/scsi-qla2xxx-Reserve-extra-IRQ-vectors.patch +++ b/patches.suse/scsi-qla2xxx-Reserve-extra-IRQ-vectors.patch @@ -3,7 +3,7 @@ Date: Mon, 12 Apr 2021 19:57:40 +0300 Subject: scsi: qla2xxx: Reserve extra IRQ vectors Patch-mainline: v5.13-rc1 Git-commit: f02d4086a8f36a0e1aaebf559b54cf24a177a486 -References: bsc#1185491 +References: bsc#1185491 CVE-2021-46964 bsc#1220538 Commit a6dcfe08487e ("scsi: qla2xxx: Limit interrupt vectors to number of CPUs") lowers the number of allocated MSI-X vectors to the number of CPUs. diff --git a/patches.suse/scsi-qla2xxx-Split-FCE-EFT-trace-control.patch b/patches.suse/scsi-qla2xxx-Split-FCE-EFT-trace-control.patch new file mode 100644 index 0000000..710c139 --- /dev/null +++ b/patches.suse/scsi-qla2xxx-Split-FCE-EFT-trace-control.patch @@ -0,0 +1,222 @@ +From: Quinn Tran +Date: Tue, 27 Feb 2024 22:11:19 +0530 +Subject: scsi: qla2xxx: Split FCE|EFT trace control +Patch-mainline: v6.9-rc2 +Git-commit: 76a192e1a566e15365704b9f8fb3b70825f85064 +References: bsc1221816 + +Current code combines the allocation of FCE|EFT trace buffers and enables +the features all in 1 step. + +Split this step into separate steps in preparation for follow-on patch to +allow user to have a choice to enable / disable FCE trace feature. + +Cc: stable@vger.kernel.org +Reported-by: kernel test robot +Signed-off-by: Quinn Tran +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-4-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_init.c | 102 ++++++++++++++++------------------------ + 1 file changed, 41 insertions(+), 61 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -2682,6 +2682,40 @@ qla83xx_nic_core_fw_load(scsi_qla_host_t + return rval; + } + ++static void qla_enable_fce_trace(scsi_qla_host_t *vha) ++{ ++ int rval; ++ struct qla_hw_data *ha = vha->hw; ++ ++ if (ha->fce) { ++ ha->flags.fce_enabled = 1; ++ memset(ha->fce, 0, fce_calc_size(ha->fce_bufs)); ++ rval = qla2x00_enable_fce_trace(vha, ++ ha->fce_dma, ha->fce_bufs, ha->fce_mb, &ha->fce_bufs); ++ ++ if (rval) { ++ ql_log(ql_log_warn, vha, 0x8033, ++ "Unable to reinitialize FCE (%d).\n", rval); ++ ha->flags.fce_enabled = 0; ++ } ++ } ++} ++ ++static void qla_enable_eft_trace(scsi_qla_host_t *vha) ++{ ++ int rval; ++ struct qla_hw_data *ha = vha->hw; ++ ++ if (ha->eft) { ++ memset(ha->eft, 0, EFT_SIZE); ++ rval = qla2x00_enable_eft_trace(vha, ha->eft_dma, EFT_NUM_BUFFERS); ++ ++ if (rval) { ++ ql_log(ql_log_warn, vha, 0x8034, ++ "Unable to reinitialize EFT (%d).\n", rval); ++ } ++ } ++} + /* + * qla2x00_initialize_adapter + * Initialize board. +@@ -3685,9 +3719,8 @@ qla24xx_chip_diag(scsi_qla_host_t *vha) + } + + static void +-qla2x00_init_fce_trace(scsi_qla_host_t *vha) ++qla2x00_alloc_fce_trace(scsi_qla_host_t *vha) + { +- int rval; + dma_addr_t tc_dma; + void *tc; + struct qla_hw_data *ha = vha->hw; +@@ -3716,27 +3749,17 @@ qla2x00_init_fce_trace(scsi_qla_host_t * + return; + } + +- rval = qla2x00_enable_fce_trace(vha, tc_dma, FCE_NUM_BUFFERS, +- ha->fce_mb, &ha->fce_bufs); +- if (rval) { +- ql_log(ql_log_warn, vha, 0x00bf, +- "Unable to initialize FCE (%d).\n", rval); +- dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc, tc_dma); +- return; +- } +- + ql_dbg(ql_dbg_init, vha, 0x00c0, + "Allocated (%d KB) for FCE...\n", FCE_SIZE / 1024); + +- ha->flags.fce_enabled = 1; + ha->fce_dma = tc_dma; + ha->fce = tc; ++ ha->fce_bufs = FCE_NUM_BUFFERS; + } + + static void +-qla2x00_init_eft_trace(scsi_qla_host_t *vha) ++qla2x00_alloc_eft_trace(scsi_qla_host_t *vha) + { +- int rval; + dma_addr_t tc_dma; + void *tc; + struct qla_hw_data *ha = vha->hw; +@@ -3761,14 +3784,6 @@ qla2x00_init_eft_trace(scsi_qla_host_t * + return; + } + +- rval = qla2x00_enable_eft_trace(vha, tc_dma, EFT_NUM_BUFFERS); +- if (rval) { +- ql_log(ql_log_warn, vha, 0x00c2, +- "Unable to initialize EFT (%d).\n", rval); +- dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, tc_dma); +- return; +- } +- + ql_dbg(ql_dbg_init, vha, 0x00c3, + "Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024); + +@@ -3776,13 +3791,6 @@ qla2x00_init_eft_trace(scsi_qla_host_t * + ha->eft = tc; + } + +-static void +-qla2x00_alloc_offload_mem(scsi_qla_host_t *vha) +-{ +- qla2x00_init_fce_trace(vha); +- qla2x00_init_eft_trace(vha); +-} +- + void + qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) + { +@@ -3837,10 +3845,10 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *v + if (ha->tgt.atio_ring) + mq_size += ha->tgt.atio_q_length * sizeof(request_t); + +- qla2x00_init_fce_trace(vha); ++ qla2x00_alloc_fce_trace(vha); + if (ha->fce) + fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE; +- qla2x00_init_eft_trace(vha); ++ qla2x00_alloc_eft_trace(vha); + if (ha->eft) + eft_size = EFT_SIZE; + } +@@ -4268,7 +4276,6 @@ qla2x00_setup_chip(scsi_qla_host_t *vha) + struct qla_hw_data *ha = vha->hw; + struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; + unsigned long flags; +- uint16_t fw_major_version; + int done_once = 0; + + if (IS_P3P_TYPE(ha)) { +@@ -4335,7 +4342,6 @@ qla2x00_setup_chip(scsi_qla_host_t *vha) + goto failed; + + enable_82xx_npiv: +- fw_major_version = ha->fw_major_version; + if (IS_P3P_TYPE(ha)) + qla82xx_check_md_needed(vha); + else +@@ -4364,12 +4370,11 @@ qla2x00_setup_chip(scsi_qla_host_t *vha) + if (rval != QLA_SUCCESS) + goto failed; + +- if (!fw_major_version && !(IS_P3P_TYPE(ha))) +- qla2x00_alloc_offload_mem(vha); +- + if (ql2xallocfwdump && !(IS_P3P_TYPE(ha))) + qla2x00_alloc_fw_dump(vha); + ++ qla_enable_fce_trace(vha); ++ qla_enable_eft_trace(vha); + } else { + goto failed; + } +@@ -7501,7 +7506,6 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_ + int + qla2x00_abort_isp(scsi_qla_host_t *vha) + { +- int rval; + uint8_t status = 0; + struct qla_hw_data *ha = vha->hw; + struct scsi_qla_host *vp, *tvp; +@@ -7595,31 +7599,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) + + if (IS_QLA81XX(ha) || IS_QLA8031(ha)) + qla2x00_get_fw_version(vha); +- if (ha->fce) { +- ha->flags.fce_enabled = 1; +- memset(ha->fce, 0, +- fce_calc_size(ha->fce_bufs)); +- rval = qla2x00_enable_fce_trace(vha, +- ha->fce_dma, ha->fce_bufs, ha->fce_mb, +- &ha->fce_bufs); +- if (rval) { +- ql_log(ql_log_warn, vha, 0x8033, +- "Unable to reinitialize FCE " +- "(%d).\n", rval); +- ha->flags.fce_enabled = 0; +- } +- } + +- if (ha->eft) { +- memset(ha->eft, 0, EFT_SIZE); +- rval = qla2x00_enable_eft_trace(vha, +- ha->eft_dma, EFT_NUM_BUFFERS); +- if (rval) { +- ql_log(ql_log_warn, vha, 0x8034, +- "Unable to reinitialize EFT " +- "(%d).\n", rval); +- } +- } + } else { /* failed the ISP abort */ + vha->flags.online = 1; + if (test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) { diff --git a/patches.suse/scsi-qla2xxx-Update-manufacturer-detail.patch b/patches.suse/scsi-qla2xxx-Update-manufacturer-detail.patch new file mode 100644 index 0000000..870bbf4 --- /dev/null +++ b/patches.suse/scsi-qla2xxx-Update-manufacturer-detail.patch @@ -0,0 +1,32 @@ +From: Bikash Hazarika +Date: Tue, 27 Feb 2024 22:11:20 +0530 +Subject: scsi: qla2xxx: Update manufacturer detail +Patch-mainline: v6.9-rc2 +Git-commit: 688fa069fda6fce24d243cddfe0c7024428acb74 +References: bsc1221816 + +Update manufacturer detail from "Marvell Semiconductor, Inc." to +"Marvell". + +Cc: stable@vger.kernel.org +Signed-off-by: Bikash Hazarika +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-5-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_def.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/qla2xxx/qla_def.h ++++ b/drivers/scsi/qla2xxx/qla_def.h +@@ -83,7 +83,7 @@ typedef union { + #include "qla_nvme.h" + #define QLA2XXX_DRIVER_NAME "qla2xxx" + #define QLA2XXX_APIDEV "ql2xapidev" +-#define QLA2XXX_MANUFACTURER "Marvell Semiconductor, Inc." ++#define QLA2XXX_MANUFACTURER "Marvell" + + /* + * We have MAILBOX_REGISTER_COUNT sized arrays in a few places, diff --git a/patches.suse/scsi-qla2xxx-Update-version-to-10.02.09.200-k.patch b/patches.suse/scsi-qla2xxx-Update-version-to-10.02.09.200-k.patch new file mode 100644 index 0000000..2e58cd7 --- /dev/null +++ b/patches.suse/scsi-qla2xxx-Update-version-to-10.02.09.200-k.patch @@ -0,0 +1,30 @@ +From: Nilesh Javali +Date: Tue, 27 Feb 2024 22:11:27 +0530 +Subject: scsi: qla2xxx: Update version to 10.02.09.200-k +Patch-mainline: v6.9-rc2 +Git-commit: b8260ca37930a4b007f7b662d4b501a030a4935f +References: bsc1221816 + +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240227164127.36465-12-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Acked-by: Daniel Wagner +--- + drivers/scsi/qla2xxx/qla_version.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_version.h ++++ b/drivers/scsi/qla2xxx/qla_version.h +@@ -7,9 +7,9 @@ + /* + * Driver version + */ +-#define QLA2XXX_VERSION "10.02.09.100-k" ++#define QLA2XXX_VERSION "10.02.09.200-k" + + #define QLA_DRIVER_MAJOR_VER 10 + #define QLA_DRIVER_MINOR_VER 2 + #define QLA_DRIVER_PATCH_VER 9 +-#define QLA_DRIVER_BETA_VER 100 ++#define QLA_DRIVER_BETA_VER 200 diff --git a/patches.suse/serial-rp2-use-request_firmware-instead-of-request_f.patch b/patches.suse/serial-rp2-use-request_firmware-instead-of-request_f.patch index ba439d7..318ce90 100644 --- a/patches.suse/serial-rp2-use-request_firmware-instead-of-request_f.patch +++ b/patches.suse/serial-rp2-use-request_firmware-instead-of-request_f.patch @@ -4,7 +4,7 @@ Date: Fri, 21 May 2021 06:08:43 +0000 Subject: [PATCH] serial: rp2: use 'request_firmware' instead of 'request_firmware_nowait' Git-commit: 016002848c82eeb5d460489ce392d91fe18c475c Patch-mainline: v5.13-rc4 -References: git-fixes +References: git-fixes CVE-2021-47169 bsc#1222000 In 'rp2_probe', the driver registers 'rp2_uart_interrupt' then calls 'rp2_fw_cb' through 'request_firmware_nowait'. In 'rp2_fw_cb', if the diff --git a/patches.suse/tcp-make-sure-init-the-accept_queue-s-spinlocks-once.patch b/patches.suse/tcp-make-sure-init-the-accept_queue-s-spinlocks-once.patch new file mode 100644 index 0000000..fc4d1f5 --- /dev/null +++ b/patches.suse/tcp-make-sure-init-the-accept_queue-s-spinlocks-once.patch @@ -0,0 +1,158 @@ +From: Zhengchao Shao +Date: Thu, 18 Jan 2024 09:20:19 +0800 +Subject: tcp: make sure init the accept_queue's spinlocks once +Patch-mainline: v6.8-rc2 +Git-commit: 198bc90e0e734e5f98c3d2833e8390cac3df61b2 +References: bsc#1221293 CVE-2024-26614 + +When I run syz's reproduction C program locally, it causes the following +issue: +pvqspinlock: lock 0xffff9d181cd5c660 has corrupted value 0x0! +WARNING: CPU: 19 PID: 21160 at __pv_queued_spin_unlock_slowpath (kernel/locking/qspinlock_paravirt.h:508) +Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 +RIP: 0010:__pv_queued_spin_unlock_slowpath (kernel/locking/qspinlock_paravirt.h:508) +Code: 73 56 3a ff 90 c3 cc cc cc cc 8b 05 bb 1f 48 01 85 c0 74 05 c3 cc cc cc cc 8b 17 48 89 fe 48 c7 c7 +30 20 ce 8f e8 ad 56 42 ff <0f> 0b c3 cc cc cc cc 0f 0b 0f 1f 40 00 90 90 90 90 90 90 90 90 90 +RSP: 0018:ffffa8d200604cb8 EFLAGS: 00010282 +RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffff9d1ef60e0908 +RDX: 00000000ffffffd8 RSI: 0000000000000027 RDI: ffff9d1ef60e0900 +RBP: ffff9d181cd5c280 R08: 0000000000000000 R09: 00000000ffff7fff +R10: ffffa8d200604b68 R11: ffffffff907dcdc8 R12: 0000000000000000 +R13: ffff9d181cd5c660 R14: ffff9d1813a3f330 R15: 0000000000001000 +FS: 00007fa110184640(0000) GS:ffff9d1ef60c0000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000020000000 CR3: 000000011f65e000 CR4: 00000000000006f0 +Call Trace: + + _raw_spin_unlock (kernel/locking/spinlock.c:186) + inet_csk_reqsk_queue_add (net/ipv4/inet_connection_sock.c:1321) + inet_csk_complete_hashdance (net/ipv4/inet_connection_sock.c:1358) + tcp_check_req (net/ipv4/tcp_minisocks.c:868) + tcp_v4_rcv (net/ipv4/tcp_ipv4.c:2260) + ip_protocol_deliver_rcu (net/ipv4/ip_input.c:205) + ip_local_deliver_finish (net/ipv4/ip_input.c:234) + __netif_receive_skb_one_core (net/core/dev.c:5529) + process_backlog (./include/linux/rcupdate.h:779) + __napi_poll (net/core/dev.c:6533) + net_rx_action (net/core/dev.c:6604) + __do_softirq (./arch/x86/include/asm/jump_label.h:27) + do_softirq (kernel/softirq.c:454 kernel/softirq.c:441) + + + __local_bh_enable_ip (kernel/softirq.c:381) + __dev_queue_xmit (net/core/dev.c:4374) + ip_finish_output2 (./include/net/neighbour.h:540 net/ipv4/ip_output.c:235) + __ip_queue_xmit (net/ipv4/ip_output.c:535) + __tcp_transmit_skb (net/ipv4/tcp_output.c:1462) + tcp_rcv_synsent_state_process (net/ipv4/tcp_input.c:6469) + tcp_rcv_state_process (net/ipv4/tcp_input.c:6657) + tcp_v4_do_rcv (net/ipv4/tcp_ipv4.c:1929) + __release_sock (./include/net/sock.h:1121 net/core/sock.c:2968) + release_sock (net/core/sock.c:3536) + inet_wait_for_connect (net/ipv4/af_inet.c:609) + __inet_stream_connect (net/ipv4/af_inet.c:702) + inet_stream_connect (net/ipv4/af_inet.c:748) + __sys_connect (./include/linux/file.h:45 net/socket.c:2064) + __x64_sys_connect (net/socket.c:2073 net/socket.c:2070 net/socket.c:2070) + do_syscall_64 (arch/x86/entry/common.c:51 arch/x86/entry/common.c:82) + entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:129) + RIP: 0033:0x7fa10ff05a3d + Code: 5b 41 5c c3 66 0f 1f 84 00 00 00 00 00 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 + c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d ab a3 0e 00 f7 d8 64 89 01 48 + RSP: 002b:00007fa110183de8 EFLAGS: 00000202 ORIG_RAX: 000000000000002a + RAX: ffffffffffffffda RBX: 0000000020000054 RCX: 00007fa10ff05a3d + RDX: 000000000000001c RSI: 0000000020000040 RDI: 0000000000000003 + RBP: 00007fa110183e20 R08: 0000000000000000 R09: 0000000000000000 + R10: 0000000000000000 R11: 0000000000000202 R12: 00007fa110184640 + R13: 0000000000000000 R14: 00007fa10fe8b060 R15: 00007fff73e23b20 + + +The issue triggering process is analyzed as follows: +Thread A Thread B +tcp_v4_rcv //receive ack TCP packet inet_shutdown + tcp_check_req tcp_disconnect //disconnect sock + ... tcp_set_state(sk, TCP_CLOSE) + inet_csk_complete_hashdance ... + inet_csk_reqsk_queue_add inet_listen //start listen + spin_lock(&queue->rskq_lock) inet_csk_listen_start + ... reqsk_queue_alloc + ... spin_lock_init + spin_unlock(&queue->rskq_lock) //warning + +When the socket receives the ACK packet during the three-way handshake, +it will hold spinlock. And then the user actively shutdowns the socket +and listens to the socket immediately, the spinlock will be initialized. +When the socket is going to release the spinlock, a warning is generated. +Also the same issue to fastopenq.lock. + +Move init spinlock to inet_create and inet_accept to make sure init the +accept_queue's spinlocks once. + +Fixes: fff1f3001cc5 ("tcp: add a spinlock to protect struct request_sock_queue") +Fixes: 168a8f58059a ("tcp: TCP Fast Open Server - main code path") +Reported-by: Ming Shu +Signed-off-by: Zhengchao Shao +Reviewed-by: Eric Dumazet +Link: https://lore.kernel.org/r/20240118012019.1751966-1-shaozhengchao@huawei.com +Signed-off-by: Jakub Kicinski +Acked-by: Thomas Bogendoerfer +--- + include/net/inet_connection_sock.h | 9 +++++++++ + net/core/request_sock.c | 3 --- + net/ipv4/af_inet.c | 3 +++ + net/ipv4/inet_connection_sock.c | 4 ++++ + 4 files changed, 16 insertions(+), 3 deletions(-) + +--- a/include/net/inet_connection_sock.h ++++ b/include/net/inet_connection_sock.h +@@ -328,4 +328,13 @@ void inet_csk_update_fastreuse(struct in + struct sock *sk); + + struct dst_entry *inet_csk_update_pmtu(struct sock *sk, u32 mtu); ++ ++static inline void inet_init_csk_locks(struct sock *sk) ++{ ++ struct inet_connection_sock *icsk = inet_csk(sk); ++ ++ spin_lock_init(&icsk->icsk_accept_queue.rskq_lock); ++ spin_lock_init(&icsk->icsk_accept_queue.fastopenq.lock); ++} ++ + #endif /* _INET_CONNECTION_SOCK_H */ +--- a/net/core/request_sock.c ++++ b/net/core/request_sock.c +@@ -37,9 +37,6 @@ + + void reqsk_queue_alloc(struct request_sock_queue *queue) + { +- spin_lock_init(&queue->rskq_lock); +- +- spin_lock_init(&queue->fastopenq.lock); + queue->fastopenq.rskq_rst_head = NULL; + queue->fastopenq.rskq_rst_tail = NULL; + queue->fastopenq.qlen = 0; +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -324,6 +324,9 @@ lookup_protocol: + if (INET_PROTOSW_REUSE & answer_flags) + sk->sk_reuse = SK_CAN_REUSE; + ++ if (INET_PROTOSW_ICSK & answer_flags) ++ inet_init_csk_locks(sk); ++ + inet = inet_sk(sk); + inet->is_icsk = (INET_PROTOSW_ICSK & answer_flags) != 0; + +--- a/net/ipv4/inet_connection_sock.c ++++ b/net/ipv4/inet_connection_sock.c +@@ -512,6 +512,10 @@ out: + } + if (req) + reqsk_put(req); ++ ++ if (newsk) ++ inet_init_csk_locks(newsk); ++ + return newsk; + out_err: + newsk = NULL; diff --git a/patches.suse/tracing-Restructure-trace_clock_global-to-never-block.patch b/patches.suse/tracing-Restructure-trace_clock_global-to-never-block.patch index e5bf27c..f7aa02f 100644 --- a/patches.suse/tracing-Restructure-trace_clock_global-to-never-block.patch +++ b/patches.suse/tracing-Restructure-trace_clock_global-to-never-block.patch @@ -3,7 +3,7 @@ Date: Fri, 30 Apr 2021 12:17:58 -0400 Subject: tracing: Restructure trace_clock_global() to never block Git-commit: aafe104aa9096827a429bc1358f8260ee565b7cc Patch-mainline: v5.13-rc1 -References: git-fixes +References: git-fixes CVE-2021-46939 bsc#1220580 It was reported that a fix to the ring buffer recursion detection would cause a hung machine when performing suspend / resume testing. The diff --git a/patches.suse/tun-honor-IOCB_NOWAIT-flag.patch b/patches.suse/tun-honor-IOCB_NOWAIT-flag.patch new file mode 100644 index 0000000..34d2827 --- /dev/null +++ b/patches.suse/tun-honor-IOCB_NOWAIT-flag.patch @@ -0,0 +1,63 @@ +From a04c006bb1f0374f9868de5db4888efc435205db Mon Sep 17 00:00:00 2001 +From: Jens Axboe +Date: Fri, 20 Nov 2020 07:59:54 -0700 +Subject: [PATCH 5/8] tun: honor IOCB_NOWAIT flag +Git-commit: 5aac0390a63b8718237a61dd0d24a29201d1c94a +References: git-fixes +Patch-mainline: v5.10-rc6 + +tun only checks the file O_NONBLOCK flag, but it should also be checking +the iocb IOCB_NOWAIT flag. Any fops using ->read/write_iter() should check +both, otherwise it breaks users that correctly expect O_NONBLOCK semantics +if IOCB_NOWAIT is set. + +Signed-off-by: Jens Axboe +Link: https://lore.kernel.org/r/e9451860-96cc-c7c7-47b8-fe42cadd5f4c@kernel.dk +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + drivers/net/tun.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/tun.c b/drivers/net/tun.c +index 14d0ad3a98eb..46b02fdb50b7 100644 +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -2019,12 +2019,15 @@ static ssize_t tun_chr_write_iter(struct kiocb *iocb, struct iov_iter *from) + struct tun_file *tfile = file->private_data; + struct tun_struct *tun = tun_get(tfile); + ssize_t result; ++ int noblock = 0; + + if (!tun) + return -EBADFD; + +- result = tun_get_user(tun, tfile, NULL, from, +- file->f_flags & O_NONBLOCK, false); ++ if ((file->f_flags & O_NONBLOCK) || (iocb->ki_flags & IOCB_NOWAIT)) ++ noblock = 1; ++ ++ result = tun_get_user(tun, tfile, NULL, from, noblock, false); + + tun_put(tun); + return result; +@@ -2245,10 +2248,15 @@ static ssize_t tun_chr_read_iter(struct kiocb *iocb, struct iov_iter *to) + struct tun_file *tfile = file->private_data; + struct tun_struct *tun = tun_get(tfile); + ssize_t len = iov_iter_count(to), ret; ++ int noblock = 0; + + if (!tun) + return -EBADFD; +- ret = tun_do_read(tun, tfile, to, file->f_flags & O_NONBLOCK, NULL); ++ ++ if ((file->f_flags & O_NONBLOCK) || (iocb->ki_flags & IOCB_NOWAIT)) ++ noblock = 1; ++ ++ ret = tun_do_read(tun, tfile, to, noblock, NULL); + ret = min_t(ssize_t, ret, len); + if (ret > 0) + iocb->ki_pos = ret; +-- +2.16.4 + diff --git a/patches.suse/udf_rename-only-access-the-child-content-on-cross-di.patch b/patches.suse/udf_rename-only-access-the-child-content-on-cross-di.patch new file mode 100644 index 0000000..5c9f903 --- /dev/null +++ b/patches.suse/udf_rename-only-access-the-child-content-on-cross-di.patch @@ -0,0 +1,73 @@ +From 9d35cebb794bb7be93db76c3383979c7deacfef9 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Tue, 17 Oct 2023 14:44:23 -0400 +Subject: [PATCH] udf_rename(): only access the child content on + cross-directory rename +Git-commit: 9d35cebb794bb7be93db76c3383979c7deacfef9 +Patch-mainline: v6.8-rc1 +References: bsc#1221044 CVE-2023-52591 + +We can't really afford locking the source on same-directory rename; +currently vfs_rename() tries to do that, but it will have to be +changed. The logics in udf_rename() is lazy and goes looking for +".." in source even in same-directory case. It's not hard to get +rid of that, leaving that behaviour only for cross-directory case; +that VFS can get locks safely (and will keep doing that after the +coming changes). + +Reviewed-by: Jan Kara +Signed-off-by: Al Viro +Acked-by: Jan Kara + +--- + fs/udf/namei.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +--- a/fs/udf/namei.c ++++ b/fs/udf/namei.c +@@ -1104,6 +1104,7 @@ static int udf_rename(struct inode *old_ + struct fileIdentDesc *ofi = NULL, *nfi = NULL, *dir_fi = NULL; + struct fileIdentDesc ocfi, ncfi; + struct buffer_head *dir_bh = NULL; ++ bool is_dir = false; + int retval = -ENOENT; + struct kernel_lb_addr tloc; + struct udf_inode_info *old_iinfo = UDF_I(old_inode); +@@ -1138,13 +1139,16 @@ static int udf_rename(struct inode *old_ + nfi = NULL; + } + if (S_ISDIR(old_inode->i_mode)) { +- int offset = udf_ext0_offset(old_inode); +- + if (new_inode) { + retval = -ENOTEMPTY; + if (!empty_dir(new_inode)) + goto end_rename; + } ++ is_dir = true; ++ } ++ if (is_dir && old_dir != new_dir) { ++ int offset = udf_ext0_offset(old_inode); ++ + retval = -EIO; + if (old_iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { + dir_fi = udf_get_fileident( +@@ -1202,7 +1206,7 @@ static int udf_rename(struct inode *old_ + mark_inode_dirty(old_dir); + mark_inode_dirty(new_dir); + +- if (dir_fi) { ++ if (is_dir && old_dir != new_dir) { + dir_fi->icb.extLocation = cpu_to_lelb(UDF_I(new_dir)->i_location); + udf_update_tag((char *)dir_fi, + (sizeof(struct fileIdentDesc) + +@@ -1211,7 +1215,9 @@ static int udf_rename(struct inode *old_ + mark_inode_dirty(old_inode); + else + mark_buffer_dirty_inode(dir_bh, old_inode); ++ } + ++ if (is_dir) { + inode_dec_link_count(old_dir); + if (new_inode) + inode_dec_link_count(new_inode); diff --git a/patches.suse/usb-dwc3-Fix-race-between-dwc3_set_mode-and-__dwc3_s.patch b/patches.suse/usb-dwc3-Fix-race-between-dwc3_set_mode-and-__dwc3_s.patch index 3d99ec9..0be7630 100644 --- a/patches.suse/usb-dwc3-Fix-race-between-dwc3_set_mode-and-__dwc3_s.patch +++ b/patches.suse/usb-dwc3-Fix-race-between-dwc3_set_mode-and-__dwc3_s.patch @@ -53,38 +53,39 @@ Link: https://lore.kernel.org/r/20221128161526.79730-1-sven@svenpeter.dev Signed-off-by: Greg Kroah-Hartman Signed-off-by: Oliver Neukum --- - drivers/usb/dwc3/core.c | 17 +++++++++++------ - 1 file changed, 11 insertions(+), 6 deletions(-) + drivers/usb/dwc3/core.c | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c -@@ -118,17 +118,22 @@ static void __dwc3_set_mode(struct work_ - struct dwc3 *dwc = work_to_dwc(work); +@@ -121,19 +121,23 @@ static void __dwc3_set_mode(struct work_ unsigned long flags; int ret; + u32 reg; + u32 desired_dr_role; + mutex_lock(&dwc->mutex); + - if (!dwc->desired_dr_role) + spin_lock_irqsave(&dwc->lock, flags); + desired_dr_role = dwc->desired_dr_role; + spin_unlock_irqrestore(&dwc->lock, flags); -+ + if (!desired_dr_role) - return; + goto out; - if (dwc->desired_dr_role == dwc->current_dr_role) + if (desired_dr_role == dwc->current_dr_role) - return; + goto out; if (dwc->dr_mode != USB_DR_MODE_OTG) - return; + goto out; - if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG) + if (desired_dr_role == DWC3_GCTL_PRTCAP_OTG) - return; + goto out; switch (dwc->current_dr_role) { -@@ -145,13 +150,13 @@ static void __dwc3_set_mode(struct work_ +@@ -169,13 +173,13 @@ static void __dwc3_set_mode(struct work_ spin_lock_irqsave(&dwc->lock, flags); diff --git a/patches.suse/usb-dwc3-core-Do-core-softreset-when-switch-mode.patch b/patches.suse/usb-dwc3-core-Do-core-softreset-when-switch-mode.patch new file mode 100644 index 0000000..61f2d1e --- /dev/null +++ b/patches.suse/usb-dwc3-core-Do-core-softreset-when-switch-mode.patch @@ -0,0 +1,172 @@ +From f88359e1588b85cf0e8209ab7d6620085f3441d9 Mon Sep 17 00:00:00 2001 +From: Yu Chen +Date: Thu, 15 Apr 2021 15:20:30 -0700 +Subject: [PATCH] usb: dwc3: core: Do core softreset when switch mode +Git-commit: f88359e1588b85cf0e8209ab7d6620085f3441d9 +References: bsc#1220628 CVE-2021-46941 +Patch-mainline: v5.13-rc1 + +From: John Stultz + +According to the programming guide, to switch mode for DRD controller, +the driver needs to do the following. + +To switch from device to host: +1. Reset controller with GCTL.CoreSoftReset +2. Set GCTL.PrtCapDir(host mode) +3. Reset the host with USBCMD.HCRESET +4. Then follow up with the initializing host registers sequence + +To switch from host to device: +1. Reset controller with GCTL.CoreSoftReset +2. Set GCTL.PrtCapDir(device mode) +3. Reset the device with DCTL.CSftRst +4. Then follow up with the initializing registers sequence + +Currently we're missing step 1) to do GCTL.CoreSoftReset and step 3) of +switching from host to device. John Stult reported a lockup issue seen +with HiKey960 platform without these steps[1]. Similar issue is observed +with Ferry's testing platform[2]. + +So, apply the required steps along with some fixes to Yu Chen's and John +Stultz's version. The main fixes to their versions are the missing wait +for clocks synchronization before clearing GCTL.CoreSoftReset and only +apply DCTL.CSftRst when switching from host to device. + +[1] https://lore.kernel.org/linux-usb/20210108015115.27920-1-john.stultz@linaro.org/ +[2] https://lore.kernel.org/linux-usb/0ba7a6ba-e6a7-9cd4-0695-64fc927e01f1@gmail.com/ + +Fixes: 41ce1456e1db ("usb: dwc3: core: make dwc3_set_mode() work properly") +Cc: Andy Shevchenko +Cc: Ferry Toth +Cc: Wesley Cheng +Cc: +Tested-by: John Stultz +Tested-by: Wesley Cheng +Signed-off-by: Yu Chen +Signed-off-by: John Stultz +Signed-off-by: Thinh Nguyen +Link: https://lore.kernel.org/r/374440f8dcd4f06c02c2caf4b1efde86774e02d9.1618521663.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum + +--- + drivers/usb/dwc3/core.c | 37 +++++++++++++++++++++++++++++++++---- + drivers/usb/dwc3/core.h | 5 +++++ + 2 files changed, 38 insertions(+), 4 deletions(-) + +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -113,23 +113,28 @@ static void dwc3_set_prtcap(struct dwc3 + dwc3_writel(dwc->regs, DWC3_GCTL, reg); + } + ++static int dwc3_core_soft_reset(struct dwc3 *dwc); ++ + static void __dwc3_set_mode(struct work_struct *work) + { + struct dwc3 *dwc = work_to_dwc(work); + unsigned long flags; + int ret; ++ u32 reg; ++ ++ mutex_lock(&dwc->mutex); + + if (!dwc->desired_dr_role) +- return; ++ goto out; + + if (dwc->desired_dr_role == dwc->current_dr_role) +- return; ++ goto out; + + if (dwc->dr_mode != USB_DR_MODE_OTG) +- return; ++ goto out; + + if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG) +- return; ++ goto out; + + switch (dwc->current_dr_role) { + case DWC3_GCTL_PRTCAP_HOST: +@@ -143,6 +148,25 @@ static void __dwc3_set_mode(struct work_ + break; + } + ++ /* For DRD host or device mode only */ ++ if (dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) { ++ reg = dwc3_readl(dwc->regs, DWC3_GCTL); ++ reg |= DWC3_GCTL_CORESOFTRESET; ++ dwc3_writel(dwc->regs, DWC3_GCTL, reg); ++ ++ /* ++ * Wait for internal clocks to synchronized. DWC_usb31 and ++ * DWC_usb32 may need at least 50ms (less for DWC_usb3). To ++ * keep it consistent across different IPs, let's wait up to ++ * 100ms before clearing GCTL.CORESOFTRESET. ++ */ ++ msleep(100); ++ ++ reg = dwc3_readl(dwc->regs, DWC3_GCTL); ++ reg &= ~DWC3_GCTL_CORESOFTRESET; ++ dwc3_writel(dwc->regs, DWC3_GCTL, reg); ++ } ++ + spin_lock_irqsave(&dwc->lock, flags); + + dwc3_set_prtcap(dwc, dwc->desired_dr_role); +@@ -158,6 +182,8 @@ static void __dwc3_set_mode(struct work_ + dev_err(dwc->dev, "failed to initialize host\n"); + break; + case DWC3_GCTL_PRTCAP_DEVICE: ++ dwc3_core_soft_reset(dwc); ++ + dwc3_event_buffers_setup(dwc); + ret = dwc3_gadget_init(dwc); + if (ret) +@@ -166,6 +192,8 @@ static void __dwc3_set_mode(struct work_ + default: + break; + } ++out: ++ mutex_unlock(&dwc->mutex); + } + + void dwc3_set_mode(struct dwc3 *dwc, u32 mode) +@@ -1237,6 +1265,7 @@ static int dwc3_probe(struct platform_de + dwc3_cache_hwparams(dwc); + + spin_lock_init(&dwc->lock); ++ mutex_init(&dwc->mutex); + + pm_runtime_set_active(dev); + pm_runtime_use_autosuspend(dev); +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -21,6 +21,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -776,6 +777,7 @@ struct dwc3_scratchpad_array { + * @scratch_addr: dma address of scratchbuf + * @ep0_in_setup: one control transfer is completed and enter setup phase + * @lock: for synchronizing ++ * @mutex: for mode switching + * @dev: pointer to our struct device + * @xhci: pointer to our xHCI child + * @event_buffer_list: a list of event buffers +@@ -883,6 +885,9 @@ struct dwc3 { + /* device lock */ + spinlock_t lock; + ++ /* mode switching lock */ ++ struct mutex mutex; ++ + struct device *dev; + struct device *sysdev; + diff --git a/patches.suse/usb-dwc3-core-Do-not-perform-GCTL_CORE_SOFTRESET-dur.patch b/patches.suse/usb-dwc3-core-Do-not-perform-GCTL_CORE_SOFTRESET-dur.patch new file mode 100644 index 0000000..9a32175 --- /dev/null +++ b/patches.suse/usb-dwc3-core-Do-not-perform-GCTL_CORE_SOFTRESET-dur.patch @@ -0,0 +1,49 @@ +From 07903626d98853e605fe63e5ce149f1b7314bbea Mon Sep 17 00:00:00 2001 +From: Rohith Kollalsi +Date: Thu, 14 Jul 2022 10:26:25 +0530 +Subject: [PATCH] usb: dwc3: core: Do not perform GCTL_CORE_SOFTRESET during + bootup +Git-commit: 07903626d98853e605fe63e5ce149f1b7314bbea +References: bsc#1220628 CVE-2021-46941 +Patch-mainline: v6.0-rc1 + +According to the programming guide, it is recommended to +perform a GCTL_CORE_SOFTRESET only when switching the mode +from device to host or host to device. However, it is found +that during bootup when __dwc3_set_mode() is called for the +first time, GCTL_CORESOFTRESET is done with suspendable bit(BIT 17) +of DWC3_GUSB3PIPECTL set. This some times leads to issues +like controller going into bad state and controller registers +reading value zero. Until GCTL_CORESOFTRESET is done and +run/stop bit is set core initialization is not complete. +Setting suspendable bit of DWC3_GUSB3PIPECTL and then +performing GCTL_CORESOFTRESET is therefore not recommended. +Avoid this by only performing the reset if current_dr_role is set, +that is, when doing subsequent role switching. + +Fixes: f88359e1588b ("usb: dwc3: core: Do core softreset when switch mode") +Signed-off-by: Rohith Kollalsi +Link: https://lore.kernel.org/r/20220714045625.20377-1-quic_rkollals@quicinc.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum + +--- + drivers/usb/dwc3/core.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -148,8 +148,11 @@ static void __dwc3_set_mode(struct work_ + break; + } + +- /* For DRD host or device mode only */ +- if (dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) { ++ /* ++ * When current_dr_role is not set, there's no role switching. ++ * Only perform GCTL.CoreSoftReset when there's DRD role switching. ++ */ ++ if (dwc->current_dr_role && dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) { + reg = dwc3_readl(dwc->regs, DWC3_GCTL); + reg |= DWC3_GCTL_CORESOFTRESET; + dwc3_writel(dwc->regs, DWC3_GCTL, reg); diff --git a/patches.suse/usb-dwc3-core-balance-phy-init-and-exit.patch b/patches.suse/usb-dwc3-core-balance-phy-init-and-exit.patch new file mode 100644 index 0000000..2153a54 --- /dev/null +++ b/patches.suse/usb-dwc3-core-balance-phy-init-and-exit.patch @@ -0,0 +1,86 @@ +From 8cfac9a6744fcb143cb3e94ce002f09fd17fadbb Mon Sep 17 00:00:00 2001 +From: Li Jun +Date: Wed, 8 Sep 2021 10:28:19 +0800 +Subject: [PATCH] usb: dwc3: core: balance phy init and exit +Git-commit: 8cfac9a6744fcb143cb3e94ce002f09fd17fadbb +References: bsc#1220628 CVE-2021-46941 +Patch-mainline: v5.15-rc3 + +After we start to do core soft reset while usb role switch, +the phy init is invoked at every switch to device mode, but +its counter part de-init is missing, this causes the actual +phy init can not be done when we really want to re-init phy +like system resume, because the counter maintained by phy +core is not 0. considering phy init is actually redundant for +role switch, so move out the phy init from core soft reset to +dwc3 core init where is the only place required. + +Fixes: f88359e1588b ("usb: dwc3: core: Do core softreset when switch mode") +Cc: +Tested-by: faqiang.zhu +Tested-by: John Stultz #HiKey960 +Acked-by: Felipe Balbi +Signed-off-by: Li Jun +Link: https://lore.kernel.org/r/1631068099-13559-1-git-send-email-jun.li@nxp.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum + +--- + drivers/usb/dwc3/core.c | 30 +++++++++++++----------------- + 1 file changed, 13 insertions(+), 17 deletions(-) + +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -229,19 +229,6 @@ static int dwc3_core_soft_reset(struct d + { + u32 reg; + int retries = 1000; +- int ret; +- +- usb_phy_init(dwc->usb2_phy); +- usb_phy_init(dwc->usb3_phy); +- ret = phy_init(dwc->usb2_generic_phy); +- if (ret < 0) +- return ret; +- +- ret = phy_init(dwc->usb3_generic_phy); +- if (ret < 0) { +- phy_exit(dwc->usb2_generic_phy); +- return ret; +- } + + /* + * We're resetting only the device side because, if we're in host mode, +@@ -263,9 +250,6 @@ static int dwc3_core_soft_reset(struct d + udelay(1); + } while (--retries); + +- phy_exit(dwc->usb3_generic_phy); +- phy_exit(dwc->usb2_generic_phy); +- + return -ETIMEDOUT; + + done: +@@ -850,9 +834,21 @@ static int dwc3_core_init(struct dwc3 *d + dwc->phys_ready = true; + } + ++ usb_phy_init(dwc->usb2_phy); ++ usb_phy_init(dwc->usb3_phy); ++ ret = phy_init(dwc->usb2_generic_phy); ++ if (ret < 0) ++ goto err0a; ++ ++ ret = phy_init(dwc->usb3_generic_phy); ++ if (ret < 0) { ++ phy_exit(dwc->usb2_generic_phy); ++ goto err0a; ++ } ++ + ret = dwc3_core_soft_reset(dwc); + if (ret) +- goto err0a; ++ goto err1; + + if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD && + dwc->revision > DWC3_REVISION_194A) { diff --git a/patches.suse/usb-hub-Guard-against-accesses-to-uninitialized-BOS-.patch b/patches.suse/usb-hub-Guard-against-accesses-to-uninitialized-BOS-.patch new file mode 100644 index 0000000..360c735 --- /dev/null +++ b/patches.suse/usb-hub-Guard-against-accesses-to-uninitialized-BOS-.patch @@ -0,0 +1,140 @@ +From f74a7afc224acd5e922c7a2e52244d891bbe44ee Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ricardo=20Ca=C3=B1uelo?= +Date: Wed, 30 Aug 2023 12:04:18 +0200 +Subject: [PATCH] usb: hub: Guard against accesses to uninitialized BOS + descriptors +Mime-version: 1.0 +Content-type: text/plain; charset=UTF-8 +Content-transfer-encoding: 8bit +Git-commit: f74a7afc224acd5e922c7a2e52244d891bbe44ee +References: bsc#1220790 CVE-2023-52477 +Patch-mainline: v6.6-rc6 + +Many functions in drivers/usb/core/hub.c and drivers/usb/core/hub.h +access fields inside udev->bos without checking if it was allocated and +initialized. If usb_get_bos_descriptor() fails for whatever +reason, udev->bos will be NULL and those accesses will result in a +Crash: + +Bug: kernel NULL pointer dereference, address: 0000000000000018 +PGD 0 P4D 0 +Oops: 0000 [#1] PREEMPT SMP NOPTI +Cpu: 5 PID: 17818 Comm: kworker/5:1 Tainted: G W 5.15.108-18910-gab0e1cb584e1 #1 +Hardware name: Google Kindred/Kindred, BIOS Google_Kindred.12672.413.0 02/03/2021 +Workqueue: usb_hub_wq hub_event +Rip: 0010:hub_port_reset+0x193/0x788 +Code: 89 f7 e8 20 f7 15 00 48 8b 43 08 80 b8 96 03 00 00 03 75 36 0f b7 88 92 03 00 00 81 f9 10 03 00 00 72 27 48 8b 80 a8 03 00 00 <48> 83 78 18 00 74 19 48 89 df 48 8b 75 b0 ba 02 00 00 00 4c 89 e9 +Rsp: 0018:ffffab740c53fcf8 EFLAGS: 00010246 +Rax: 0000000000000000 RBX: ffffa1bc5f678000 RCX: 0000000000000310 +Rdx: fffffffffffffdff RSI: 0000000000000286 RDI: ffffa1be9655b840 +Rbp: ffffab740c53fd70 R08: 00001b7d5edaa20c R09: ffffffffb005e060 +R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000 +R13: ffffab740c53fd3e R14: 0000000000000032 R15: 0000000000000000 +Fs: 0000000000000000(0000) GS:ffffa1be96540000(0000) knlGS:0000000000000000 +Cs: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +Cr2: 0000000000000018 CR3: 000000022e80c005 CR4: 00000000003706e0 +Call Trace: +hub_event+0x73f/0x156e +? hub_activate+0x5b7/0x68f +process_one_work+0x1a2/0x487 +worker_thread+0x11a/0x288 +kthread+0x13a/0x152 +? process_one_work+0x487/0x487 +? kthread_associate_blkcg+0x70/0x70 +ret_from_fork+0x1f/0x30 + +Fall back to a default behavior if the BOS descriptor isn't accessible +and skip all the functionalities that depend on it: LPM support checks, +Super Speed capabilitiy checks, U1/U2 states setup. + +Signed-off-by: Ricardo Cañuelo +Cc: stable +Link: https://lore.kernel.org/r/20230830100418.1952143-1-ricardo.canuelo@collabora.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum + +--- + drivers/usb/core/hub.c | 30 ++++++++++++++++++++++++++---- + drivers/usb/core/hub.h | 2 +- + 2 files changed, 27 insertions(+), 5 deletions(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -145,6 +145,10 @@ int usb_device_supports_lpm(struct usb_d + if (udev->quirks & USB_QUIRK_NO_LPM) + return 0; + ++ /* Skip if the device BOS descriptor couldn't be read */ ++ if (!udev->bos) ++ return 0; ++ + /* USB 2.1 (and greater) devices indicate LPM support through + * their USB 2.0 Extended Capabilities BOS descriptor. + */ +@@ -321,6 +325,10 @@ static void usb_set_lpm_parameters(struc + if (!udev->lpm_capable || udev->speed < USB_SPEED_SUPER) + return; + ++ /* Skip if the device BOS descriptor couldn't be read */ ++ if (!udev->bos) ++ return; ++ + hub = usb_hub_to_struct_hub(udev->parent); + /* It doesn't take time to transition the roothub into U0, since it + * doesn't have an upstream link. +@@ -2683,10 +2691,14 @@ static int port_speed_is_ssp(struct usb_ + int ssa_count; + u32 ss_attr; + int i; +- struct usb_ssp_cap_descriptor *ssp_cap = hdev->bos->ssp_cap; ++ struct usb_ssp_cap_descriptor *ssp_cap; ++ ++ if (!hdev->bos) ++ goto out; + ++ ssp_cap = hdev->bos->ssp_cap; + if (!ssp_cap) +- return 0; ++ goto out; + + ssa_count = le32_to_cpu(ssp_cap->bmAttributes) & + USB_SSP_SUBLINK_SPEED_ATTRIBS; +@@ -2696,6 +2708,7 @@ static int port_speed_is_ssp(struct usb_ + if (speed_id == (ss_attr & USB_SSP_SUBLINK_SPEED_SSID)) + return !!(ss_attr & USB_SSP_SUBLINK_SPEED_LP); + } ++out: + return 0; + } + +@@ -4086,8 +4099,17 @@ static void usb_enable_link_state(struct + enum usb3_link_state state) + { + int timeout, ret; +- __u8 u1_mel = udev->bos->ss_cap->bU1devExitLat; +- __le16 u2_mel = udev->bos->ss_cap->bU2DevExitLat; ++ __u8 u1_mel; ++ __le16 u2_mel; ++ ++ /* Skip if the device BOS descriptor couldn't be read */ ++ if (!udev->bos) ++ return; ++ if(!udev->bos->ss_cap) ++ return; ++ ++ u1_mel = udev->bos->ss_cap->bU1devExitLat; ++ u2_mel = udev->bos->ss_cap->bU2DevExitLat; + + /* If the device says it doesn't have *any* exit latency to come out of + * U1 or U2, it's probably lying. Assume it doesn't implement that link +--- a/drivers/usb/core/hub.h ++++ b/drivers/usb/core/hub.h +@@ -141,7 +141,7 @@ static inline int hub_is_superspeedplus( + { + return (hdev->descriptor.bDeviceProtocol == USB_HUB_PR_SS && + le16_to_cpu(hdev->descriptor.bcdUSB) >= 0x0310 && +- hdev->bos->ssp_cap); ++ hdev->bos && hdev->bos->ssp_cap); + } + + static inline unsigned hub_power_on_good_delay(struct usb_hub *hub) diff --git a/patches.suse/usb-storage-set-1.50-as-the-lower-bcdDevice-for-olde.patch b/patches.suse/usb-storage-set-1.50-as-the-lower-bcdDevice-for-olde.patch new file mode 100644 index 0000000..6b48d9d --- /dev/null +++ b/patches.suse/usb-storage-set-1.50-as-the-lower-bcdDevice-for-olde.patch @@ -0,0 +1,39 @@ +From 0e3139e6543b241b3e65956a55c712333bef48ac Mon Sep 17 00:00:00 2001 +From: LihaSika +Date: Fri, 27 Oct 2023 20:28:04 +0300 +Subject: [PATCH] usb: storage: set 1.50 as the lower bcdDevice for older + "Super Top" compatibility +Git-commit: 0e3139e6543b241b3e65956a55c712333bef48ac +References: git-fixes +Patch-mainline: v6.7-rc1 + +Change lower bcdDevice value for "Super Top USB 2.0 SATA BRIDGE" to match +1.50. I have such an older device with bcdDevice=1.50 and it will not work +otherwise. + +Cc: stable@vger.kernel.org +Signed-off-by: Liha Sikanen +Link: https://lore.kernel.org/r/ccf7d12a-8362-4916-b3e0-f4150f54affd@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum + +--- + drivers/usb/storage/unusual_cypress.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/storage/unusual_cypress.h b/drivers/usb/storage/unusual_cypress.h +index 0547daf116a2..5df40759d77a 100644 +--- a/drivers/usb/storage/unusual_cypress.h ++++ b/drivers/usb/storage/unusual_cypress.h +@@ -19,7 +19,7 @@ UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999, + "Cypress ISD-300LP", + USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), + +-UNUSUAL_DEV( 0x14cd, 0x6116, 0x0160, 0x0160, ++UNUSUAL_DEV( 0x14cd, 0x6116, 0x0150, 0x0160, + "Super Top", + "USB 2.0 SATA BRIDGE", + USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), +-- +2.44.0 + diff --git a/patches.suse/usb-typec-class-fix-typec_altmode_put_partner-to-put.patch b/patches.suse/usb-typec-class-fix-typec_altmode_put_partner-to-put.patch new file mode 100644 index 0000000..85667d6 --- /dev/null +++ b/patches.suse/usb-typec-class-fix-typec_altmode_put_partner-to-put.patch @@ -0,0 +1,72 @@ +From 5962ded777d689cd8bf04454273e32228d7fb71f Mon Sep 17 00:00:00 2001 +From: RD Babiera +Date: Wed, 3 Jan 2024 18:17:55 +0000 +Subject: [PATCH] usb: typec: class: fix typec_altmode_put_partner to put plugs +Git-commit: 5962ded777d689cd8bf04454273e32228d7fb71f +References: git-fixes +Patch-mainline: v6.8-rc1 + +When typec_altmode_put_partner is called by a plug altmode upon release, +the port altmode the plug belongs to will not remove its reference to the +plug. The check to see if the altmode being released is a plug evaluates +against the released altmode's partner instead of the calling altmode, so +change adev in typec_altmode_put_partner to properly refer to the altmode +being released. + +Because typec_altmode_set_partner calls get_device() on the port altmode, +add partner_adev that points to the port altmode in typec_put_partner to +call put_device() on. typec_altmode_set_partner is not called for port +altmodes, so add a check in typec_altmode_release to prevent +typec_altmode_put_partner() calls on port altmode release. + +Fixes: 8a37d87d72f0 ("usb: typec: Bus type for alternate modes") +Cc: +Co-developed-by: Christian A. Ehrhardt +Signed-off-by: Christian A. Ehrhardt +Signed-off-by: RD Babiera +Tested-by: Christian A. Ehrhardt +Acked-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20240103181754.2492492-2-rdbabiera@google.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Oliver Neukum + +--- + drivers/usb/typec/class.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/drivers/usb/typec/class.c ++++ b/drivers/usb/typec/class.c +@@ -188,11 +188,13 @@ static void typec_altmode_put_partner(st + { + struct altmode *partner = altmode->partner; + struct typec_altmode *adev; ++ struct typec_altmode *partner_adev; + + if (!partner) + return; + +- adev = &partner->adev; ++ adev = &altmode->adev; ++ partner_adev = &partner->adev; + + if (is_typec_plug(adev->dev.parent)) { + struct typec_plug *plug = to_typec_plug(adev->dev.parent); +@@ -201,7 +203,7 @@ static void typec_altmode_put_partner(st + } else { + partner->partner = NULL; + } +- put_device(&adev->dev); ++ put_device(&partner_adev->dev); + } + + static int __typec_port_match(struct device *dev, const void *name) +@@ -459,7 +461,8 @@ static void typec_altmode_release(struct + { + struct altmode *alt = to_altmode(to_typec_altmode(dev)); + +- typec_altmode_put_partner(alt); ++ if (!is_typec_port(dev->parent)) ++ typec_altmode_put_partner(alt); + + altmode_id_remove(alt->adev.dev.parent, alt->id); + kfree(alt); diff --git a/patches.suse/userfaultfd-release-page-in-error-path-to-avoid-BUG_ON.patch b/patches.suse/userfaultfd-release-page-in-error-path-to-avoid-BUG_ON.patch new file mode 100644 index 0000000..72657aa --- /dev/null +++ b/patches.suse/userfaultfd-release-page-in-error-path-to-avoid-BUG_ON.patch @@ -0,0 +1,62 @@ +From: Axel Rasmussen +Date: Fri, 14 May 2021 17:27:19 -0700 +Subject: userfaultfd: release page in error path to avoid BUG_ON +Git-commit: 7ed9d238c7dbb1fdb63ad96a6184985151b0171c +Patch-mainline: v5.13-rc2 +References: CVE-2021-46988 bsc#1220706 + +Consider the following sequence of events: + +1. Userspace issues a UFFD ioctl, which ends up calling into + shmem_mfill_atomic_pte(). We successfully account the blocks, we + shmem_alloc_page(), but then the copy_from_user() fails. We return + -ENOENT. We don't release the page we allocated. +2. Our caller detects this error code, tries the copy_from_user() after + dropping the mmap_lock, and retries, calling back into + shmem_mfill_atomic_pte(). +3. Meanwhile, let's say another process filled up the tmpfs being used. +4. So shmem_mfill_atomic_pte() fails to account blocks this time, and + immediately returns - without releasing the page. + +This triggers a BUG_ON in our caller, which asserts that the page +should always be consumed, unless -ENOENT is returned. + +To fix this, detect if we have such a "dangling" page when accounting +fails, and if so, release it before returning. + +Link: https://lkml.kernel.org/r/20210428230858.348400-1-axelrasmussen@google.com +Fixes: cb658a453b93 ("userfaultfd: shmem: avoid leaking blocks and used blocks in UFFDIO_COPY") +Signed-off-by: Axel Rasmussen +Reported-by: Hugh Dickins +Acked-by: Hugh Dickins +Reviewed-by: Peter Xu +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Vlastimil Babka +--- + mm/shmem.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +--- a/mm/shmem.c ++++ b/mm/shmem.c +@@ -2246,8 +2246,18 @@ int shmem_mcopy_atomic_pte(struct mm_str + pgoff_t offset, max_off; + + ret = -ENOMEM; +- if (!shmem_inode_acct_block(inode, 1)) ++ if (!shmem_inode_acct_block(inode, 1)) { ++ /* ++ * We may have got a page, returned -ENOENT triggering a retry, ++ * and now we find ourselves with -ENOMEM. Release the page, to ++ * avoid a BUG_ON in our caller. ++ */ ++ if (unlikely(*pagep)) { ++ put_page(*pagep); ++ *pagep = NULL; ++ } + goto out; ++ } + + if (!*pagep) { + page = shmem_alloc_page(gfp, info, pgoff); diff --git a/patches.suse/vsock-virtio-free-queued-packets-when-closing-socket.patch b/patches.suse/vsock-virtio-free-queued-packets-when-closing-socket.patch index e465bcb..f4cf511 100644 --- a/patches.suse/vsock-virtio-free-queued-packets-when-closing-socket.patch +++ b/patches.suse/vsock-virtio-free-queued-packets-when-closing-socket.patch @@ -1,6 +1,6 @@ Patch-mainline: v5.13-rc1 Git-commit: 8432b8114957235f42e070a16118a7f750de9d39 -References: git-fixes +References: git-fixes CVE-2021-47024 bsc#1220637 From: Stefano Garzarella Date: Tue, 20 Apr 2021 13:07:27 +0200 Subject: [PATCH] vsock/virtio: free queued packets when closing socket diff --git a/patches.suse/wifi-ath10k-fix-NULL-pointer-dereference-in-ath10k_w.patch b/patches.suse/wifi-ath10k-fix-NULL-pointer-dereference-in-ath10k_w.patch new file mode 100644 index 0000000..95d48b5 --- /dev/null +++ b/patches.suse/wifi-ath10k-fix-NULL-pointer-dereference-in-ath10k_w.patch @@ -0,0 +1,35 @@ +From: Xingyuan Mo +Date: Sun, 17 Dec 2023 13:29:01 +0200 +Subject: wifi: ath10k: fix NULL pointer dereference in + ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev() +Patch-mainline: v6.9-rc1 +Git-commit: ad25ee36f00172f7d53242dc77c69fff7ced0755 +References: bsc#1218336 CVE-2023-7042 + +We should check whether the WMI_TLV_TAG_STRUCT_MGMT_TX_COMPL_EVENT tlv is +present before accessing it, otherwise a null pointer deference error will +occur. + +Fixes: dc405152bb64 ("ath10k: handle mgmt tx completion event") +Signed-off-by: Xingyuan Mo +Acked-by: Jeff Johnson +Signed-off-by: Kalle Valo +Link: https://msgid.link/20231208043433.271449-1-hdthky0@gmail.com +Acked-by: Chun-Yi Lee +--- + drivers/net/wireless/ath/ath10k/wmi-tlv.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c ++++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c +@@ -678,6 +678,10 @@ ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev( + } + + ev = tb[WMI_TLV_TAG_STRUCT_MGMT_TX_COMPL_EVENT]; ++ if (!ev) { ++ kfree(tb); ++ return -EPROTO; ++ } + + arg->desc_id = ev->desc_id; + arg->status = ev->status; diff --git a/patches.suse/x86-CPU-AMD-Update-the-Zenbleed-microcode-revisions.patch b/patches.suse/x86-CPU-AMD-Update-the-Zenbleed-microcode-revisions.patch new file mode 100644 index 0000000..f82fe98 --- /dev/null +++ b/patches.suse/x86-CPU-AMD-Update-the-Zenbleed-microcode-revisions.patch @@ -0,0 +1,40 @@ +From: "Borislav Petkov (AMD)" +Date: Fri, 15 Mar 2024 22:42:27 +0100 +Subject: x86/CPU/AMD: Update the Zenbleed microcode revisions +Git-commit: 5c84b051bd4e777cf37aaff983277e58c99618d5 +Patch-mainline: v6.9-rc1 +References: git-fixes + +Update them to the correct revision numbers. + +Fixes: 522b1d69219d ("x86/cpu/amd: Add a Zenbleed fix") +Signed-off-by: Borislav Petkov (AMD) +Cc: +Signed-off-by: Linus Torvalds +Acked-by: Nikolay Borisov +--- + arch/x86/kernel/cpu/amd.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c +index 3282a747b645..6d8677e80ddb 100644 +--- a/arch/x86/kernel/cpu/amd.c ++++ b/arch/x86/kernel/cpu/amd.c +@@ -864,11 +864,11 @@ static bool cpu_has_zenbleed_microcode(void) + u32 good_rev = 0; + + switch (boot_cpu_data.x86_model) { +- case 0x30 ... 0x3f: good_rev = 0x0830107a; break; +- case 0x60 ... 0x67: good_rev = 0x0860010b; break; +- case 0x68 ... 0x6f: good_rev = 0x08608105; break; +- case 0x70 ... 0x7f: good_rev = 0x08701032; break; +- case 0xa0 ... 0xaf: good_rev = 0x08a00008; break; ++ case 0x30 ... 0x3f: good_rev = 0x0830107b; break; ++ case 0x60 ... 0x67: good_rev = 0x0860010c; break; ++ case 0x68 ... 0x6f: good_rev = 0x08608107; break; ++ case 0x70 ... 0x7f: good_rev = 0x08701033; break; ++ case 0xa0 ... 0xaf: good_rev = 0x08a00009; break; + + default: + return false; + diff --git a/patches.suse/x86-kvm-Disable-kvmclock-on-all-CPUs-on-shutdown.patch b/patches.suse/x86-kvm-Disable-kvmclock-on-all-CPUs-on-shutdown.patch index 0a9df49..ded0b4a 100644 --- a/patches.suse/x86-kvm-Disable-kvmclock-on-all-CPUs-on-shutdown.patch +++ b/patches.suse/x86-kvm-Disable-kvmclock-on-all-CPUs-on-shutdown.patch @@ -3,7 +3,7 @@ Date: Wed, 14 Apr 2021 14:35:42 +0200 Subject: x86/kvm: Disable kvmclock on all CPUs on shutdown Patch-mainline: v5.13-rc2 Git-commit: c02027b5742b5aa804ef08a4a9db433295533046 -References: bsc#1185308 +References: bsc#1185308 CVE-2021-47110 bsc#1221532 Currenly, we disable kvmclock from machine_shutdown() hook and this only happens for boot CPU. We need to disable it for all CPUs to diff --git a/patches.suse/x86-kvm-Teardown-PV-features-on-boot-CPU-as-well.patch b/patches.suse/x86-kvm-Teardown-PV-features-on-boot-CPU-as-well.patch index 8a17302..b891bf9 100644 --- a/patches.suse/x86-kvm-Teardown-PV-features-on-boot-CPU-as-well.patch +++ b/patches.suse/x86-kvm-Teardown-PV-features-on-boot-CPU-as-well.patch @@ -3,7 +3,7 @@ Date: Wed, 14 Apr 2021 14:35:41 +0200 Subject: x86/kvm: Teardown PV features on boot CPU as well Patch-mainline: v5.13-rc2 Git-commit: 8b79feffeca28c5459458fe78676b081e87c93a4 -References: bsc#1185308 +References: bsc#1185308 CVE-2021-47112 bsc#1221541 Various PV features (Async PF, PV EOI, steal time) work through memory shared with hypervisor and when we restore from hibernation we must diff --git a/patches.suse/x86-mmio-Disable-KVM-mitigation-when-X86_FEATURE_CLEAR_CPU.patch b/patches.suse/x86-mmio-Disable-KVM-mitigation-when-X86_FEATURE_CLEAR_CPU.patch new file mode 100644 index 0000000..922591f --- /dev/null +++ b/patches.suse/x86-mmio-Disable-KVM-mitigation-when-X86_FEATURE_CLEAR_CPU.patch @@ -0,0 +1,59 @@ +From: Pawan Gupta +Date: Mon, 11 Mar 2024 12:29:43 -0700 +Subject: x86/mmio: Disable KVM mitigation when X86_FEATURE_CLEAR_CPU_BUF is + set +Git-commit: e95df4ec0c0c9791941f112db699fae794b9862a +Patch-mainline: v6.9-rc1 +References: bsc#1213456 CVE-2023-28746 + +Currently MMIO Stale Data mitigation for CPUs not affected by MDS/TAA is +to only deploy VERW at VMentry by enabling mmio_stale_data_clear static +branch. No mitigation is needed for kernel->user transitions. If such +CPUs are also affected by RFDS, its mitigation may set +X86_FEATURE_CLEAR_CPU_BUF to deploy VERW at kernel->user and VMentry. +This could result in duplicate VERW at VMentry. + +Fix this by disabling mmio_stale_data_clear static branch when +X86_FEATURE_CLEAR_CPU_BUF is enabled. + +Signed-off-by: Pawan Gupta +Signed-off-by: Dave Hansen +Reviewed-by: Dave Hansen +Acked-by: Nikolay Borisov +--- + arch/x86/kernel/cpu/bugs.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c +index 48d049cd74e7..cd6ac89c1a0d 100644 +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -422,6 +422,13 @@ static void __init mmio_select_mitigation(void) + if (boot_cpu_has_bug(X86_BUG_MDS) || (boot_cpu_has_bug(X86_BUG_TAA) && + boot_cpu_has(X86_FEATURE_RTM))) + setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF); ++ ++ /* ++ * X86_FEATURE_CLEAR_CPU_BUF could be enabled by other VERW based ++ * mitigations, disable KVM-only mitigation in that case. ++ */ ++ if (boot_cpu_has(X86_FEATURE_CLEAR_CPU_BUF)) ++ static_branch_disable(&mmio_stale_data_clear); + else + static_branch_enable(&mmio_stale_data_clear); + +@@ -498,8 +505,11 @@ static void __init md_clear_update_mitigation(void) + taa_mitigation = TAA_MITIGATION_VERW; + taa_select_mitigation(); + } +- if (mmio_mitigation == MMIO_MITIGATION_OFF && +- boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) { ++ /* ++ * MMIO_MITIGATION_OFF is not checked here so that mmio_stale_data_clear ++ * gets updated correctly as per X86_FEATURE_CLEAR_CPU_BUF state. ++ */ ++ if (boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) { + mmio_mitigation = MMIO_MITIGATION_VERW; + mmio_select_mitigation(); + } + diff --git a/patches.suse/x86-rfds-Mitigate-Register-File-Data-Sampling-RFDS.patch b/patches.suse/x86-rfds-Mitigate-Register-File-Data-Sampling-RFDS.patch index 5f4751a..98abad8 100644 --- a/patches.suse/x86-rfds-Mitigate-Register-File-Data-Sampling-RFDS.patch +++ b/patches.suse/x86-rfds-Mitigate-Register-File-Data-Sampling-RFDS.patch @@ -1,7 +1,8 @@ From: Pawan Gupta Date: Tue, 5 Mar 2024 15:21:53 +0200 Subject: x86/rfds: Mitigate Register File Data Sampling (RFDS) -Patch-mainline: Not yet, embargo +Git-commit: 8076fcde016c9c0e0660543e67bff86cb48a7c9c +Patch-mainline: v6.9-rc1 References: bsc#1213456 CVE-2023-28746 RFDS is a CPU vulnerability that may allow userspace to infer kernel @@ -24,15 +25,15 @@ Acked-by: Josh Poimboeuf Signed-off-by: Pawan Gupta Acked-by: Nikolay Borisov --- - Documentation/ABI/testing/sysfs-devices-system-cpu | 2 + Documentation/ABI/testing/sysfs-devices-system-cpu | 2 Documentation/admin-guide/kernel-parameters.txt | 21 +++++ arch/x86/Kconfig | 12 +++ - arch/x86/include/asm/cpufeatures.h | 1 + arch/x86/include/asm/cpufeatures.h | 1 arch/x86/include/asm/msr-index.h | 8 ++ arch/x86/kernel/cpu/bugs.c | 80 ++++++++++++++++++++- arch/x86/kernel/cpu/common.c | 31 +++++++- drivers/base/cpu.c | 8 ++ - include/linux/cpu.h | 2 + include/linux/cpu.h | 2 9 files changed, 161 insertions(+), 4 deletions(-) --- a/Documentation/ABI/testing/sysfs-devices-system-cpu @@ -51,7 +52,7 @@ Acked-by: Nikolay Borisov @@ -2478,6 +2478,26 @@ in the "bleeding edge" mini2440 support kernel at http://repo.or.cz/w/linux-2.6/mini2440.git - + + reg_file_data_sampling= + [X86] Controls mitigation for Register File Data + Sampling (RFDS) vulnerability. RFDS is a CPU @@ -86,9 +87,9 @@ Acked-by: Nikolay Borisov --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2400,6 +2400,18 @@ source "kernel/livepatch/Kconfig" - + endmenu - + +config MITIGATION_RFDS + bool "RFDS Mitigation" + depends on CPU_SUP_INTEL @@ -107,12 +108,12 @@ Acked-by: Nikolay Borisov --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -430,6 +430,7 @@ - + /* First extended bug word */ #define X86_BUG_DIV0 X86_BUG(1*32 + 0) /* AMD DIV0 speculation bug */ +#define X86_BUG_RFDS X86_BUG(1*32 + 1) /* CPU is vulnerable to Register File Data Sampling */ - - + + #endif /* _ASM_X86_CPUFEATURES_H */ --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -128,14 +129,14 @@ Acked-by: Nikolay Borisov + * VERW clears CPU Register + * File. + */ - + #define MSR_IA32_BBL_CR_CTL 0x00000119 #define MSR_IA32_BBL_CR_CTL3 0x0000011e --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -493,6 +493,58 @@ static int __init mmio_stale_data_parse_ early_param("mmio_stale_data", mmio_stale_data_parse_cmdline); - + #undef pr_fmt +#define pr_fmt(fmt) "Register File Data Sampling: " fmt + @@ -190,7 +191,7 @@ Acked-by: Nikolay Borisov + +#undef pr_fmt #define pr_fmt(fmt) "" fmt - + static void __init md_clear_update_mitigation(void) @@ -522,6 +574,11 @@ static void __init md_clear_update_mitig mmio_mitigation = MMIO_MITIGATION_VERW; @@ -211,14 +212,14 @@ Acked-by: Nikolay Borisov + if (boot_cpu_has_bug(X86_BUG_RFDS)) + pr_info("Register File Data Sampling: %s\n", rfds_strings[rfds_mitigation]); } - + static void __init md_clear_select_mitigation(void) @@ -538,11 +597,12 @@ static void __init md_clear_select_mitig mds_select_mitigation(); taa_select_mitigation(); mmio_select_mitigation(); + rfds_select_mitigation(); - + /* - * As MDS, TAA and MMIO Stale Data mitigations are inter-related, update - * and print their mitigation after MDS, TAA and MMIO Stale Data @@ -232,7 +233,7 @@ Acked-by: Nikolay Borisov @@ -2485,6 +2545,11 @@ static ssize_t mmio_stale_data_show_stat sched_smt_active() ? "vulnerable" : "disabled"); } - + +static ssize_t rfds_show_state(char *buf) +{ + return sysfs_emit(buf, "%s\n", rfds_strings[rfds_mitigation]); @@ -244,7 +245,7 @@ Acked-by: Nikolay Borisov @@ -2648,6 +2713,10 @@ static ssize_t cpu_show_common(struct de case X86_BUG_GDS: return gds_show_state(buf); - + + case X86_BUG_RFDS: + return rfds_show_state(buf); + @@ -270,7 +271,7 @@ Acked-by: Nikolay Borisov #define GDS BIT(5) +/* CPU is affected by Register File Data Sampling */ +#define RFDS BIT(6) - + static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { VULNBL_INTEL_STEPPINGS(IVYBRIDGE, X86_STEPPING_ANY, SRBDS), @@ -1045,7 +1047,12 @@ static const struct x86_cpu_id cpu_vuln_ @@ -284,13 +285,13 @@ Acked-by: Nikolay Borisov + VULNBL_INTEL_STEPPINGS(ATOM_GOLDMONT, X86_STEPPING_ANY, RFDS), + VULNBL_INTEL_STEPPINGS(ATOM_GOLDMONT_D, X86_STEPPING_ANY, RFDS), + VULNBL_INTEL_STEPPINGS(ATOM_GOLDMONT_PLUS, X86_STEPPING_ANY, RFDS), - + VULNBL_AMD(0x15, RETBLEED), VULNBL_AMD(0x16, RETBLEED), @@ -1079,6 +1086,25 @@ static bool arch_cap_mmio_immune(u64 ia3 ia32_cap & ARCH_CAP_SBDR_SSDP_NO); } - + +static bool __init vulnerable_to_rfds(u64 ia32_cap) +{ + /* The "immunity" bit trumps everything else: */ @@ -316,19 +317,19 @@ Acked-by: Nikolay Borisov @@ -1182,6 +1208,9 @@ static void __init cpu_set_bug_bits(stru boot_cpu_has(X86_FEATURE_AVX)) setup_force_cpu_bug(X86_BUG_GDS); - + + if (vulnerable_to_rfds(ia32_cap)) + setup_force_cpu_bug(X86_BUG_RFDS); + if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) return; - + --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -575,6 +575,12 @@ ssize_t __weak cpu_show_gds(struct devic return sysfs_emit(buf, "Not affected\n"); } - + +ssize_t __weak cpu_show_reg_file_data_sampling(struct device *dev, + struct device_attribute *attr, char *buf) +{ @@ -343,7 +344,7 @@ Acked-by: Nikolay Borisov static DEVICE_ATTR(spec_rstack_overflow, 0444, cpu_show_spec_rstack_overflow, NULL); static DEVICE_ATTR(gather_data_sampling, 0444, cpu_show_gds, NULL); +static DEVICE_ATTR(reg_file_data_sampling, 0444, cpu_show_reg_file_data_sampling, NULL); - + static struct attribute *cpu_root_vulnerabilities_attrs[] = { &dev_attr_meltdown.attr, @@ -603,6 +610,7 @@ static struct attribute *cpu_root_vulner @@ -353,7 +354,7 @@ Acked-by: Nikolay Borisov + &dev_attr_reg_file_data_sampling.attr, NULL }; - + --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -73,6 +73,8 @@ extern ssize_t cpu_show_spec_rstack_over @@ -362,6 +363,6 @@ Acked-by: Nikolay Borisov struct device_attribute *attr, char *buf); +extern ssize_t cpu_show_reg_file_data_sampling(struct device *dev, + struct device_attribute *attr, char *buf); - + extern __printf(4, 5) struct device *cpu_device_create(struct device *parent, void *drvdata, diff --git a/patches.suse/x86-srso-fix-sbpb-enablement-for-spec_rstack_overflow-off.patch b/patches.suse/x86-srso-fix-sbpb-enablement-for-spec_rstack_overflow-off.patch index 79e1d63..e2b76d8 100644 --- a/patches.suse/x86-srso-fix-sbpb-enablement-for-spec_rstack_overflow-off.patch +++ b/patches.suse/x86-srso-fix-sbpb-enablement-for-spec_rstack_overflow-off.patch @@ -3,7 +3,7 @@ Date: Mon, 4 Sep 2023 22:04:48 -0700 Subject: x86/srso: Fix SBPB enablement for spec_rstack_overflow=off Git-commit: 01b057b2f4cc2d905a0bd92195657dbd9a7005ab Patch-mainline: v6.6-rc3 -References: git-fixes +References: git-fixes CVE-2023-52575 bsc#1220871 If the user has requested no SRSO mitigation, other mitigations can use the lighter-weight SBPB instead of IBPB. diff --git a/rpm/dtb.spec.in.in b/rpm/dtb.spec.in.in index 569936e..279536a 100644 --- a/rpm/dtb.spec.in.in +++ b/rpm/dtb.spec.in.in @@ -35,16 +35,19 @@ Summary: Device Tree files for $MACHINES License: GPL-2.0-only Group: System/Boot URL: https://www.kernel.org/ +BuildRequires: cpp +BuildRequires: dtc >= 1.4.3 +BuildRequires: xz %if ! 0%{?is_kotd} || ! %{?is_kotd_qa}%{!?is_kotd_qa:0} $ARCH_RESTRICTIONS %else ExclusiveArch: do_not_build %endif -BuildRequires: cpp -BuildRequires: dtc >= 1.4.3 -BuildRequires: xz -Requires: kernel = %version + +%define dtbdir /boot/dtb-%kernelrelease + @SOURCES@ +Requires: kernel = %version %description Device Tree files for $MACHINES. @@ -57,7 +60,6 @@ $SUBPKG_DESC cd linux-%srcversion %_sourcedir/apply-patches %_sourcedir/series.conf .. - %build source=linux-%srcversion cp $source/COPYING . @@ -75,10 +77,7 @@ for dts in $ALL_SUPPORTED_DTB; do dtc $DTC_FLAGS -I dts -O dtb -i ./$(dirname $target) -o $PPDIR/$target.dtb $PPDIR/$target.dts done -%define dtbdir /boot/dtb-%kernelrelease - %install - cd pp for dts in $ALL_SUPPORTED_DTB; do target=${dts%*.dts} @@ -95,6 +94,4 @@ for dts in $ALL_SUPPORTED_DTB; do done cd - -$SUBPKG_POST -$SUBPKG_FILES %changelog diff --git a/rpm/group-source-files.pl b/rpm/group-source-files.pl index 3a8aa85..4b0f6a4 100755 --- a/rpm/group-source-files.pl +++ b/rpm/group-source-files.pl @@ -19,6 +19,12 @@ sub main &output($dev, $ndev, $dev_output, $ndev_output); } +sub rpm_quote_filename +{ + # technically should also quote % -> %% " -> \" \ -> \\ + return map { "\"$_\"" } @_; +} + sub scan { # Normalize file path, mainly to strip away the ending forward slash, @@ -53,8 +59,14 @@ sub scan $is_devel ? push(@dev, $abs_path) : push(@ndev, $abs_path); } - push(@dev, &calc_dirs($abs_loc, \@dev)); - push(@ndev, &calc_dirs($abs_loc, \@ndev)); + my @dev_dirs = calc_dirs($abs_loc, \@dev); + my @ndev_dirs = calc_dirs($abs_loc, \@ndev); + @dev = rpm_quote_filename(@dev); + @ndev = rpm_quote_filename(@ndev); + @dev_dirs = map { "\%dir $_" } rpm_quote_filename(@dev_dirs); + @ndev_dirs = map { "\%dir $_" } rpm_quote_filename(@ndev_dirs); + push(@dev, @dev_dirs); + push(@ndev, @ndev_dirs); return (\@dev, \@ndev); } @@ -75,7 +87,7 @@ sub calc_dirs # This loop also makes sure that $base itself is included. } - return map { "\%dir $_" } keys %dirs; + return keys %dirs; } sub output diff --git a/rpm/kernel-binary.spec.in b/rpm/kernel-binary.spec.in index 43f2c59..328906a 100644 --- a/rpm/kernel-binary.spec.in +++ b/rpm/kernel-binary.spec.in @@ -29,96 +29,22 @@ %define split_base @SPLIT_BASE@ %define split_optional @SPLIT_OPTIONAL@ %define supported_modules_check @SUPPORTED_MODULES_CHECK@ +%define build_flavor @FLAVOR@ %include %_sourcedir/kernel-spec-macros -%define build_flavor @FLAVOR@ -%define build_default ("%build_flavor" == "default") -%define build_vanilla ("%build_flavor" == "vanilla") -%define vanilla_only %{lua: if (rpm.expand("%variant") == "-vanilla") then print(1) else print(0) end} - -%if ! %build_vanilla -%define src_install_dir /usr/src/linux-%kernelrelease%variant -%else -%define src_install_dir /usr/src/linux-%kernelrelease-vanilla -%endif -%define obj_install_dir /usr/src/linux-%kernelrelease%variant-obj -%define rpm_install_dir %buildroot%obj_install_dir -%define kernel_build_dir %my_builddir/linux-%srcversion/linux-obj - -%if 0%{?_project:1} && ( %(echo %_project | grep -Ex -f %_sourcedir/release-projects | grep -v ^PTF | grep -vc openSUSE) || %(echo %_project | grep -Ec "^(Devel:)?Kernel:") ) - %define klp_symbols 1 -%endif - %(chmod +x %_sourcedir/{@SCRIPTS@}) -%global cpu_arch %(%_sourcedir/arch-symbols %_target_cpu) -%define cpu_arch_flavor %cpu_arch/%build_flavor - -%global certs %( for f in %_sourcedir/*.crt; do \ - if ! test -e "$f"; then \ - continue \ - fi \ - h=$(openssl x509 -inform PEM -fingerprint -noout -in "$f") \ - if [ -z "$h" ] ; then \ - echo Cannot parse "$f" >&2 \ - confinue \ - fi \ - cert=$(echo "$h" | sed -rn 's/^SHA1 Fingerprint=//; T; s/://g; s/(.{8}).*/\\1/p') \ - echo Found signing certificate "$f" "($cert)" >&2 \ - cat "$f" >>%_sourcedir/.kernel_signing_key.pem \ - mkdir -p %_sourcedir/.kernel_signing_certs \ - openssl x509 -inform PEM -in "$f" -outform DER -out %_sourcedir/.kernel_signing_certs/"$cert".crt \ - echo -n "$cert" "" \ -done ) - -%ifarch %ix86 x86_64 -%define image vmlinuz -%endif -%ifarch ppc ppc64 ppc64le -%define image vmlinux -%endif -%ifarch s390 s390x -%define image image -%endif -%ifarch %arm -%define image zImage -%endif -%ifarch aarch64 riscv64 -%define image Image -%endif - -# Define some CONFIG variables as rpm macros as well. (rpm cannot handle -# defining them all at once.) -%define config_vars CONFIG_MODULES CONFIG_MODULE_SIG CONFIG_MODULE_SIG_HASH CONFIG_KMSG_IDS CONFIG_SUSE_KERNEL_SUPPORTED CONFIG_EFI_STUB CONFIG_LIVEPATCH_IPA_CLONES CONFIG_DEBUG_INFO_BTF_MODULES CONFIG_PREEMPT_DYNAMIC -%{expand:%(eval "$(test -n "%cpu_arch_flavor" && tar -xjf %_sourcedir/config.tar.bz2 --to-stdout config/%cpu_arch_flavor)"; for config in %config_vars; do echo "%%global $config ${!config:-n}"; done)} -%define split_extra ("%CONFIG_MODULES" == "y" && "%CONFIG_SUSE_KERNEL_SUPPORTED" == "y") - -%if "%CONFIG_MODULES" != "y" - %define klp_symbols 0 -%endif - -%ifarch %ix86 x86_64 -%define install_vdso 1 -%if 0%{?suse_version} > 1500 || 0%{?sle_version} >= 150500 -%define separate_vdso 1 -%endif -%else -%define install_vdso 0 -%endif - -%define modules_dir %kernel_module_directory/%kernelrelease-%build_flavor - Name: kernel-@FLAVOR@ -Summary: @SUMMARY@ -License: GPL-2.0-only -Group: System/Kernel Version: @RPMVERSION@ %if 0%{?is_kotd} Release: .g@COMMIT@ %else Release: @RELEASE@ %endif +Summary: @SUMMARY@ +License: GPL-2.0-only +Group: System/Kernel URL: https://www.kernel.org/ %if 0%{?suse_version} > 1500 || 0%{?sle_version} > 150300 BuildRequires: bash-sh @@ -159,19 +85,93 @@ BuildRequires: u-boot-tools # Remove some packages that are installed automatically by the build system, # but are not needed to build the kernel #!BuildIgnore: autoconf automake gettext-runtime libtool cvs gettext-tools udev insserv -@SOURCES@ %if ! 0%{?is_kotd} || ! %{?is_kotd_qa}%{!?is_kotd_qa:0} ExclusiveArch: @ARCHS@ %else ExclusiveArch: do_not_build %endif + +%ifarch %ix86 x86_64 +%define image vmlinuz +%endif +%ifarch ppc ppc64 ppc64le +%define image vmlinux +%endif +%ifarch s390 s390x +%define image image +%endif +%ifarch %arm +%define image zImage +%endif +%ifarch aarch64 riscv64 +%define image Image +%endif + +%ifarch %ix86 x86_64 +%define install_vdso 1 +%if 0%{?suse_version} > 1500 || 0%{?sle_version} >= 150500 +%define separate_vdso 1 +%endif +%else +%define install_vdso 0 +%endif + +%define build_default ("%build_flavor" == "default") +%define build_vanilla ("%build_flavor" == "vanilla") +%define vanilla_only %{lua: if (rpm.expand("%variant") == "-vanilla") then print(1) else print(0) end} + +%if ! %build_vanilla +%define src_install_dir /usr/src/linux-%kernelrelease%variant +%else +%define src_install_dir /usr/src/linux-%kernelrelease-vanilla +%endif +%define obj_install_dir /usr/src/linux-%kernelrelease%variant-obj +%define rpm_install_dir %buildroot%obj_install_dir +%define kernel_build_dir %my_builddir/linux-%srcversion/linux-obj +%define modules_dir %kernel_module_directory/%kernelrelease-%build_flavor + +%global cpu_arch %(%_sourcedir/arch-symbols %_target_cpu) +%define cpu_arch_flavor %cpu_arch/%build_flavor + +%if 0%{?_project:1} && ( %(echo %_project | grep -Ex -f %_sourcedir/release-projects | grep -v ^PTF | grep -vc openSUSE) || %(echo %_project | grep -Ec "^(Devel:)?Kernel:") ) + %define klp_symbols 1 +%endif + +# Define some CONFIG variables as rpm macros as well. (rpm cannot handle +# defining them all at once.) +%define config_vars CONFIG_MODULES CONFIG_MODULE_SIG CONFIG_MODULE_SIG_HASH CONFIG_KMSG_IDS CONFIG_SUSE_KERNEL_SUPPORTED CONFIG_EFI_STUB CONFIG_LIVEPATCH_IPA_CLONES CONFIG_DEBUG_INFO_BTF_MODULES CONFIG_PREEMPT_DYNAMIC +%{expand:%(eval "$(test -n "%cpu_arch_flavor" && tar -xjf %_sourcedir/config.tar.bz2 --to-stdout config/%cpu_arch_flavor)"; for config in %config_vars; do echo "%%global $config ${!config:-n}"; done)} +%define split_extra ("%CONFIG_MODULES" == "y" && "%CONFIG_SUSE_KERNEL_SUPPORTED" == "y") + +%if "%CONFIG_MODULES" != "y" + %define klp_symbols 0 +%endif + +%global certs %( space="" ; for f in %_sourcedir/*.crt; do \ + if ! test -e "$f"; then \ + continue \ + fi \ + h=$(openssl x509 -inform PEM -fingerprint -noout -in "$f") \ + if [ -z "$h" ] ; then \ + echo Cannot parse "$f" >&2 \ + confinue \ + fi \ + cert=$(echo "$h" | sed -rn 's/^SHA1 Fingerprint=//; T; s/://g; s/(.{8}).*/\\1/p') \ + echo Found signing certificate "$f" "($cert)" >&2 \ + cat "$f" >>%_sourcedir/.kernel_signing_key.pem \ + mkdir -p %_sourcedir/.kernel_signing_certs \ + openssl x509 -inform PEM -in "$f" -outform DER -out %_sourcedir/.kernel_signing_certs/"$cert".crt \ + echo -n "$space$cert" ; space=" " \ +done ) + +@SOURCES@ + %ifarch %ix86 # Only i386/default supports i586, mark other flavors' packages as i686 %if ! %build_default BuildArch: i686 %endif %endif - # Force bzip2 instead of lzma compression to # 1) allow install on older dist versions, and # 2) decrease build times (bsc#962356 boo#1175882) @@ -229,7 +229,7 @@ Requires(post): dracut # the grub entry has correct title (bnc#757565) Requires(post): distribution-release -%if 0%{?usrmerged} +%if %{usrmerged} # make sure we have a post-usrmerge system Conflicts: filesystem < 16 %endif @@ -296,1241 +296,1242 @@ Provides: kernel-preempt_%_target_cpu = %version-%source_rel %source_timestamp -%prep -if ! [ -e %{S:0} ]; then - echo "The %name-%version.nosrc.rpm package does not contain the" \ - "complete sources. Please install kernel-source-%version.src.rpm." - exit 1 -fi -SYMBOLS= -if test -e %_sourcedir/extra-symbols; then - SYMBOLS=$(cat %_sourcedir/extra-symbols) - echo "extra symbol(s):" $SYMBOLS -fi - -# Unpack all sources and patches -%setup -q -c -T -a 0 @UNPACK_PATCHES@ - -mkdir -p %kernel_build_dir - -# Generate a list of modules with their support status marking -# The first marker is supposed to be either "+external", "-" or "-!optional", -# where "+external" is for an externally supported module, "-" is for an -# unsuppored module, "-!optional" is for Leap-only unsupported module. -# There can be an optional arch-specific second marker with "+arch" (e.g. -# +arm64), which enforces the module to be supported on the specific arch. -%_sourcedir/guards --list --with-guards <%_sourcedir/supported.conf | \ -awk '{ - t = ""; - for (i = 1; i < NF; i++) { - if ($i == "+external") { - t = " external"; - } else if ($i == "+'%cpu_arch'") { - t = ""; - } else if ($i ~ "^-") { - t = " no"; - } - } - print $(NF) t; -}' >%kernel_build_dir/Module.supported -subpackages=( - base -%if "%CONFIG_SUSE_KERNEL_SUPPORTED" == "y" - @KMPS@ +%pre +%if "%build_flavor" != "zfcpdump" +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/rpm-pre --name "%name" \ + --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ + --image "%image" --flavor "%build_flavor" --variant "%variant" \ + --usrmerged "%{usrmerged}" --certs "%certs" "$@" %endif -) -for package in "${subpackages[@]}"; do - %_sourcedir/guards --default=0 "$package" \ - <%_sourcedir/supported.conf | sed 's,.*/,,; s,\.ko$,,' | \ - sort -u >%kernel_build_dir/Module."$package" -done -%if %split_extra && %split_optional -# Module.optional is in a special form, containing guard markers for -# both extra and optional modules, which is processed by split-modules -%_sourcedir/guards --list --with-guards <%_sourcedir/supported.conf | \ -awk '{ - t = ""; - for (i = 1; i < NF; i++) { - if ($i == "+'%cpu_arch'") { - t = ""; - } else if ($i ~ "^-") { - t = $i - } - } - if (t != "") {print t,$(NF);} -}' >%kernel_build_dir/Module.optional +%post +%if "%build_flavor" != "zfcpdump" +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/rpm-post --name "%name" \ + --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ + --image "%image" --flavor "%build_flavor" --variant "%variant" \ + --usrmerged "%{usrmerged}" --certs "%certs" "$@" %endif - -cd linux-%srcversion - -%_sourcedir/apply-patches \ -%if %{build_vanilla} && ! %vanilla_only - --vanilla \ +%preun +%if "%build_flavor" != "zfcpdump" +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/rpm-preun --name "%name" \ + --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ + --image "%image" --flavor "%build_flavor" --variant "%variant" \ + --usrmerged "%{usrmerged}" --certs "%certs" "$@" %endif - %_sourcedir/series.conf .. $SYMBOLS - -cd %kernel_build_dir +%postun +%if "%build_flavor" != "zfcpdump" +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/rpm-postun --name "%name" \ + --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ + --image "%image" --flavor "%build_flavor" --variant "%variant" \ + --usrmerged "%{usrmerged}" --certs "%certs" "$@" +%endif +%posttrans +%if "%build_flavor" != "zfcpdump" +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/rpm-posttrans --name "%name" \ + --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ + --image "%image" --flavor "%build_flavor" --variant "%variant" \ + --usrmerged "%{usrmerged}" --certs "%certs" "$@" +%endif +%files -f kernel-main.files -# Override the timestamp 'uname -v' reports with the source timestamp and -# the commit hash. -date=$(head -n 1 %_sourcedir/source-timestamp) -commit=$(sed -n 's/GIT Revision: //p' %_sourcedir/source-timestamp) -cat > .kernel-binary.spec.buildenv < localversion -fi - -config_base="default" +%if "%CONFIG_MODULES" == "y" && %split_base +%package base +Summary: @SUMMARY@ - base modules +Group: System/Kernel +Url: http://www.kernel.org/ +Provides: kernel-base = %version-%source_rel +Provides: multiversion(kernel) +Conflicts: %name = %version-%source_rel +@COMMON_DEPS@ +@PROVIDES_OBSOLETES_BASE@ +%obsolete_rebuilds %name-base %ifarch %ix86 -config_base="pae" +Conflicts: libc.so.6()(64bit) %endif -if ! [ -f %my_builddir/config/%cpu_arch/$config_base ] ; then - config_base=%variant - config_base=${config_base#-} -fi -if ! grep -q CONFIG_MMU= "%my_builddir/config/%cpu_arch_flavor"; then -cp "%my_builddir/config/%cpu_arch/$config_base" .config -../scripts/kconfig/merge_config.sh -m .config \ - %my_builddir/config/%cpu_arch_flavor -else -cp %my_builddir/config/%cpu_arch_flavor .config -fi -if test -e %my_builddir/config.addon/%cpu_arch_flavor; then - # FIXME: config.addon doesn't affect the %CONFIG_ macros defined at - # the top of the specfile - ../scripts/kconfig/merge_config.sh -m .config %my_builddir/config.addon/%cpu_arch_flavor -fi -CONFIG_SUSE_KERNEL_RELEASED="--disable CONFIG_SUSE_KERNEL_RELEASED" -%if 0%{?_project:1} -if echo %_project | grep -Eqx -f %_sourcedir/release-projects; then - CONFIG_SUSE_KERNEL_RELEASED="--enable CONFIG_SUSE_KERNEL_RELEASED" -fi -%endif +%description base +@DESCRIPTION@ -DEBUG_INFO_TYPE="$(grep "CONFIG_DEBUG_INFO_DWARF.*=y" .config)" -DEBUG_INFO_TYPE="${DEBUG_INFO_TYPE%%=y}" -DEBUG_INFO_TYPE="${DEBUG_INFO_TYPE##CONFIG_DEBUG_INFO_}" -echo "Kernel debuginfo type: ${DEBUG_INFO_TYPE}" +This package contains only the base modules, required in all installs. -../scripts/config \ - --set-str CONFIG_LOCALVERSION -%source_rel-%build_flavor \ - --enable CONFIG_SUSE_KERNEL \ - $CONFIG_SUSE_KERNEL_RELEASED \ -%if 0%{?__debug_package:1} - --enable CONFIG_DEBUG_INFO -%else - --disable CONFIG_DEBUG_INFO \ - --disable CONFIG_DEBUG_INFO_"${DEBUG_INFO_TYPE}" \ - --enable CONFIG_DEBUG_INFO_NONE -%endif -if [ %CONFIG_MODULE_SIG = "y" ]; then - if [ -n "%certs" ] ; then - ln -s %_sourcedir/.kernel_signing_key.pem . - else - if ! [ -f .kernel.genkey ] ; then - cat > .kernel.genkey </dev/null 2>&1 ; then - makeoutputsync=--output-sync -else - echo make does not support --output-sync flag. Build messages may be mangled. 1>&2 -fi -MAKE_ARGS="$MAKE_ARGS $makeoutputsync %{?_smp_mflags}" -echo export MAKE_ARGS=\""$MAKE_ARGS"\" >> .kernel-binary.spec.buildenv +%posttrans base +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/rpm-posttrans --name "%name-base" \ + --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ + --image "%image" --flavor "%build_flavor" --variant "%variant" \ + --usrmerged "%{usrmerged}" --certs "%certs" "$@" -KERN_DIRS="-C .. O=$PWD" -if test -e %_sourcedir/TOLERATE-UNKNOWN-NEW-CONFIG-OPTIONS; then - yes '' | make oldconfig $MAKE_ARGS $KERN_DIRS -else - cp .config .config.orig - if test -f ../scripts/kconfig/Makefile && \ - grep -q syncconfig ../scripts/kconfig/Makefile; then - syncconfig="syncconfig" - else - syncconfig="silentoldconfig" - fi - make $syncconfig $MAKE_ARGS $KERN_DIRS < /dev/null - %_sourcedir/check-for-config-changes .config.orig .config - rm .config.orig -fi +%files base -f kernel-base.files +%endif -make prepare $MAKE_ARGS -make scripts $MAKE_ARGS -krel=$(make -s kernelrelease $MAKE_ARGS) +%package extra +Summary: @SUMMARY@ - Unsupported kernel modules +Group: System/Kernel +URL: https://www.kernel.org/ +Provides: %name-extra_%_target_cpu = %version-%source_rel +Provides: kernel-extra = %version-%source_rel +Provides: multiversion(kernel) +Requires: %{name}_%_target_cpu = %version-%source_rel +Requires(pre): coreutils awk +Requires(post): modutils +Requires(post): perl-Bootloader +Requires(post): dracut +@PROVIDES_OBSOLETES_EXTRA@ +%obsolete_rebuilds %name-extra +Supplements: packageand(product(SLED):%{name}_%_target_cpu) +Supplements: packageand(product(sle-we):%{name}_%_target_cpu) +Supplements: packageand(product(Leap):%{name}_%_target_cpu) +%ifarch %ix86 +Conflicts: libc.so.6()(64bit) +%endif +%if %build_default +%if "%CONFIG_PREEMPT_DYNAMIC" == "y" +Provides: kernel-preempt-extra = %version-%release +Provides: kernel-preempt-extra_%_target_cpu = %version-%source_rel +%endif +%endif -if [ "$krel" != "%kernelrelease-%build_flavor" ]; then - echo "Kernel release mismatch: $krel != %kernelrelease-%build_flavor" >&2 - exit 1 -fi +%description extra +@DESCRIPTION@ -make clean $MAKE_ARGS +This package contains additional modules not supported by SUSE. -rm -f source -find . ! -type d ! -name 'Module.base' ! -name 'Module.*-kmp' ! -name 'Module.optional' -printf '%%P\n' \ - > %my_builddir/obj-files -%build -cd %kernel_build_dir -source .kernel-binary.spec.buildenv +%source_timestamp -# create *.symref files in the tree -if test -e %my_builddir/kabi/%cpu_arch/symtypes-%build_flavor; then - %_sourcedir/modversions --unpack . < $_ -fi +%pre extra +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-pre --name "%name-extra" \ + --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ + --image "%image" --flavor "%build_flavor" --variant "%variant" \ + --usrmerged "%{usrmerged}" --certs "%certs" "$@" -%if "%CONFIG_KMSG_IDS" == "y" - chmod +x ../scripts/kmsg-doc - MAKE_ARGS="$MAKE_ARGS D=2" -%endif +%post extra +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-post --name "%name-extra" \ + --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ + --image "%image" --flavor "%build_flavor" --variant "%variant" \ + --usrmerged "%{usrmerged}" --certs "%certs" "$@" -mkdir -p %_topdir/OTHER -log=%_topdir/OTHER/make-stderr.log -while true; do - make all $MAKE_ARGS 2> >(tee "$log") - if test "${PIPESTATUS[0]}" -eq 0; then - break - fi - # In the linux-next and vanilla branches, we try harder to build a - # package. - if test 0%vanilla_only -gt 0 && - %_sourcedir/try-disable-staging-driver "$log"; then - echo "Retrying make" - else - exit 1 - fi -done +%preun extra +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-preun --name "%name-extra" \ + --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ + --image "%image" --flavor "%build_flavor" --variant "%variant" \ + --usrmerged "%{usrmerged}" --certs "%certs" "$@" -# Generate list of symbols that are used to create kernel livepatches -%if 0%{?klp_symbols} - %_sourcedir/klp-symbols . Symbols.list -%endif +%postun extra +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-postun --name "%name-extra" \ + --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ + --image "%image" --flavor "%build_flavor" --variant "%variant" \ + --usrmerged "%{usrmerged}" --certs "%certs" "$@" -%install - -# get rid of /usr/lib/rpm/brp-strip-debug -# strip removes too much from the vmlinux ELF binary -export NO_BRP_STRIP_DEBUG=true -export STRIP_KEEP_SYMTAB='*/vmlinux*' - -# %kernel_module_directory/%kernelrelease-%build_flavor/source points to the source -# directory installed by kernel-devel. The kernel-%build_flavor-devel package -# has a correct dependency on kernel-devel, but the brp check does not see -# kernel-devel during build. -export NO_BRP_STALE_LINK_ERROR=yes - -cd %kernel_build_dir -source .kernel-binary.spec.buildenv - -mkdir -p %buildroot/boot -# (Could strip out non-public symbols.) -cp -p System.map %buildroot/boot/System.map-%kernelrelease-%build_flavor - -add_vmlinux() -{ - local vmlinux=boot/vmlinux-%kernelrelease-%build_flavor +%posttrans extra +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-posttrans --name "%name-extra" \ + --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ + --image "%image" --flavor "%build_flavor" --variant "%variant" \ + --usrmerged "%{usrmerged}" --certs "%certs" "$@" - cp vmlinux %buildroot/$vmlinux - # make sure that find-debuginfo.sh picks it up. In the filelist, we - # mark the file 0644 again - chmod +x %buildroot/$vmlinux - if test $1 == "--compressed"; then - # avoid using the gzip -n option to make kdump happy (bnc#880848#c20) - ts="$(head -n1 %_sourcedir/source-timestamp)" - touch -d "$ts" %buildroot/$vmlinux - touch %buildroot/$vmlinux.%{compress_vmlinux} -%if 0%{?__debug_package:1} - # compress the vmlinux image after find-debuginfo.sh has processed it -%global __debug_install_post %__debug_install_post \ -%_sourcedir/compress-vmlinux.sh %buildroot/boot/vmlinux-%kernelrelease-%build_flavor -%else - %_sourcedir/compress-vmlinux.sh %buildroot/$vmlinux -%endif - ghost_vmlinux=true - else - ghost_vmlinux=false - fi -} +%if %split_extra -# architecture specifics -%ifarch %ix86 x86_64 - add_vmlinux --compressed - cp -p arch/x86/boot/bzImage %buildroot/boot/%image-%kernelrelease-%build_flavor -%endif -%ifarch ppc ppc64 ppc64le - add_vmlinux -%endif -%ifarch s390 s390x - add_vmlinux --compressed - image=image - if test ! -f arch/s390/boot/$image; then - image=bzImage - fi - cp -p arch/s390/boot/$image %buildroot/boot/%image-%kernelrelease-%build_flavor -%if "%CONFIG_KMSG_IDS" == "y" - mkdir -p %buildroot/usr/share/man/man9 - find man -name '*.9' -exec install -m 644 -D '{}' %buildroot/usr/share/man/man9/ ';' -%endif -%if 0%{?suse_version} > 1500 || 0%{?sle_version} >= 150300 - s390x_vmlinux=arch/s390/boot/compressed/vmlinux - if [ ! -f "$s390x_vmlinux" ]; then - s390x_vmlinux=arch/s390/boot/vmlinux - fi - objcopy -R .rodata.compressed "$s390x_vmlinux" %buildroot/boot/zdebug-%kernelrelease-%build_flavor -%endif -%endif -%ifarch %arm - add_vmlinux --compressed - cp -p arch/arm/boot/%image %buildroot/boot/%image-%kernelrelease-%build_flavor -%endif -%ifarch aarch64 - add_vmlinux --compressed - cp -p arch/arm64/boot/%image %buildroot/boot/%image-%kernelrelease-%build_flavor -%endif -%ifarch riscv64 - add_vmlinux --compressed - cp -p arch/riscv/boot/%image %buildroot/boot/%image-%kernelrelease-%build_flavor +%files extra -f kernel-extra.files %endif -# sign the modules, firmware and possibly the kernel in the buildservice -BRP_PESIGN_FILES="" -%if "%CONFIG_EFI_STUB" == "y" -%if 0%{?usrmerged} -BRP_PESIGN_FILES="%modules_dir/%image" -%else -BRP_PESIGN_FILES="/boot/%image-%kernelrelease-%build_flavor" -%endif -%endif -%if ! %sb_efi_only -%ifarch s390x ppc64 ppc64le -%if 0%{?usrmerged} -BRP_PESIGN_FILES="%modules_dir/%image" -%else -BRP_PESIGN_FILES="/boot/%image-%kernelrelease-%build_flavor" -%endif -%endif -%endif -%if "%CONFIG_MODULE_SIG" == "y" -BRP_PESIGN_FILES="$BRP_PESIGN_FILES *.ko" -%endif +%if %split_extra && %split_optional +%package optional +Summary: @SUMMARY@ - Optional kernel modules +Group: System/Kernel +URL: https://www.kernel.org/ +Provides: %name-optional_%_target_cpu = %version-%source_rel +Provides: kernel-optional = %version-%source_rel +Provides: multiversion(kernel) +Requires: %name-extra_%_target_cpu = %version-%source_rel +Requires(pre): coreutils awk +Requires(post): modutils +Requires(post): perl-Bootloader +Requires(post): dracut +@PROVIDES_OBSOLETES_OPTIONAL@ +%obsolete_rebuilds %name-optional +Supplements: packageand(product(Leap):%{name}_%_target_cpu) %ifarch %ix86 -# XXX: do not sign on x86, as the repackaging changes kernel-pae -# from i686 to i586 -BRP_PESIGN_FILES="" +Conflicts: libc.so.6()(64bit) %endif -export BRP_PESIGN_FILES -%if "%{compress_modules}" != "none" -export BRP_PESIGN_COMPRESS_MODULE=%{compress_modules} +%if %build_default +%if "%CONFIG_PREEMPT_DYNAMIC" == "y" +Provides: kernel-preempt-optional = %version-%release +Provides: kernel-preempt-optional_%_target_cpu = %version-%source_rel %endif -# Do not sign vanilla kernels released in official projects -%if %build_vanilla && ! %vanilla_only -BRP_PESIGN_FILES="" %endif -if test -x /usr/lib/rpm/pesign/gen-hmac; then - $_ -r %buildroot /boot/%image-%kernelrelease-%build_flavor -fi +%description optional +@DESCRIPTION@ -# Package the compiled-in certificates as DER files in /etc/uefi/certs -# and have mokutil enroll them when the kernel is installed -echo Signing certificates "%certs" -if test %CONFIG_MODULE_SIG = "y" -a -d %_sourcedir/.kernel_signing_certs ; then - for f in %_sourcedir/.kernel_signing_certs/*.crt; do - mkdir -p %buildroot/etc/uefi/certs - cp -v $f %buildroot/etc/uefi/certs - done -fi +This package contains optional modules only for openSUSE Leap. -cp -p .config %buildroot/boot/config-%kernelrelease-%build_flavor -sysctl_file=%buildroot/boot/sysctl.conf-%kernelrelease-%build_flavor -for file in %my_builddir/sysctl/{defaults,%cpu_arch/arch-defaults,%cpu_arch_flavor}; do - if [ -f "$file" ]; then - cat "$file" - fi -done | sed '1i # Generated file - do not edit.' >$sysctl_file -if [ ! -s $sysctl_file ]; then - rm $sysctl_file -fi -%if %install_vdso -# Install the unstripped vdso's that are linked in the kernel image -make vdso_install $MAKE_ARGS INSTALL_MOD_PATH=%buildroot -rm -rf %buildroot%kernel_module_directory/%kernelrelease-%build_flavor/vdso/.build-id -%endif +%source_timestamp -# Create a dummy initrd with roughly the size the real one will have. -# That way, YaST will know that this package requires some additional -# space in /boot. -dd if=/dev/zero of=%buildroot/boot/initrd-%kernelrelease-%build_flavor \ - bs=1024 seek=2047 count=1 -# Also reserve some space for the kdump initrd -cp %buildroot/boot/initrd-%kernelrelease-%build_flavor{,-kdump} -%if 0%{?suse_version} >= 1500 -# Use same permissions as dracut -chmod 0600 %buildroot/boot/initrd-%kernelrelease-%build_flavor{,-kdump} -%endif +%pre optional +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-pre --name "%name-optional" \ + --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ + --image "%image" --flavor "%build_flavor" --variant "%variant" \ + --usrmerged "%{usrmerged}" --certs "%certs" "$@" -if [ %CONFIG_MODULES = y ]; then - mkdir -p %rpm_install_dir/%cpu_arch_flavor - mkdir -p %buildroot/usr/src/linux-obj/%cpu_arch - install -m 755 -D -t %rpm_install_dir/%cpu_arch_flavor/scripts/mod/ scripts/mod/ksym-provides +%post optional +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-post --name "%name-optional" \ + --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ + --image "%image" --flavor "%build_flavor" --variant "%variant" \ + --usrmerged "%{usrmerged}" --certs "%certs" "$@" - gzip -n -c9 < Module.symvers > %buildroot/boot/symvers-%kernelrelease-%build_flavor.gz +%preun optional +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-preun --name "%name-optional" \ + --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ + --image "%image" --flavor "%build_flavor" --variant "%variant" \ + --usrmerged "%{usrmerged}" --certs "%certs" "$@" - make modules_install $MAKE_ARGS INSTALL_MOD_PATH=%buildroot +%postun optional +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-postun --name "%name-optional" \ + --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ + --image "%image" --flavor "%build_flavor" --variant "%variant" \ + --usrmerged "%{usrmerged}" --certs "%certs" "$@" -%ifarch s390 s390x - expoline=arch/s390/lib/expoline/expoline.o - if test -f arch/s390/lib/expoline/expoline.o ; then - install -m 644 -D -t %rpm_install_dir/%cpu_arch_flavor/$(dirname $expoline) $expoline - fi +%posttrans optional +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-posttrans --name "%name-optional" \ + --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ + --image "%image" --flavor "%build_flavor" --variant "%variant" \ + --usrmerged "%{usrmerged}" --certs "%certs" "$@" + +%files optional -f kernel-optional.files %endif - # Also put the resulting file in %rpm_install_dir/%cpu_arch/%build_flavor - # so that kernel-devel + kernel-%build_flavor is sufficient for building - # modules that have modversions as well. - mkdir -p %rpm_install_dir/%cpu_arch/%build_flavor - cp Module.symvers %rpm_install_dir/%cpu_arch/%build_flavor +%if "%CONFIG_KMSG_IDS" == "y" - # List of symbols that are used to generate kernel livepatches - %if 0%{?klp_symbols} - cp Symbols.list %rpm_install_dir/%cpu_arch/%build_flavor - echo %obj_install_dir/%cpu_arch/%build_flavor/Symbols.list > %my_builddir/livepatch-files.no_dir +%package man +Summary: The collection of man pages generated by the kmsg script +Group: System/Kernel - %if "%CONFIG_LIVEPATCH_IPA_CLONES" == "y" - find %kernel_build_dir -name "*.ipa-clones" ! -size 0 | sed -e 's|^%kernel_build_dir/||' | sort > ipa-clones.list - cp ipa-clones.list %rpm_install_dir/%cpu_arch/%build_flavor - echo %obj_install_dir/%cpu_arch/%build_flavor/ipa-clones.list >> %my_builddir/livepatch-files.no_dir - tar -C %kernel_build_dir \ -%if ! 0%{?suse_version} || 0%{?suse_version} >= 1500 - --verbatim-files-from \ +%description man +This package includes the man pages that have been generated from the +kmsg message documentation comments. + + +%source_timestamp +%files man +/usr/share/man/man9/* %endif - -T ipa-clones.list -cf- | tar -C %rpm_install_dir/%cpu_arch/%build_flavor -xvf- - cat ipa-clones.list | sed -e 's|^|%obj_install_dir/%cpu_arch/%build_flavor/|' >> %my_builddir/livepatch-files.no_dir - %endif - %endif - # Table of types used in exported symbols (for modversion debugging). - %_sourcedir/modversions --pack . > %buildroot/boot/symtypes-%kernelrelease-%build_flavor - if [ -s %buildroot/boot/symtypes-%kernelrelease-%build_flavor ]; then - gzip -n -9 %buildroot/boot/symtypes-%kernelrelease-%build_flavor - else - rm -f %buildroot/boot/symtypes-%kernelrelease-%build_flavor - fi +%if 0%{?separate_vdso} +%package vdso +Summary: vdso binaries for debugging purposes +Group: System/Kernel - # Some architecture's $(uname -m) output is different from the ARCH - # parameter that needs to be passed to kbuild. Create symlinks from - # $(uname -m) to the ARCH directory. - if [ ! -e %rpm_install_dir/%kmp_target_cpu ]; then - ln -sf %cpu_arch %rpm_install_dir/%kmp_target_cpu - ln -sf %cpu_arch %buildroot/usr/src/linux-obj/%kmp_target_cpu - fi +%description vdso +This package includes the vdso binaries. They can be used for debugging. The +actual binary linked to the programs is loaded from the in-memory image, not +from this package. - # We were building in %my_builddir/linux-%srcversion, but the sources will - # later be installed in /usr/src/linux-%srcversion-%source_rel. Fix up the - # build symlink. - rm -f %buildroot%kernel_module_directory/%kernelrelease-%build_flavor/{source,build} - ln -s %src_install_dir \ - %buildroot%kernel_module_directory/%kernelrelease-%build_flavor/source - ln -s %obj_install_dir/%cpu_arch/%build_flavor \ - %buildroot%kernel_module_directory/%kernelrelease-%build_flavor/build - # Abort if there are any undefined symbols - msg="$(/sbin/depmod -F %buildroot/boot/System.map-%kernelrelease-%build_flavor \ - -b %buildroot -ae %kernelrelease-%build_flavor 2>&1)" - if [ $? -ne 0 ] || echo "$msg" | grep 'needs unknown symbol'; then - exit 1 - fi +%source_timestamp +%files vdso +%modules_dir/vdso/ +%endif - %_sourcedir/split-modules -d %buildroot \ - -o %my_builddir \ - -b %kernel_build_dir \ -%if "%CONFIG_SUSE_KERNEL_SUPPORTED" == "y" - -e \ +%package devel +Summary: Development files necessary for building kernel modules +Group: Development/Sources +Provides: %name-devel = %version-%source_rel +Provides: multiversion(kernel) +%if ! %build_vanilla && ! %vanilla_only +Requires: kernel-devel%variant = %version-%source_rel +Recommends: make +Recommends: gcc +Recommends: perl +# for objtool +Requires: libelf-devel +Supplements: packageand(%name:kernel-devel%variant) +%else +Requires: kernel-source-vanilla = %version-%source_rel +Supplements: packageand(%name:kernel-source-vanilla) %endif -%if ! %supported_modules_check - -i \ +%if "%CONFIG_DEBUG_INFO_BTF_MODULES" == "y" +Requires: dwarves >= 1.22 +%endif +%if %build_default +%if "%CONFIG_PREEMPT_DYNAMIC" == "y" +Provides: kernel-preempt-devel = %version-%release %endif - %nil -%if ! %split_extra - cat %my_builddir/unsupported-modules >>%my_builddir/main-modules %endif +@PROVIDES_OBSOLETES_DEVEL@ +%obsolete_rebuilds %name-devel +PreReq: coreutils - # The modules.dep file is sorted randomly which produces strange file - # checksums. As the file is not included in the resulting RPM, it's - # pointless to rely on its contents. Replacing by zeros to make the - # checksums always the same for several builds of the same package. - test -s %buildroot%kernel_module_directory/%kernelrelease-%build_flavor/modules.dep && \ - dd if=/dev/zero of=%buildroot%kernel_module_directory/%kernelrelease-%build_flavor/modules.dep ibs=$(stat -c%s %buildroot%kernel_module_directory/%kernelrelease-%build_flavor/modules.dep) count=1 +%description devel +This package contains files necessary for building kernel modules (and +kernel module packages) against the %build_flavor flavor of the kernel. - res=0 - if test -e %my_builddir/kabi/%cpu_arch/symvers-%build_flavor; then - # check for kabi changes - %_sourcedir/kabi.pl --rules %my_builddir/kabi/severities \ - %my_builddir/kabi/%cpu_arch/symvers-%build_flavor \ - Module.symvers || res=$? - fi - if [ $res -ne 0 ]; then - # %ignore_kabi_badness is defined in the Kernel:* projects in the - # OBS to be able to build the KOTD in spite of kabi errors - if [ 0%{?ignore_kabi_badness} -eq 0 -a \ - ! -e %my_builddir/kabi/%cpu_arch/ignore-%build_flavor -a \ - ! -e %_sourcedir/IGNORE-KABI-BADNESS ]; then - echo "Create a file IGNORE-KABI-BADNESS in the kernel-source" \ - "directory to build this kernel even though its badness is" \ - "higher than allowed for an official kernel." - exit 1 - fi - fi - # Check the license in each module - if ! sh %_sourcedir/check-module-license %buildroot; then - echo "Please fix the missing licenses!" -%if "%CONFIG_SUSE_KERNEL_SUPPORTED" == "y" - exit 1 -%endif - fi +%source_timestamp - # These files are required for building external modules - for FILE in arch/powerpc/lib/crtsavres.o arch/arm64/kernel/ftrace-mod.o \ - arch/*/kernel/macros.s scripts/module.lds - do - if [ -f %kernel_build_dir/$FILE ]; then - echo $FILE >> %my_builddir/obj-files - fi - done +%if "%CONFIG_MODULES" == "y" - tar --exclude=\*.ipa-clones --exclude=.config.old --exclude=.kernel-binary.spec.buildenv \ - --exclude=.kernel_signing_key.pem --exclude=.kernel.genkey \ - -cf - -T %my_builddir/obj-files | \ - tar -xf - -C %rpm_install_dir/%cpu_arch_flavor - # bnc#507084 - find %rpm_install_dir/%cpu_arch_flavor/scripts -type f -perm -111 | \ - while read f; do - case "$(file -b "$f")" in - ELF\ *\ executable*) - strip "$f" - esac - done +%pre devel - # Recreate the generated Makefile with correct path - # - # Linux 5.13 no longer has mkmakefile - if [ -f ../scripts/mkmakefile ] ; then - sh ../scripts/mkmakefile ../../../%{basename:%src_install_dir} \ - %rpm_install_dir/%cpu_arch_flavor \ - $(echo %srcversion | sed -r 's/^([0-9]+)\.([0-9]+).*/\1 \2/') - else - echo include ../../../%{basename:%src_install_dir}/Makefile > %rpm_install_dir/%cpu_arch_flavor/Makefile - fi +# handle update from an older kernel-source with linux-obj as symlink +if [ -h /usr/src/linux-obj ]; then + rm -vf /usr/src/linux-obj fi -# CONFIG_GDB_SCRIPTS -if [ -e vmlinux-gdb.py ]; then - DEST=%rpm_install_dir/%cpu_arch_flavor/ - install -m 755 -d "$DEST" - # set sys.path to our devel.rpm scripts - sed 's@\(sys\.path\.insert(0, \).*@\1"%obj_install_dir/%cpu_arch_flavor/scripts/gdb/")@' vmlinux-gdb.py > "$DEST/vmlinux-gdb.py" - - DEST=%rpm_install_dir/%cpu_arch_flavor/scripts/gdb/linux - install -m 755 -d "$DEST" - pushd scripts/gdb/linux/ - for file in *.py; do - if test -L "$file"; then - # relink against our devel.rpm sources, not of buildroot's - ln -s "%src_install_dir/scripts/gdb/linux/$file" "$DEST/$file" - else - cp -p "$file" "$DEST" - fi - done - popd +%post devel +%relink_function - DEST=%{buildroot}%{_datadir}/gdb/auto-load%modules_dir - install -m 755 -d "$DEST" - ln -s %obj_install_dir/%cpu_arch_flavor/vmlinux-gdb.py "$DEST/vmlinux-gdb.py" -fi +relink ../../linux-%{kernelrelease}%{variant}-obj/"%cpu_arch_flavor" /usr/src/linux-obj/"%cpu_arch_flavor" -rm -rf %{buildroot}/lib/firmware +%files devel -f kernel-devel.files +%dir /usr/src/linux-obj +%dir /usr/src/linux-obj/%cpu_arch +%ghost /usr/src/linux-obj/%cpu_arch_flavor +%exclude %obj_install_dir/%cpu_arch_flavor/Symbols.list +%if "%kmp_target_cpu" != "%cpu_arch" +%obj_install_dir/%kmp_target_cpu +/usr/src/linux-obj/%kmp_target_cpu +%endif -add_dirs_to_filelist() { - sed -rn ' - # print file name - p - # remove filelist macros - s:%%[a-z]+(\([^)]+\))? ?::g - # add %%dir prefix - s:^:%%dir : - # print all parents - :a - # skip directories owned by other packages - s:^%%dir (/boot|/etc|(/usr)?/lib/(modules|firmware)|/usr/share|/usr/src)/[^/]+$:: - s:/[^/]+$::p - ta - ' "$@" | sort -u -} +%if "%livepatch" != "" && "%CONFIG_SUSE_KERNEL_SUPPORTED" == "y" && (("%variant" == "" && %build_default) || ("%variant" == "-rt" && 0%livepatch_rt)) +%if "%livepatch" == "kgraft" +%define patch_package %{livepatch}-patch +%else +%define patch_package kernel-%{livepatch} +%endif +%package %{livepatch} +Summary: Metapackage to pull in matching %patch_package package +Group: System/Kernel +Requires: %{patch_package}-%(echo %{version}-%{source_rel} | sed 'y/\./_/')-%{build_flavor} +Provides: multiversion(kernel) +%if "%variant" != "-rt" +Provides: kernel-default-kgraft = %version +Provides: kernel-xen-kgraft = %version +%if "%livepatch" != "kgraft" +Obsoletes: kernel-default-kgraft < %version +Obsoletes: kernel-xen-kgraft < %version +%endif +%endif -# Collect the file lists. -if [ -f %my_builddir/livepatch-files.no_dir ] ; then - cat %my_builddir/livepatch-files.no_dir | add_dirs_to_filelist > %my_builddir/livepatch-files -fi +%description %{livepatch} +This is a metapackage that pulls in the matching %patch_package package for a +given kernel version. The advantage of the metapackage is that its name is +static, unlike the %{patch_package}--flavor package names. -# does not exist for non-modularized kernels -%if 0%{?usrmerged} - mkdir -p %{buildroot}%modules_dir +%files %{livepatch} +# rpmlint complains about empty packages, so lets own something +%dir %modules_dir %endif -shopt -s nullglob dotglob -> %my_builddir/kernel-devel.files -{ - echo "%modules_dir/build" - echo "%modules_dir/source" - cd %buildroot - for file in boot/symtypes*; do -%if 0%{?usrmerged} - l="${file##*/}" - l="%modules_dir/${l//-%kernelrelease-%build_flavor}" - mv "$file" "%{buildroot}$l" - ln -s "..$l" $file - echo "$l" - echo "%%ghost /$file" -%else - echo "/$file" + +%if 0%{?klp_symbols} && "%livepatch" != "" +%package %{livepatch}-devel +Summary: Kernel symbols file used during kGraft patch development +Group: System/Kernel +Provides: klp-symbols = %version + +%description %{livepatch}-devel +This package brings a file named Symbols.list, which contains a list of all +kernel symbols and its respective kernel object . This list is to be used by +the klp-convert tool, which helps livepatch developers by enabling automatic +symbol resolution. + +%files %{livepatch}-devel -f livepatch-files %endif - done - if test -d .%{_datadir}/gdb/; then - find .%obj_install_dir/%cpu_arch_flavor/scripts/gdb/linux/ -name '*.py' -type l | sed -e 's/^[.]//' - echo "%{_datadir}/gdb/auto-load%modules_dir/vmlinux-gdb.py" - fi -} | add_dirs_to_filelist >%my_builddir/kernel-devel.files -( cd %buildroot ; find .%obj_install_dir/%cpu_arch_flavor -type f ; ) | \ -sed -e 's/^[.]//' | grep -v -e '[.]ipa-clones$' -e '/Symbols[.]list$' -e '/ipa-clones[.]list$'| \ -add_dirs_to_filelist >> %my_builddir/kernel-devel.files -{ echo %ghost /boot/%image - echo %ghost /boot/initrd - cd %buildroot - for f in boot/*; do - l="${f##*/}" - l="%modules_dir/${l//-%kernelrelease-%build_flavor}" - if test -L "$f"; then - echo "%%ghost /$f" - continue - elif test ! -f "$f"; then - continue - fi - case "$f" in - boot/initrd-*) - echo "%%ghost /$f" - continue - ;; - boot/vmlinux-*.%{compress_vmlinux}) - ;; - boot/vmlinux-*) - if $ghost_vmlinux; then - # fall through to mark next echo as %ghost - echo -n "%%ghost " - fi - ;; -%if 0%{?usrmerged} - boot/vmlinuz-*) - echo -n "%%attr(0644, root, root) " - ;; -%endif - boot/symtypes*) -%if 0%{?usrmerged} - echo "%exclude $l" -%endif - continue - ;; - esac -%if 0%{?usrmerged} - mv "$f" "./$l" - ln -s "..$l" $f - # the find in the CONFIG_MODULES condition below also finds the files - # but there's sort -u later, so this is ok - echo "$l" # note: must be first after case statement above - echo "%%ghost /$f" -%else - echo "%%attr(0644, root, root) /$f" -%endif - done - - if [ %CONFIG_MODULES = y ]; then - MODULES=%{lua: print(rpm.expand('%kernel_module_directory'):sub(2))}/%kernelrelease-%build_flavor - find "$MODULES" \ -%if 0%{?separate_vdso} - -path "$MODULES/vdso" -prune -o \ -%endif - -type d -o \ - \( -path '*/modules.*' ! -path '*/modules.order' \ - ! -path '*/modules.builtin' \ - ! -path '*/modules.builtin.modinfo' \) -printf '%%%%ghost /%%p\n' \ - -o -name '*.ko' -prune \ - -o \( -type f \ -%if 0%{?usrmerged} - ! -path '*/symtypes*' ! -path '*/vmlinu*' \ -%endif - \) -printf '/%%p\n' - cat %my_builddir/base-modules - fi - if test %CONFIG_MODULE_SIG = "y" -a -d etc/uefi/certs; then - find etc/uefi/certs -type f -printf '/%%p\n' - fi - if test -d lib/firmware/%kernelrelease-%build_flavor; then - echo "%%dir /lib/firmware/%kernelrelease-%build_flavor" - cat %my_builddir/base-firmware - fi - if [ -e .%_docdir/%name ]; then - echo "%%doc %_docdir/%name" - fi -} | sort -u | add_dirs_to_filelist >%my_builddir/kernel-base.files - -{ - add_dirs_to_filelist %my_builddir/kernel-base.files - if [ %CONFIG_MODULES = y ]; then - add_dirs_to_filelist %my_builddir/main-modules - fi - if test -d %buildroot/lib/firmware/%kernelrelease-%build_flavor; then - echo "/lib/firmware/%kernelrelease-%build_flavor" - fi -} > %my_builddir/kernel-main.files - -%if %split_extra - add_dirs_to_filelist %my_builddir/unsupported-modules > %my_builddir/kernel-extra.files -%if %split_extra && %split_optional - add_dirs_to_filelist %my_builddir/optional-modules > %my_builddir/kernel-optional.files -%endif - -%if 0%{?sle_version} >= 150000 - # By default, loading unsupported modules is disabled on SLE through - # /etc/modprobe.d/10-unsupported-modules.conf from the suse-module-tools - # package. - # modules in kernel-$flavor-extra don't have the supported flag set, - # yet loading them should be possible if the package is installed. - # CAUTION PACKAGERS: The file content below must not change between - # kernel versions, otherwise file conflicts might arise with - # multiversion(kernel). - - modprobe_d_dir=/etc/modprobe.d - %if 0%{?sle_version} > 150300 - modprobe_d_dir=/lib/modprobe.d - %endif - %if 0%{?usrmerged} - modprobe_d_dir=/usr/lib/modprobe.d - %endif - - mkdir -p %buildroot$modprobe_d_dir - cat >%buildroot$modprobe_d_dir/20-kernel-%{build_flavor}-extra.conf <> %my_builddir/kernel-extra.files - echo "%%config(noreplace) $modprobe_d_dir/20-kernel-%{build_flavor}-extra.conf" >> %my_builddir/kernel-extra.files -%endif -%endif -for f in %my_builddir/*-kmp-modules; do - f2=${f%%-modules}.files - add_dirs_to_filelist "$f" >"$f2" -done - -if [ %CONFIG_MODULES = y ]; then - install -m 644 %_sourcedir/modules.fips %{buildroot}%modules_dir/modules.fips - echo %modules_dir/modules.fips >> %my_builddir/kernel-base.files - echo %modules_dir/modules.fips >> %my_builddir/kernel-main.files -fi - -# Hardlink duplicate files automatically (from package fdupes): It doesn't save -# much, but it keeps rpmlint from breaking the package build. Note that we skip -# /usr/src/linux-obj intentionally, to not accidentally break timestamps there -%fdupes %buildroot%modules_dir - -%pre -%if "%build_flavor" != "zfcpdump" -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/rpm-pre --name "%name" \ - --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ - --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" -%endif -%post -%if "%build_flavor" != "zfcpdump" -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/rpm-post --name "%name" \ - --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ - --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" -%endif -%preun -%if "%build_flavor" != "zfcpdump" -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/rpm-preun --name "%name" \ - --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ - --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" -%endif -%postun -%if "%build_flavor" != "zfcpdump" -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/rpm-postun --name "%name" \ - --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ - --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" -%endif -%posttrans -%if "%build_flavor" != "zfcpdump" -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/rpm-posttrans --name "%name" \ - --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ - --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" -%endif -%files -f kernel-main.files - -%if "%CONFIG_MODULES" == "y" && %split_base -%package base -Summary: @SUMMARY@ - base modules +%if "%CONFIG_SUSE_KERNEL_SUPPORTED" == "y" +# BEGIN KMP +%package -n @KMP_NAME@-%build_flavor +Summary: @KMP_SUMMARY@ Group: System/Kernel -Url: http://www.kernel.org/ -Provides: kernel-base = %version-%source_rel +Requires: %name = %version-%source_rel +Provides: @KMP_NAME@ = %version-%source_rel Provides: multiversion(kernel) -Conflicts: %name = %version-%source_rel -@COMMON_DEPS@ -@PROVIDES_OBSOLETES_BASE@ -%obsolete_rebuilds %name-base -%ifarch %ix86 -Conflicts: libc.so.6()(64bit) +# tell weak-modules2 to ignore this package +Provides: kmp_in_kernel +Requires(post): suse-module-tools >= 12.4 +%if %build_default +%if "%CONFIG_PREEMPT_DYNAMIC" == "y" +Provides: @KMP_NAME@-preempt = %version-%release %endif +%endif +Enhances: %name +Supplements: packageand(%name:@KMP_NAME@-%build_flavor) +@KMP_DEPS@ -%description base -@DESCRIPTION@ - -This package contains only the base modules, required in all installs. - +%description -n @KMP_NAME@-%build_flavor +@KMP_DESCRIPTION@ -%source_timestamp -%pre base -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/rpm-pre --name "%name-base" \ +%pre -n @KMP_NAME@-%build_flavor +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-pre --name "@KMP_NAME@-%build_flavor" \ --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" + --usrmerged "%{usrmerged}" --certs "%certs" "$@" -%post base -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/rpm-post --name "%name-base" \ +%post -n @KMP_NAME@-%build_flavor +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-post --name "@KMP_NAME@-%build_flavor" \ --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" + --usrmerged "%{usrmerged}" --certs "%certs" "$@" -%preun base -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/rpm-preun --name "%name-base" \ +%preun -n @KMP_NAME@-%build_flavor +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-preun --name "@KMP_NAME@-%build_flavor" \ --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" + --usrmerged "%{usrmerged}" --certs "%certs" "$@" -%postun base -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/rpm-postun --name "%name-base" \ +%postun -n @KMP_NAME@-%build_flavor +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-postun --name "@KMP_NAME@-%build_flavor" \ --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" + --usrmerged "%{usrmerged}" --certs "%certs" "$@" -%posttrans base -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/rpm-posttrans --name "%name-base" \ +%posttrans -n @KMP_NAME@-%build_flavor +%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-posttrans --name "@KMP_NAME@-%build_flavor" \ --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" - -%files base -f kernel-base.files -%endif + --usrmerged "%{usrmerged}" --certs "%certs" "$@" -%package extra -Summary: @SUMMARY@ - Unsupported kernel modules -Group: System/Kernel -URL: https://www.kernel.org/ -Provides: %name-extra_%_target_cpu = %version-%source_rel -Provides: kernel-extra = %version-%source_rel -Provides: multiversion(kernel) -Requires: %{name}_%_target_cpu = %version-%source_rel -Requires(pre): coreutils awk -Requires(post): modutils -Requires(post): perl-Bootloader -Requires(post): dracut -@PROVIDES_OBSOLETES_EXTRA@ -%obsolete_rebuilds %name-extra -Supplements: packageand(product(SLED):%{name}_%_target_cpu) -Supplements: packageand(product(sle-we):%{name}_%_target_cpu) -Supplements: packageand(product(Leap):%{name}_%_target_cpu) -%ifarch %ix86 -Conflicts: libc.so.6()(64bit) -%endif -%if %build_default -%if "%CONFIG_PREEMPT_DYNAMIC" == "y" -Provides: kernel-preempt-extra = %version-%release -Provides: kernel-preempt-extra_%_target_cpu = %version-%source_rel -%endif -%endif +%files -n @KMP_NAME@-%build_flavor -f @KMP_NAME@.files +# END KMP +%endif # %CONFIG_SUSE_KERNEL_SUPPORTED +%endif # %CONFIG_MODULES -%description extra -@DESCRIPTION@ - -This package contains additional modules not supported by SUSE. - - -%source_timestamp - -%pre extra -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-pre --name "%name-extra" \ - --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ - --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" - -%post extra -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-post --name "%name-extra" \ - --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ - --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" - -%preun extra -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-preun --name "%name-extra" \ - --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ - --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" +%prep +if ! [ -e %{S:0} ]; then + echo "The %name-%version.nosrc.rpm package does not contain the" \ + "complete sources. Please install kernel-source-%version.src.rpm." + exit 1 +fi -%postun extra -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-postun --name "%name-extra" \ - --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ - --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" +SYMBOLS= +if test -e %_sourcedir/extra-symbols; then + SYMBOLS=$(cat %_sourcedir/extra-symbols) + echo "extra symbol(s):" $SYMBOLS +fi -%posttrans extra -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-posttrans --name "%name-extra" \ - --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ - --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" +# Unpack all sources and patches +%setup -q -c -T -a 0 @UNPACK_PATCHES@ -%if %split_extra +mkdir -p %kernel_build_dir -%files extra -f kernel-extra.files +# Generate a list of modules with their support status marking +# The first marker is supposed to be either "+external", "-" or "-!optional", +# where "+external" is for an externally supported module, "-" is for an +# unsuppored module, "-!optional" is for Leap-only unsupported module. +# There can be an optional arch-specific second marker with "+arch" (e.g. +# +arm64), which enforces the module to be supported on the specific arch. +%_sourcedir/guards --list --with-guards <%_sourcedir/supported.conf | \ +awk '{ + t = ""; + for (i = 1; i < NF; i++) { + if ($i == "+external") { + t = " external"; + } else if ($i == "+'%cpu_arch'") { + t = ""; + } else if ($i ~ "^-") { + t = " no"; + } + } + print $(NF) t; +}' >%kernel_build_dir/Module.supported +subpackages=( + base +%if "%CONFIG_SUSE_KERNEL_SUPPORTED" == "y" + @KMPS@ %endif - +) +for package in "${subpackages[@]}"; do + %_sourcedir/guards --default=0 "$package" \ + <%_sourcedir/supported.conf | sed 's,.*/,,; s,\.ko$,,' | \ + sort -u >%kernel_build_dir/Module."$package" +done %if %split_extra && %split_optional -%package optional -Summary: @SUMMARY@ - Optional kernel modules -Group: System/Kernel -URL: https://www.kernel.org/ -Provides: %name-optional_%_target_cpu = %version-%source_rel -Provides: kernel-optional = %version-%source_rel -Provides: multiversion(kernel) -Requires: %name-extra_%_target_cpu = %version-%source_rel -Requires(pre): coreutils awk -Requires(post): modutils -Requires(post): perl-Bootloader -Requires(post): dracut -@PROVIDES_OBSOLETES_OPTIONAL@ -%obsolete_rebuilds %name-optional -Supplements: packageand(product(Leap):%{name}_%_target_cpu) -%ifarch %ix86 -Conflicts: libc.so.6()(64bit) -%endif -%if %build_default -%if "%CONFIG_PREEMPT_DYNAMIC" == "y" -Provides: kernel-preempt-optional = %version-%release -Provides: kernel-preempt-optional_%_target_cpu = %version-%source_rel -%endif +# Module.optional is in a special form, containing guard markers for +# both extra and optional modules, which is processed by split-modules +%_sourcedir/guards --list --with-guards <%_sourcedir/supported.conf | \ +awk '{ + t = ""; + for (i = 1; i < NF; i++) { + if ($i == "+'%cpu_arch'") { + t = ""; + } else if ($i ~ "^-") { + t = $i + } + } + if (t != "") {print t,$(NF);} +}' >%kernel_build_dir/Module.optional %endif -%description optional -@DESCRIPTION@ - -This package contains optional modules only for openSUSE Leap. - - -%source_timestamp - -%pre optional -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-pre --name "%name-optional" \ - --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ - --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" +cd linux-%srcversion -%post optional -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-post --name "%name-optional" \ - --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ - --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" +%_sourcedir/apply-patches \ +%if %{build_vanilla} && ! %vanilla_only + --vanilla \ +%endif + %_sourcedir/series.conf .. $SYMBOLS -%preun optional -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-preun --name "%name-optional" \ - --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ - --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" +cd %kernel_build_dir -%postun optional -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-postun --name "%name-optional" \ - --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ - --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" +# Override the timestamp 'uname -v' reports with the source timestamp and +# the commit hash. +date=$(head -n 1 %_sourcedir/source-timestamp) +commit=$(sed -n 's/GIT Revision: //p' %_sourcedir/source-timestamp) +cat > .kernel-binary.spec.buildenv < localversion +fi -%files optional -f kernel-optional.files +config_base="default" +%ifarch %ix86 +config_base="pae" %endif +if ! [ -f %my_builddir/config/%cpu_arch/$config_base ] ; then + config_base=%variant + config_base=${config_base#-} +fi +if ! grep -q CONFIG_MMU= "%my_builddir/config/%cpu_arch_flavor"; then +cp "%my_builddir/config/%cpu_arch/$config_base" .config +../scripts/kconfig/merge_config.sh -m .config \ + %my_builddir/config/%cpu_arch_flavor +else +cp %my_builddir/config/%cpu_arch_flavor .config +fi +if test -e %my_builddir/config.addon/%cpu_arch_flavor; then + # FIXME: config.addon doesn't affect the %CONFIG_ macros defined at + # the top of the specfile + ../scripts/kconfig/merge_config.sh -m .config %my_builddir/config.addon/%cpu_arch_flavor +fi -%if "%CONFIG_KMSG_IDS" == "y" - -%package man -Summary: The collection of man pages generated by the kmsg script -Group: System/Kernel - -%description man -This package includes the man pages that have been generated from the -kmsg message documentation comments. +CONFIG_SUSE_KERNEL_RELEASED="--disable CONFIG_SUSE_KERNEL_RELEASED" +%if 0%{?_project:1} +if echo %_project | grep -Eqx -f %_sourcedir/release-projects; then + CONFIG_SUSE_KERNEL_RELEASED="--enable CONFIG_SUSE_KERNEL_RELEASED" +fi +%endif +DEBUG_INFO_TYPE="$(grep "CONFIG_DEBUG_INFO_DWARF.*=y" .config)" +DEBUG_INFO_TYPE="${DEBUG_INFO_TYPE%%=y}" +DEBUG_INFO_TYPE="${DEBUG_INFO_TYPE##CONFIG_DEBUG_INFO_}" +echo "Kernel debuginfo type: ${DEBUG_INFO_TYPE}" -%source_timestamp -%files man -/usr/share/man/man9/* +../scripts/config \ + --set-str CONFIG_LOCALVERSION -%source_rel-%build_flavor \ + --enable CONFIG_SUSE_KERNEL \ + $CONFIG_SUSE_KERNEL_RELEASED \ +%if 0%{?__debug_package:1} + --enable CONFIG_DEBUG_INFO +%else + --disable CONFIG_DEBUG_INFO \ + --disable CONFIG_DEBUG_INFO_"${DEBUG_INFO_TYPE}" \ + --enable CONFIG_DEBUG_INFO_NONE %endif -%if 0%{?separate_vdso} -%package vdso -Summary: vdso binaries for debugging purposes -Group: System/Kernel +if [ %CONFIG_MODULE_SIG = "y" ]; then + if [ -n "%certs" ] ; then + ln -s %_sourcedir/.kernel_signing_key.pem . + else + if ! [ -f .kernel.genkey ] ; then + cat > .kernel.genkey <= 1.22 -%endif -%if %build_default -%if "%CONFIG_PREEMPT_DYNAMIC" == "y" -Provides: kernel-preempt-devel = %version-%release -%endif -%endif -@PROVIDES_OBSOLETES_DEVEL@ -%obsolete_rebuilds %name-devel -PreReq: coreutils +makeoutputsync= +if make --output-sync --help >/dev/null 2>&1 ; then + makeoutputsync=--output-sync +else + echo make does not support --output-sync flag. Build messages may be mangled. 1>&2 +fi +MAKE_ARGS="$MAKE_ARGS $makeoutputsync %{?_smp_mflags}" +echo export MAKE_ARGS=\""$MAKE_ARGS"\" >> .kernel-binary.spec.buildenv -%description devel -This package contains files necessary for building kernel modules (and -kernel module packages) against the %build_flavor flavor of the kernel. +KERN_DIRS="-C .. O=$PWD" +if test -e %_sourcedir/TOLERATE-UNKNOWN-NEW-CONFIG-OPTIONS; then + yes '' | make oldconfig $MAKE_ARGS $KERN_DIRS +else + cp .config .config.orig + if test -f ../scripts/kconfig/Makefile && \ + grep -q syncconfig ../scripts/kconfig/Makefile; then + syncconfig="syncconfig" + else + syncconfig="silentoldconfig" + fi + make $syncconfig $MAKE_ARGS $KERN_DIRS < /dev/null + %_sourcedir/check-for-config-changes .config.orig .config + rm .config.orig +fi +make prepare $MAKE_ARGS +make scripts $MAKE_ARGS +krel=$(make -s kernelrelease $MAKE_ARGS) -%source_timestamp +if [ "$krel" != "%kernelrelease-%build_flavor" ]; then + echo "Kernel release mismatch: $krel != %kernelrelease-%build_flavor" >&2 + exit 1 +fi -%if "%CONFIG_MODULES" == "y" +make clean $MAKE_ARGS -%pre devel +rm -f source +find . ! -type d ! -name 'Module.base' ! -name 'Module.*-kmp' ! -name 'Module.optional' -printf '%%P\n' \ + > %my_builddir/obj-files -# handle update from an older kernel-source with linux-obj as symlink -if [ -h /usr/src/linux-obj ]; then - rm -vf /usr/src/linux-obj +%build +cd %kernel_build_dir +source .kernel-binary.spec.buildenv + +# create *.symref files in the tree +if test -e %my_builddir/kabi/%cpu_arch/symtypes-%build_flavor; then + %_sourcedir/modversions --unpack . < $_ fi -%post devel -%relink_function +%if "%CONFIG_KMSG_IDS" == "y" + chmod +x ../scripts/kmsg-doc + MAKE_ARGS="$MAKE_ARGS D=2" +%endif -relink ../../linux-%{kernelrelease}%{variant}-obj/"%cpu_arch_flavor" /usr/src/linux-obj/"%cpu_arch_flavor" +mkdir -p %_topdir/OTHER +log=%_topdir/OTHER/make-stderr.log +while true; do + make all $MAKE_ARGS 2> >(tee "$log") + if test "${PIPESTATUS[0]}" -eq 0; then + break + fi + # In the linux-next and vanilla branches, we try harder to build a + # package. + if test 0%vanilla_only -gt 0 && + %_sourcedir/try-disable-staging-driver "$log"; then + echo "Retrying make" + else + exit 1 + fi +done -%files devel -f kernel-devel.files -%dir /usr/src/linux-obj -%dir /usr/src/linux-obj/%cpu_arch -%ghost /usr/src/linux-obj/%cpu_arch_flavor -%exclude %obj_install_dir/%cpu_arch_flavor/Symbols.list -%if "%kmp_target_cpu" != "%cpu_arch" -%obj_install_dir/%kmp_target_cpu -/usr/src/linux-obj/%kmp_target_cpu +# Generate list of symbols that are used to create kernel livepatches +%if 0%{?klp_symbols} + %_sourcedir/klp-symbols . Symbols.list %endif -%if "%livepatch" != "" && "%CONFIG_SUSE_KERNEL_SUPPORTED" == "y" && (("%variant" == "" && %build_default) || ("%variant" == "-rt" && 0%livepatch_rt)) -%if "%livepatch" == "kgraft" -%define patch_package %{livepatch}-patch -%else -%define patch_package kernel-%{livepatch} -%endif -%package %{livepatch} -Summary: Metapackage to pull in matching %patch_package package -Group: System/Kernel -Requires: %{patch_package}-%(echo %{version}-%{source_rel} | sed 'y/\./_/')-%{build_flavor} -Provides: multiversion(kernel) -%if "%variant" != "-rt" -Provides: kernel-default-kgraft = %version -Provides: kernel-xen-kgraft = %version -%if "%livepatch" != "kgraft" -Obsoletes: kernel-default-kgraft < %version -Obsoletes: kernel-xen-kgraft < %version -%endif -%endif +%install -%description %{livepatch} -This is a metapackage that pulls in the matching %patch_package package for a -given kernel version. The advantage of the metapackage is that its name is -static, unlike the %{patch_package}--flavor package names. +# get rid of /usr/lib/rpm/brp-strip-debug +# strip removes too much from the vmlinux ELF binary +export NO_BRP_STRIP_DEBUG=true +export STRIP_KEEP_SYMTAB='*/vmlinux*' -%files %{livepatch} -# rpmlint complains about empty packages, so lets own something -%dir %modules_dir -%endif +# %kernel_module_directory/%kernelrelease-%build_flavor/source points to the source +# directory installed by kernel-devel. The kernel-%build_flavor-devel package +# has a correct dependency on kernel-devel, but the brp check does not see +# kernel-devel during build. +export NO_BRP_STALE_LINK_ERROR=yes -%if 0%{?klp_symbols} && "%livepatch" != "" -%package %{livepatch}-devel -Summary: Kernel symbols file used during kGraft patch development -Group: System/Kernel -Provides: klp-symbols = %version +cd %kernel_build_dir +source .kernel-binary.spec.buildenv -%description %{livepatch}-devel -This package brings a file named Symbols.list, which contains a list of all -kernel symbols and its respective kernel object . This list is to be used by -the klp-convert tool, which helps livepatch developers by enabling automatic -symbol resolution. +mkdir -p %buildroot/boot +# (Could strip out non-public symbols.) +cp -p System.map %buildroot/boot/System.map-%kernelrelease-%build_flavor -%files %{livepatch}-devel -f livepatch-files +add_vmlinux() +{ + local vmlinux=boot/vmlinux-%kernelrelease-%build_flavor + + cp vmlinux %buildroot/$vmlinux + # make sure that find-debuginfo.sh picks it up. In the filelist, we + # mark the file 0644 again + chmod +x %buildroot/$vmlinux + if test $1 == "--compressed"; then + # avoid using the gzip -n option to make kdump happy (bnc#880848#c20) + ts="$(head -n1 %_sourcedir/source-timestamp)" + touch -d "$ts" %buildroot/$vmlinux + touch %buildroot/$vmlinux.%{compress_vmlinux} +%if 0%{?__debug_package:1} + # compress the vmlinux image after find-debuginfo.sh has processed it +%global __debug_install_post %__debug_install_post \ +%_sourcedir/compress-vmlinux.sh %buildroot/boot/vmlinux-%kernelrelease-%build_flavor +%else + %_sourcedir/compress-vmlinux.sh %buildroot/$vmlinux %endif + ghost_vmlinux=true + else + ghost_vmlinux=false + fi +} -%if "%CONFIG_SUSE_KERNEL_SUPPORTED" == "y" -# BEGIN KMP -%package -n @KMP_NAME@-%build_flavor -Summary: @KMP_SUMMARY@ -Group: System/Kernel -Requires: %name = %version-%source_rel -Provides: @KMP_NAME@ = %version-%source_rel -Provides: multiversion(kernel) -# tell weak-modules2 to ignore this package -Provides: kmp_in_kernel -Requires(post): suse-module-tools >= 12.4 -%if %build_default -%if "%CONFIG_PREEMPT_DYNAMIC" == "y" -Provides: @KMP_NAME@-preempt = %version-%release +# architecture specifics +%ifarch %ix86 x86_64 + add_vmlinux --compressed + cp -p arch/x86/boot/bzImage %buildroot/boot/%image-%kernelrelease-%build_flavor %endif +%ifarch ppc ppc64 ppc64le + add_vmlinux +%endif +%ifarch s390 s390x + add_vmlinux --compressed + image=image + if test ! -f arch/s390/boot/$image; then + image=bzImage + fi + cp -p arch/s390/boot/$image %buildroot/boot/%image-%kernelrelease-%build_flavor +%if "%CONFIG_KMSG_IDS" == "y" + mkdir -p %buildroot/usr/share/man/man9 + find man -name '*.9' -exec install -m 644 -D '{}' %buildroot/usr/share/man/man9/ ';' +%endif +%if 0%{?suse_version} > 1500 || 0%{?sle_version} >= 150300 + s390x_vmlinux=arch/s390/boot/compressed/vmlinux + if [ ! -f "$s390x_vmlinux" ]; then + s390x_vmlinux=arch/s390/boot/vmlinux + fi + objcopy -R .rodata.compressed "$s390x_vmlinux" %buildroot/boot/zdebug-%kernelrelease-%build_flavor +%endif +%endif +%ifarch %arm + add_vmlinux --compressed + cp -p arch/arm/boot/%image %buildroot/boot/%image-%kernelrelease-%build_flavor +%endif +%ifarch aarch64 + add_vmlinux --compressed + cp -p arch/arm64/boot/%image %buildroot/boot/%image-%kernelrelease-%build_flavor +%endif +%ifarch riscv64 + add_vmlinux --compressed + cp -p arch/riscv/boot/%image %buildroot/boot/%image-%kernelrelease-%build_flavor %endif -Enhances: %name -Supplements: packageand(%name:@KMP_NAME@-%build_flavor) -@KMP_DEPS@ - -%description -n @KMP_NAME@-%build_flavor -@KMP_DESCRIPTION@ - -%pre -n @KMP_NAME@-%build_flavor -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-pre --name "@KMP_NAME@-%build_flavor" \ - --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ - --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" - -%post -n @KMP_NAME@-%build_flavor -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-post --name "@KMP_NAME@-%build_flavor" \ - --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ - --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" - -%preun -n @KMP_NAME@-%build_flavor -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-preun --name "@KMP_NAME@-%build_flavor" \ - --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ - --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" - -%postun -n @KMP_NAME@-%build_flavor -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-postun --name "@KMP_NAME@-%build_flavor" \ - --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ - --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" -%posttrans -n @KMP_NAME@-%build_flavor -%run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/inkmp-posttrans --name "@KMP_NAME@-%build_flavor" \ - --version "%version" --release "%release" --kernelrelease "%kernelrelease" \ - --image "%image" --flavor "%build_flavor" --variant "%variant" \ - --usrmerged "0%{?usrmerged}" --certs "%certs" "$@" +# sign the modules, firmware and possibly the kernel in the buildservice +BRP_PESIGN_FILES="" +%if "%CONFIG_EFI_STUB" == "y" +%if %{usrmerged} +BRP_PESIGN_FILES="%modules_dir/%image" +%else +BRP_PESIGN_FILES="/boot/%image-%kernelrelease-%build_flavor" +%endif +%endif +%if ! %sb_efi_only +%ifarch s390x ppc64 ppc64le +%if %{usrmerged} +BRP_PESIGN_FILES="%modules_dir/%image" +%else +BRP_PESIGN_FILES="/boot/%image-%kernelrelease-%build_flavor" +%endif +%endif +%endif +%if "%CONFIG_MODULE_SIG" == "y" +BRP_PESIGN_FILES="$BRP_PESIGN_FILES *.ko" +%endif +%ifarch %ix86 +# XXX: do not sign on x86, as the repackaging changes kernel-pae +# from i686 to i586 +BRP_PESIGN_FILES="" +%endif +export BRP_PESIGN_FILES +%if "%{compress_modules}" != "none" +export BRP_PESIGN_COMPRESS_MODULE=%{compress_modules} +%endif +# Do not sign vanilla kernels released in official projects +%if %build_vanilla && ! %vanilla_only +BRP_PESIGN_FILES="" +%endif -%files -n @KMP_NAME@-%build_flavor -f @KMP_NAME@.files -# END KMP -%endif # %CONFIG_SUSE_KERNEL_SUPPORTED -%endif # %CONFIG_MODULES +if test -x /usr/lib/rpm/pesign/gen-hmac; then + $_ -r %buildroot /boot/%image-%kernelrelease-%build_flavor +fi + +# Package the compiled-in certificates as DER files in /etc/uefi/certs +# and have mokutil enroll them when the kernel is installed +echo Signing certificates "%certs" +if test %CONFIG_MODULE_SIG = "y" -a -d %_sourcedir/.kernel_signing_certs ; then + for f in %_sourcedir/.kernel_signing_certs/*.crt; do + mkdir -p %buildroot/etc/uefi/certs + cp -v $f %buildroot/etc/uefi/certs + done +fi + +cp -p .config %buildroot/boot/config-%kernelrelease-%build_flavor +sysctl_file=%buildroot/boot/sysctl.conf-%kernelrelease-%build_flavor +for file in %my_builddir/sysctl/{defaults,%cpu_arch/arch-defaults,%cpu_arch_flavor}; do + if [ -f "$file" ]; then + cat "$file" + fi +done | sed '1i # Generated file - do not edit.' >$sysctl_file +if [ ! -s $sysctl_file ]; then + rm $sysctl_file +fi + +%if %install_vdso +# Install the unstripped vdso's that are linked in the kernel image +make vdso_install $MAKE_ARGS INSTALL_MOD_PATH=%buildroot +rm -rf %buildroot%kernel_module_directory/%kernelrelease-%build_flavor/vdso/.build-id +%endif + +# Create a dummy initrd with roughly the size the real one will have. +# That way, YaST will know that this package requires some additional +# space in /boot. +dd if=/dev/zero of=%buildroot/boot/initrd-%kernelrelease-%build_flavor \ + bs=1024 seek=2047 count=1 +# Also reserve some space for the kdump initrd +cp %buildroot/boot/initrd-%kernelrelease-%build_flavor{,-kdump} +%if 0%{?suse_version} >= 1500 +# Use same permissions as dracut +chmod 0600 %buildroot/boot/initrd-%kernelrelease-%build_flavor{,-kdump} +%endif + +if [ %CONFIG_MODULES = y ]; then + mkdir -p %rpm_install_dir/%cpu_arch_flavor + mkdir -p %buildroot/usr/src/linux-obj/%cpu_arch + install -m 755 -D -t %rpm_install_dir/%cpu_arch_flavor/scripts/mod/ scripts/mod/ksym-provides + + gzip -n -c9 < Module.symvers > %buildroot/boot/symvers-%kernelrelease-%build_flavor.gz + + make modules_install $MAKE_ARGS INSTALL_MOD_PATH=%buildroot + +%ifarch s390 s390x + expoline=arch/s390/lib/expoline/expoline.o + if test -f arch/s390/lib/expoline/expoline.o ; then + install -m 644 -D -t %rpm_install_dir/%cpu_arch_flavor/$(dirname $expoline) $expoline + fi +%endif + + # Also put the resulting file in %rpm_install_dir/%cpu_arch/%build_flavor + # so that kernel-devel + kernel-%build_flavor is sufficient for building + # modules that have modversions as well. + mkdir -p %rpm_install_dir/%cpu_arch/%build_flavor + cp Module.symvers %rpm_install_dir/%cpu_arch/%build_flavor + + # List of symbols that are used to generate kernel livepatches + %if 0%{?klp_symbols} + cp Symbols.list %rpm_install_dir/%cpu_arch/%build_flavor + echo %obj_install_dir/%cpu_arch/%build_flavor/Symbols.list > %my_builddir/livepatch-files.no_dir + + %if "%CONFIG_LIVEPATCH_IPA_CLONES" == "y" + find %kernel_build_dir -name "*.ipa-clones" ! -size 0 | sed -e 's|^%kernel_build_dir/||' | sort > ipa-clones.list + cp ipa-clones.list %rpm_install_dir/%cpu_arch/%build_flavor + echo %obj_install_dir/%cpu_arch/%build_flavor/ipa-clones.list >> %my_builddir/livepatch-files.no_dir + tar -C %kernel_build_dir \ +%if ! 0%{?suse_version} || 0%{?suse_version} >= 1500 + --verbatim-files-from \ +%endif + -T ipa-clones.list -cf- | tar -C %rpm_install_dir/%cpu_arch/%build_flavor -xvf- + cat ipa-clones.list | sed -e 's|^|%obj_install_dir/%cpu_arch/%build_flavor/|' >> %my_builddir/livepatch-files.no_dir + %endif + %endif + + # Table of types used in exported symbols (for modversion debugging). + %_sourcedir/modversions --pack . > %buildroot/boot/symtypes-%kernelrelease-%build_flavor + if [ -s %buildroot/boot/symtypes-%kernelrelease-%build_flavor ]; then + gzip -n -9 %buildroot/boot/symtypes-%kernelrelease-%build_flavor + else + rm -f %buildroot/boot/symtypes-%kernelrelease-%build_flavor + fi + + # Some architecture's $(uname -m) output is different from the ARCH + # parameter that needs to be passed to kbuild. Create symlinks from + # $(uname -m) to the ARCH directory. + if [ ! -e %rpm_install_dir/%kmp_target_cpu ]; then + ln -sf %cpu_arch %rpm_install_dir/%kmp_target_cpu + ln -sf %cpu_arch %buildroot/usr/src/linux-obj/%kmp_target_cpu + fi + + # We were building in %my_builddir/linux-%srcversion, but the sources will + # later be installed in /usr/src/linux-%srcversion-%source_rel. Fix up the + # build symlink. + rm -f %buildroot%kernel_module_directory/%kernelrelease-%build_flavor/{source,build} + ln -s %src_install_dir \ + %buildroot%kernel_module_directory/%kernelrelease-%build_flavor/source + ln -s %obj_install_dir/%cpu_arch/%build_flavor \ + %buildroot%kernel_module_directory/%kernelrelease-%build_flavor/build + + # Abort if there are any undefined symbols + msg="$(/sbin/depmod -F %buildroot/boot/System.map-%kernelrelease-%build_flavor \ + -b %buildroot -ae %kernelrelease-%build_flavor 2>&1)" + if [ $? -ne 0 ] || echo "$msg" | grep 'needs unknown symbol'; then + exit 1 + fi + + %_sourcedir/split-modules -d %buildroot \ + -o %my_builddir \ + -b %kernel_build_dir \ +%if "%CONFIG_SUSE_KERNEL_SUPPORTED" == "y" + -e \ +%endif +%if ! %supported_modules_check + -i \ +%endif + %nil +%if ! %split_extra + cat %my_builddir/unsupported-modules >>%my_builddir/main-modules +%endif + + # The modules.dep file is sorted randomly which produces strange file + # checksums. As the file is not included in the resulting RPM, it's + # pointless to rely on its contents. Replacing by zeros to make the + # checksums always the same for several builds of the same package. + test -s %buildroot%kernel_module_directory/%kernelrelease-%build_flavor/modules.dep && \ + dd if=/dev/zero of=%buildroot%kernel_module_directory/%kernelrelease-%build_flavor/modules.dep ibs=$(stat -c%s %buildroot%kernel_module_directory/%kernelrelease-%build_flavor/modules.dep) count=1 + + res=0 + if test -e %my_builddir/kabi/%cpu_arch/symvers-%build_flavor; then + # check for kabi changes + %_sourcedir/kabi.pl --rules %my_builddir/kabi/severities \ + %my_builddir/kabi/%cpu_arch/symvers-%build_flavor \ + Module.symvers || res=$? + fi + if [ $res -ne 0 ]; then + # %ignore_kabi_badness is defined in the Kernel:* projects in the + # OBS to be able to build the KOTD in spite of kabi errors + if [ 0%{?ignore_kabi_badness} -eq 0 -a \ + ! -e %my_builddir/kabi/%cpu_arch/ignore-%build_flavor -a \ + ! -e %_sourcedir/IGNORE-KABI-BADNESS ]; then + echo "Create a file IGNORE-KABI-BADNESS in the kernel-source" \ + "directory to build this kernel even though its badness is" \ + "higher than allowed for an official kernel." + exit 1 + fi + fi + + # Check the license in each module + if ! sh %_sourcedir/check-module-license %buildroot; then + echo "Please fix the missing licenses!" +%if "%CONFIG_SUSE_KERNEL_SUPPORTED" == "y" + exit 1 +%endif + fi + + # These files are required for building external modules + for FILE in arch/powerpc/lib/crtsavres.o arch/arm64/kernel/ftrace-mod.o \ + arch/*/kernel/macros.s scripts/module.lds + do + if [ -f %kernel_build_dir/$FILE ]; then + echo $FILE >> %my_builddir/obj-files + fi + done + + tar --exclude=\*.ipa-clones --exclude=.config.old --exclude=.kernel-binary.spec.buildenv \ + --exclude=.kernel_signing_key.pem --exclude=.kernel.genkey \ + -cf - -T %my_builddir/obj-files | \ + tar -xf - -C %rpm_install_dir/%cpu_arch_flavor + # bnc#507084 + find %rpm_install_dir/%cpu_arch_flavor/scripts -type f -perm -111 | \ + while read f; do + case "$(file -b "$f")" in + ELF\ *\ executable*) + strip "$f" + esac + done + + # Recreate the generated Makefile with correct path + # + # Linux 5.13 no longer has mkmakefile + if [ -f ../scripts/mkmakefile ] ; then + sh ../scripts/mkmakefile ../../../%{basename:%src_install_dir} \ + %rpm_install_dir/%cpu_arch_flavor \ + $(echo %srcversion | sed -r 's/^([0-9]+)\.([0-9]+).*/\1 \2/') + else + echo include ../../../%{basename:%src_install_dir}/Makefile > %rpm_install_dir/%cpu_arch_flavor/Makefile + fi +fi + +# CONFIG_GDB_SCRIPTS +if [ -e vmlinux-gdb.py ]; then + DEST=%rpm_install_dir/%cpu_arch_flavor/ + install -m 755 -d "$DEST" + # set sys.path to our devel.rpm scripts + sed 's@\(sys\.path\.insert(0, \).*@\1"%obj_install_dir/%cpu_arch_flavor/scripts/gdb/")@' vmlinux-gdb.py > "$DEST/vmlinux-gdb.py" + + DEST=%rpm_install_dir/%cpu_arch_flavor/scripts/gdb/linux + install -m 755 -d "$DEST" + pushd scripts/gdb/linux/ + for file in *.py; do + if test -L "$file"; then + # relink against our devel.rpm sources, not of buildroot's + ln -s "%src_install_dir/scripts/gdb/linux/$file" "$DEST/$file" + else + cp -p "$file" "$DEST" + fi + done + popd + + DEST=%{buildroot}%{_datadir}/gdb/auto-load%modules_dir + install -m 755 -d "$DEST" + ln -s %obj_install_dir/%cpu_arch_flavor/vmlinux-gdb.py "$DEST/vmlinux-gdb.py" +fi + +rm -rf %{buildroot}/lib/firmware + +add_dirs_to_filelist() { + sed -rn ' + # print file name + p + # remove filelist macros + s:%%[a-z]+(\([^)]+\))? ?::g + # add %%dir prefix + s:^:%%dir : + # print all parents + :a + # skip directories owned by other packages + s:^%%dir (/boot|/etc|(/usr)?/lib/(modules|firmware)|/usr/share|/usr/src)/[^/]+$:: + s:/[^/]+$::p + ta + ' "$@" | sort -u +} + +# Collect the file lists. +if [ -f %my_builddir/livepatch-files.no_dir ] ; then + cat %my_builddir/livepatch-files.no_dir | add_dirs_to_filelist > %my_builddir/livepatch-files +fi + +# does not exist for non-modularized kernels +%if %{usrmerged} + mkdir -p %{buildroot}%modules_dir +%endif +shopt -s nullglob dotglob +> %my_builddir/kernel-devel.files +{ + echo "%modules_dir/build" + echo "%modules_dir/source" + cd %buildroot + for file in boot/symtypes*; do +%if %{usrmerged} + l="${file##*/}" + l="%modules_dir/${l//-%kernelrelease-%build_flavor}" + mv "$file" "%{buildroot}$l" + ln -s "..$l" $file + echo "$l" + echo "%%ghost /$file" +%else + echo "/$file" +%endif + done + if test -d .%{_datadir}/gdb/; then + find .%obj_install_dir/%cpu_arch_flavor/scripts/gdb/linux/ -name '*.py' -type l | sed -e 's/^[.]//' + echo "%{_datadir}/gdb/auto-load%modules_dir/vmlinux-gdb.py" + fi +} | add_dirs_to_filelist >%my_builddir/kernel-devel.files +( cd %buildroot ; find .%obj_install_dir/%cpu_arch_flavor -type f ; ) | \ +sed -e 's/^[.]//' | grep -v -e '[.]ipa-clones$' -e '/Symbols[.]list$' -e '/ipa-clones[.]list$'| \ +add_dirs_to_filelist >> %my_builddir/kernel-devel.files + +{ echo %ghost /boot/%image + echo %ghost /boot/initrd + cd %buildroot + for f in boot/*; do + l="${f##*/}" + l="%modules_dir/${l//-%kernelrelease-%build_flavor}" + if test -L "$f"; then + echo "%%ghost /$f" + continue + elif test ! -f "$f"; then + continue + fi + case "$f" in + boot/initrd-*) + echo "%%ghost /$f" + continue + ;; + boot/vmlinux-*.%{compress_vmlinux}) + ;; + boot/vmlinux-*) + if $ghost_vmlinux; then + # fall through to mark next echo as %ghost + echo -n "%%ghost " + fi + ;; +%if %{usrmerged} + boot/vmlinuz-*) + echo -n "%%attr(0644, root, root) " + ;; +%endif + boot/symtypes*) +%if %{usrmerged} + echo "%exclude $l" +%endif + continue + ;; + esac +%if %{usrmerged} + mv "$f" "./$l" + ln -s "..$l" $f + # the find in the CONFIG_MODULES condition below also finds the files + # but there's sort -u later, so this is ok + echo "$l" # note: must be first after case statement above + echo "%%ghost /$f" +%else + echo "%%attr(0644, root, root) /$f" +%endif + done + + if [ %CONFIG_MODULES = y ]; then + MODULES=%{lua: print(rpm.expand('%kernel_module_directory'):sub(2))}/%kernelrelease-%build_flavor + find "$MODULES" \ +%if 0%{?separate_vdso} + -path "$MODULES/vdso" -prune -o \ +%endif + -type d -o \ + \( -path '*/modules.*' ! -path '*/modules.order' \ + ! -path '*/modules.builtin' \ + ! -path '*/modules.builtin.modinfo' \) -printf '%%%%ghost /%%p\n' \ + -o -name '*.ko' -prune \ + -o \( -type f \ +%if %{usrmerged} + ! -path '*/symtypes*' ! -path '*/vmlinu*' \ +%endif + \) -printf '/%%p\n' + cat %my_builddir/base-modules + fi + if test %CONFIG_MODULE_SIG = "y" -a -d etc/uefi/certs; then + find etc/uefi/certs -type f -printf '/%%p\n' + fi + if test -d lib/firmware/%kernelrelease-%build_flavor; then + echo "%%dir /lib/firmware/%kernelrelease-%build_flavor" + cat %my_builddir/base-firmware + fi + if [ -e .%_docdir/%name ]; then + echo "%%doc %_docdir/%name" + fi +} | sort -u | add_dirs_to_filelist >%my_builddir/kernel-base.files + +{ + add_dirs_to_filelist %my_builddir/kernel-base.files + if [ %CONFIG_MODULES = y ]; then + add_dirs_to_filelist %my_builddir/main-modules + fi + if test -d %buildroot/lib/firmware/%kernelrelease-%build_flavor; then + echo "/lib/firmware/%kernelrelease-%build_flavor" + fi +} > %my_builddir/kernel-main.files + +%if %split_extra + add_dirs_to_filelist %my_builddir/unsupported-modules > %my_builddir/kernel-extra.files +%if %split_extra && %split_optional + add_dirs_to_filelist %my_builddir/optional-modules > %my_builddir/kernel-optional.files +%endif + +%if 0%{?sle_version} >= 150000 + # By default, loading unsupported modules is disabled on SLE through + # /etc/modprobe.d/10-unsupported-modules.conf from the suse-module-tools + # package. + # modules in kernel-$flavor-extra don't have the supported flag set, + # yet loading them should be possible if the package is installed. + # CAUTION PACKAGERS: The file content below must not change between + # kernel versions, otherwise file conflicts might arise with + # multiversion(kernel). + + modprobe_d_dir=/etc/modprobe.d + %if 0%{?sle_version} > 150300 + modprobe_d_dir=/lib/modprobe.d + %endif + %if %{usrmerged} + modprobe_d_dir=/usr/lib/modprobe.d + %endif + + mkdir -p %buildroot$modprobe_d_dir + cat >%buildroot$modprobe_d_dir/20-kernel-%{build_flavor}-extra.conf <> %my_builddir/kernel-extra.files + echo "%%config(noreplace) $modprobe_d_dir/20-kernel-%{build_flavor}-extra.conf" >> %my_builddir/kernel-extra.files +%endif +%endif +for f in %my_builddir/*-kmp-modules; do + f2=${f%%-modules}.files + add_dirs_to_filelist "$f" >"$f2" +done + +if [ %CONFIG_MODULES = y ]; then + install -m 644 %_sourcedir/modules.fips %{buildroot}%modules_dir/modules.fips + echo %modules_dir/modules.fips >> %my_builddir/kernel-base.files + echo %modules_dir/modules.fips >> %my_builddir/kernel-main.files +fi + +# Hardlink duplicate files automatically (from package fdupes): It doesn't save +# much, but it keeps rpmlint from breaking the package build. Note that we skip +# /usr/src/linux-obj intentionally, to not accidentally break timestamps there +%fdupes %buildroot%modules_dir %changelog diff --git a/rpm/kernel-docs.spec.in b/rpm/kernel-docs.spec.in index 7a32d2e..0ef9d84 100644 --- a/rpm/kernel-docs.spec.in +++ b/rpm/kernel-docs.spec.in @@ -28,15 +28,16 @@ %(chmod +x %_sourcedir/{@SCRIPTS@}) Name: kernel-docs@VARIANT@ -Summary: Kernel Documentation -License: GPL-2.0-only -Group: Documentation/Man Version: @RPMVERSION@ %if 0%{?is_kotd} Release: .g@COMMIT@ %else Release: @RELEASE@ %endif +Summary: Kernel Documentation +License: GPL-2.0-only +Group: Documentation/Man +URL: https://www.kernel.org/ %if 0%{?suse_version} > 1500 || 0%{?sle_version} > 150300 BuildRequires: bash-sh %endif @@ -83,21 +84,29 @@ BuildRequires: texlive-xetex BuildRequires: texlive-zapfding %endif %endif -URL: https://www.kernel.org/ -Provides: %name = %version-%source_rel -Provides: %name-srchash-%git_commit %if ! 0%{?is_kotd} || ! %{?is_kotd_qa}%{!?is_kotd_qa:0} BuildArch: noarch %else ExclusiveArch: do_not_build %endif @SOURCES@ +Provides: %name = %version-%source_rel +Provides: %name-srchash-%git_commit %description A few basic documents from the current kernel sources. %source_timestamp +%files +%if 0%{?suse_version} && 0%{?suse_version} < 1500 +%doc COPYING +%else +%license COPYING +%endif +%doc CREDITS MAINTAINERS README +%doc old_changelog.txt + %if %build_pdf %package pdf Summary: Kernel Documentation (PDF) @@ -107,6 +116,11 @@ Group: Documentation/Other These are PDF documents built from the current kernel sources. %source_timestamp + +%files pdf +%dir %{_datadir}/doc/kernel +%docdir %{_datadir}/doc/kernel/pdf +%{_datadir}/doc/kernel/pdf %endif %if %build_html @@ -118,6 +132,11 @@ Group: Documentation/HTML These are HTML documents built from the current kernel sources. %source_timestamp + +%files html +%dir %{_datadir}/doc/kernel +%docdir %{_datadir}/doc/kernel/html +%{_datadir}/doc/kernel/html %endif %prep @@ -161,27 +180,4 @@ for i in pdf/Documentation/output/latex/*.pdf; do done %endif -%files -%if 0%{?suse_version} && 0%{?suse_version} < 1500 -%doc COPYING -%else -%license COPYING -%endif -%doc CREDITS MAINTAINERS README -%doc old_changelog.txt - -%if %build_pdf -%files pdf -%dir %{_datadir}/doc/kernel -%docdir %{_datadir}/doc/kernel/pdf -%{_datadir}/doc/kernel/pdf -%endif - -%if %build_html -%files html -%dir %{_datadir}/doc/kernel -%docdir %{_datadir}/doc/kernel/html -%{_datadir}/doc/kernel/html -%endif - %changelog diff --git a/rpm/kernel-module-subpackage b/rpm/kernel-module-subpackage index fa4c9bb..387d9d7 100644 --- a/rpm/kernel-module-subpackage +++ b/rpm/kernel-module-subpackage @@ -73,27 +73,27 @@ END { exit(! good) } %{-b:KMP_NEEDS_MKINITRD=1; export KMP_NEEDS_MKINITRD} %run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/kmp-pre --name "%{-n*}-kmp-%1" \ --version "%_this_kmp_version" --release "%{-r*}" --kernelrelease "%2" \ - --flavor "%1" --usrmerged "0%{?usrmerged}" "$@" + --flavor "%1" --usrmerged "%{usrmerged}" "$@" %post -n %{-n*}-kmp-%1 %{-b:KMP_NEEDS_MKINITRD=1; export KMP_NEEDS_MKINITRD} %run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/kmp-post --name "%{-n*}-kmp-%1" \ --version "%_this_kmp_version" --release "%{-r*}" --kernelrelease "%2" \ - --flavor "%1" --usrmerged "0%{?usrmerged}" "$@" + --flavor "%1" --usrmerged "%{usrmerged}" "$@" %preun -n %{-n*}-kmp-%1 %{-b:KMP_NEEDS_MKINITRD=1; export KMP_NEEDS_MKINITRD} %run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/kmp-preun --name "%{-n*}-kmp-%1" \ --version "%_this_kmp_version" --release "%{-r*}" --kernelrelease "%2" \ - --flavor "%1" --usrmerged "0%{?usrmerged}" "$@" + --flavor "%1" --usrmerged "%{usrmerged}" "$@" %postun -n %{-n*}-kmp-%1 %{-b:KMP_NEEDS_MKINITRD=1; export KMP_NEEDS_MKINITRD} %run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/kmp-postun --name "%{-n*}-kmp-%1" \ --version "%_this_kmp_version" --release "%{-r*}" --kernelrelease "%2" \ - --flavor "%1" --usrmerged "0%{?usrmerged}" "$@" + --flavor "%1" --usrmerged "%{usrmerged}" "$@" %posttrans -n %{-n*}-kmp-%1 %{-b:KMP_NEEDS_MKINITRD=1; export KMP_NEEDS_MKINITRD} %run_if_exists /usr/lib/module-init-tools/kernel-scriptlets/kmp-posttrans --name "%{-n*}-kmp-%1" \ --version "%_this_kmp_version" --release "%{-r*}" --kernelrelease "%2" \ - --flavor "%1" --usrmerged "0%{?usrmerged}" "$@" + --flavor "%1" --usrmerged "%{usrmerged}" "$@" %files -n %{-n*}-kmp-%1 %{-f:%{expand:%(cd %_sourcedir; cat %{-f*})}} %{!-f:%defattr (-,root,root)} diff --git a/rpm/kernel-obs-build.spec.in b/rpm/kernel-obs-build.spec.in index 35ba177..e9ba426 100644 --- a/rpm/kernel-obs-build.spec.in +++ b/rpm/kernel-obs-build.spec.in @@ -24,51 +24,49 @@ %include %_sourcedir/kernel-spec-macros -Name: kernel-obs-build -BuildRequires: coreutils -BuildRequires: device-mapper -BuildRequires: util-linux - %if 0%{?suse_version} %if "@OBS_BUILD_VARIANT@" -%define kernel_flavor @OBS_BUILD_VARIANT@ +%global kernel_flavor @OBS_BUILD_VARIANT@ %else %ifarch %ix86 -%define kernel_flavor -pae +%global kernel_flavor -pae %else %ifarch armv7l armv7hl -%define kernel_flavor -lpae +%global kernel_flavor -lpae %else -%define kernel_flavor -default +%global kernel_flavor -default %endif %endif %endif +%global kernel_package kernel%kernel_flavor-srchash-@COMMIT_FULL@ %endif -BuildRequires: kernel%kernel_flavor-srchash-@COMMIT_FULL@ - %if 0%{?rhel_version} -BuildRequires: kernel -%define kernel_flavor "" +%global kernel_package kernel %endif -%if ! 0%{?is_kotd} || %{?is_kotd_qa}%{!?is_kotd_qa:0} -ExclusiveArch: @ARCHS@ -%else -ExclusiveArch: do_not_build -%endif -BuildRequires: dracut -Summary: package kernel and initrd for OBS VM builds -License: GPL-2.0-only -Group: SLES +Name: kernel-obs-build Version: @RPMVERSION@ %if 0%{?is_kotd} Release: .g@COMMIT@ %else Release: @RELEASE@ %endif +Summary: package kernel and initrd for OBS VM builds +License: GPL-2.0-only +Group: SLES +BuildRequires: coreutils +BuildRequires: device-mapper +BuildRequires: dracut +BuildRequires: %kernel_package +BuildRequires: util-linux %if 0%{?suse_version} > 1550 || 0%{?sle_version} > 150200 BuildRequires: zstd %endif +%if ! 0%{?is_kotd} || %{?is_kotd_qa}%{!?is_kotd_qa:0} +ExclusiveArch: @ARCHS@ +%else +ExclusiveArch: do_not_build +%endif %description This package is repackaging already compiled kernels to make them usable @@ -76,6 +74,13 @@ inside of Open Build Service (OBS) VM builds. An initrd with some basic kernel modules is generated as well, but further kernel modules can be loaded during build when installing the kernel package. +%files +/.build.cmdline.* +/.build.console.* +/.build.hostarch.* +/.build.initrd.* +/.build.kernel.* + %prep %build @@ -176,11 +181,4 @@ fi #see obs-build commit e47399d738e51 uname -m > %{buildroot}/.build.hostarch.kvm -%files -/.build.cmdline.* -/.build.console.* -/.build.hostarch.* -/.build.initrd.* -/.build.kernel.* - %changelog diff --git a/rpm/kernel-obs-qa.spec.in b/rpm/kernel-obs-qa.spec.in index 9c35f37..3514ab3 100644 --- a/rpm/kernel-obs-qa.spec.in +++ b/rpm/kernel-obs-qa.spec.in @@ -23,6 +23,15 @@ %include %_sourcedir/kernel-spec-macros Name: kernel-obs-qa +Version: @RPMVERSION@ +%if 0%{?is_kotd} +Release: .g@COMMIT@ +%else +Release: @RELEASE@ +%endif +Summary: Basic QA tests for the kernel +License: GPL-2.0-only +Group: SLES BuildRequires: kernel-default # kernel-obs-build must be also configured as VMinstall, but is required # here as well to avoid that qa and build package build parallel @@ -33,20 +42,14 @@ ExclusiveArch: @ARCHS@ %else ExclusiveArch: do_not_build %endif -Summary: Basic QA tests for the kernel -License: GPL-2.0-only -Group: SLES -Version: @RPMVERSION@ -%if 0%{?is_kotd} -Release: .g@COMMIT@ -%else -Release: @RELEASE@ -%endif %description This package is using the kernel compiled within Open Build Service(OBS) projects and runs basic tests. +%files +/usr/share/%name + %prep %build @@ -70,7 +73,4 @@ fi mkdir -p %{buildroot}/usr/share/%name touch %{buildroot}/usr/share/%name/logfile -%files -/usr/share/%name - %changelog diff --git a/rpm/kernel-source.spec.in b/rpm/kernel-source.spec.in index 839bfe6..ec2b6e0 100644 --- a/rpm/kernel-source.spec.in +++ b/rpm/kernel-source.spec.in @@ -23,12 +23,7 @@ %include %_sourcedir/kernel-spec-macros -%define src_install_dir usr/src/linux-%kernelrelease%variant - -# if undefined use legacy location of before SLE15 -%if %{undefined _rpmmacrodir} -%define _rpmmacrodir /etc/rpm -%endif +%(chmod +x %_sourcedir/{@SCRIPTS@}) Name: kernel-source@VARIANT@ Version: @RPMVERSION@ @@ -48,7 +43,20 @@ BuildRequires: bash-sh BuildRequires: coreutils BuildRequires: fdupes BuildRequires: sed -Requires(post): coreutils sed +%if ! 0%{?is_kotd} || ! %{?is_kotd_qa}%{!?is_kotd_qa:0} +BuildArch: noarch +%else +ExclusiveArch: do_not_build +%endif +Prefix: /usr/src + +%define src_install_dir usr/src/linux-%kernelrelease%variant + +# if undefined use legacy location of before SLE15 +%if %{undefined _rpmmacrodir} +%define _rpmmacrodir /etc/rpm +%endif + Source0: @TARBALL_URL@linux-%srcversion.tar.xz %if "@TARBALL_URL@" != "" Source1: @TARBALL_URL@linux-%srcversion.tar.sign @@ -122,12 +130,7 @@ Source113: patches.kabi.tar.bz2 Source114: patches.drm.tar.bz2 Source120: kabi.tar.bz2 Source121: sysctl.tar.bz2 -%if ! 0%{?is_kotd} || ! %{?is_kotd_qa}%{!?is_kotd_qa:0} -BuildArch: noarch -%else -ExclusiveArch: do_not_build -%endif -Prefix: /usr/src +Requires(post): coreutils sed # Source is only complete with devel files. Requires: kernel-devel%variant = %version-%source_rel Provides: %name = %version-%source_rel @@ -150,8 +153,6 @@ Recommends: kernel-install-tools %endif %obsolete_rebuilds %name -%(chmod +x %_sourcedir/{@SCRIPTS@}) - # Force bzip2 instead of lzma compression to # 1) allow install on older dist versions, and # 2) decrease build times (bsc#962356 boo#1175882) @@ -166,8 +167,15 @@ Linux kernel sources with many fixes and improvements. %source_timestamp + +%post +%relink_function + +relink linux-%kernelrelease%variant /usr/src/linux%variant + +%files -f nondevel.files + %package -n kernel-devel%variant -%obsolete_rebuilds kernel-devel%variant Summary: Development files needed for building kernel modules Group: Development/Sources AutoReqProv: off @@ -175,13 +183,24 @@ Provides: kernel-devel%variant = %version-%source_rel Provides: multiversion(kernel) Requires: kernel-macros Requires(post): coreutils +%obsolete_rebuilds kernel-devel%variant %description -n kernel-devel%variant Kernel-level headers and Makefiles required for development of external kernel modules. + %source_timestamp +%post -n kernel-devel%variant +%relink_function + +relink linux-%kernelrelease%variant /usr/src/linux%variant + +%files -n kernel-devel%variant -f devel.files +%ghost /usr/src/linux%variant +%doc /usr/share/doc/packages/* + # Note: The kernel-macros package intentionally does not provide # multiversion(kernel) nor is its name decorated with the variant (-rt) %package -n kernel-macros @@ -192,8 +211,17 @@ Provides: kernel-subpackage-macros %description -n kernel-macros This package provides the rpm macros and templates for Kernel Module Packages + %source_timestamp +%if "%variant" == "" +%files -n kernel-macros +%{_rpmmacrodir}/macros.kernel-source +/usr/lib/rpm/kernel-*-subpackage +%dir /usr/lib/rpm/kernel +/usr/lib/rpm/kernel/* +%endif + %package vanilla %obsolete_rebuilds %name-vanilla Summary: Vanilla Linux kernel sources with minor build fixes @@ -213,6 +241,11 @@ Vanilla Linux kernel sources with minor build fixes. %source_timestamp +%if %do_vanilla +%files vanilla +/usr/src/linux-%kernelrelease-vanilla +%endif + %prep echo "Symbol(s): %symbols" @@ -293,37 +326,6 @@ done # the future and be thus lower than the timestamps of files built from the # source (bnc#669669). ts="$(head -n1 %_sourcedir/source-timestamp)" -find %buildroot/usr/src/linux* ! -type l | xargs touch -d "$ts" - -%post -%relink_function - -relink linux-%kernelrelease%variant /usr/src/linux%variant - -%post -n kernel-devel%variant -%relink_function - -relink linux-%kernelrelease%variant /usr/src/linux%variant - -%files -f nondevel.files - -%files -n kernel-devel%variant -f devel.files -%ghost /usr/src/linux%variant -%doc /usr/share/doc/packages/* - -%if "%variant" == "" -%files -n kernel-macros -%{_rpmmacrodir}/macros.kernel-source -/usr/lib/rpm/kernel-*-subpackage -%dir /usr/lib/rpm/kernel -/usr/lib/rpm/kernel/* -%endif - - -%if %do_vanilla - -%files vanilla -/usr/src/linux-%kernelrelease-vanilla -%endif +find %buildroot/usr/src/linux* ! -type l -print0 | xargs -0 touch -d "$ts" %changelog diff --git a/rpm/kernel-spec-macros b/rpm/kernel-spec-macros index edd768a..55f613b 100644 --- a/rpm/kernel-spec-macros +++ b/rpm/kernel-spec-macros @@ -11,8 +11,10 @@ %endif # TW is usrmerged -%if %{undefined usrmerged} && 0%{?suse_version} >= 1550 +%if 0%{?suse_version} >= 1550 %define usrmerged 1 +%else +%define usrmerged 0 %endif # source_rel is the package release string, without the rebuild counter @@ -68,7 +70,7 @@ rm -f "$2" && ln -s "$1" "$2" \ } -%if 0%{?usrmerged} +%if %{usrmerged} %define kernel_module_directory /usr/lib/modules %else %define kernel_module_directory /lib/modules diff --git a/rpm/kernel-syms.spec.in b/rpm/kernel-syms.spec.in index 3c546f1..94b79aa 100644 --- a/rpm/kernel-syms.spec.in +++ b/rpm/kernel-syms.spec.in @@ -22,9 +22,6 @@ %include %_sourcedir/kernel-spec-macros Name: kernel-syms@VARIANT@ -Summary: Kernel Symbol Versions (modversions) -License: GPL-2.0-only -Group: Development/Sources Version: @RPMVERSION@ %if %using_buildservice %if 0%{?is_kotd} @@ -36,22 +33,25 @@ Release: @RELEASE@ %define kernel_source_release %(LC_ALL=C rpm -q kernel-devel%variant-%version --qf "%{RELEASE}" | grep -v 'not installed' || echo 0) Release: %kernel_source_release %endif +Summary: Kernel Symbol Versions (modversions) +License: GPL-2.0-only +Group: Development/Sources URL: https://www.kernel.org/ -AutoReqProv: off BuildRequires: coreutils -@REQUIRES@ -Requires: pesign-obs-integration -Provides: %name = %version-%source_rel -Provides: %name-srchash-%git_commit -Provides: multiversion(kernel) -Source: README.KSYMS -Requires: kernel-devel%variant = %version-%source_rel %if ! 0%{?is_kotd} || ! %{?is_kotd_qa}%{!?is_kotd_qa:0} ExclusiveArch: @ARCHS@ %else ExclusiveArch: do_not_build %endif Prefix: /usr/src +AutoReqProv: off +Source: README.KSYMS +@REQUIRES@ +Requires: pesign-obs-integration +Requires: kernel-devel%variant = %version-%source_rel +Provides: %name = %version-%source_rel +Provides: %name-srchash-%git_commit +Provides: multiversion(kernel) # Force bzip2 instead of lzma compression to # 1) allow install on older dist versions, and @@ -68,13 +68,14 @@ package dependencies. %source_timestamp -%prep - -%install -install -m 644 -D %{SOURCE0} %buildroot/%_docdir/%name/README.SUSE %files %dir %_docdir/%name %_docdir/%name/README.SUSE +%prep + +%install +install -m 644 -D %{SOURCE0} %buildroot/%_docdir/%name/README.SUSE + %changelog diff --git a/rpm/macros.kernel-source b/rpm/macros.kernel-source index 78b4126..c2ec2be 100644 --- a/rpm/macros.kernel-source +++ b/rpm/macros.kernel-source @@ -6,6 +6,7 @@ else \ print( "" ) \ end } +%usrmerged %{lua: susever = rpm.expand('%{?suse_version}'); if susever ~= '' and tonumber(susever) > 1550 then print('1') else print('0') end } %kernel_module_package_release 1 %kernel_module_package_buildreqs modutils kernel-syms kmod-compat suse-kernel-rpm-scriptlets %kernel_build_shell_package diff --git a/rpm/mkspec-dtb b/rpm/mkspec-dtb index 897b65f..2bb997b 100755 --- a/rpm/mkspec-dtb +++ b/rpm/mkspec-dtb @@ -107,8 +107,6 @@ sub generate_spec($$$) unless ($exclusive_arch eq 'none'); my $subpkg_desc = ""; - my $subpkg_post = ""; - my $subpkg_files = ""; my $all_supported_dtb = ""; my $DTS_folder = "arch/arm/boot/dts"; if ($exclusive_arch =~ /aarch64/) { @@ -150,7 +148,7 @@ sub generate_spec($$$) "%description -n $PKG_NAME\n" . "Device Tree files for $MACHINES.\n\n"; - $subpkg_post .= + $subpkg_desc .= "%post -n $PKG_NAME\n" . "cd /boot\n" . "# If /boot/dtb is a symlink, remove it, so that we can replace it.\n" . @@ -170,7 +168,7 @@ sub generate_spec($$$) $dtb_subdir .= "%dir %{dtbdir}$path\n"; } - $subpkg_files .= + $subpkg_desc .= "%ifarch aarch64 riscv64\n" . "%files -n $PKG_NAME -f $PKG_NAME.list\n" . "%else\n" . @@ -194,8 +192,6 @@ sub generate_spec($$$) $_ =~ s/\$DTS_folder/$DTS_folder/g; $_ =~ s/\$SUBPKG_DESC/$subpkg_desc/g; $_ =~ s/\$ALL_SUPPORTED_DTB/$all_supported_dtb/g; - $_ =~ s/\$SUBPKG_POST\n?/$subpkg_post/g; - $_ =~ s/\$SUBPKG_FILES\n?/$subpkg_files/g; print SPEC $_; } diff --git a/scripts/check-kernel-fix b/scripts/check-kernel-fix new file mode 100755 index 0000000..8ea73fe --- /dev/null +++ b/scripts/check-kernel-fix @@ -0,0 +1,379 @@ +#!/bin/bash +# vim: sw=4:sts=4:et + +. $(dirname "$0")/common-functions + +usage() +{ + echo "Check state of a kernel fix and eventually suggest needed actions" + echo + echo "Expect upstream kernel tree sha or CVE number as the parameter." + echo "The script checks whether the commit is already in the upstream" + echo "baseline or backported in kernel-source tree." + echo + echo "If backported, checks for CVE/bsc references and recommends adding these" + echo "if they are missing. (Requires VULNS_GIT pointing to" + echo "https://git.kernel.org/pub/scm/linux/security/vulns.git tree." + echo "This will also allow cve number instead of sha and it resolves proer" + echo "upstream commit automatically." + echo + echo "Also the script looks for \"Fixes:\" tag of the given \"sha\"." + echo "When defined, the script informs where the fix has to be backported." + echo + echo "The script also takes into account the hierarchy of branches." + echo "It checks all branches. But the action is proposed only for" + echo "the top level ones. The assumption is that the other branches" + echo "will get the fix via a merge." + echo + echo "If the patch has CVE number with CVSS score associated then limits" + echo "actions only to CVSS affected branches." + echo + echo "Usage: ${0##*/} [options] sha|CVE" + echo + echo "Parameters:" + echo " sha: sha of the upstream commit" + echo " cve: CVE-XXXX-YYYY of the upstream commit (requires VULNS_GIT)" + echo + echo "Options:" + echo " -h: help" + echo " -q: quiet mode (no progress)" + echo " -v: verbose mode: show state of each branch and even NOP actions" + echo " -r: refresh any cached data. Use if cve->sha or cve->cvss fails" + echo " (git pull VULNS_GIT, cve, bsc medata)" +} + +branch= +bprefix= +sha= +references= + +cve= +top_level= + +tmpdir=$(mktemp -d /tmp/${0##*/}.XXXXXX) +trap 'rm -rf "$tmpdir"' EXIT + +branch_state_file="$tmpdir/branch-state" +patch_file="$tmpdir/patches" +actions_file="$tmpdir/actions" + +print_branch_state() +{ + local msg="$@" + + if [ -n "$verbose_mode" ] ; then + echo "$msg" + elif [ -z "$quiet_mode" ] ; then + # show progress + echo -n "." + fi + + echo "$msg" >> "$branch_state_file" +} + +# Check state of the given branch and store +# The states are stored $tmpdir/branch-state are are the following: +# +# + nope: branch not affected +# + ok: branch has the fix and all references +# + missing_references: all or some references were not found +# + missing_patch: patch has to be backported +# + maybe_missing_patch: patch is missing and it is not known which commit +# introduced the bug +# +# When found, the name of the patch is stored into "$patch_file". +check_branch_state() +{ + local branch="$1" + local sha="$2" + shift 2 + local references="$@" + + [ -z "$branch" ] && fail "check_branch_state: No branch provided" + [ -z "$sha" ] && fail "check_branch_state: No sha provided" + + local patch= + local base= + local ref= + local missing_references= + local msg_prefix="$branch:$sha" + + + base=$(branch_base_ver $branch) + + # Already merged upstream? + if sha_merged_in_upstream_tag "$sha" "$base" ; then + print_branch_state "$msg_prefix:nope" + return + fi + + # Does the patch exist? + patch=$(sha_to_patch_in_branch "$sha" "$branch") + + if [ -n "$patch" ] ; then + echo "$branch:$patch" >> "$patch_file" + + # Check references + for ref in $references ; do + if ! patch_has_reference_in_branch "$patch" "$ref" "$branch" ; then + [ -n "$missing_references" ] && missing_references="$missing_references " + missing_references="$missing_references$ref" + fi + done + + if [ -z "$missing_references" ] ; then + print_branch_state "$msg_prefix:ok" + else + print_branch_state "$msg_prefix:missing_references:$missing_references" + fi + + return + fi + + # Sha is not backported + # Do we need to backport it because of the Fixes tag? + local sha_git_fixes=$(sha_get_upstream_git_fixes $sha) + if [ -n "$sha_git_fixes" ] ; then + local affected_by_git_fixes="$(affected_by_git_fixes "$branch" "$base" $sha_git_fixes)" + + if [ -n "$affected_by_git_fixes" ] ; then + print_branch_state "$msg_prefix:missing_patch:$affected_by_git_fixes" + else + print_branch_state "$msg_prefix:nope" + fi + + return + fi + + # missing git fixes + print_branch_state "$msg_prefix:maybe_missing_patch:$ref" +} + +print_action() +{ + local branch="$1" + local sha="$2" + local state="$3" + shift 3 + local references="$@" + + [ -z "$branch" ] && fail "print_action: No branch provided" + [ -z "$sha" ] && fail "print action: No sha provided" + [ -z "$state" ] && fail "print action: No state provided" + + # make sure tha the file exists + touch "$patch_file" + + patch= + action= + case "$state" in + missing_patch) + action="$branch: MANUAL: backport $sha ($references)" + ;; + + maybe_missing_patch) + action="$branch: MANUAL: might need backport of $sha ($references)" + ;; + + missing_references) + patch=$(grep "^$branch:" "$patch_file" | cut -d : -f 2) + if [ -n "$patch" ] ; then + ref_args=$(printf -- '-r %s ' $references) + action="$branch: RUN: scripts/cve_tools/add-missing-reference $ref_args$patch" + else + action="$branch: MANUAL: no patch has the references: $references" + fi + ;; + + nope) + [ -n "$verbose_mode" ] && action="$branch: NOPE: no problema for $sha $references" + ;; + + ok) + [ -n "$verbose_mode" ] && action="$branch: NOPE: up-to-date $sha $references" + ;; + + *) + echo "print_action: Unknown action: $action" >&2 + echo "for $branch:$sha:$state:$references" >&2 + exit 1 + ;; + esac + + if [ -n "$action" ] ; then + if [ ! -e "$actions_file" ] ; then + # first action + echo "ACTION NEEDED!" + touch "$actions_file" + fi + + echo "$action" + fi +} + +cvss_affects_branch() +{ + local branch="$1" + local cvss="$2" + + local ret=1 + if [[ "$branch" =~ .*-EB.* ]] + then + [ $cvss -ge 9 ] && ret=0 + elif [[ "$branch" =~ .*-GA.* ]] + then + [ $cvss -ge 7 ] && ret=0 + elif [[ "$branch" =~ .*-LTSS.* ]] + then + [ $cvss -ge 7 ] && ret=0 + else + ret=0 + fi + return $ret +} + +find_and_print_toplevel_actions() +{ + local branch="$1" + local cvss="${2%%.*}" + local action_parameters= + local merge_branch= + local mb_line= + local line= + local merge_found= + local state= + local mb_state= + + [ -z "$branch" ] && fail "find_and_print_toplevel_actions: No branch provided" + + grep "^$branch:" "$branch_state_file" | \ + while read line ; do + state=$(echo $line | cut -d: -f3) + + # We only want to print branches which really need CVE fix backported + # CVSS 9+ EB branches + # CVSS 7+ LTSS branches + # Any CVSS for regular branch + # If we just need to add a reference then print everything + if [ -n "$cvss" -a "$state" != "missing_references" ] + then + if ! cvss_affects_branch "$branch" "$cvss" + then + continue + fi + fi + + for merge_branch in $(print_merge_branches $branches_conf $branch) ; do + + # Make sure merge_branches are in the same cvss scope + if [ -n "$cvss" -a "$state" != "missing_references" ] + then + if ! cvss_affects_branch "$merge_branch" "$cvss" + then + continue + fi + fi + + # branch name might include '/', e.g. cve/linux-4.12 + mb_line=$(echo -n "$line" | sed -e "s|^$branch:|$merge_branch:|") + + # ignore the state when the same change is needed in a merge branch + if grep -q "^$mb_line$" "$branch_state_file" ; then + merge_found=1 + fi + + mb_state=$(echo $mb_line | cut -d: -f3) + + if [ "$state" == "missing_references" -o \ + "$state" == "missing_patch" -o \ + "$state" == "maybe_missing_patch" ] ; then + + # No action is needed when the patch is backported + # and has all the references in the merge branch + if [ "$mb_state" == "ok" ] ; then + merge_found=1 + fi + fi + + done + + if [ -z "$merge_found" ] ; then + # split line into parameters + print_action ${line//:/ } + fi + done +} + +verbose_mode= +quiet_mode= + +while getopts "hvrq" OPT +do + case $OPT in + h) + usage + exit + ;; + v) + verbose_mode=1 + ;; + r) + refresh=1 + ;; + q) + quiet_mode=1 + ;; + esac +done + +shift "$(($OPTIND-1))" + +[ -n "$verbose_mode" ] && quiet_mode= + +if [ -z "$1" ] ; then + echo "No references provided" + usage + exit 1 +fi + +sha=$1 +if ! sha_in_upstream "$1" ; then + sha=$(cve2sha $1 $refresh) + if [ -z "$sha" ] + then + [ -z "$VULNS_GIT" ] && fail "VULNS_GIT not defined. It has to point https://git.kernel.org/pub/scm/linux/security/vulns.git tree clone." + fail "Can find't sha in upstream: $1." + fi +fi + +print_upstream_sha_summary $sha + +cve=$(sha2cve $sha $refresh) +bsc= +if [ -n "$cve" ] +then + bsc=$(cve2bugzilla $cve $refresh) + cvss=$(cve2cvss $cve $refresh) + echo "Security fix for $cve $bsc with CVSS ${cvss:-unknown}" +else + # emulate no CVE fix as CVSS==0. This will typically happen + # for upstream commit with Fixes: which we want to target to + # less conservative branches only + cvss=0 +fi +references="$cve $bsc" + +branches_conf="$(fetch_branches $refresh)" + +# Check state of each branch +for_each_build_branch "$branches_conf" check_branch_state $sha $references + +# Newline after the dots showing progress +[ -z "$quiet_mode" ] && echo + +for_each_build_branch "$branches_conf" find_and_print_toplevel_actions $cvss + +if [ ! -e "$actions_file" ] ; then + echo "EVERYTHING IS OK!" +fi + diff --git a/scripts/common-functions b/scripts/common-functions new file mode 100644 index 0000000..2cd4a78 --- /dev/null +++ b/scripts/common-functions @@ -0,0 +1,502 @@ +#!/bin/bash +# vim: sw=4:sts=4:et + +fetch_cache() +{ + local CACHE_URL=$1 + local CACHE_FILE=$2 + local EXPIRE=$3 + local REFRESH=$4 + + [ -n "$REFRESH" ] && rm "$CACHE_FILE" + if [[ $(find "$CACHE_FILE" -mtime -${EXPIRE:-7} -print 2>/dev/null) \ + && -s "$CACHE_FILE" ]]; then + echo $CACHE_FILE + return + fi + curl -L "$CACHE_URL" -o "$CACHE_FILE" >/dev/null 2>&1 && echo $CACHE_FILE +} + +fetch_branches() +{ + local CACHED_BRANCHES="/tmp/$USER-branches.conf" + local URL="https://kerncvs.suse.de/branches.conf" + local REFRESH=$1 + branches=$CACHED_BRANCHES + fetch_cache $URL $CACHED_BRANCHES 7 $REFRESH +} + +fetch_cve2bugzilla() +{ + local CACHED_CVE2BSC="/tmp/$USER-cve2bugzilla" + local URL="https://gitlab.suse.de/security/cve-database/-/raw/master/data/cve2bugzilla" + local REFRESH=$1 + fetch_cache $URL $CACHED_CVE2BSC 1 $REFRESH +} + +cve2bugzilla() +{ + local CVE=$1 + local CVE2BUGZILLA=$(fetch_cve2bugzilla $2) + local NR_TO_REPORT=1 + # The first bsc should be the actual report others are product specific (e.g. LP) + for bsc in $(grep $CVE $CVE2BUGZILLA | cut -d: -f2 | head -n $NR_TO_REPORT) + do + echo -n "bsc#$bsc" + done +} + +fetch_cve2cvss() +{ + local CACHED_CVE2CVSS="/tmp/$USER-cve2cvss" + local URL="http://ftp.suse.com/pub/projects/security/yaml/suse-cvss-scores.yaml" + local REFRESH=$1 + fetch_cache $URL $CACHED_CVE2CVSS 1 $REFRESH +} + +cve2cvss() +{ + local CVE=$1 + local REFRESH=$2 + local CVE2CVSS=$(fetch_cve2cvss $REFRESH) + local cvss="$(grep $CVE -A3 $CVE2CVSS | grep score:)" + + echo ${cvss##*:} +} + +cve2sha() +{ + local arg=$1 + local REFRESH=$2 + sha="$(cd $VULNS_GIT; [ -n "$REFRESH" ] && git pull >/dev/null 2>&1; scripts/cve_search $arg 2>/dev/null | cut -d" " -f7)" + + if [ $(echo $sha | wc -c) -eq 41 ] + then + echo $sha + fi +} + +sha2cve() +{ + local arg=$1 + local REFRESH=$2 + cve_sha="$(cd $VULNS_GIT; [ -n "$REFRESH" ] && git pull >/dev/null 2>&1; scripts/cve_search $arg 2>/dev/null | cut -d" " -f1,7)" + + if [ $(echo ${cve_sha##* } | wc -c) -eq 41 ] + then + echo ${cve_sha%% *} + fi +} + +current_branch() +{ + git branch --show-current +} + +print_merge_branches() +{ + local branches_conf="$1" + local branch="$2" + local merge_branch= + + [ -z "$branches_conf" ] && fail "megre_branches: No branches_conf provided" + [ -z "$branch" ] && fail "merge_branches: No branch provided" + + for word in $(grep -w "^$branch:" "$branches_conf") ; do + if [ "${word#merge:}" != "$word" ] ; then + merge_branch="${word#merge:}" + merge_branch="${merge_branch#-}" + [ -z "$merge_branch" ] && fail "print_merge_branges: non supported syntax" + echo "$merge_branch" + fi + done +} + +for_each_build_branch() +{ + local branches_conf="$1" + local fn="$2" + shift 2 + local args="$@" + + grep -w build "$branches_conf" | grep -v -E "^(master|vanilla|linux-next|stable|slowroll)" | \ + while read line ; do + line=${line%%\#*} + branch=${line%%:*} + + # empty line or comment + if [ -z "$branch" ] ; then + continue + fi + + $fn $branch $args || break + done +} + +fail() +{ + echo $* >&2 + exit 1 +} + +branch_base_ver() +{ + local branch="origin/$1" + git show-ref --verify --quiet "refs/remotes/${branch}" || fail "$branch invalid branch" + + local base_ver="v$(git grep SRCVERSION $branch -- rpm/config.sh | sed 's@.*=@@')" + + echo $base_ver +} + +sha_get_upstream_git_fixes() +{ + local sha=$1 + local upstream_git=${2:-$LINUX_GIT} + + [ -z "$sha" ] && fail "No commit provided" + [ -z "$upstream_git" ] && fail "No upstream git tree" + + git --git-dir="$upstream_git/.git" show $sha | grep -i "^[[:space:]]*fixes:" | awk '{print $2}' +} + +print_upstream_sha_info() +{ + local sha=$1 + local upstream_git=${2:-$LINUX_GIT} + + echo -n "$(git --git-dir="$upstream_git/.git" show -s --pretty='format:%h ("%s")' $sha) merged " + git --git-dir="$upstream_git/.git" describe --contains --abbrev=0 --match="v*" $sha +} + +print_upstream_sha_summary() +{ + local sha=$1 + local upstream_git=${2:-$LINUX_GIT} + + print_upstream_sha_info $sha $upstream_git + for fix in $(sha_get_upstream_git_fixes $1 $upstream_git) + do + echo -n "Fixes: " + print_upstream_sha_info $fix $upstream_git + done +} + +sha_merged_in_upstream_tag() +{ + local sha=$1 + local base=$2 + local upstream_git=${3:-$LINUX_GIT} + + [ -z "$sha" ] && fail "sha_merged_in_upstream_tag: No sha provided" + [ -z "$base" ] && fail "sha_merged_in_upstream_tag: No base provided" + [ -z "$upstream_git" ] && fail "sha_merged_in_upstream_tag: No upstream git tree" + + git --git-dir="$LINUX_GIT/.git" merge-base --is-ancestor "$sha" "$base" 2>/dev/null +} + +sha_in_upstream() +{ + local sha=$1 + local upstream_git=${2:-$LINUX_GIT} + + [ -z "$sha" ] && fail "sha_in_upstream: No sha provided" + [ -z "$upstream_git" ] && fail "sha_in_upstream: No upstream git tree" + + sha_merged_in_upstream_tag $sha origin/master $upstream_git +} + + +sha_has_git_fixes() +{ + local sha="$1" + local base="$2" + local upstream_git=${3:-$LINUX_GIT} + + [ -z "$sha" ] && fail "sha_affected_by_git_fixes: No sha provided" + [ -z "$base" ] && fail "sha_affected_by_git_fixes: No tag provided" + [ -z "$upstream_git" ] && fail "sha_affected_by_git_fixes: No upstream_git provided" + + # Check git fixes when the bug was introduced + local git_fixes="$(sha_get_upstream_git_fixes $sha)" + + test -n "$git_fixes" +} + + +affected_by_git_fixes() +{ + local branch="$1" + local base="$2" + shift 2 + local git_fixes="$@" + + [ -z "$branch" ] && fail "affected_by_git_fixes: No branch provided" + [ -z "$base" ] && fail "affected_by_git_fixes: No tag provided" + [ -z "$git_fixes" ] && fail "affected_by_git_fixes: No git fixes provided" + + # Check git fixes when the bug was introduced + local git_fix= + local affected_by= + + for git_fix in $git_fixes ; do + local needs_fix= + + # Is it merged in the upstream base kernel? + if sha_merged_in_upstream_tag "$git_fix" "$base" ; then + needs_fix=1 + fi + + # Do we have it backported? + if sha_merged_in_suse_tree "$git_fix" "$branch" ; then + needs_fix=1 + fi + + if [ -n "$needs_fix" ] ; then + if [ -z "$affected_by" ] ; then + affected_by="$git_fix" + else + affected_by="$affected_by $git_fix" + fi + fi + done + + if [ -n "$affected_by" ] ; then + echo "Fixes: $affected_by" + fi +} + +sha_to_patch_in_branch() +{ + local sha="$1" + local branch="$2" + + [ -z "$sha" ] && fail "sha_to_patch_in_branch: No sha provided" + [ -z "$branch" ] && fail "sha_to_patch_in_branch: No branch provided" + + branch_file=$(git --no-pager grep -l -i "^git-commit[[:space:]]*:[[:space:]]*$sha" "origin/$branch") + + echo "${branch_file#origin/$branch:}" +} + +sha_to_patch() +{ + local sha="$1" + + [ -z "$sha" ] && fail "sha_to_patch: No sha provided" + + git --no-pager grep -l -i "^git-commit[[:space:]]*:[[:space:]]*$sha" +} + +sha_merged_in_suse_tree() +{ + local sha="$1" + local branch="$2" + + [ -z "$sha" ] && fail "sha_merged_in_suse_tree: No sha provided" + [ -z "$branch" ] && fail "sha_merged_in_suse_tree: No branch provided" + + local patch=$(sha_to_patch_in_branch "$sha" "$branch") + + test -n "$patch" +} + +references_to_patches_in_branch() +{ + local branch="$1" + shift + local references="$@" + + [ -z "$branch" ] && fail "references_to_patches_in_branch: No branch provided" + [ -z "$references" ] && fail "references_to_patches_in_branch: No references provided" + + local pattern_prefix="^references[[:space:]]*:[[:space:]]*" + local pattern= + + for ref in $references ; do + [ -n "$pattern" ] && pattern="$pattern|" + pattern="$pattern$pattern_prefix$ref" + done + + branch_files=$(git --no-pager grep -l -E -i "$pattern" "origin/$branch") + + for branch_file in $branch_files ; do + echo "${branch_file#origin/$branch:}" + done +} + +patch_has_reference() +{ + local ref="$1" + local patch="$2" + + [ -z "$patch" ] && fail "No patch provided" + [ -z "$ref" ] && fail "No reference provided" + + grep -q -i "^references:.*$ref" "$patch" +} + +patch_has_reference_in_branch() +{ + local patch="$1" + local ref="$2" + local branch="$3" + + [ -z "$patch" ] && fail "patch_has_reference_in_branch: No patch provided" + [ -z "$ref" ] && fail "patch_has_reference_in_branch: No reference provided" + [ -z "$branch" ] && fail "patch_has_reference_in_branch: No branch provided" + + git --no-pager grep -w -q -i "^references:.*$ref" "origin/$branch" -- "$patch" +} + +sha_has_reference_in_branch() +{ + local sha="$1" + local ref="$2" + local branch="$3" + local patch= + + [ -z "$sha" ] && fail "sha_has_reference_in_branch: No sha provided" + [ -z "$ref" ] && fail "sha_has_reference_in_branch: No reference provided" + [ -z "$branch" ] && fail "sha_has_reference_in_branch: No branch provided" + + patch=$(sha_to_patch_in_branch "$sha" "$branch") + + if [ -n "$patch" ] ; then + patch_has_reference_in_branch "$patch" "$ref" "$branch" + else + # no patch, no refence needed + true + fi +} + +patch_add_reference() +{ + local ref=$1 + local patch=$2 + + [ -z "$patch" ] && fail "No patch provided" + [ -z "$ref" ] && fail "No reference provided" + + if ! patch_has_reference "$ref" "$patch" ; then + local references=$(grep -i "^references:" $patch | sed -e 's/^[Rr]eferences:[[:space:]]//') + + references="$references $ref" + patch-tag --delete "references" "$patch" + patch-tag --add "References=$references" "$patch" + + change_to_commit=1 + fi + + if ! patch_has_reference "$ref" "$patch" ; then + fail "Failed to add reference '$ref' into $patch" + fi +} + +current_branch_state() +{ + local state_line + + status_line=$(git status | grep "Your branch") + + [ -z "$status_line" ] && fail "Can't get status of the current branch" + + if (echo "$status_line" | grep -q "up to date") ; then + echo "up to date" + elif (echo "$status_line" | grep -q "ahead") ; then + echo "ahead" + elif (echo "$status_line" | grep -q "behind.*fast-forwarded") ; then + echo "behind-ff" + elif (echo "$status_line" | grep -q "have diverged") ; then + echo "diverged" + else + echo "unknown" + fi +} + +push_list_name() +{ + local type=$1 + + [ -z "$type" ] && fail "push_list_name: called with no type" + + echo "push-list.$type" +} + +push_list_has_branch() +{ + local type=$1 + local branch=$2 + local file= + + [ -z "$type" ] && fail "push_list_has_branch: called with no type" + [ -z "$branch" ] && fail "push_list_has_branch: called with no branch" + + file=$(push_list_name $type) + + if [ -e "$file" ] ; then + grep -q "^branch\$" "$file" + else + false + fi +} + +push_list_add_branch() +{ + local type="$1" + local branch="$2" + local file= + + [ -z "$type" ] && fail "push_list_update: called with no type" + [ -z "$branch" ] && fail "push_list_has_branch: called with no branch" + + if ! $(push_list_has_branch $type $branch) ; then + file=$(push_list_name $type) + echo "$branch" >> "$file" + fi +} + +queue_push() +{ + local branch_state= + + branch_state=$(current_branch_state) + + case "$branch_state" in + "up to date") + // nope + ;; + ahead) + push_list_add_branch "ready" $(current_branch) + ;; + *) + push_list_add_branch "manual" $(current_branch) + ;; + esac +} + +push_list_msg() +{ + local type="$1" + local msg="$2" + local file= + + [ -z "$type" ] && fail "push_list_msg: called with no type" + [ -z "$msg" ] && fail "push_list_msg: called with no message" + + file=$(push_list_name "$type") + + if ! grep -q "^$msg$" "$file" ; then + echo "$msg" >> "$file" + fi +} + +log_fail() +{ + local msg="$1" + + [ -z "$msg" ] && fail "log_failure: called with no message" + + push_list_msg "failure" "$msg" + fail "$msg" +} diff --git a/scripts/cve_tools/add-missing-reference b/scripts/cve_tools/add-missing-reference new file mode 100755 index 0000000..72af708 --- /dev/null +++ b/scripts/cve_tools/add-missing-reference @@ -0,0 +1,31 @@ +#!/usr/bin/python3 + +import argparse +import sys +import os.path + +scriptsdir = os.path.dirname(__file__) +sys.path.append(os.path.join(scriptsdir, "../git_sort")) +from patch import Patch + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Add references to patch file") + parser.add_argument("-r", "--reference", action="append", + help="bsc# or CVE token used to tag the patch file. The option can be used more times.") + parser.add_argument("patches", help="Patch files.", + nargs=argparse.REMAINDER) + args = parser.parse_args() + + + added_refs = list(args.reference) + for f in args.patches: + with Patch(open(f, "r+b")) as patch: + refs = "".join(patch.get("References")) + refs = list(refs.replace(",", " ").split()) + new_refs = refs + [r for r in added_refs if not r in refs] + if new_refs == refs: + continue + patch.change("References", " ".join(new_refs)) + + diff --git a/scripts/cve_tools/cve2metadata.sh b/scripts/cve_tools/cve2metadata.sh new file mode 100755 index 0000000..d0dd51d --- /dev/null +++ b/scripts/cve_tools/cve2metadata.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# +# Usage: +# cve2metadata.sh CVE-NUM[...CVE-NUM] +# +# expects: +# VULNS_GIT to point to vulns DB git tree (clone from https://git.kernel.org/pub/scm/linux/security/vulns.git) + +if [ -z "$VULNS_GIT" -o ! -d "$VULNS_GIT" ] +then + echo "VULNS_GIT should point to vulns git tree" >&2 + echo "clone from https://git.kernel.org/pub/scm/linux/security/vulns.git" >&2 + exit 1 +fi + +. scripts/common-functions + +while [ $# -gt 0 ] +do + arg=$1 + cve_sha="$(cd $VULNS_GIT; scripts/cve_search $arg 2>/dev/null | cut -d" " -f1,7)" + cve=${cve_sha%% *} + sha=${cve_sha##* } + if [ $(echo $sha | wc -c) -eq 41 ] + then + echo -n "$sha" + cvss="$(cve2cvss $cve)" + echo -n " score:${cvss:-unknown}" + bsc="$(cve2bugzilla $cve)" + echo " $cve $bsc" + else + echo $arg cannot be resolved to a CVE >&2 + fi + shift +done diff --git a/scripts/git-commit-msg b/scripts/git-commit-msg index 5adcd80..2e9fe87 100755 --- a/scripts/git-commit-msg +++ b/scripts/git-commit-msg @@ -21,23 +21,23 @@ commit_file="$1" +# Empty means abort anyway +test -z "$(grep -vE '^#|^\s*$' "$commit_file")" && exit + +git_dir=$(git rev-parse --git-dir) +test -f "$git_dir/MERGE_HEAD" && exit + err=0 -git diff-index --name-status --diff-filter=AM --cached HEAD | ( -while read stat file garbage; do - case "$file" in - patches.*/*) - new_refs=$(git diff-index -p --cached HEAD "$file" | \ - awk '/^+References:/ {for (i=2; i <= NF; i++) refs[$i]++} - /^-References:/ {for (i=2; i <= NF; i++) refs[$i]--} - END { for (r in refs) if (refs[r] > 0) print(r)}') - for ref in $new_refs ; do - grep -q $ref $commit_file || { echo "New reference '$ref' missing in the commit message." ; err=1 ; } - done - ;; - esac +new_refs=$(git diff-index -M -p --cached HEAD "patches.*/*" | \ + awk -v FPAT='[^, ]+' \ + '/^+References:/ {for (i=2; i <= NF; i++) refs[$i]++} + /^-References:/ {for (i=2; i <= NF; i++) refs[$i]--} + END { for (r in refs) if (refs[r] > 0) print(r)}') +for ref in $new_refs ; do + grep -q $ref $commit_file || { echo "New reference '$ref' missing in the commit message." ; err=1 ; } done if test "$err" != 0; then echo "Aborting." exit "$err" -fi ) || exit +fi diff --git a/scripts/git_sort/git_sort.py b/scripts/git_sort/git_sort.py index 46a745e..b3eb3aa 100755 --- a/scripts/git_sort/git_sort.py +++ b/scripts/git_sort/git_sort.py @@ -240,6 +240,8 @@ remotes = ( Head(RepoURL("git://git.linux-nfs.org/projects/anna/linux-nfs.git"), "linux-next"), Head(RepoURL("acme/linux.git"), "perf/core"), Head(RepoURL("acme/linux.git"), "perf-tools"), + Head(RepoURL("perf/perf-tools.git"), "perf-tools"), + Head(RepoURL("perf/perf-tools-next.git"), "perf-tools-next"), Head(RepoURL("will/linux.git"), "for-joerg/arm-smmu/updates"), Head(RepoURL("herbert/crypto-2.6.git"), "master"), Head(RepoURL("jarkko/linux-tpmdd"), "next"), diff --git a/scripts/log2 b/scripts/log2 index 7ef1ca9..cde8650 100755 --- a/scripts/log2 +++ b/scripts/log2 @@ -424,7 +424,7 @@ if only_patches; then commit_single_patches || exit else # FIXME: -a should not be the default - do_commit -a || exit + do_commit $no_edit -a || exit fi branch=$(get_branch_name) diff --git a/scripts/patch-tag b/scripts/patch-tag index 7db3cfd..b0db0c5 100755 --- a/scripts/patch-tag +++ b/scripts/patch-tag @@ -89,9 +89,6 @@ my $VERSION = "0.11"; my $default_comment = "from:subject:patch-mainline:Git-commit:references:signed-off-by:acked-by:reviewed-by:"; my $post_comment_tags = "signed-off-by acked-by reviewed-by"; -# when these are in the bk comment, and non-bk section, use the non-bk one -my $non_dup_tags = "from subject"; - # command line options my %tags; # hash of tags to be replaced my %print_tags; # hash of tags for printing to stdout @@ -109,7 +106,6 @@ my $replace_empty_comment; # new value for empty non-tag comment # globals my @output_array; # the finished comment as printed my @all_tags; # array used to do final tag output -my @bk_footer_tags; # holds signed-off-by and acked-by from bk my %replaced_tags; # copy of %tags so we can detect which ones are found my $replace = 0; # should we overwrite the patch file? my $outfh; # current output file handle (could be a temp file) @@ -197,40 +193,15 @@ sub process_tag($$) { delete $replaced_tags{$t}; } -# tags that get pulled from bk comments get special treatment -sub process_bk_tag($$) { - my ($tag, $value) = @_; - my $always_tags = "signed-off-by acked-by reviewed-by"; - - if ($always_tags =~ m/$tag/) { - push @bk_footer_tags, [$tag, $value]; - return; - } - # don't pull the bk tag out if it already exists - foreach my $v (@all_tags) { - $v =~ m/$tag_re/; - my $t = $1; - if (lc($t) eq $tag) { - return; - } - } - $replaced_tags{$tag} = $value; -} - # look for any tags that we were asked to print or replace from # the command line. Build the array of tags found in the comment sub check_tags($$$) { my ($infh, $buf, $line) = @_; - my $filespec = ""; - my $bk_comment = 0; my $orig_line; - my $bkold_style = 0; again: $orig_line = $line; - if ($bk_comment) { - $line =~ s/^#\s*//; - } + # Preserve git From line if ($line =~ m/$git_re/) { push @output_array, $orig_line; @@ -246,77 +217,9 @@ again: $line =~ m/(^[^:\s#]*):\s*(.*)/s; my $lc_tag = lc($1); my $value = $2; - if ($bk_comment) { - # only pull out specific tags from the bk comment stream - if ($post_comment_tags =~ m/$lc_tag/) { - process_bk_tag($lc_tag, $value); - } - if (!%print_tags) { - push @output_array, $orig_line; - } - } else { - process_tag($lc_tag, $value); - } + process_tag($lc_tag, $value); } elsif (!%print_tags) { push @output_array, $orig_line; - } - # did we find a bitkeeper style patch header? - # if so, just parse the whole thing here - if ($line =~ m/^# The following is the BitKeeper ChangeSet Log/ || - $line =~ m/^# This is a BitKeeper generated diff -Nru style patch/) { - # there are two bk patch styles - # old: - # # ------------------- - # # date author changset - # # subject - # new: - # # - # # Changeset - # # date time author - # # subject - - $bk_comment = 1; - my $next = read_next_line($infh, $buf); - push @output_array, $next if (!%print_tags); - if ($next =~ m/^# ---------/) { - $bkold_style = 1; - } else { - # read empty line - $next = read_next_line($infh, $buf); - push @output_array, $next if (!%print_tags); - } - $next = read_next_line($infh, $buf); - push @output_array, $next if (!%print_tags); - my @words = split /\s+/, $next; - if ($bkold_style) { - process_bk_tag('from', $words[2]); - } else { - process_bk_tag('from', $words[3]); - } - $next = read_next_line($infh, $buf); - push @output_array, $next if (!%print_tags); - chomp($next); - $next =~ s/^#\s*//; - # sometimes the bk comment is empty and there is just a filename - # there's no good way to tell. - if (!($next =~ m/(.*\/)+?.*?\.(c|h|s)$/)) { - process_bk_tag('subject', $next); - } - - # we've read the from tag and subject tag, the goto again - # will loop through the ChangeSet Log section looking - # for other tags - } - if ($bk_comment) { - $line = read_next_line($infh, $buf); - # old style bk comments end with a line full of dashes - # new style bk comments end with a # filename or no # at all - if (($bkold_style && $line =~ m/^# --------/) || - (!$bkold_style && $line =~ m/^# \S|^[^#]/)) { - push @$buf, $line; - return; - } - goto again; } } @@ -645,7 +548,6 @@ foreach my $guarded_input (@files) { %replaced_tags = (%tags, %add_tags); @all_tags = (); @output_array = (); - @bk_footer_tags = (); my %tmp_always_add = %always_add_tags; if ($replace) { @@ -679,9 +581,6 @@ foreach my $guarded_input (@files) { while($output_array[scalar(@output_array)-1] =~ m/^\s*\n$/) { pop @output_array; } - foreach my $h (@bk_footer_tags) { - process_tag($h->[0], $h->[1]); - } # add any new tags left over, but do From and Subject first add_output_tag('from', \%replaced_tags); add_output_tag('subject', \%replaced_tags); diff --git a/scripts/sequence-patch.sh b/scripts/sequence-patch.sh index bdfac19..8e6bc7c 100755 --- a/scripts/sequence-patch.sh +++ b/scripts/sequence-patch.sh @@ -499,7 +499,7 @@ fi # Create fresh $SCRATCH_AREA/linux-$SRCVERSION. if ! [ -d $ORIG_DIR ]; then unpack_tarball "$SRCVERSION" "$ORIG_DIR" "$URL" - find $ORIG_DIR -type f | xargs chmod a-w,a+r + find $ORIG_DIR -type f -exec chmod a-w,a+r {} + fi if $VANILLA; then diff --git a/scripts/update-symvers b/scripts/update-symvers index d09b17e..d611ad3 100755 --- a/scripts/update-symvers +++ b/scripts/update-symvers @@ -165,6 +165,9 @@ add_flat_files() { set -- $tmpdir/usr/src/linux-*-obj/*/*/Module.$type fi if [ $# -eq 0 ]; then + set -- $tmpdir/usr/lib/modules/*/symtypes.gz + fi + if [ $# -eq 0 ]; then echo "No $type file found in $rpm" >&2 status=1 return @@ -188,6 +191,11 @@ add_flat_files() { flavor=${flavor#*/} flavor=${flavor%/Module.symvers} ;; + $tmpdir/usr/lib/modules/*/*) + flavor=${file##*/modules/} + flavor=${flavor%/*} + flavor=${flavor##*-} + ;; esac target=kabi/$arch/$type-$flavor @@ -421,7 +429,7 @@ for rpm in "${rpms[@]}"; do rm -rf $tmpdir/{boot,usr} rpm2cpio "$rpm" \ | ( cd $tmpdir && cpio -dim --quiet './boot/symvers-*' './boot/symsets-*' \ - './boot/symtypes-*' './usr/src/linux-*-obj/*/*/Module.symvers' ) + './usr/lib/modules/*/symtypes.gz' './boot/symtypes-*' './usr/src/linux-*-obj/*/*/Module.symvers' ) if $do_symvers; then add_flat_files symvers diff --git a/series.conf b/series.conf index 0e61a36..78e4984 100644 --- a/series.conf +++ b/series.conf @@ -33088,6 +33088,7 @@ patches.suse/qed-Add-new-TLV-to-request-PF-to-update-MAC-in-bulle.patch patches.suse/sfc-set-and-clear-interrupt-affinity-hints.patch patches.suse/lan78xx-Read-MAC-address-from-DT-if-present.patch + patches.suse/lan78xx-Add-support-to-dump-lan78xx-registers.patch patches.suse/tun-do-not-compute-the-rxhash-if-not-needed.patch patches.suse/bpftool-Support-new-prog-types-and-attach-types.patch patches.suse/libbpf-Support-guessing-post_bind-4-6-progs.patch @@ -33226,6 +33227,7 @@ patches.suse/bnxt_en-Reserve-rings-at-driver-open-if-none-was-res.patch patches.suse/udp-remove-stray-export-symbol.patch patches.suse/lan78xx-Lan7801-Support-for-Fixed-PHY.patch + patches.suse/lan78xx-Modify-error-messages.patch patches.suse/opa_vnic-Just-use-skb_get_hash-instead-of-skb_tx_has.patch patches.suse/mlx4-Don-t-bother-using-skb_tx_hash-in-mlx4_en_selec.patch patches.suse/net-Revoke-export-for-__skb_tx_hash-update-it-to-jus.patch @@ -35566,6 +35568,7 @@ patches.suse/iio-buffer-fix-the-function-signature-to-match-imple patches.suse/0001-btrfs-quota-Set-rescan-progress-to-u64-1-if-we-hit-l.patch patches.suse/r8152-napi-hangup-fix-after-disconnect + patches.suse/net-lan78xx-Allow-for-VLAN-headers-in-timeout-calcs.patch patches.suse/nfp-flower-fix-mpls-ether-type-detection.patch patches.suse/nfp-reject-binding-to-shared-blocks.patch patches.suse/nfp-cast-sizeof-to-int-when-comparing-with-error-cod.patch @@ -37601,6 +37604,7 @@ patches.suse/net-Remove-some-unneeded-semicolon.patch patches.suse/net-cisco-enic-Replace-GFP_ATOMIC-with-GFP_KERNEL.patch patches.suse/tun-not-use-hardcoded-mask-value.patch + patches.suse/net-usb-Use-ARRAY_SIZE-instead-of-calculating-the-ar.patch patches.suse/ethtool-Remove-trailing-semicolon-for-static-inline.patch patches.suse/bnxt_en-Update-firmware-interface-version-to-1.9.2.2.patch patches.suse/bnxt_en-Adjust-timer-based-on-ethtool-stats-block-us.patch @@ -42008,6 +42012,7 @@ patches.suse/nfp-validate-rtsym-accesses-fall-within-the-symbol.patch patches.suse/nfp-separate-VXLAN-and-GRE-feature-handling.patch patches.suse/0012-net-lan78xx-Bail-out-if-lan78xx_get_endpoints-fails.patch + patches.suse/net-lan78xx-Make-declaration-style-consistent.patch patches.suse/qed-Utilize-FW-8.37.7.0.patch patches.suse/net-mlx5-Change-flow-counters-addlist-type-to-single.patch patches.suse/net-mlx5-Add-new-list-to-store-deleted-flow-counters.patch @@ -42033,6 +42038,7 @@ patches.suse/sch_htb-Remove-local-SKB-queue-handling-code.patch patches.suse/sch_netem-Move-private-queue-handler-to-generic-loca.patch patches.suse/infiniband-nes-Use-skb_peek_next-and-skb_queue_walk.patch + patches.suse/lan78xx-Do-not-access-skb_queue_head-list-pointers-d.patch patches.suse/bnx2fc_fcoe-use-skb_queue_walk_safe patches.suse/net-Add-and-use-skb_mark_not_on_list.patch patches.suse/net-Add-and-use-skb_list_del_init.patch @@ -52872,6 +52878,7 @@ patches.suse/crypto-caam-free-resources-in-case-caam_rng-registra.patch patches.suse/crypto-skcipher-Unmap-pages-after-an-external-error.patch patches.suse/crypto-cavium-zip-Add-missing-single_release.patch + patches.suse/net-lan78xx-Merge-memcpy-lexx_to_cpus-to-get_unalign.patch patches.suse/ax88179_178a-Merge-memcpy-le32_to_cpus-to-get_unalig.patch patches.suse/net-usb-Merge-cpu_to_le32s-memcpy-to-put_unaligned_l.patch patches.suse/e1000e-Use-dev_get_drvdata-where-possible.patch @@ -54120,6 +54127,7 @@ patches.suse/net-ena-ethtool-support-set_channels-callback.patch patches.suse/net-smc-improve-close-of-terminated-socket patches.suse/net-sched-Avoid-using-yield-in-a-busy-waiting-loop.patch + patches.suse/net-lan78xx-remove-set-but-not-used-variable-event.patch patches.suse/fsl-fman-don-t-touch-liodn-base-regs-reserved-on-non.patch patches.suse/dpaa_eth-defer-probing-after-qbman.patch patches.suse/dpaa_eth-remove-redundant-code.patch @@ -56533,6 +56541,9 @@ patches.suse/net-dsa-bcm_sf2-Ensure-correct-sub-node-is-parsed.patch patches.suse/NFSv4-pnfs-Return-valid-stateids-in-nfs_layout_find_.patch patches.suse/NFS-direct.c-Fix-memory-leak-of-dreq-when-nfs_get_lo.patch + patches.suse/NFS-commit-errors-should-be-fatal.patch + patches.suse/NFS-Fix-O_DIRECT-commit-verifier-handling.patch + patches.suse/NFS-Fix-a-request-reference-leak-in-nfs_direct_write.patch patches.suse/NFS-Fix-memory-leaks-in-nfs_pageio_stop_mirroring.patch patches.suse/0001-mm-memory_hotplug.c-only-respect-mem-parameter-durin.patch patches.suse/include-linux-swapops-h-correct-guards-for-non_swap_entry.patch @@ -57435,6 +57446,7 @@ patches.suse/nfsd-Fix-svc_xprt-refcnt-leak-when-setup-callback-cl.patch patches.suse/crypto-cavium-nitrox-Fix-nitrox_get_first_device-whe.patch patches.suse/net-sunrpc-Fix-off-by-one-issues-in-rpc_ntop6.patch + patches.suse/NFS-Fix-direct-WRITE-throughput-regression.patch patches.suse/drm-sun4i-hdmi-ddc-clk-Fix-size-of-m-divider.patch patches.suse/ALSA-usb-audio-Fix-inconsistent-card-PM-state-after-.patch patches.suse/ALSA-usb-audio-Add-vendor-product-and-profile-name-f.patch @@ -58969,6 +58981,7 @@ patches.suse/ima-Remove-semicolon-at-the-end-of-ima_get_binary_ru.patch patches.suse/ibmvnic-store-RX-and-TX-subCRQ-handle-array-in-ibmvn.patch patches.suse/ibmvnic-Fix-use-after-free-of-VNIC-login-response-bu.patch + patches.suse/net-atheros-switch-from-pci_-to-dma_-API.patch patches.suse/ibmvnic-compare-adapter-init_done_rc-with-more-reada.patch patches.suse/ibmvnic-improve-ibmvnic_init-and-ibmvnic_reset_init.patch patches.suse/ibmvnic-remove-never-executed-if-statement.patch @@ -59405,6 +59418,8 @@ patches.suse/net-b44-fix-error-return-code-in-b44_init_one.patch patches.suse/inet_diag-Fix-error-path-to-cancel-the-meseage-in-in.patch patches.suse/net-usb-qmi_wwan-Set-DTR-quirk-for-MR400.patch + patches.suse/atl1c-fix-error-return-code-in-atl1c_probe.patch + patches.suse/atl1e-fix-error-return-code-in-atl1e_probe.patch patches.suse/mlxsw-core-Use-variable-timeout-for-EMAD-retries.patch patches.suse/page_frag-Recover-from-memory-pressure.patch patches.suse/net-mlx5-Add-handling-of-port-type-in-rule-deletion.patch @@ -59466,6 +59481,7 @@ patches.suse/0004-bonding-wait-for-sysfs-kobject-destruction-before-fr.patch patches.suse/usbnet-ipheth-fix-connectivity-with-iOS-14.patch patches.suse/net-af_iucv-set-correct-sk_protocol-for-child-sockets + patches.suse/tun-honor-IOCB_NOWAIT-flag.patch patches.suse/ibmvnic-fix-call_netdevice_notifiers-in-do_reset.patch patches.suse/ibmvnic-notify-peers-when-failover-and-migration-hap.patch patches.suse/ibmvnic-skip-tx-timeout-reset-while-in-resetting.patch @@ -59564,6 +59580,7 @@ patches.suse/cfg80211-initialize-rekey_data.patch patches.suse/mac80211-mesh-fix-mesh_pathtbl_init-error-path.patch patches.suse/can-softing-softing_netdev_open-fix-error-handling.patch + patches.suse/net-stmmac-free-tx-skb-buffer-in-stmmac_resume.patch patches.suse/net-mlx4_en-Avoid-scheduling-restart-task-if-it-is-a.patch patches.suse/net-mlx4_en-Handle-TX-error-CQE.patch patches.suse/i40e-avoid-premature-Rx-buffer-reuse.patch @@ -59631,6 +59648,7 @@ patches.suse/mm-memory_failure-always-pin-the-page-in-madvise_inj.patch patches.suse/mm-don-t-wake-kswapd-prematurely-when-watermark-boosting-is-disabled.patch patches.suse/wimax-fix-duplicate-initializer-warning.patch + patches.suse/net-usb-lan78xx-Remove-lots-of-set-but-unused-ret-va.patch patches.suse/ibmvnic-Ensure-that-device-queue-memory-is-cache-lin.patch patches.suse/ibmvnic-Correctly-re-enable-interrupts-in-NAPI-polli.patch patches.suse/ibmvnic-Use-netdev_alloc_skb-instead-of-alloc_skb-to.patch @@ -59644,6 +59662,7 @@ patches.suse/ath10k-Fix-an-error-handling-path.patch patches.suse/ath10k-Release-some-resources-in-an-error-handling-p.patch patches.suse/ibmvnic-add-some-debugs.patch + patches.suse/net-mlx5-Properly-convey-driver-version-to-firmware.patch patches.suse/Bluetooth-Fix-null-pointer-dereference-in-hci_event_.patch patches.suse/Bluetooth-Fix-slab-out-of-bounds-read-in-hci_le_dire.patch patches.suse/Bluetooth-btusb-Fix-detection-of-some-fake-CSR-contr.patch @@ -59910,6 +59929,7 @@ patches.suse/powerpc-perf-Exclude-kernel-samples-while-counting-e.patch patches.suse/powerpc-pseries-memhotplug-Quieten-some-DLPAR-operat.patch patches.suse/net-bcmgenet-Fix-a-resource-leak-in-an-error-handlin.patch + patches.suse/net-allwinner-Fix-some-resources-leak-in-the-error-h.patch patches.suse/net-core-introduce-__netdev_notify_peers.patch patches.suse/use-__netdev_notify_peers-in-ibmvnic.patch patches.suse/qlcnic-Fix-error-code-in-probe.patch @@ -59967,6 +59987,7 @@ patches.suse/i40e-Fix-Error-I40E_AQ_RC_EINVAL-when-removing-VFs.patch patches.suse/net-mvpp2-Add-TCAM-entry-to-drop-flow-control-pause-.patch patches.suse/net-mvpp2-prs-fix-PPPoE-with-ipv6-packet-parse.patch + patches.suse/ethernet-ucc_geth-fix-definition-and-size-of-ucc_get.patch patches.suse/ethernet-ucc_geth-fix-use-after-free-in-ucc_geth_rem.patch patches.suse/net-mvpp2-Fix-GoP-port-3-Networking-Complex-Control-.patch patches.suse/ibmvnic-fix-login-buffer-memory-leak.patch @@ -60769,6 +60790,7 @@ patches.suse/USB-serial-usb_wwan-fix-TIOCSSERIAL-jiffies-conversi.patch patches.suse/USB-serial-usb_wwan-fix-unprivileged-TIOCCSERIAL.patch patches.suse/USB-serial-fix-return-value-for-unsupported-ioctls.patch + patches.suse/usb-dwc3-core-Do-core-softreset-when-switch-mode.patch patches.suse/firmware-raspberrypi-Keep-count-of-all-consumers.patch patches.suse/firmware-raspberrypi-Introduce-devm_rpi_firmware_get.patch patches.suse/bus-qcom-Put-child-node-before-return.patch @@ -60869,6 +60891,7 @@ patches.suse/drm-amdkfd-fix-build-error-with-AMD_IOMMU_V2-m.patch patches.suse/i915_vma-Rename-vma_lookup-to-i915_vma_lookup patches.suse/drm-omap-fix-misleading-indentation-in-pixinc.patch + patches.suse/0001-drm-bridge-panel-Cleanup-connector-on-bridge-detach.patch patches.suse/drm-amdgpu-fix-NULL-pointer-dereference.patch patches.suse/0003-drm-msm-Small-msm_gem_purge-fix.patch patches.suse/drm-msm-mdp5-Configure-PP_SYNC_HEIGHT-to-double-the-.patch @@ -61126,6 +61149,7 @@ patches.suse/cifs-add-shutdown-support.patch patches.suse/cifs-detect-dead-connections-only-when-echoes-are-enabled-.patch patches.suse/cifs-use-echo_interval-even-when-connection-not-ready-.patch + patches.suse/ARM-9064-1-hw_breakpoint-Do-not-directly-check-the-e.patch patches.suse/ACPI-custom_method-fix-potential-use-after-free-issu.patch patches.suse/ACPI-custom_method-fix-a-possible-memory-leak.patch patches.suse/ftrace-handle-commands-when-closing-set_ftrace_filter-file.patch @@ -61187,6 +61211,7 @@ patches.suse/nvmet-use-new-ana_log_size-instead-the-old-one.patch patches.suse/blk-mq-Swap-two-calls-in-blk_mq_exit_queue.patch patches.suse/squashfs-fix-divide-error-in-calculate_skip.patch + patches.suse/userfaultfd-release-page-in-error-path-to-avoid-BUG_ON.patch patches.suse/usb-typec-ucsi-Put-fwnode-in-any-case-during-probe.patch patches.suse/usb-dwc3-omap-improve-extcon-initialization.patch patches.suse/usb-fotg210-hcd-Fix-an-error-message.patch @@ -61264,8 +61289,10 @@ patches.suse/gve-Correct-SKB-queue-index-validation.patch patches.suse/cxgb4-avoid-accessing-registers-when-clearing-filter.patch patches.suse/ixgbe-fix-large-MTU-request-from-VF.patch + patches.suse/net-macb-ensure-the-device-is-available-before-acces.patch patches.suse/net-hso-fix-control-request-directions.patch patches.suse/net-usb-fix-memory-leak-in-smsc75xx_bind.patch + patches.suse/bnx2x-Fix-missing-error-code-in-bnx2x_iov_init_one.patch patches.suse/bpf-Wrap-aux-data-inside-bpf_sanitize_info-container.patch patches.suse/bpf-Fix-mask-direction-swap-upon-off-reg-sign-change.patch patches.suse/bpf-No-need-to-simulate-speculative-domain-for-immed.patch @@ -61288,6 +61315,7 @@ patches.suse/scsi-libsas-Use-_safe-loop-in-sas_resume_port patches.suse/scsi-vmw_pvscsi-Set-correct-residual-data-length.patch patches.suse/scsi-target-qla2xxx-Wait-for-stop_phase1-at-WWN-remo.patch + patches.suse/USB-usbfs-Don-t-WARN-about-excessively-large-memory-.patch patches.suse/misc-uss720-fix-memory-leak-in-uss720_probe.patch patches.suse/usb-typec-tcpm-Use-LE-to-CPU-conversion-when-accessi.patch patches.suse/USB-serial-ftdi_sio-add-IDs-for-IDS-GmbH-Products.patch @@ -61318,6 +61346,7 @@ patches.suse/vfio-platform-fix-module_put-call-in-error-flow.patch patches.suse/ALSA-timer-Fix-master-timer-notification.patch patches.suse/nfc-fix-NULL-ptr-dereference-in-llcp_sock_getname-af.patch + patches.suse/ethernet-myri10ge-Fix-missing-error-code-in-myri10ge.patch patches.suse/i40e-add-correct-exception-tracing-for-XDP.patch patches.suse/ixgbevf-add-correct-exception-tracing-for-XDP.patch patches.suse/Bluetooth-fix-the-erroneous-flush_work-order.patch @@ -61865,6 +61894,7 @@ patches.suse/i40e-Fix-log-TC-creation-failure-when-max-num-of-que.patch patches.suse/can-raw-raw_setsockopt-fix-raw_rcv-panic-for-sock-UA.patch patches.suse/mlx4-Fix-missing-error-code-in-mlx4_load_one.patch + patches.suse/net-qla3xxx-fix-schedule-while-atomic-in-ql_sem_spin.patch patches.suse/net-mlx5-Fix-flow-table-chaining.patch patches.suse/net-mlx5e-Fix-nullptr-in-mlx5e_hairpin_get_mdev.patch patches.suse/sctp-fix-return-value-check-in-__sctp_rcv_asconf_loo.patch @@ -62035,6 +62065,11 @@ patches.suse/xen-netfront-don-t-read-data-from-request-on-the-rin.patch patches.suse/xen-netfront-disentangle-tx_skb_freelist.patch patches.suse/xen-netfront-don-t-trust-the-backend-response-data-b.patch + patches.suse/lan78xx-Fix-white-space-and-style-issues.patch + patches.suse/lan78xx-Add-missing-return-code-checks.patch + patches.suse/lan78xx-Fix-exception-on-link-speed-change.patch + patches.suse/lan78xx-Fix-partial-packet-errors-on-suspend-resume.patch + patches.suse/lan78xx-Fix-race-conditions-in-suspend-resume-handli.patch patches.suse/msft-hv-2430-net-mana-Move-NAPI-from-EQ-to-CQ.patch patches.suse/msft-hv-2431-net-mana-Add-support-for-EQ-sharing.patch patches.suse/msft-hv-2432-net-mana-Add-WARN_ON_ONCE-in-case-of-CQE-read-overfl.patch @@ -62241,6 +62276,7 @@ patches.suse/qed-Handle-management-FW-error.patch patches.suse/msft-hv-2437-net-mana-Prefer-struct_size-over-open-coded-arithmet.patch patches.suse/bnxt_en-Clean-up-completion-ring-page-arrays-complet.patch + patches.suse/bnx2x-Fix-enabling-network-interfaces-without-VFs.patch patches.suse/ptp-dp83640-don-t-define-PAGE0.patch patches.suse/xen-balloon-use-a-kernel-thread-instead-a-workqueue.patch patches.suse/PM-base-power-don-t-try-to-use-non-existing-RTC-for-.patch @@ -62263,6 +62299,7 @@ patches.suse/s390-qeth-fix-deadlock-during-failing-recovery patches.suse/qed-rdma-don-t-wait-for-resources-under-hw-error-rec.patch patches.suse/net-mlx4_en-Don-t-allow-aRFS-for-encapsulated-packet.patch + patches.suse/usb-dwc3-core-balance-phy-init-and-exit.patch patches.suse/Re-enable-UAS-for-LaCie-Rugged-USB3-FW-with-fk-quirk.patch patches.suse/usb-storage-Add-quirk-for-ScanLogic-SL11R-IDE-older-.patch patches.suse/usb-musb-tusb6010-uninitialized-data-in-tusb_fifo_wr.patch @@ -63197,6 +63234,7 @@ patches.suse/can-mcba_usb-mcba_usb_start_xmit-fix-double-dev_kfre.patch patches.suse/gfs2-assign-rgrp-glock-before-compute_bitstructs.patch patches.suse/gfs2-Make-sure-FITRIM-minlen-is-rounded-up-to-fs-block-size.patch + patches.suse/Input-add-bounds-checking-to-input_set_capability.patch patches.suse/cifs-do-not-skip-link-targets-when-an-I-O-fails.patch patches.suse/cifs-convert-the-path-to-utf16-in-smb2_query_info_compound.patch patches.suse/cifs-change-smb2_query_info_compound-to-use-a-cached-fid-if-availa.patch @@ -63293,6 +63331,7 @@ patches.suse/x86-fpu-prevent-fpu-state-corruption.patch patches.suse/writeback-Avoid-skipping-inode-writeback-846a3351ddfe.patch patches.suse/cgroup-cpuset-Remove-cpus_allowed-mems_allowed-setup-in-cpuset_init_smp.patch + patches.suse/net-Fix-features-skip-in-for_each_netdev_feature.patch patches.suse/dim-initialize-all-struct-fields.patch patches.suse/s390-ctcm-fix-variable-dereferenced-before-check patches.suse/s390-ctcm-fix-potential-memory-leak @@ -63595,6 +63634,7 @@ patches.suse/spmi-trace-fix-stack-out-of-bound-access-in-SPMI-tracing-functions.patch patches.suse/usb-host-Fix-refcount-leak-in-ehci_hcd_ppc_of_probe.patch patches.suse/usb-ohci-nxp-Fix-refcount-leak-in-ohci_hcd_nxp_probe.patch + patches.suse/usb-dwc3-core-Do-not-perform-GCTL_CORE_SOFTRESET-dur.patch patches.suse/KVM-x86-Mark-TSS-busy-during-LTR-emulation-_after_-a.patch patches.suse/KVM-x86-Set-error-code-to-segment-selector-on-LLDT-L.patch patches.suse/KVM-nVMX-Set-UMIP-bit-CR4_FIXED1-MSR-when-emulating-.patch @@ -63700,6 +63740,7 @@ patches.suse/fs-add-mode_strip_sgid-helper.patch patches.suse/fs-Add-missing-umask-strip-in-vfs_tmpfile.patch patches.suse/fs-move-S_ISGID-stripping-into-the-vfs_-helpers.patch + patches.suse/nfs-only-issue-commit-in-DIO-codepath-if-we-have-unc.patch patches.suse/NFSv4.1-RECLAIM_COMPLETE-must-handle-EACCES.patch patches.suse/SUNRPC-Reinitialise-the-backchannel-request-buffers-.patch patches.suse/Makefile-link-with-z-noexecstack-no-warn-rwx-segment.patch @@ -64342,6 +64383,7 @@ patches.suse/media-platform-ti-Add-missing-check-for-devm_regulat.patch patches.suse/media-rc-Fix-use-after-free-bugs-caused-by-ene_tx_ir.patch patches.suse/media-usb-siano-Fix-use-after-free-bugs-caused-by-do.patch + patches.suse/netfilter-ctnetlink-fix-possible-refcount-leak-in-ct.patch patches.suse/vc_screen-modify-vcs_size-handling-in-vcs_read.patch patches.suse/vc_screen-don-t-clobber-return-value-in-vcs_read.patch patches.suse/ext4-fail-ext4_iget-if-special-inode-unallocated.patch @@ -64506,6 +64548,7 @@ patches.suse/xfs-fix-rm_offset-flag-handling-in-rmap-keys.patch patches.suse/NFSv4.1-Always-send-a-RECLAIM_COMPLETE-after-establi.patch patches.suse/SUNRPC-remove-the-maximum-number-of-retries-in-call_.patch + patches.suse/fs-introduce-lock_rename_child-helper.patch patches.suse/RDMA-mlx4-Prevent-shift-wrapping-in-set_user_sq_size.patch patches.suse/ext4-fix-i_disksize-exceeding-i_size-problem-in-pari.patch patches.suse/Input-raspberrypi-ts-fix-refcount-leak-in-rpi_ts_pro.patch @@ -64568,6 +64611,9 @@ patches.suse/msft-hv-2818-Revert-PCI-hv-Fix-a-timing-issue-which-causes-kdump-.patch patches.suse/msft-hv-2819-PCI-hv-Add-a-per-bus-mutex-state_lock.patch patches.suse/fs-sysv-Null-check-to-prevent-null-ptr-deref-bug.patch + patches.suse/fs-Establish-locking-order-for-unrelated-directories.patch + patches.suse/fs-Lock-moved-directories.patch + patches.suse/fs-Restrict-lock_two_nondirectories-to-non-directory.patch patches.suse/SUNRPC-Fix-UAF-in-svc_tcp_listen_data_ready.patch patches.suse/NFSD-add-encoding-of-op_recall-flag-for-write-delega.patch patches.suse/svcrdma-Prevent-page-release-when-nothing-was-receiv.patch @@ -64630,6 +64676,8 @@ patches.suse/media-videodev2.h-Fix-struct-v4l2_input-tuner-index-.patch patches.suse/media-usb-siano-Fix-warning-due-to-null-work_func_t-.patch patches.suse/Bluetooth-L2CAP-Fix-use-after-free-in-l2cap_sock_rea.patch + patches.suse/fs-no-need-to-check-source.patch + patches.suse/fs-don-t-assume-arguments-are-non-NULL.patch patches.suse/drm-amdgpu-Fix-potential-fence-use-after-free-v2.patch patches.suse/ring-buffer-Fix-deadloop-issue-on-reading-trace_pipe.patch patches.suse/netfilter-nf_tables-prevent-OOB-access-in-nft_byteor.patch @@ -64785,6 +64833,7 @@ patches.suse/s390-zcrypt-don-t-leak-memory-if-dev_set_name-fails.patch patches.suse/netfilter-xt_sctp-validate-the-flag_info-count.patch patches.suse/netfilter-xt_u32-validate-user-space-input.patch + patches.suse/bpf-sockmap-Fix-preempt_rt-splat-when-using-raw_spin.patch patches.suse/gve-fix-frag_list-chaining.patch patches.suse/veth-Fixing-transmit-return-status-for-dropped-packe.patch patches.suse/net-sched-sch_qfq-Fix-UAF-in-qfq_dequeue.patch @@ -64808,6 +64857,9 @@ patches.suse/nfsd-fix-change_info-in-NFSv4-RENAME-replies.patch patches.suse/scsi-qla2xxx-Use-raw_smp_processor_id-instead-of-smp.patch patches.suse/scsi-qla2xxx-Fix-NULL-vs-IS_ERR-bug-for-debugfs_crea.patch + patches.suse/NFS-Fix-error-handling-for-O_DIRECT-write-scheduling.patch + patches.suse/NFS-Fix-O_DIRECT-locking-issues.patch + patches.suse/NFS-More-O_DIRECT-accounting-fixes-for-error-paths.patch patches.suse/NFS-pNFS-Report-EINVAL-errors-from-connect-to-the-se.patch patches.suse/ipv4-fix-null-deref-in-ipv4_link_failure.patch patches.suse/team-fix-null-ptr-deref-when-team-device-type-is-cha.patch @@ -64836,6 +64888,8 @@ patches.suse/ceph-fix-incorrect-revoked-caps-assert-in-ceph_fill_f.patch patches.suse/libceph-use-kernel_connect.patch patches.suse/Input-powermate-fix-use-after-free-in-powermate_conf.patch + patches.suse/perf-x86-lbr-Filter-vsyscall-addresses.patch + patches.suse/usb-hub-Guard-against-accesses-to-uninitialized-BOS-.patch patches.suse/usb-xhci-xhci-ring-Use-sysdev-for-mapping-bounce-buf.patch patches.suse/xhci-Clear-EHB-bit-only-at-end-of-interrupt-handler.patch patches.suse/nfc-nci-fix-possible-NULL-pointer-dereference-in-sen.patch @@ -64849,11 +64903,13 @@ patches.suse/xfrm6-fix-inet6_dev-refcount-underflow-problem.patch patches.suse/nvme-sanitize-metadata-bounce-buffer-for-reads.patch patches.suse/scsi-qla2xxx-Fix-double-free-of-dsd_list-during-driv.patch + patches.suse/pNFS-flexfiles-Check-the-layout-validity-in-ff_layou.patch patches.suse/USB-serial-option-add-Telit-LE910C4-WWX-0x1035-compo.patch patches.suse/USB-serial-option-add-entry-for-Sierra-EM9191-with-n.patch patches.suse/USB-serial-option-add-Fibocom-to-DELL-custom-modem-F.patch patches.suse/s390-pci-fix-iommu-bitmap-allocation.patch patches.suse/perf-Disallow-mis-matched-inherited-group-reads.patch + patches.suse/nfsd-lock_rename-needs-both-directories-to-live-on-t.patch patches.suse/net-usb-smsc95xx-Fix-uninit-value-access-in-smsc95xx.patch patches.suse/r8152-Increase-USB-control-msg-timeout-to-5000ms-as-.patch patches.suse/r8152-Run-the-unload-routine-if-we-have-errors-durin.patch @@ -64865,14 +64921,17 @@ patches.suse/PCI-Prevent-xHCI-driver-from-claiming-AMD-VanGogh-US.patch patches.suse/libnvdimm-of_pmem-Use-devm_kstrdup-instead-of-kstrdu-6fd4.patch patches.suse/scsi-qla2xxx-Use-FIELD_GET-to-extract-PCIe-capabilit.patch + patches.suse/fs-ocfs2-check-status-values.patch patches.suse/s390-cmma-fix-initial-kernel-address-space-page-table-walk.patch patches.suse/s390-mm-add-missing-arch_set_page_dat-call-to-vmem_crst_alloc.patch patches.suse/s390-mm-add-missing-arch_set_page_dat-call-to-gmap-allocations.patch patches.suse/s390-cmma-fix-detection-of-DAT-pages.patch patches.suse/s390-cmma-fix-handling-of-swapper_pg_dir-and-invalid_pg_dir.patch + patches.suse/usb-storage-set-1.50-as-the-lower-bcdDevice-for-olde.patch patches.suse/gfs2-ignore-negated-quota-changes.patch patches.suse/xfs-fix-units-conversion-error-in-xfs_bmap_del_extent_delay.patch patches.suse/xfs-make-sure-maxlen-is-still-congruent-with-prod-when-rounding-down.patch + patches.suse/SUNRPC-Fix-RPC-client-cleaned-up-the-freed-pipefs-de.patch patches.suse/Fix-termination-state-for-idr_for_each_entry_ul.patch patches.suse/gve-Fixes-for-napi_poll-when-budget-is-0.patch patches.suse/netfilter-nf_tables-fix-pointer-math-issue-in-nft_by.patch @@ -64886,7 +64945,9 @@ patches.suse/s390-dasd-protect-device-queue-against-concurrent-access.patch patches.suse/nvmet-nul-terminate-the-NQNs-passed-in-the-connect-c.patch patches.suse/usb-config-fix-iteration-issue-in-usb_get_bos_descri.patch + patches.suse/USB-serial-option-don-t-claim-interface-4-for-ZTE-MF.patch patches.suse/USB-serial-option-fix-FM101R-GL-defines.patch + patches.suse/USB-serial-option-add-Fibocom-L7xx-modules.patch patches.suse/ipv4-igmp-fix-refcnt-uaf-issue-when-receiving-igmp-q.patch patches.suse/dm-verity-don-t-perform-FEC-for-failed-readahead-IO-0193.patch patches.suse/dm-verity-align-struct-dm_verity_fec_io-properly-38bc.patch @@ -64921,25 +64982,44 @@ patches.suse/EDAC-thunderx-Fix-possible-out-of-bounds-string-access.patch patches.suse/x86-lib-Fix-overflow-when-counting-digits.patch patches.suse/powerpc-pseries-memhp-Fix-access-beyond-end-of-drmem.patch + patches.suse/powerpc-mm-Fix-null-pointer-dereference-in-pgtable_c.patch patches.suse/powerpc-powernv-Add-a-null-pointer-check-in-opal_eve.patch patches.suse/powerpc-powernv-Add-a-null-pointer-check-in-opal_pow.patch patches.suse/mtd-Fix-gluebi-NULL-pointer-dereference-caused-by-ftl-notifier.patch patches.suse/ACPI-extlog-fix-NULL-pointer-dereference-check.patch patches.suse/pstore-ram_core-fix-possible-overflow-in-persistent_ram_init_ecc.patch + patches.suse/NFSv4.1-pnfs-Ensure-we-handle-the-error-NFS4ERR_RETU.patch + patches.suse/pNFS-Fix-the-pnfs-block-driver-s-calculation-of-layo.patch + patches.suse/s390-ptrace-handle-setting-of-fpc-register-correctly.patch patches.suse/KVM-s390-fix-setting-of-fpc-register.patch patches.suse/md-bypass-block-throttle-for-superblock-update-d6e0.patch patches.suse/Revert-md-raid5-Wait-for-MD_SB_CHANGE_PENDING-in-rai.patch + patches.suse/reiserfs-Avoid-touching-renamed-directory-if-parent-.patch + patches.suse/ocfs2-Avoid-touching-renamed-directory-if-parent-doe.patch + patches.suse/udf_rename-only-access-the-child-content-on-cross-di.patch + patches.suse/ext2-Avoid-reading-renamed-directory-if-parent-does-.patch + patches.suse/ext4-don-t-access-the-source-subdirectory-content-on.patch + patches.suse/f2fs-Avoid-reading-renamed-directory-if-parent-does-.patch + patches.suse/rename-fix-the-locking-of-subdirectories.patch + patches.suse/kill-lock_two_inodes.patch + patches.suse/rename-avoid-a-deadlock-in-the-case-of-parents-havin.patch + patches.suse/drm-radeon-check-the-alloc_workqueue-return-value-in.patch + patches.suse/drivers-amd-pm-fix-a-use-after-free-in-kv_parse_powe.patch patches.suse/media-pvrusb2-fix-use-after-free-on-context-disconne.patch patches.suse/KVM-s390-vsie-Fix-STFLE-interpretive-execution-identification.patch patches.suse/x86-kvm-Do-not-try-to-disable-kvmclock-if-it-was-not-enabl.patch + patches.suse/usb-typec-class-fix-typec_altmode_put_partner-to-put.patch patches.suse/mlxsw-spectrum_acl_tcam-Fix-NULL-pointer-dereference.patch patches.suse/nvmet-tcp-Fix-a-kernel-panic-when-host-sends-an-inva.patch patches.suse/nvmet-tcp-fix-a-crash-in-nvmet_req_complete.patch patches.suse/nvmet-tcp-remove-boilerplate-code.patch patches.suse/nvmet-tcp-Fix-the-H2C-expected-PDU-len-calculation.patch + patches.suse/ceph-fix-deadlock-or-deadcode-of-misusing-dget.patch patches.suse/apparmor-avoid-crash-when-parsed-profile-name-is-emp.patch patches.suse/xen-netback-don-t-produce-zero-size-SKB-frags.patch + patches.suse/tcp-make-sure-init-the-accept_queue-s-spinlocks-once.patch patches.suse/net-rds-Fix-UBSAN-array-index-out-of-bounds-in-rds_c.patch + patches.suse/ipv6-init-the-accept_queue-s-spinlocks-in-inet6_crea.patch patches.suse/netfilter-nf_tables-reject-QUEUE-DROP-verdict-parame.patch patches.suse/tracing-trigger-Fix-to-return-error-if-failed-to-alloc-snapshot.patch patches.suse/gve-Fix-skb-truesize-underestimation.patch @@ -64956,8 +65036,37 @@ patches.suse/x86-bugs-Use-ALTERNATIVE-instead-of-mds_user_clear-static-.patch patches.suse/KVM-VMX-Use-BT-JNC-i.e.-EFLAGS.CF-to-select-VMRESUME-vs.-V.patch patches.suse/KVM-VMX-Move-VERW-closer-to-VMentry-for-MDS-mitigation.patch + patches.suse/lan78xx-enable-auto-speed-configuration-for-LAN7850-.patch patches.suse/net-usb-dm9601-fix-wrong-return-value-in-dm9601_mdio.patch + patches.suse/Bluetooth-rfcomm-Fix-null-ptr-deref-in-rfcomm_check_-2535b848.patch patches.suse/tomoyo-fix-UAF-write-bug-in-tomoyo_write_control.patch + patches.suse/net-lan78xx-fix-runtime-PM-count-underflow-on-link-s.patch + patches.suse/netfilter-nf_tables-disallow-anonymous-set-with-time.patch + patches.suse/aoe-fix-the-potential-use-after-free-problem-in-aoec.patch + patches.suse/x86-mmio-Disable-KVM-mitigation-when-X86_FEATURE_CLEAR_CPU.patch + patches.suse/Documentation-hw-vuln-Add-documentation-for-RFDS.patch + patches.suse/x86-rfds-Mitigate-Register-File-Data-Sampling-RFDS.patch + patches.suse/KVM-x86-Export-RFDS_NO-and-RFDS_CLEAR-to-guests.patch + patches.suse/SUNRPC-fix-a-memleak-in-gss_import_v2_context.patch + patches.suse/SUNRPC-fix-some-memleaks-in-gssx_dec_option_array.patch + patches.suse/NFSD-Reset-cb_seq_status-after-NFS4ERR_DELAY.patch + patches.suse/NFSD-Retransmit-callbacks-after-client-reconnects.patch + patches.suse/wifi-ath10k-fix-NULL-pointer-dereference-in-ath10k_w.patch + patches.suse/x86-CPU-AMD-Update-the-Zenbleed-microcode-revisions.patch + patches.suse/net-sunrpc-Fix-an-off-by-one-in-rpc_sockaddr2uaddr.patch + patches.suse/NFS-Fix-an-off-by-one-in-root_nfs_cat.patch + patches.suse/s390-vtime-fix-average-steal-time-calculation.patch + patches.suse/scsi-qla2xxx-Prevent-command-send-on-chip-reset.patch + patches.suse/scsi-qla2xxx-Fix-N2N-stuck-connection.patch + patches.suse/scsi-qla2xxx-Split-FCE-EFT-trace-control.patch + patches.suse/scsi-qla2xxx-Update-manufacturer-detail.patch + patches.suse/scsi-qla2xxx-NVME-FCP-prefer-flag-not-being-honored.patch + patches.suse/scsi-qla2xxx-Fix-command-flush-on-cable-pull.patch + patches.suse/scsi-qla2xxx-Fix-double-free-of-the-ha-vp_map-pointe.patch + patches.suse/scsi-qla2xxx-Fix-double-free-of-fcport.patch + patches.suse/scsi-qla2xxx-Change-debug-message-during-driver-unlo.patch + patches.suse/scsi-qla2xxx-Delay-I-O-Abort-on-PCI-error.patch + patches.suse/scsi-qla2xxx-Update-version-to-10.02.09.200-k.patch # dhowells/linux-fs keys-uefi patches.suse/0001-KEYS-Allow-unrestricted-boot-time-addition-of-keys-t.patch @@ -64966,6 +65075,9 @@ patches.suse/0005-MODSIGN-Allow-the-db-UEFI-variable-to-be-suppressed.patch patches.suse/0006-modsign-Use-secondary-trust-keyring-for-module-signi.patch + # bpf/bpf + patches.suse/bpf-sockmap-Prevent-lock-inversion-deadlock-in-map-d.patch + # out-of-tree patches patches.suse/net-mvpp2-fix-condition-for-setting-up-link-interrup.patch patches.suse/cifs-handle-netapp-error-codes.patch @@ -65097,9 +65209,6 @@ patches.suse/CVE-Mitigation-for-CVE-2022-29900-and-CVE-2022-29901.patch - patches.suse/Documentation-hw-vuln-Add-documentation-for-RFDS.patch - patches.suse/x86-rfds-Mitigate-Register-File-Data-Sampling-RFDS.patch - patches.suse/KVM-x86-Export-RFDS_NO-and-RFDS_CLEAR-to-guests.patch ######################################################## # S/390 @@ -65314,6 +65423,9 @@ patches.suse/Revert-mei-me-enable-asynchronous-probing.patch + # bsc#1220445 / CVE-2023-52474 + patches.suse/IB-hfi1-Fix-bugs-with-non-PAGE_SIZE-end-multi-iovec-.patch + ######################################################## # Filesystem ######################################################## @@ -65397,6 +65509,7 @@ patches.suse/sunrpc-make-lockless-test-safe.patch patches.suse/SUNRPC-always-clear-XPRT_SOCK_CONNECTING-before-xprt.patch patches.suse/nfsd-drop-st_mutex-and-rp_mutex-before-calling-move_.patch + patches.suse/NFS-add-atomic_open-for-NFSv3-to-handle-O_TRUNC-corr.patch ######################################################## # CIFS @@ -66033,6 +66146,8 @@ patches.kabi/preserve-KABI-for-struct-sfp_socket_ops.patch patches.kabi/kabi-restore-return-type-of-dst_ops-gc-callback.patch patches.kabi/team-Hide-new-member-header-ops.patch + patches.kabi/pNFS-Fix-the-pnfs-block-driver-s-calculation-of-layo.patch + patches.kabi/dwc3-switch-to-a-global-mutex.patch ######################################################## # You'd better have a good reason for adding a patch