From: Greg Kroah-Hartman Date: Thu, 28 Dec 2023 12:13:30 +0000 (+0000) Subject: 6.6-stable patches X-Git-Tag: v6.1.70~20 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=938975d5fedf80a228747eea441c7dd7a8bfea51;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: 9p-prevent-read-overrun-in-protocol-dump-tracepoint.patch drm-i915-dmc-don-t-enable-any-pipe-dmc-events.patch drm-i915-reject-async-flips-with-bigjoiner.patch dt-bindings-nvmem-mxs-ocotp-document-fsl-ocotp.patch input-soc_button_array-add-mapping-for-airplane-mode-button.patch net-9p-avoid-freeing-uninit-memory-in-p9pdu_vreadf.patch net-avoid-build-bug-in-skb-extension-length-calculation.patch net-ks8851-fix-tx-stall-caused-by-tx-buffer-overrun.patch net-rfkill-gpio-set-gpio-direction.patch net-stmmac-fix-incorrect-flag-check-in-timestamp-interrupt.patch nfsd-call-nfsd_last_thread-before-final-nfsd_put.patch smb-client-fix-oob-in-cifsd-when-receiving-compounded-resps.patch smb-client-fix-oob-in-smb2_query_info_init.patch smb-client-fix-oob-in-smbcalcsize.patch smb-client-fix-potential-oob-in-cifs_dump_detail.patch --- diff --git a/queue-6.6/9p-prevent-read-overrun-in-protocol-dump-tracepoint.patch b/queue-6.6/9p-prevent-read-overrun-in-protocol-dump-tracepoint.patch new file mode 100644 index 00000000000..68c5cad81d6 --- /dev/null +++ b/queue-6.6/9p-prevent-read-overrun-in-protocol-dump-tracepoint.patch @@ -0,0 +1,102 @@ +From a931c6816078af3e306e0f444f492396ce40de31 Mon Sep 17 00:00:00 2001 +From: JP Kobryn +Date: Mon, 4 Dec 2023 12:23:20 -0800 +Subject: 9p: prevent read overrun in protocol dump tracepoint + +From: JP Kobryn + +commit a931c6816078af3e306e0f444f492396ce40de31 upstream. + +An out of bounds read can occur within the tracepoint 9p_protocol_dump. In +the fast assign, there is a memcpy that uses a constant size of 32 (macro +named P9_PROTO_DUMP_SZ). When the copy is invoked, the source buffer is not +guaranteed match this size. It was found that in some cases the source +buffer size is less than 32, resulting in a read that overruns. + +The size of the source buffer seems to be known at the time of the +tracepoint being invoked. The allocations happen within p9_fcall_init(), +where the capacity field is set to the allocated size of the payload +buffer. This patch tries to fix the overrun by changing the fixed array to +a dynamically sized array and using the minimum of the capacity value or +P9_PROTO_DUMP_SZ as its length. The trace log statement is adjusted to +account for this. Note that the trace log no longer splits the payload on +the first 16 bytes. The full payload is now logged to a single line. + +To repro the orignal problem, operations to a plan 9 managed resource can +be used. The simplest approach might just be mounting a shared filesystem +(between host and guest vm) using the plan 9 protocol while the tracepoint +is enabled. + +mount -t 9p -o trans=virtio + +The bpftrace program below can be used to show the out of bounds read. +Note that a recent version of bpftrace is needed for the raw tracepoint +support. The script was tested using v0.19.0. + +/* from include/net/9p/9p.h */ +struct p9_fcall { + u32 size; + u8 id; + u16 tag; + size_t offset; + size_t capacity; + struct kmem_cache *cache; + u8 *sdata; + bool zc; +}; + +tracepoint:9p:9p_protocol_dump +{ + /* out of bounds read can happen when this tracepoint is enabled */ +} + +rawtracepoint:9p_protocol_dump +{ + $pdu = (struct p9_fcall *)arg1; + $dump_sz = (uint64)32; + + if ($dump_sz > $pdu->capacity) { + printf("reading %zu bytes from src buffer of %zu bytes\n", + $dump_sz, $pdu->capacity); + } +} + +Signed-off-by: JP Kobryn +Message-ID: <20231204202321.22730-1-inwardvessel@gmail.com> +Fixes: 60ece0833b6c ("net/9p: allocate appropriate reduced message buffers") +Cc: stable@vger.kernel.org +Reviewed-by: Christian Schoenebeck +Signed-off-by: Dominique Martinet +Signed-off-by: Greg Kroah-Hartman +--- + include/trace/events/9p.h | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +--- a/include/trace/events/9p.h ++++ b/include/trace/events/9p.h +@@ -178,18 +178,21 @@ TRACE_EVENT(9p_protocol_dump, + __field( void *, clnt ) + __field( __u8, type ) + __field( __u16, tag ) +- __array( unsigned char, line, P9_PROTO_DUMP_SZ ) ++ __dynamic_array(unsigned char, line, ++ min_t(size_t, pdu->capacity, P9_PROTO_DUMP_SZ)) + ), + + TP_fast_assign( + __entry->clnt = clnt; + __entry->type = pdu->id; + __entry->tag = pdu->tag; +- memcpy(__entry->line, pdu->sdata, P9_PROTO_DUMP_SZ); ++ memcpy(__get_dynamic_array(line), pdu->sdata, ++ __get_dynamic_array_len(line)); + ), +- TP_printk("clnt %lu %s(tag = %d)\n%.3x: %16ph\n%.3x: %16ph\n", ++ TP_printk("clnt %lu %s(tag = %d)\n%*ph\n", + (unsigned long)__entry->clnt, show_9p_op(__entry->type), +- __entry->tag, 0, __entry->line, 16, __entry->line + 16) ++ __entry->tag, __get_dynamic_array_len(line), ++ __get_dynamic_array(line)) + ); + + diff --git a/queue-6.6/drm-i915-dmc-don-t-enable-any-pipe-dmc-events.patch b/queue-6.6/drm-i915-dmc-don-t-enable-any-pipe-dmc-events.patch new file mode 100644 index 00000000000..22a82ae284b --- /dev/null +++ b/queue-6.6/drm-i915-dmc-don-t-enable-any-pipe-dmc-events.patch @@ -0,0 +1,100 @@ +From 49e0a85ec3441edc6c77aa40206d6e5ee4597efc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Mon, 11 Dec 2023 23:37:47 +0200 +Subject: drm/i915/dmc: Don't enable any pipe DMC events +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ville Syrjälä + +commit 49e0a85ec3441edc6c77aa40206d6e5ee4597efc upstream. + +The pipe DMC seems to be making a mess of things in ADL. Various weird +symptoms have been observed such as missing vblank irqs, typicalle +happening when using multiple displays. + +Keep all pipe DMC event handlers disabled until needed (which is never +atm). This is also what Windows does on ADL+. + +We can also drop DG2 from disable_all_flip_queue_events() since +on DG2 the pipe DMC is the one that handles the flip queue events. + +Cc: stable@vger.kernel.org +Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/8685 +Signed-off-by: Ville Syrjälä +Link: https://patchwork.freedesktop.org/patch/msgid/20231211213750.27109-2-ville.syrjala@linux.intel.com +Reviewed-by: Imre Deak +(cherry picked from commit 648d7be8ecf47b0556e32550145c70db153b16fb) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/i915/display/intel_dmc.c | 43 +++++++++++++++++++++++++++++-- + 1 file changed, 41 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/i915/display/intel_dmc.c ++++ b/drivers/gpu/drm/i915/display/intel_dmc.c +@@ -389,7 +389,7 @@ disable_all_flip_queue_events(struct drm + enum intel_dmc_id dmc_id; + + /* TODO: check if the following applies to all D13+ platforms. */ +- if (!IS_DG2(i915) && !IS_TIGERLAKE(i915)) ++ if (!IS_TIGERLAKE(i915)) + return; + + for_each_dmc_id(dmc_id) { +@@ -493,6 +493,45 @@ void intel_dmc_disable_pipe(struct drm_i + intel_de_rmw(i915, PIPEDMC_CONTROL(pipe), PIPEDMC_ENABLE, 0); + } + ++static bool is_dmc_evt_ctl_reg(struct drm_i915_private *i915, ++ enum intel_dmc_id dmc_id, i915_reg_t reg) ++{ ++ u32 offset = i915_mmio_reg_offset(reg); ++ u32 start = i915_mmio_reg_offset(DMC_EVT_CTL(i915, dmc_id, 0)); ++ u32 end = i915_mmio_reg_offset(DMC_EVT_CTL(i915, dmc_id, DMC_EVENT_HANDLER_COUNT_GEN12)); ++ ++ return offset >= start && offset < end; ++} ++ ++static bool disable_dmc_evt(struct drm_i915_private *i915, ++ enum intel_dmc_id dmc_id, ++ i915_reg_t reg, u32 data) ++{ ++ if (!is_dmc_evt_ctl_reg(i915, dmc_id, reg)) ++ return false; ++ ++ /* keep all pipe DMC events disabled by default */ ++ if (dmc_id != DMC_FW_MAIN) ++ return true; ++ ++ return false; ++} ++ ++static u32 dmc_mmiodata(struct drm_i915_private *i915, ++ struct intel_dmc *dmc, ++ enum intel_dmc_id dmc_id, int i) ++{ ++ if (disable_dmc_evt(i915, dmc_id, ++ dmc->dmc_info[dmc_id].mmioaddr[i], ++ dmc->dmc_info[dmc_id].mmiodata[i])) ++ return REG_FIELD_PREP(DMC_EVT_CTL_TYPE_MASK, ++ DMC_EVT_CTL_TYPE_EDGE_0_1) | ++ REG_FIELD_PREP(DMC_EVT_CTL_EVENT_ID_MASK, ++ DMC_EVT_CTL_EVENT_ID_FALSE); ++ else ++ return dmc->dmc_info[dmc_id].mmiodata[i]; ++} ++ + /** + * intel_dmc_load_program() - write the firmware from memory to register. + * @i915: i915 drm device. +@@ -532,7 +571,7 @@ void intel_dmc_load_program(struct drm_i + for_each_dmc_id(dmc_id) { + for (i = 0; i < dmc->dmc_info[dmc_id].mmio_count; i++) { + intel_de_write(i915, dmc->dmc_info[dmc_id].mmioaddr[i], +- dmc->dmc_info[dmc_id].mmiodata[i]); ++ dmc_mmiodata(i915, dmc, dmc_id, i)); + } + } + diff --git a/queue-6.6/drm-i915-reject-async-flips-with-bigjoiner.patch b/queue-6.6/drm-i915-reject-async-flips-with-bigjoiner.patch new file mode 100644 index 00000000000..a2862a8a479 --- /dev/null +++ b/queue-6.6/drm-i915-reject-async-flips-with-bigjoiner.patch @@ -0,0 +1,47 @@ +From 88a173e5dd05e788068e8fa20a8c37c44bd8f416 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Mon, 11 Dec 2023 10:11:34 +0200 +Subject: drm/i915: Reject async flips with bigjoiner +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ville Syrjälä + +commit 88a173e5dd05e788068e8fa20a8c37c44bd8f416 upstream. + +Currently async flips are busted when bigjoiner is in use. +As a short term fix simply reject async flips in that case. + +Cc: stable@vger.kernel.org +Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/9769 +Signed-off-by: Ville Syrjälä +Link: https://patchwork.freedesktop.org/patch/msgid/20231211081134.2698-1-ville.syrjala@linux.intel.com +Reviewed-by: Stanislav Lisovskiy +(cherry picked from commit e93bffc2ac0a833b42841f31fff955549d38ce98) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/i915/display/intel_display.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/gpu/drm/i915/display/intel_display.c ++++ b/drivers/gpu/drm/i915/display/intel_display.c +@@ -5977,6 +5977,17 @@ static int intel_async_flip_check_hw(str + return -EINVAL; + } + ++ /* ++ * FIXME: Bigjoiner+async flip is busted currently. ++ * Remove this check once the issues are fixed. ++ */ ++ if (new_crtc_state->bigjoiner_pipes) { ++ drm_dbg_kms(&i915->drm, ++ "[CRTC:%d:%s] async flip disallowed with bigjoiner\n", ++ crtc->base.base.id, crtc->base.name); ++ return -EINVAL; ++ } ++ + for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, + new_plane_state, i) { + if (plane->pipe != crtc->pipe) diff --git a/queue-6.6/dt-bindings-nvmem-mxs-ocotp-document-fsl-ocotp.patch b/queue-6.6/dt-bindings-nvmem-mxs-ocotp-document-fsl-ocotp.patch new file mode 100644 index 00000000000..b2e69b1bcb9 --- /dev/null +++ b/queue-6.6/dt-bindings-nvmem-mxs-ocotp-document-fsl-ocotp.patch @@ -0,0 +1,58 @@ +From a2a8aefecbd0f87d6127951cef33b3def8439057 Mon Sep 17 00:00:00 2001 +From: Fabio Estevam +Date: Fri, 15 Dec 2023 11:13:57 +0000 +Subject: dt-bindings: nvmem: mxs-ocotp: Document fsl,ocotp + +From: Fabio Estevam + +commit a2a8aefecbd0f87d6127951cef33b3def8439057 upstream. + +Both imx23.dtsi and imx28.dtsi describe the OCOTP nodes in +the format: + +compatible = "fsl,imx28-ocotp", "fsl,ocotp"; + +Document the "fsl,ocotp" entry to fix the following schema +warning: + +efuse@8002c000: compatible: ['fsl,imx23-ocotp', 'fsl,ocotp'] is too long +from schema $id: http://devicetree.org/schemas/nvmem/mxs-ocotp.yaml# + +Fixes: 2c504460f502 ("dt-bindings: nvmem: Convert MXS OCOTP to json-schema") +Cc: +Signed-off-by: Fabio Estevam +Acked-by: Conor Dooley +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20231215111358.316727-2-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/devicetree/bindings/nvmem/mxs-ocotp.yaml | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/Documentation/devicetree/bindings/nvmem/mxs-ocotp.yaml ++++ b/Documentation/devicetree/bindings/nvmem/mxs-ocotp.yaml +@@ -14,9 +14,11 @@ allOf: + + properties: + compatible: +- enum: +- - fsl,imx23-ocotp +- - fsl,imx28-ocotp ++ items: ++ - enum: ++ - fsl,imx23-ocotp ++ - fsl,imx28-ocotp ++ - const: fsl,ocotp + + reg: + maxItems: 1 +@@ -34,7 +36,7 @@ unevaluatedProperties: false + examples: + - | + ocotp: efuse@8002c000 { +- compatible = "fsl,imx28-ocotp"; ++ compatible = "fsl,imx28-ocotp", "fsl,ocotp"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x8002c000 0x2000>; diff --git a/queue-6.6/input-soc_button_array-add-mapping-for-airplane-mode-button.patch b/queue-6.6/input-soc_button_array-add-mapping-for-airplane-mode-button.patch new file mode 100644 index 00000000000..72fb79bd1d7 --- /dev/null +++ b/queue-6.6/input-soc_button_array-add-mapping-for-airplane-mode-button.patch @@ -0,0 +1,43 @@ +From ea3715941a9b7d816a1e9096ac0577900af2a69e Mon Sep 17 00:00:00 2001 +From: Christoffer Sandberg +Date: Fri, 22 Dec 2023 23:25:38 -0800 +Subject: Input: soc_button_array - add mapping for airplane mode button + +From: Christoffer Sandberg + +commit ea3715941a9b7d816a1e9096ac0577900af2a69e upstream. + +This add a mapping for the airplane mode button on the TUXEDO Pulse Gen3. + +While it is physically a key it behaves more like a switch, sending a key +down on first press and a key up on 2nd press. Therefor the switch event +is used here. Besides this behaviour it uses the HID usage-id 0xc6 +(Wireless Radio Button) and not 0xc8 (Wireless Radio Slider Switch), but +since neither 0xc6 nor 0xc8 are currently implemented at all in +soc_button_array this not to standard behaviour is not put behind a quirk +for the moment. + +Signed-off-by: Christoffer Sandberg +Signed-off-by: Werner Sembach +Link: https://lore.kernel.org/r/20231215171718.80229-1-wse@tuxedocomputers.com +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/misc/soc_button_array.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/input/misc/soc_button_array.c ++++ b/drivers/input/misc/soc_button_array.c +@@ -299,6 +299,11 @@ static int soc_button_parse_btn_desc(str + info->name = "power"; + info->event_code = KEY_POWER; + info->wakeup = true; ++ } else if (upage == 0x01 && usage == 0xc6) { ++ info->name = "airplane mode switch"; ++ info->event_type = EV_SW; ++ info->event_code = SW_RFKILL_ALL; ++ info->active_low = false; + } else if (upage == 0x01 && usage == 0xca) { + info->name = "rotation lock switch"; + info->event_type = EV_SW; diff --git a/queue-6.6/net-9p-avoid-freeing-uninit-memory-in-p9pdu_vreadf.patch b/queue-6.6/net-9p-avoid-freeing-uninit-memory-in-p9pdu_vreadf.patch new file mode 100644 index 00000000000..a3f622758ba --- /dev/null +++ b/queue-6.6/net-9p-avoid-freeing-uninit-memory-in-p9pdu_vreadf.patch @@ -0,0 +1,82 @@ +From ff49bf1867578f23a5ffdd38f927f6e1e16796c4 Mon Sep 17 00:00:00 2001 +From: Fedor Pchelkin +Date: Wed, 6 Dec 2023 23:09:13 +0300 +Subject: net: 9p: avoid freeing uninit memory in p9pdu_vreadf + +From: Fedor Pchelkin + +commit ff49bf1867578f23a5ffdd38f927f6e1e16796c4 upstream. + +If some of p9pdu_readf() calls inside case 'T' in p9pdu_vreadf() fails, +the error path is not handled properly. *wnames or members of *wnames +array may be left uninitialized and invalidly freed. + +Initialize *wnames to NULL in beginning of case 'T'. Initialize the first +*wnames array element to NULL and nullify the failing *wnames element so +that the error path freeing loop stops on the first NULL element and +doesn't proceed further. + +Found by Linux Verification Center (linuxtesting.org). + +Fixes: ace51c4dd2f9 ("9p: add new protocol support code") +Signed-off-by: Fedor Pchelkin +Message-ID: <20231206200913.16135-1-pchelkin@ispras.ru> +Cc: stable@vger.kernel.org +Reviewed-by: Simon Horman +Reviewed-by: Christian Schoenebeck +Signed-off-by: Dominique Martinet +Signed-off-by: Greg Kroah-Hartman +--- + net/9p/protocol.c | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +--- a/net/9p/protocol.c ++++ b/net/9p/protocol.c +@@ -394,6 +394,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int p + uint16_t *nwname = va_arg(ap, uint16_t *); + char ***wnames = va_arg(ap, char ***); + ++ *wnames = NULL; ++ + errcode = p9pdu_readf(pdu, proto_version, + "w", nwname); + if (!errcode) { +@@ -403,6 +405,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int p + GFP_NOFS); + if (!*wnames) + errcode = -ENOMEM; ++ else ++ (*wnames)[0] = NULL; + } + + if (!errcode) { +@@ -414,8 +418,10 @@ p9pdu_vreadf(struct p9_fcall *pdu, int p + proto_version, + "s", + &(*wnames)[i]); +- if (errcode) ++ if (errcode) { ++ (*wnames)[i] = NULL; + break; ++ } + } + } + +@@ -423,11 +429,14 @@ p9pdu_vreadf(struct p9_fcall *pdu, int p + if (*wnames) { + int i; + +- for (i = 0; i < *nwname; i++) ++ for (i = 0; i < *nwname; i++) { ++ if (!(*wnames)[i]) ++ break; + kfree((*wnames)[i]); ++ } ++ kfree(*wnames); ++ *wnames = NULL; + } +- kfree(*wnames); +- *wnames = NULL; + } + } + break; diff --git a/queue-6.6/net-avoid-build-bug-in-skb-extension-length-calculation.patch b/queue-6.6/net-avoid-build-bug-in-skb-extension-length-calculation.patch new file mode 100644 index 00000000000..0f51cf19a59 --- /dev/null +++ b/queue-6.6/net-avoid-build-bug-in-skb-extension-length-calculation.patch @@ -0,0 +1,52 @@ +From d6e5794b06c0fab74fe6e4fa55d508a5ceb14735 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= +Date: Mon, 18 Dec 2023 18:06:54 +0100 +Subject: net: avoid build bug in skb extension length calculation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Weißschuh + +commit d6e5794b06c0fab74fe6e4fa55d508a5ceb14735 upstream. + +GCC seems to incorrectly fail to evaluate skb_ext_total_length() at +compile time under certain conditions. + +The issue even occurs if all values in skb_ext_type_len[] are "0", +ruling out the possibility of an actual overflow. + +As the patch has been in mainline since v6.6 without triggering the +problem it seems to be a very uncommon occurrence. + +As the issue only occurs when -fno-tree-loop-im is specified as part of +CFLAGS_GCOV, disable the BUILD_BUG_ON() only when building with coverage +reporting enabled. + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202312171924.4FozI5FG-lkp@intel.com/ +Suggested-by: Arnd Bergmann +Link: https://lore.kernel.org/lkml/487cfd35-fe68-416f-9bfd-6bb417f98304@app.fastmail.com/ +Fixes: 5d21d0a65b57 ("net: generalize calculation of skb extensions length") +Cc: +Signed-off-by: Thomas Weißschuh +Acked-by: Arnd Bergmann +Link: https://lore.kernel.org/r/20231218-net-skbuff-build-bug-v1-1-eefc2fb0a7d3@weissschuh.net +Signed-off-by: Paolo Abeni +Signed-off-by: Greg Kroah-Hartman +--- + net/core/skbuff.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -4810,7 +4810,9 @@ static __always_inline unsigned int skb_ + static void skb_extensions_init(void) + { + BUILD_BUG_ON(SKB_EXT_NUM >= 8); ++#if !IS_ENABLED(CONFIG_KCOV_INSTRUMENT_ALL) + BUILD_BUG_ON(skb_ext_total_length() > 255); ++#endif + + skbuff_ext_cache = kmem_cache_create("skbuff_ext_cache", + SKB_EXT_ALIGN_VALUE * skb_ext_total_length(), diff --git a/queue-6.6/net-ks8851-fix-tx-stall-caused-by-tx-buffer-overrun.patch b/queue-6.6/net-ks8851-fix-tx-stall-caused-by-tx-buffer-overrun.patch new file mode 100644 index 00000000000..7731bfb1191 --- /dev/null +++ b/queue-6.6/net-ks8851-fix-tx-stall-caused-by-tx-buffer-overrun.patch @@ -0,0 +1,234 @@ +From 3dc5d44545453de1de9c53cc529cc960a85933da Mon Sep 17 00:00:00 2001 +From: Ronald Wahl +Date: Thu, 14 Dec 2023 19:11:12 +0100 +Subject: net: ks8851: Fix TX stall caused by TX buffer overrun + +From: Ronald Wahl + +commit 3dc5d44545453de1de9c53cc529cc960a85933da upstream. + +There is a bug in the ks8851 Ethernet driver that more data is written +to the hardware TX buffer than actually available. This is caused by +wrong accounting of the free TX buffer space. + +The driver maintains a tx_space variable that represents the TX buffer +space that is deemed to be free. The ks8851_start_xmit_spi() function +adds an SKB to a queue if tx_space is large enough and reduces tx_space +by the amount of buffer space it will later need in the TX buffer and +then schedules a work item. If there is not enough space then the TX +queue is stopped. + +The worker function ks8851_tx_work() dequeues all the SKBs and writes +the data into the hardware TX buffer. The last packet will trigger an +interrupt after it was send. Here it is assumed that all data fits into +the TX buffer. + +In the interrupt routine (which runs asynchronously because it is a +threaded interrupt) tx_space is updated with the current value from the +hardware. Also the TX queue is woken up again. + +Now it could happen that after data was sent to the hardware and before +handling the TX interrupt new data is queued in ks8851_start_xmit_spi() +when the TX buffer space had still some space left. When the interrupt +is actually handled tx_space is updated from the hardware but now we +already have new SKBs queued that have not been written to the hardware +TX buffer yet. Since tx_space has been overwritten by the value from the +hardware the space is not accounted for. + +Now we have more data queued then buffer space available in the hardware +and ks8851_tx_work() will potentially overrun the hardware TX buffer. In +many cases it will still work because often the buffer is written out +fast enough so that no overrun occurs but for example if the peer +throttles us via flow control then an overrun may happen. + +This can be fixed in different ways. The most simple way would be to set +tx_space to 0 before writing data to the hardware TX buffer preventing +the queuing of more SKBs until the TX interrupt has been handled. I have +chosen a slightly more efficient (and still rather simple) way and +track the amount of data that is already queued and not yet written to +the hardware. When new SKBs are to be queued the already queued amount +of data is honoured when checking free TX buffer space. + +I tested this with a setup of two linked KS8851 running iperf3 between +the two in bidirectional mode. Before the fix I got a stall after some +minutes. With the fix I saw now issues anymore after hours. + +Fixes: 3ba81f3ece3c ("net: Micrel KS8851 SPI network driver") +Cc: "David S. Miller" +Cc: Eric Dumazet +Cc: Jakub Kicinski +Cc: Paolo Abeni +Cc: Ben Dooks +Cc: Tristram Ha +Cc: netdev@vger.kernel.org +Cc: stable@vger.kernel.org # 5.10+ +Signed-off-by: Ronald Wahl +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/20231214181112.76052-1-rwahl@gmx.de +Signed-off-by: Paolo Abeni +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/micrel/ks8851.h | 3 ++ + drivers/net/ethernet/micrel/ks8851_common.c | 20 ++++++------- + drivers/net/ethernet/micrel/ks8851_spi.c | 42 ++++++++++++++++++---------- + 3 files changed, 40 insertions(+), 25 deletions(-) + +--- a/drivers/net/ethernet/micrel/ks8851.h ++++ b/drivers/net/ethernet/micrel/ks8851.h +@@ -350,6 +350,8 @@ union ks8851_tx_hdr { + * @rxd: Space for receiving SPI data, in DMA-able space. + * @txd: Space for transmitting SPI data, in DMA-able space. + * @msg_enable: The message flags controlling driver output (see ethtool). ++ * @tx_space: Free space in the hardware TX buffer (cached copy of KS_TXMIR). ++ * @queued_len: Space required in hardware TX buffer for queued packets in txq. + * @fid: Incrementing frame id tag. + * @rc_ier: Cached copy of KS_IER. + * @rc_ccr: Cached copy of KS_CCR. +@@ -399,6 +401,7 @@ struct ks8851_net { + struct work_struct rxctrl_work; + + struct sk_buff_head txq; ++ unsigned int queued_len; + + struct eeprom_93cx6 eeprom; + struct regulator *vdd_reg; +--- a/drivers/net/ethernet/micrel/ks8851_common.c ++++ b/drivers/net/ethernet/micrel/ks8851_common.c +@@ -362,16 +362,18 @@ static irqreturn_t ks8851_irq(int irq, v + handled |= IRQ_RXPSI; + + if (status & IRQ_TXI) { +- handled |= IRQ_TXI; ++ unsigned short tx_space = ks8851_rdreg16(ks, KS_TXMIR); + +- /* no lock here, tx queue should have been stopped */ ++ netif_dbg(ks, intr, ks->netdev, ++ "%s: txspace %d\n", __func__, tx_space); + +- /* update our idea of how much tx space is available to the +- * system */ +- ks->tx_space = ks8851_rdreg16(ks, KS_TXMIR); ++ spin_lock(&ks->statelock); ++ ks->tx_space = tx_space; ++ if (netif_queue_stopped(ks->netdev)) ++ netif_wake_queue(ks->netdev); ++ spin_unlock(&ks->statelock); + +- netif_dbg(ks, intr, ks->netdev, +- "%s: txspace %d\n", __func__, ks->tx_space); ++ handled |= IRQ_TXI; + } + + if (status & IRQ_RXI) +@@ -414,9 +416,6 @@ static irqreturn_t ks8851_irq(int irq, v + if (status & IRQ_LCI) + mii_check_link(&ks->mii); + +- if (status & IRQ_TXI) +- netif_wake_queue(ks->netdev); +- + return IRQ_HANDLED; + } + +@@ -500,6 +499,7 @@ static int ks8851_net_open(struct net_de + ks8851_wrreg16(ks, KS_ISR, ks->rc_ier); + ks8851_wrreg16(ks, KS_IER, ks->rc_ier); + ++ ks->queued_len = 0; + netif_start_queue(ks->netdev); + + netif_dbg(ks, ifup, ks->netdev, "network device up\n"); +--- a/drivers/net/ethernet/micrel/ks8851_spi.c ++++ b/drivers/net/ethernet/micrel/ks8851_spi.c +@@ -287,6 +287,18 @@ static void ks8851_wrfifo_spi(struct ks8 + } + + /** ++ * calc_txlen - calculate size of message to send packet ++ * @len: Length of data ++ * ++ * Returns the size of the TXFIFO message needed to send ++ * this packet. ++ */ ++static unsigned int calc_txlen(unsigned int len) ++{ ++ return ALIGN(len + 4, 4); ++} ++ ++/** + * ks8851_rx_skb_spi - receive skbuff + * @ks: The device state + * @skb: The skbuff +@@ -305,7 +317,9 @@ static void ks8851_rx_skb_spi(struct ks8 + */ + static void ks8851_tx_work(struct work_struct *work) + { ++ unsigned int dequeued_len = 0; + struct ks8851_net_spi *kss; ++ unsigned short tx_space; + struct ks8851_net *ks; + unsigned long flags; + struct sk_buff *txb; +@@ -322,6 +336,8 @@ static void ks8851_tx_work(struct work_s + last = skb_queue_empty(&ks->txq); + + if (txb) { ++ dequeued_len += calc_txlen(txb->len); ++ + ks8851_wrreg16_spi(ks, KS_RXQCR, + ks->rc_rxqcr | RXQCR_SDA); + ks8851_wrfifo_spi(ks, txb, last); +@@ -332,6 +348,13 @@ static void ks8851_tx_work(struct work_s + } + } + ++ tx_space = ks8851_rdreg16_spi(ks, KS_TXMIR); ++ ++ spin_lock(&ks->statelock); ++ ks->queued_len -= dequeued_len; ++ ks->tx_space = tx_space; ++ spin_unlock(&ks->statelock); ++ + ks8851_unlock_spi(ks, &flags); + } + +@@ -347,18 +370,6 @@ static void ks8851_flush_tx_work_spi(str + } + + /** +- * calc_txlen - calculate size of message to send packet +- * @len: Length of data +- * +- * Returns the size of the TXFIFO message needed to send +- * this packet. +- */ +-static unsigned int calc_txlen(unsigned int len) +-{ +- return ALIGN(len + 4, 4); +-} +- +-/** + * ks8851_start_xmit_spi - transmit packet using SPI + * @skb: The buffer to transmit + * @dev: The device used to transmit the packet. +@@ -386,16 +397,17 @@ static netdev_tx_t ks8851_start_xmit_spi + + spin_lock(&ks->statelock); + +- if (needed > ks->tx_space) { ++ if (ks->queued_len + needed > ks->tx_space) { + netif_stop_queue(dev); + ret = NETDEV_TX_BUSY; + } else { +- ks->tx_space -= needed; ++ ks->queued_len += needed; + skb_queue_tail(&ks->txq, skb); + } + + spin_unlock(&ks->statelock); +- schedule_work(&kss->tx_work); ++ if (ret == NETDEV_TX_OK) ++ schedule_work(&kss->tx_work); + + return ret; + } diff --git a/queue-6.6/net-rfkill-gpio-set-gpio-direction.patch b/queue-6.6/net-rfkill-gpio-set-gpio-direction.patch new file mode 100644 index 00000000000..ead05bcbe4b --- /dev/null +++ b/queue-6.6/net-rfkill-gpio-set-gpio-direction.patch @@ -0,0 +1,45 @@ +From 23484d817082c3005252d8edfc8292c8a1006b5b Mon Sep 17 00:00:00 2001 +From: Rouven Czerwinski +Date: Thu, 7 Dec 2023 08:58:36 +0100 +Subject: net: rfkill: gpio: set GPIO direction + +From: Rouven Czerwinski + +commit 23484d817082c3005252d8edfc8292c8a1006b5b upstream. + +Fix the undefined usage of the GPIO consumer API after retrieving the +GPIO description with GPIO_ASIS. The API documentation mentions that +GPIO_ASIS won't set a GPIO direction and requires the user to set a +direction before using the GPIO. + +This can be confirmed on i.MX6 hardware, where rfkill-gpio is no longer +able to enabled/disable a device, presumably because the GPIO controller +was never configured for the output direction. + +Fixes: b2f750c3a80b ("net: rfkill: gpio: prevent value glitch during probe") +Cc: stable@vger.kernel.org +Signed-off-by: Rouven Czerwinski +Link: https://msgid.link/20231207075835.3091694-1-r.czerwinski@pengutronix.de +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + net/rfkill/rfkill-gpio.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/net/rfkill/rfkill-gpio.c ++++ b/net/rfkill/rfkill-gpio.c +@@ -126,6 +126,14 @@ static int rfkill_gpio_probe(struct plat + return -EINVAL; + } + ++ ret = gpiod_direction_output(rfkill->reset_gpio, true); ++ if (ret) ++ return ret; ++ ++ ret = gpiod_direction_output(rfkill->shutdown_gpio, true); ++ if (ret) ++ return ret; ++ + rfkill->rfkill_dev = rfkill_alloc(rfkill->name, &pdev->dev, + rfkill->type, &rfkill_gpio_ops, + rfkill); diff --git a/queue-6.6/net-stmmac-fix-incorrect-flag-check-in-timestamp-interrupt.patch b/queue-6.6/net-stmmac-fix-incorrect-flag-check-in-timestamp-interrupt.patch new file mode 100644 index 00000000000..7b01443a1eb --- /dev/null +++ b/queue-6.6/net-stmmac-fix-incorrect-flag-check-in-timestamp-interrupt.patch @@ -0,0 +1,40 @@ +From bd7f77dae69532ffc027ee50ff99e3792dc30b7f Mon Sep 17 00:00:00 2001 +From: Lai Peter Jun Ann +Date: Mon, 18 Dec 2023 15:51:32 +0800 +Subject: net: stmmac: fix incorrect flag check in timestamp interrupt + +From: Lai Peter Jun Ann + +commit bd7f77dae69532ffc027ee50ff99e3792dc30b7f upstream. + +The driver should continue get the timestamp if STMMAC_FLAG_EXT_SNAPSHOT_EN +flag is set. + +Fixes: aa5513f5d95f ("net: stmmac: replace the ext_snapshot_en field with a flag") +Cc: # 6.6 +Signed-off-by: Song Yoong Siang +Signed-off-by: Lai Peter Jun Ann +Reviewed-by: Jacob Keller +Reviewed-by: Serge Semin +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c +index 540f6a4ec0b8..f05bd757dfe5 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c +@@ -237,7 +237,7 @@ static void timestamp_interrupt(struct stmmac_priv *priv) + */ + ts_status = readl(priv->ioaddr + GMAC_TIMESTAMP_STATUS); + +- if (priv->plat->flags & STMMAC_FLAG_EXT_SNAPSHOT_EN) ++ if (!(priv->plat->flags & STMMAC_FLAG_EXT_SNAPSHOT_EN)) + return; + + num_snapshot = (ts_status & GMAC_TIMESTAMP_ATSNS_MASK) >> +-- +2.43.0 + diff --git a/queue-6.6/nfsd-call-nfsd_last_thread-before-final-nfsd_put.patch b/queue-6.6/nfsd-call-nfsd_last_thread-before-final-nfsd_put.patch new file mode 100644 index 00000000000..dfd2811aaa2 --- /dev/null +++ b/queue-6.6/nfsd-call-nfsd_last_thread-before-final-nfsd_put.patch @@ -0,0 +1,74 @@ +From 2a501f55cd641eb4d3c16a2eab0d678693fac663 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Fri, 15 Dec 2023 11:56:31 +1100 +Subject: nfsd: call nfsd_last_thread() before final nfsd_put() + +From: NeilBrown + +commit 2a501f55cd641eb4d3c16a2eab0d678693fac663 upstream. + +If write_ports_addfd or write_ports_addxprt fail, they call nfsd_put() +without calling nfsd_last_thread(). This leaves nn->nfsd_serv pointing +to a structure that has been freed. + +So remove 'static' from nfsd_last_thread() and call it when the +nfsd_serv is about to be destroyed. + +Fixes: ec52361df99b ("SUNRPC: stop using ->sv_nrthreads as a refcount") +Signed-off-by: NeilBrown +Reviewed-by: Jeff Layton +Cc: +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfsctl.c | 9 +++++++-- + fs/nfsd/nfsd.h | 1 + + fs/nfsd/nfssvc.c | 2 +- + 3 files changed, 9 insertions(+), 3 deletions(-) + +--- a/fs/nfsd/nfsctl.c ++++ b/fs/nfsd/nfsctl.c +@@ -704,8 +704,10 @@ static ssize_t __write_ports_addfd(char + + err = svc_addsock(nn->nfsd_serv, net, fd, buf, SIMPLE_TRANSACTION_LIMIT, cred); + +- if (err >= 0 && +- !nn->nfsd_serv->sv_nrthreads && !xchg(&nn->keep_active, 1)) ++ if (err < 0 && !nn->nfsd_serv->sv_nrthreads && !nn->keep_active) ++ nfsd_last_thread(net); ++ else if (err >= 0 && ++ !nn->nfsd_serv->sv_nrthreads && !xchg(&nn->keep_active, 1)) + svc_get(nn->nfsd_serv); + + nfsd_put(net); +@@ -756,6 +758,9 @@ out_close: + svc_xprt_put(xprt); + } + out_err: ++ if (!nn->nfsd_serv->sv_nrthreads && !nn->keep_active) ++ nfsd_last_thread(net); ++ + nfsd_put(net); + return err; + } +--- a/fs/nfsd/nfsd.h ++++ b/fs/nfsd/nfsd.h +@@ -138,6 +138,7 @@ int nfsd_vers(struct nfsd_net *nn, int v + int nfsd_minorversion(struct nfsd_net *nn, u32 minorversion, enum vers_op change); + void nfsd_reset_versions(struct nfsd_net *nn); + int nfsd_create_serv(struct net *net); ++void nfsd_last_thread(struct net *net); + + extern int nfsd_max_blksize; + +--- a/fs/nfsd/nfssvc.c ++++ b/fs/nfsd/nfssvc.c +@@ -542,7 +542,7 @@ static struct notifier_block nfsd_inet6a + /* Only used under nfsd_mutex, so this atomic may be overkill: */ + static atomic_t nfsd_notifier_refcount = ATOMIC_INIT(0); + +-static void nfsd_last_thread(struct net *net) ++void nfsd_last_thread(struct net *net) + { + struct nfsd_net *nn = net_generic(net, nfsd_net_id); + struct svc_serv *serv = nn->nfsd_serv; diff --git a/queue-6.6/series b/queue-6.6/series index f7726cef85e..6c88b8ef6db 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -114,3 +114,18 @@ bluetooth-add-more-enc-key-size-check.patch usb-typec-ucsi-fix-gpio-based-orientation-detection.patch usb-fotg210-hcd-delete-an-incorrect-bounds-test.patch net-usb-ax88179_178a-avoid-failed-operations-when-device-is-disconnected.patch +input-soc_button_array-add-mapping-for-airplane-mode-button.patch +net-9p-avoid-freeing-uninit-memory-in-p9pdu_vreadf.patch +net-rfkill-gpio-set-gpio-direction.patch +net-ks8851-fix-tx-stall-caused-by-tx-buffer-overrun.patch +net-avoid-build-bug-in-skb-extension-length-calculation.patch +net-stmmac-fix-incorrect-flag-check-in-timestamp-interrupt.patch +dt-bindings-nvmem-mxs-ocotp-document-fsl-ocotp.patch +nfsd-call-nfsd_last_thread-before-final-nfsd_put.patch +smb-client-fix-oob-in-cifsd-when-receiving-compounded-resps.patch +smb-client-fix-potential-oob-in-cifs_dump_detail.patch +smb-client-fix-oob-in-smb2_query_info_init.patch +smb-client-fix-oob-in-smbcalcsize.patch +drm-i915-reject-async-flips-with-bigjoiner.patch +drm-i915-dmc-don-t-enable-any-pipe-dmc-events.patch +9p-prevent-read-overrun-in-protocol-dump-tracepoint.patch diff --git a/queue-6.6/smb-client-fix-oob-in-cifsd-when-receiving-compounded-resps.patch b/queue-6.6/smb-client-fix-oob-in-cifsd-when-receiving-compounded-resps.patch new file mode 100644 index 00000000000..926951b6b33 --- /dev/null +++ b/queue-6.6/smb-client-fix-oob-in-cifsd-when-receiving-compounded-resps.patch @@ -0,0 +1,161 @@ +From a8f68b11158f09754418de62e6b3e7b9b7a50cc9 Mon Sep 17 00:00:00 2001 +From: Paulo Alcantara +Date: Wed, 13 Dec 2023 12:25:56 -0300 +Subject: smb: client: fix OOB in cifsd when receiving compounded resps + +From: Paulo Alcantara + +commit a8f68b11158f09754418de62e6b3e7b9b7a50cc9 upstream. + +Validate next header's offset in ->next_header() so that it isn't +smaller than MID_HEADER_SIZE(server) and then standard_receive3() or +->receive() ends up writing off the end of the buffer because +'pdu_length - MID_HEADER_SIZE(server)' wraps up to a huge length: + + BUG: KASAN: slab-out-of-bounds in _copy_to_iter+0x4fc/0x840 + Write of size 701 at addr ffff88800caf407f by task cifsd/1090 + + CPU: 0 PID: 1090 Comm: cifsd Not tainted 6.7.0-rc4 #5 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS + rel-1.16.2-3-gd478f380-rebuilt.opensuse.org 04/01/2014 + Call Trace: + + dump_stack_lvl+0x4a/0x80 + print_report+0xcf/0x650 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? __phys_addr+0x46/0x90 + kasan_report+0xd8/0x110 + ? _copy_to_iter+0x4fc/0x840 + ? _copy_to_iter+0x4fc/0x840 + kasan_check_range+0x105/0x1b0 + __asan_memcpy+0x3c/0x60 + _copy_to_iter+0x4fc/0x840 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? hlock_class+0x32/0xc0 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? __pfx__copy_to_iter+0x10/0x10 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? lock_is_held_type+0x90/0x100 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? __might_resched+0x278/0x360 + ? __pfx___might_resched+0x10/0x10 + ? srso_alias_return_thunk+0x5/0xfbef5 + __skb_datagram_iter+0x2c2/0x460 + ? __pfx_simple_copy_to_iter+0x10/0x10 + skb_copy_datagram_iter+0x6c/0x110 + tcp_recvmsg_locked+0x9be/0xf40 + ? __pfx_tcp_recvmsg_locked+0x10/0x10 + ? mark_held_locks+0x5d/0x90 + ? srso_alias_return_thunk+0x5/0xfbef5 + tcp_recvmsg+0xe2/0x310 + ? __pfx_tcp_recvmsg+0x10/0x10 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? lock_acquire+0x14a/0x3a0 + ? srso_alias_return_thunk+0x5/0xfbef5 + inet_recvmsg+0xd0/0x370 + ? __pfx_inet_recvmsg+0x10/0x10 + ? __pfx_lock_release+0x10/0x10 + ? do_raw_spin_trylock+0xd1/0x120 + sock_recvmsg+0x10d/0x150 + cifs_readv_from_socket+0x25a/0x490 [cifs] + ? __pfx_cifs_readv_from_socket+0x10/0x10 [cifs] + ? srso_alias_return_thunk+0x5/0xfbef5 + cifs_read_from_socket+0xb5/0x100 [cifs] + ? __pfx_cifs_read_from_socket+0x10/0x10 [cifs] + ? __pfx_lock_release+0x10/0x10 + ? do_raw_spin_trylock+0xd1/0x120 + ? _raw_spin_unlock+0x23/0x40 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? __smb2_find_mid+0x126/0x230 [cifs] + cifs_demultiplex_thread+0xd39/0x1270 [cifs] + ? __pfx_cifs_demultiplex_thread+0x10/0x10 [cifs] + ? __pfx_lock_release+0x10/0x10 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? mark_held_locks+0x1a/0x90 + ? lockdep_hardirqs_on_prepare+0x136/0x210 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? __kthread_parkme+0xce/0xf0 + ? __pfx_cifs_demultiplex_thread+0x10/0x10 [cifs] + kthread+0x18d/0x1d0 + ? kthread+0xdb/0x1d0 + ? __pfx_kthread+0x10/0x10 + ret_from_fork+0x34/0x60 + ? __pfx_kthread+0x10/0x10 + ret_from_fork_asm+0x1b/0x30 + + +Fixes: 8ce79ec359ad ("cifs: update multiplex loop to handle compounded responses") +Cc: stable@vger.kernel.org +Reported-by: Robert Morris +Signed-off-by: Paulo Alcantara (SUSE) +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/client/cifsglob.h | 3 ++- + fs/smb/client/connect.c | 7 ++++++- + fs/smb/client/smb2ops.c | 19 ++++++++++++------- + 3 files changed, 20 insertions(+), 9 deletions(-) + +--- a/fs/smb/client/cifsglob.h ++++ b/fs/smb/client/cifsglob.h +@@ -532,7 +532,8 @@ struct smb_version_operations { + struct mid_q_entry **, char **, int *); + enum securityEnum (*select_sectype)(struct TCP_Server_Info *, + enum securityEnum); +- int (*next_header)(char *); ++ int (*next_header)(struct TCP_Server_Info *server, char *buf, ++ unsigned int *noff); + /* ioctl passthrough for query_info */ + int (*ioctl_query_info)(const unsigned int xid, + struct cifs_tcon *tcon, +--- a/fs/smb/client/connect.c ++++ b/fs/smb/client/connect.c +@@ -1180,7 +1180,12 @@ next_pdu: + server->total_read += length; + + if (server->ops->next_header) { +- next_offset = server->ops->next_header(buf); ++ if (server->ops->next_header(server, buf, &next_offset)) { ++ cifs_dbg(VFS, "%s: malformed response (next_offset=%u)\n", ++ __func__, next_offset); ++ cifs_reconnect(server, true); ++ continue; ++ } + if (next_offset) + server->pdu_size = next_offset; + } +--- a/fs/smb/client/smb2ops.c ++++ b/fs/smb/client/smb2ops.c +@@ -5072,17 +5072,22 @@ smb3_handle_read_data(struct TCP_Server_ + NULL, 0, false); + } + +-static int +-smb2_next_header(char *buf) ++static int smb2_next_header(struct TCP_Server_Info *server, char *buf, ++ unsigned int *noff) + { + struct smb2_hdr *hdr = (struct smb2_hdr *)buf; + struct smb2_transform_hdr *t_hdr = (struct smb2_transform_hdr *)buf; + +- if (hdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) +- return sizeof(struct smb2_transform_hdr) + +- le32_to_cpu(t_hdr->OriginalMessageSize); +- +- return le32_to_cpu(hdr->NextCommand); ++ if (hdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) { ++ *noff = le32_to_cpu(t_hdr->OriginalMessageSize); ++ if (unlikely(check_add_overflow(*noff, sizeof(*t_hdr), noff))) ++ return -EINVAL; ++ } else { ++ *noff = le32_to_cpu(hdr->NextCommand); ++ } ++ if (unlikely(*noff && *noff < MID_HEADER_SIZE(server))) ++ return -EINVAL; ++ return 0; + } + + static int diff --git a/queue-6.6/smb-client-fix-oob-in-smb2_query_info_init.patch b/queue-6.6/smb-client-fix-oob-in-smb2_query_info_init.patch new file mode 100644 index 00000000000..2c9068b0ea5 --- /dev/null +++ b/queue-6.6/smb-client-fix-oob-in-smb2_query_info_init.patch @@ -0,0 +1,178 @@ +From 33eae65c6f49770fec7a662935d4eb4a6406d24b Mon Sep 17 00:00:00 2001 +From: Paulo Alcantara +Date: Wed, 13 Dec 2023 12:25:57 -0300 +Subject: smb: client: fix OOB in SMB2_query_info_init() + +From: Paulo Alcantara + +commit 33eae65c6f49770fec7a662935d4eb4a6406d24b upstream. + +A small CIFS buffer (448 bytes) isn't big enough to hold +SMB2_QUERY_INFO request along with user's input data from +CIFS_QUERY_INFO ioctl. That is, if the user passed an input buffer > +344 bytes, the client will memcpy() off the end of @req->Buffer in +SMB2_query_info_init() thus causing the following KASAN splat: + + BUG: KASAN: slab-out-of-bounds in SMB2_query_info_init+0x242/0x250 [cifs] + Write of size 1023 at addr ffff88801308c5a8 by task a.out/1240 + + CPU: 1 PID: 1240 Comm: a.out Not tainted 6.7.0-rc4 #5 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS + rel-1.16.2-3-gd478f380-rebuilt.opensuse.org 04/01/2014 + Call Trace: + + dump_stack_lvl+0x4a/0x80 + print_report+0xcf/0x650 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? __phys_addr+0x46/0x90 + kasan_report+0xd8/0x110 + ? SMB2_query_info_init+0x242/0x250 [cifs] + ? SMB2_query_info_init+0x242/0x250 [cifs] + kasan_check_range+0x105/0x1b0 + __asan_memcpy+0x3c/0x60 + SMB2_query_info_init+0x242/0x250 [cifs] + ? __pfx_SMB2_query_info_init+0x10/0x10 [cifs] + ? srso_alias_return_thunk+0x5/0xfbef5 + ? smb_rqst_len+0xa6/0xc0 [cifs] + smb2_ioctl_query_info+0x4f4/0x9a0 [cifs] + ? __pfx_smb2_ioctl_query_info+0x10/0x10 [cifs] + ? __pfx_cifsConvertToUTF16+0x10/0x10 [cifs] + ? kasan_set_track+0x25/0x30 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? __kasan_kmalloc+0x8f/0xa0 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? cifs_strndup_to_utf16+0x12d/0x1a0 [cifs] + ? __build_path_from_dentry_optional_prefix+0x19d/0x2d0 [cifs] + ? __pfx_smb2_ioctl_query_info+0x10/0x10 [cifs] + cifs_ioctl+0x11c7/0x1de0 [cifs] + ? __pfx_cifs_ioctl+0x10/0x10 [cifs] + ? srso_alias_return_thunk+0x5/0xfbef5 + ? rcu_is_watching+0x23/0x50 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? __rseq_handle_notify_resume+0x6cd/0x850 + ? __pfx___schedule+0x10/0x10 + ? blkcg_iostat_update+0x250/0x290 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? ksys_write+0xe9/0x170 + __x64_sys_ioctl+0xc9/0x100 + do_syscall_64+0x47/0xf0 + entry_SYSCALL_64_after_hwframe+0x6f/0x77 + RIP: 0033:0x7f893dde49cf + Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 + 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> + c2 3d 00 f0 ff ff 77 18 48 8b 44 24 18 64 48 2b 04 25 28 00 00 + RSP: 002b:00007ffc03ff4160 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 + RAX: ffffffffffffffda RBX: 00007ffc03ff4378 RCX: 00007f893dde49cf + RDX: 00007ffc03ff41d0 RSI: 00000000c018cf07 RDI: 0000000000000003 + RBP: 00007ffc03ff4260 R08: 0000000000000410 R09: 0000000000000001 + R10: 00007f893dce7300 R11: 0000000000000246 R12: 0000000000000000 + R13: 00007ffc03ff4388 R14: 00007f893df15000 R15: 0000000000406de0 + + +Fix this by increasing size of SMB2_QUERY_INFO request buffers and +validating input length to prevent other callers from overflowing @req +in SMB2_query_info_init() as well. + +Fixes: f5b05d622a3e ("cifs: add IOCTL for QUERY_INFO passthrough to userspace") +Cc: stable@vger.kernel.org +Reported-by: Robert Morris +Signed-off-by: Paulo Alcantara +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/client/smb2pdu.c | 29 ++++++++++++++++++++++------- + 1 file changed, 22 insertions(+), 7 deletions(-) + +--- a/fs/smb/client/smb2pdu.c ++++ b/fs/smb/client/smb2pdu.c +@@ -376,10 +376,15 @@ static int __smb2_plain_req_init(__le16 + void **request_buf, unsigned int *total_len) + { + /* BB eventually switch this to SMB2 specific small buf size */ +- if (smb2_command == SMB2_SET_INFO) ++ switch (smb2_command) { ++ case SMB2_SET_INFO: ++ case SMB2_QUERY_INFO: + *request_buf = cifs_buf_get(); +- else ++ break; ++ default: + *request_buf = cifs_small_buf_get(); ++ break; ++ } + if (*request_buf == NULL) { + /* BB should we add a retry in here if not a writepage? */ + return -ENOMEM; +@@ -3494,8 +3499,13 @@ SMB2_query_info_init(struct cifs_tcon *t + struct smb2_query_info_req *req; + struct kvec *iov = rqst->rq_iov; + unsigned int total_len; ++ size_t len; + int rc; + ++ if (unlikely(check_add_overflow(input_len, sizeof(*req), &len) || ++ len > CIFSMaxBufSize)) ++ return -EINVAL; ++ + rc = smb2_plain_req_init(SMB2_QUERY_INFO, tcon, server, + (void **) &req, &total_len); + if (rc) +@@ -3517,7 +3527,7 @@ SMB2_query_info_init(struct cifs_tcon *t + + iov[0].iov_base = (char *)req; + /* 1 for Buffer */ +- iov[0].iov_len = total_len - 1 + input_len; ++ iov[0].iov_len = len; + return 0; + } + +@@ -3525,7 +3535,7 @@ void + SMB2_query_info_free(struct smb_rqst *rqst) + { + if (rqst && rqst->rq_iov) +- cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */ ++ cifs_buf_release(rqst->rq_iov[0].iov_base); /* request */ + } + + static int +@@ -5392,6 +5402,11 @@ build_qfs_info_req(struct kvec *iov, str + return 0; + } + ++static inline void free_qfs_info_req(struct kvec *iov) ++{ ++ cifs_buf_release(iov->iov_base); ++} ++ + int + SMB311_posix_qfs_info(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_fid, u64 volatile_fid, struct kstatfs *fsdata) +@@ -5423,7 +5438,7 @@ SMB311_posix_qfs_info(const unsigned int + + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); +- cifs_small_buf_release(iov.iov_base); ++ free_qfs_info_req(&iov); + if (rc) { + cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); + goto posix_qfsinf_exit; +@@ -5474,7 +5489,7 @@ SMB2_QFS_info(const unsigned int xid, st + + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); +- cifs_small_buf_release(iov.iov_base); ++ free_qfs_info_req(&iov); + if (rc) { + cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); + goto qfsinf_exit; +@@ -5541,7 +5556,7 @@ SMB2_QFS_attr(const unsigned int xid, st + + rc = cifs_send_recv(xid, ses, server, + &rqst, &resp_buftype, flags, &rsp_iov); +- cifs_small_buf_release(iov.iov_base); ++ free_qfs_info_req(&iov); + if (rc) { + cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); + goto qfsattr_exit; diff --git a/queue-6.6/smb-client-fix-oob-in-smbcalcsize.patch b/queue-6.6/smb-client-fix-oob-in-smbcalcsize.patch new file mode 100644 index 00000000000..20c63931215 --- /dev/null +++ b/queue-6.6/smb-client-fix-oob-in-smbcalcsize.patch @@ -0,0 +1,79 @@ +From b35858b3786ddbb56e1c35138ba25d6adf8d0bef Mon Sep 17 00:00:00 2001 +From: Paulo Alcantara +Date: Fri, 15 Dec 2023 19:59:14 -0300 +Subject: smb: client: fix OOB in smbCalcSize() + +From: Paulo Alcantara + +commit b35858b3786ddbb56e1c35138ba25d6adf8d0bef upstream. + +Validate @smb->WordCount to avoid reading off the end of @smb and thus +causing the following KASAN splat: + + BUG: KASAN: slab-out-of-bounds in smbCalcSize+0x32/0x40 [cifs] + Read of size 2 at addr ffff88801c024ec5 by task cifsd/1328 + + CPU: 1 PID: 1328 Comm: cifsd Not tainted 6.7.0-rc5 #9 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS + rel-1.16.2-3-gd478f380-rebuilt.opensuse.org 04/01/2014 + Call Trace: + + dump_stack_lvl+0x4a/0x80 + print_report+0xcf/0x650 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? __phys_addr+0x46/0x90 + kasan_report+0xd8/0x110 + ? smbCalcSize+0x32/0x40 [cifs] + ? smbCalcSize+0x32/0x40 [cifs] + kasan_check_range+0x105/0x1b0 + smbCalcSize+0x32/0x40 [cifs] + checkSMB+0x162/0x370 [cifs] + ? __pfx_checkSMB+0x10/0x10 [cifs] + cifs_handle_standard+0xbc/0x2f0 [cifs] + ? srso_alias_return_thunk+0x5/0xfbef5 + cifs_demultiplex_thread+0xed1/0x1360 [cifs] + ? __pfx_cifs_demultiplex_thread+0x10/0x10 [cifs] + ? srso_alias_return_thunk+0x5/0xfbef5 + ? lockdep_hardirqs_on_prepare+0x136/0x210 + ? __pfx_lock_release+0x10/0x10 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? mark_held_locks+0x1a/0x90 + ? lockdep_hardirqs_on_prepare+0x136/0x210 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? __kthread_parkme+0xce/0xf0 + ? __pfx_cifs_demultiplex_thread+0x10/0x10 [cifs] + kthread+0x18d/0x1d0 + ? kthread+0xdb/0x1d0 + ? __pfx_kthread+0x10/0x10 + ret_from_fork+0x34/0x60 + ? __pfx_kthread+0x10/0x10 + ret_from_fork_asm+0x1b/0x30 + + +This fixes CVE-2023-6606. + +Reported-by: j51569436@gmail.com +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218218 +Cc: stable@vger.kernel.org +Signed-off-by: Paulo Alcantara (SUSE) +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/client/misc.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/fs/smb/client/misc.c ++++ b/fs/smb/client/misc.c +@@ -363,6 +363,10 @@ checkSMB(char *buf, unsigned int total_r + cifs_dbg(VFS, "Length less than smb header size\n"); + } + return -EIO; ++ } else if (total_read < sizeof(*smb) + 2 * smb->WordCount) { ++ cifs_dbg(VFS, "%s: can't read BCC due to invalid WordCount(%u)\n", ++ __func__, smb->WordCount); ++ return -EIO; + } + + /* otherwise, there is enough to get to the BCC */ diff --git a/queue-6.6/smb-client-fix-potential-oob-in-cifs_dump_detail.patch b/queue-6.6/smb-client-fix-potential-oob-in-cifs_dump_detail.patch new file mode 100644 index 00000000000..609e50508a8 --- /dev/null +++ b/queue-6.6/smb-client-fix-potential-oob-in-cifs_dump_detail.patch @@ -0,0 +1,41 @@ +From b50492b05fd02887b46aef079592207fb5c97a4c Mon Sep 17 00:00:00 2001 +From: Paulo Alcantara +Date: Sat, 16 Dec 2023 01:10:04 -0300 +Subject: smb: client: fix potential OOB in cifs_dump_detail() + +From: Paulo Alcantara + +commit b50492b05fd02887b46aef079592207fb5c97a4c upstream. + +Validate SMB message with ->check_message() before calling +->calc_smb_size(). + +Signed-off-by: Paulo Alcantara (SUSE) +Cc: stable@vger.kernel.org +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/client/cifs_debug.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/fs/smb/client/cifs_debug.c ++++ b/fs/smb/client/cifs_debug.c +@@ -40,11 +40,13 @@ void cifs_dump_detail(void *buf, struct + #ifdef CONFIG_CIFS_DEBUG2 + struct smb_hdr *smb = buf; + +- cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d\n", +- smb->Command, smb->Status.CifsError, +- smb->Flags, smb->Flags2, smb->Mid, smb->Pid); +- cifs_dbg(VFS, "smb buf %p len %u\n", smb, +- server->ops->calc_smb_size(smb)); ++ cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d Wct: %d\n", ++ smb->Command, smb->Status.CifsError, smb->Flags, ++ smb->Flags2, smb->Mid, smb->Pid, smb->WordCount); ++ if (!server->ops->check_message(buf, server->total_read, server)) { ++ cifs_dbg(VFS, "smb buf %p len %u\n", smb, ++ server->ops->calc_smb_size(smb)); ++ } + #endif /* CONFIG_CIFS_DEBUG2 */ + } +