From: Greg Kroah-Hartman Date: Thu, 16 Jul 2026 13:10:39 +0000 (+0200) Subject: 6.1-stable patches X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=500d0097f26464d1676303b96d77fccc04125a26;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: fuse-fix-device-node-leak-in-cuse_process_init_reply.patch fuse-re-lock-request-before-returning-from-fuse_ref_folio.patch i2c-core-fix-adapter-deregistration-race.patch i2c-stm32f7-truncate-clock-period-instead-of-rounding-it.patch input-elan_i2c-prevent-division-by-zero-and-arithmetic-underflow.patch input-goodix-clamp-the-device-reported-contact-count.patch input-iforce-bound-the-device-reported-force-feedback-effect-index.patch input-maple_keyb-set-driver-data-before-registering-input-device.patch input-maplecontrol-set-driver-data-before-registering-input-device.patch input-maplemouse-fix-null-pointer-dereference-in-open.patch input-maplemouse-set-driver-data-before-registering-input-device.patch input-mms114-fix-multi-touch-slot-corruption.patch input-synaptics-rmi4-bound-the-f30-keymap-to-the-gpio-led-count.patch input-synaptics-rmi4-bound-the-f3a-keymap-to-the-gpio-count.patch input-synaptics-rmi4-unregister-function-handlers-on-physical-driver-registration-failure.patch input-touchwin-reset-the-packet-index-on-every-complete-packet.patch rdma-rtrs-srv-bound-rdma-write-length-to-chunk-size-in-rdma_write_sg.patch rdma-siw-bound-read-response-placement-to-the-rread-length.patch --- diff --git a/queue-6.1/fuse-fix-device-node-leak-in-cuse_process_init_reply.patch b/queue-6.1/fuse-fix-device-node-leak-in-cuse_process_init_reply.patch new file mode 100644 index 0000000000..a58cb956f9 --- /dev/null +++ b/queue-6.1/fuse-fix-device-node-leak-in-cuse_process_init_reply.patch @@ -0,0 +1,68 @@ +From 9fa4f7a53406430ee9982f2f636a15b338185122 Mon Sep 17 00:00:00 2001 +From: Alberto Ruiz +Date: Wed, 8 Apr 2026 17:23:40 +0200 +Subject: fuse: fix device node leak in cuse_process_init_reply() + +From: Alberto Ruiz + +commit 9fa4f7a53406430ee9982f2f636a15b338185122 upstream. + +If device_add() succeeds during CUSE initialization but a subsequent +step (cdev_alloc() or cdev_add()) fails, the error path calls +put_device() without first calling device_del(). This leaks the +devtmpfs entry created by device_add(), leaving a stale /dev/ +node that persists until reboot. + +Since the cuse_conn is never linked into cuse_conntbl on the failure +path, cuse_channel_release() sees cc->dev == NULL and skips +device_unregister(), so no other code path cleans up the node. + +This has several consequences: + + - The device name is permanently poisoned: any subsequent attempt to + create a CUSE device with the same name hits the stale sysfs entry, + device_add() fails, and the new device is aborted. + + - The collision manifests as ENODEV returned to userspace with no + dmesg diagnostic, making it very difficult to debug. + + - The failure is self-perpetuating: once a name is leaked, all future + attempts with that name fail identically. + +Fix this by introducing an err_dev label that calls device_del() to +undo device_add() before falling through to err_unlock. The existing +err_unlock path from a device_add() failure correctly skips device_del() +since the device was never added. + +Testing instructions can be found at the lore link below. + +Link: https://lore.kernel.org/all/20260408-wip-cuse-leak-fix-v1-0-1c028d575e97@redhat.com/ +Signed-off-by: Alberto Ruiz +Fixes: 151060ac1314 ("CUSE: implement CUSE - Character device in Userspace") +Cc: stable@vger.kernel.org +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman +--- + fs/fuse/cuse.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/fs/fuse/cuse.c ++++ b/fs/fuse/cuse.c +@@ -386,7 +386,7 @@ static void cuse_process_init_reply(stru + rc = -ENOMEM; + cdev = cdev_alloc(); + if (!cdev) +- goto err_unlock; ++ goto err_dev; + + cdev->owner = THIS_MODULE; + cdev->ops = &cuse_frontend_fops; +@@ -412,6 +412,8 @@ out: + + err_cdev: + cdev_del(cdev); ++err_dev: ++ device_del(dev); + err_unlock: + mutex_unlock(&cuse_lock); + put_device(dev); diff --git a/queue-6.1/fuse-re-lock-request-before-returning-from-fuse_ref_folio.patch b/queue-6.1/fuse-re-lock-request-before-returning-from-fuse_ref_folio.patch new file mode 100644 index 0000000000..b97bdaa647 --- /dev/null +++ b/queue-6.1/fuse-re-lock-request-before-returning-from-fuse_ref_folio.patch @@ -0,0 +1,37 @@ +From b5befa80fdbe287a98480effed9564712924add5 Mon Sep 17 00:00:00 2001 +From: Joanne Koong +Date: Mon, 18 May 2026 22:28:07 -0700 +Subject: fuse: re-lock request before returning from fuse_ref_folio() + +From: Joanne Koong + +commit b5befa80fdbe287a98480effed9564712924add5 upstream. + +fuse_ref_folio() unlocks the request but does not re-lock it before +returning. fuse_chan_abort() can end the request and the async end +callback (eg fuse_writepage_free()) can free the args while the +subsequent copy chain logic after fuse_ref_folio() accesses them, +leading to use-after-free issues. + +Fix this by locking the request in fuse_ref_folio() before returning. + +Fixes: c3021629a0d8 ("fuse: support splice() reading from fuse device") +Cc: stable@vger.kernel.org +Signed-off-by: Joanne Koong +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman +--- + fs/fuse/dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/fuse/dev.c ++++ b/fs/fuse/dev.c +@@ -908,7 +908,7 @@ static int fuse_ref_page(struct fuse_cop + cs->nr_segs++; + cs->len = 0; + +- return 0; ++ return lock_request(cs->req); + } + + /* diff --git a/queue-6.1/i2c-core-fix-adapter-deregistration-race.patch b/queue-6.1/i2c-core-fix-adapter-deregistration-race.patch new file mode 100644 index 0000000000..47ea68fb36 --- /dev/null +++ b/queue-6.1/i2c-core-fix-adapter-deregistration-race.patch @@ -0,0 +1,58 @@ +From b1a58ed9eab146b36f41a55db8f5d7ce9fdedf3f Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 11 May 2026 16:37:13 +0200 +Subject: i2c: core: fix adapter deregistration race + +From: Johan Hovold + +commit b1a58ed9eab146b36f41a55db8f5d7ce9fdedf3f upstream. + +Adapters can be looked up by their id using i2c_get_adapter() which +takes a reference to the embedded struct device. + +Remove the adapter from the IDR before tearing it down during +deregistration (and on registration failure) to make sure its resources +are not accessed after having been freed (e.g. the device name). + +Fixes: 35fc37f81881 ("i2c: Limit core locking to the necessary sections") +Cc: stable@vger.kernel.org # 2.6.31 +Cc: Jean Delvare +Signed-off-by: Johan Hovold +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman +--- + drivers/i2c/i2c-core-base.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/i2c/i2c-core-base.c ++++ b/drivers/i2c/i2c-core-base.c +@@ -1568,7 +1568,7 @@ static int i2c_register_adapter(struct i + res = device_add(&adap->dev); + if (res) { + pr_err("adapter '%s': can't register device (%d)\n", adap->name, res); +- goto err_remove_debugfs; ++ goto err_replace_id; + } + + res = i2c_setup_smbus_alert(adap); +@@ -1612,7 +1612,10 @@ static int i2c_register_adapter(struct i + out_reg: + i2c_deregister_clients(adap); + device_del(&adap->dev); +-err_remove_debugfs: ++err_replace_id: ++ mutex_lock(&core_lock); ++ idr_replace(&i2c_adapter_idr, NULL, adap->nr); ++ mutex_unlock(&core_lock); + debugfs_remove_recursive(adap->debugfs); + init_completion(&adap->dev_released); + put_device(&adap->dev); +@@ -1802,6 +1805,8 @@ void i2c_del_adapter(struct i2c_adapter + /* First make sure that this adapter was ever added */ + mutex_lock(&core_lock); + found = idr_find(&i2c_adapter_idr, adap->nr); ++ if (found == adap) ++ idr_replace(&i2c_adapter_idr, NULL, adap->nr); + mutex_unlock(&core_lock); + if (found != adap) { + pr_debug("attempting to delete unregistered adapter [%s]\n", adap->name); diff --git a/queue-6.1/i2c-stm32f7-truncate-clock-period-instead-of-rounding-it.patch b/queue-6.1/i2c-stm32f7-truncate-clock-period-instead-of-rounding-it.patch new file mode 100644 index 0000000000..a8c13ba4e1 --- /dev/null +++ b/queue-6.1/i2c-stm32f7-truncate-clock-period-instead-of-rounding-it.patch @@ -0,0 +1,67 @@ +From 111bb7f9f4a90b32e495d70a607c67b137f3074a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Guillermo=20Rodr=C3=ADguez?= +Date: Thu, 11 Jun 2026 12:48:56 +0200 +Subject: i2c: stm32f7: truncate clock period instead of rounding it +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Guillermo Rodríguez + +commit 111bb7f9f4a90b32e495d70a607c67b137f3074a upstream. + +stm32f7_i2c_compute_timing() derives the I2C clock source period +(i2cclk) with DIV_ROUND_CLOSEST, which may round it up. When the +period is overestimated, all timings computed from it (SCLDEL, +SDADEL, SCLL, SCLH) come out shorter on the wire than calculated, +and the resulting bus rate can exceed the requested speed, violating +the I2C specification minimums for tLOW and tHIGH. + +For example, with a 104.45 MHz clock source (e.g. PCLK1, the +reset-default I2C clock source on STM32MP1), i2cclk is rounded from +9.574 ns up to 10 ns. Requesting a 400 kHz fast mode bus with +72/27 ns rise/fall times and no analog/digital filters then produces +an actual bus rate of 415.6 kHz with tLOW = 1254 ns, violating both +the 400 kHz maximum rate and the 1300 ns tLOW minimum of the +specification. + +Truncate the period instead, so that it can only be underestimated. +The error then falls on the safe side: the programmed timings come +out slightly longer than computed and the bus runs marginally below +the target rate (375.3 kHz in the example above) while meeting the +specification. + +i2cbus is left rounded-to-closest: it is only used as the target of +the clk_error comparison and is never multiplied into the programmed +timings, so nearest rounding remains accurate there. + +Fixes: aeb068c57214 ("i2c: i2c-stm32f7: add driver") +Signed-off-by: Guillermo Rodríguez +Cc: # v4.14+ +Acked-by: Alain Volmat +Reviewed-by: Pierre-Yves MORDRET +Signed-off-by: Andi Shyti +Link: https://lore.kernel.org/r/20260611104857.242153-1-guille.rodriguez@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/i2c/busses/i2c-stm32f7.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/i2c/busses/i2c-stm32f7.c ++++ b/drivers/i2c/busses/i2c-stm32f7.c +@@ -449,8 +449,13 @@ static int stm32f7_i2c_compute_timing(st + { + struct stm32f7_i2c_spec *specs; + u32 p_prev = STM32F7_PRESC_MAX; +- u32 i2cclk = DIV_ROUND_CLOSEST(NSEC_PER_SEC, +- setup->clock_src); ++ /* ++ * Truncate instead of rounding to closest: if the clock period is ++ * overestimated, the computed SCL timings will come out shorter on ++ * the wire, which can push the bus above the target rate and below ++ * the spec's tLOW/tHIGH minimums. ++ */ ++ u32 i2cclk = NSEC_PER_SEC / setup->clock_src; + u32 i2cbus = DIV_ROUND_CLOSEST(NSEC_PER_SEC, + setup->speed_freq); + u32 clk_error_prev = i2cbus; diff --git a/queue-6.1/input-elan_i2c-prevent-division-by-zero-and-arithmetic-underflow.patch b/queue-6.1/input-elan_i2c-prevent-division-by-zero-and-arithmetic-underflow.patch new file mode 100644 index 0000000000..35f2dca9d3 --- /dev/null +++ b/queue-6.1/input-elan_i2c-prevent-division-by-zero-and-arithmetic-underflow.patch @@ -0,0 +1,107 @@ +From df2b818fa009c10ff6ba875a1663ff001cda9558 Mon Sep 17 00:00:00 2001 +From: Ranjan Kumar +Date: Mon, 22 Jun 2026 22:31:05 -0700 +Subject: Input: elan_i2c - prevent division by zero and arithmetic underflow + +From: Ranjan Kumar + +commit df2b818fa009c10ff6ba875a1663ff001cda9558 upstream. + +The Elan I2C touchpad driver queries the device for its physical +dimensions and trace counts to calculate the device resolution and width. +However, if the device firmware or device tree provides invalid zero +values for x_traces or y_traces, it results in a fatal division-by-zero +exception leading to a kernel panic during device probe. + +Add checks to ensure these parameters are non-zero before performing +the division. If invalid trace values are detected, fall back to a safe +default of 1. + +Additionally, prevent an arithmetic underflow in the touch reporting +logic. Previously, if the calculated or fallback width was smaller than +ETP_FWIDTH_REDUCE (90), the subtraction would underflow, resulting in a +massive unsigned integer being reported to userspace. Clamp the adjusted +width to a minimum of 0 to safely handle small physical dimensions and +fallback scenarios. + +Completing the probe with safe fallback values ensures the sysfs nodes +are created, keeping the firmware update path intact so a recovery +firmware can be flashed to the device. + +Fixes: 6696777c6506 ("Input: add driver for Elan I2C/SMbus touchpad") +Fixes: e3a9a1290688 ("Input: elan_i2c - do not query the info if they are provided") +Signed-off-by: Ranjan Kumar +Link: https://patch.msgid.link/20260612060339.3829666-1-kumarranja@chromium.org +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/mouse/elan_i2c_core.c | 36 ++++++++++++++++++++++++++++++------ + 1 file changed, 30 insertions(+), 6 deletions(-) + +--- a/drivers/input/mouse/elan_i2c_core.c ++++ b/drivers/input/mouse/elan_i2c_core.c +@@ -425,8 +425,17 @@ static int elan_query_device_parameters( + if (error) + return error; + } +- data->width_x = data->max_x / x_traces; +- data->width_y = data->max_y / y_traces; ++ ++ if (!x_traces || !y_traces) { ++ dev_warn(&client->dev, ++ "invalid trace numbers: x=%u, y=%u\n", ++ x_traces, y_traces); ++ data->width_x = 1; ++ data->width_y = 1; ++ } else { ++ data->width_x = data->max_x / x_traces; ++ data->width_y = data->max_y / y_traces; ++ } + + if (device_property_read_u32(&client->dev, + "touchscreen-x-mm", &x_mm) || +@@ -440,8 +449,16 @@ static int elan_query_device_parameters( + data->x_res = elan_convert_resolution(hw_x_res, data->pattern); + data->y_res = elan_convert_resolution(hw_y_res, data->pattern); + } else { +- data->x_res = (data->max_x + 1) / x_mm; +- data->y_res = (data->max_y + 1) / y_mm; ++ if (unlikely(x_mm == 0 || y_mm == 0)) { ++ dev_warn(&client->dev, ++ "invalid physical dimensions: x_mm=%u, y_mm=%u\n", ++ x_mm, y_mm); ++ data->x_res = 1; ++ data->y_res = 1; ++ } else { ++ data->x_res = (data->max_x + 1) / x_mm; ++ data->y_res = (data->max_y + 1) / y_mm; ++ } + } + + if (device_property_read_bool(&client->dev, "elan,clickpad")) +@@ -960,6 +977,7 @@ static void elan_report_contact(struct e + + if (data->report_features & ETP_FEATURE_REPORT_MK) { + unsigned int mk_x, mk_y, area_x, area_y; ++ int adj_width_x, adj_width_y; + u8 mk_data = high_precision ? + packet[ETP_MK_DATA_OFFSET + contact_num] : + finger_data[3]; +@@ -971,8 +989,14 @@ static void elan_report_contact(struct e + * To avoid treating large finger as palm, let's reduce + * the width x and y per trace. + */ +- area_x = mk_x * (data->width_x - ETP_FWIDTH_REDUCE); +- area_y = mk_y * (data->width_y - ETP_FWIDTH_REDUCE); ++ ++ adj_width_x = data->width_x > ETP_FWIDTH_REDUCE ? ++ data->width_x - ETP_FWIDTH_REDUCE : 0; ++ adj_width_y = data->width_y > ETP_FWIDTH_REDUCE ? ++ data->width_y - ETP_FWIDTH_REDUCE : 0; ++ ++ area_x = mk_x * adj_width_x; ++ area_y = mk_y * adj_width_y; + + input_report_abs(input, ABS_TOOL_WIDTH, mk_x); + input_report_abs(input, ABS_MT_TOUCH_MAJOR, diff --git a/queue-6.1/input-goodix-clamp-the-device-reported-contact-count.patch b/queue-6.1/input-goodix-clamp-the-device-reported-contact-count.patch new file mode 100644 index 0000000000..7b0912ed3d --- /dev/null +++ b/queue-6.1/input-goodix-clamp-the-device-reported-contact-count.patch @@ -0,0 +1,55 @@ +From 5ed62a96e06be4e94b8296b7932afee550a70e04 Mon Sep 17 00:00:00 2001 +From: Bryam Vargas +Date: Fri, 12 Jun 2026 21:10:33 -0500 +Subject: Input: goodix - clamp the device-reported contact count + +From: Bryam Vargas + +commit 5ed62a96e06be4e94b8296b7932afee550a70e04 upstream. + +goodix_ts_read_input_report() copies the number of touch points reported +by the device into an on-stack buffer + + u8 point_data[2 + GOODIX_MAX_CONTACT_SIZE * GOODIX_MAX_CONTACTS]; + +which is sized for at most GOODIX_MAX_CONTACTS (10) contacts. The only +runtime check bounds the per-interrupt count against ts->max_touch_num, +but that value is taken verbatim from a 4-bit field of the device +configuration block and is never clamped: + + ts->max_touch_num = ts->config[MAX_CONTACTS_LOC] & 0x0f; + +The nibble can be 0..15, so a malfunctioning, malicious or counterfeit +controller (or an attacker tampering with the I2C bus) can advertise up +to 15 contacts. goodix_ts_read_input_report() then accepts a touch_num +of up to 15 and the second goodix_i2c_read() writes +ts->contact_size * (touch_num - 1) bytes past the one-contact header into +point_data - up to 30 bytes (45 with the 9-byte report format) beyond the +92-byte buffer: a stack out-of-bounds write. + +Clamp max_touch_num to GOODIX_MAX_CONTACTS, the number of contacts +point_data[] is sized for, when reading it from the configuration. + +Fixes: a7ac7c95d468 ("Input: goodix - use max touch number from device config") +Cc: stable@vger.kernel.org +Signed-off-by: Bryam Vargas +Reviewed-by: Hans de Goede +Link: https://patch.msgid.link/20260612-b4-disp-6844625d-v1-1-df0aed080c9d@proton.me +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/touchscreen/goodix.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/input/touchscreen/goodix.c ++++ b/drivers/input/touchscreen/goodix.c +@@ -1074,7 +1074,8 @@ static void goodix_read_config(struct go + } + + ts->int_trigger_type = ts->config[TRIGGER_LOC] & 0x03; +- ts->max_touch_num = ts->config[MAX_CONTACTS_LOC] & 0x0f; ++ ts->max_touch_num = min(ts->config[MAX_CONTACTS_LOC] & 0x0f, ++ GOODIX_MAX_CONTACTS); + + x_max = get_unaligned_le16(&ts->config[RESOLUTION_LOC]); + y_max = get_unaligned_le16(&ts->config[RESOLUTION_LOC + 2]); diff --git a/queue-6.1/input-iforce-bound-the-device-reported-force-feedback-effect-index.patch b/queue-6.1/input-iforce-bound-the-device-reported-force-feedback-effect-index.patch new file mode 100644 index 0000000000..82af18d453 --- /dev/null +++ b/queue-6.1/input-iforce-bound-the-device-reported-force-feedback-effect-index.patch @@ -0,0 +1,82 @@ +From 0e9943d2e4c63496b6ca84bc66fd3c71d40558e2 Mon Sep 17 00:00:00 2001 +From: Bryam Vargas +Date: Mon, 22 Jun 2026 20:47:50 -0700 +Subject: Input: iforce - bound the device-reported force-feedback effect index + +From: Bryam Vargas + +commit 0e9943d2e4c63496b6ca84bc66fd3c71d40558e2 upstream. + +iforce_process_packet() handles a status report (packet id 0x02) by +taking a force-feedback effect index straight from the device wire and +using it to address the per-effect state array: + + i = data[1] & 0x7f; + if (data[1] & 0x80) { + if (!test_and_set_bit(FF_CORE_IS_PLAYED, + iforce->core_effects[i].flags)) + ... + } else if (test_and_clear_bit(FF_CORE_IS_PLAYED, + iforce->core_effects[i].flags)) { + ... + } + +The index is masked only with 0x7f, so it ranges 0..127, but +core_effects[] holds only IFORCE_EFFECTS_MAX (32) entries. For an index +of 32..127 the test_and_set_bit()/test_and_clear_bit() is an +out-of-bounds single-bit read-modify-write past the array. core_effects[] +is the second-to-last member of struct iforce, so the write lands in the +trailing members and beyond the embedding kzalloc()'d iforce_serio / +iforce_usb object. + +data[1] is unvalidated device payload on both transports (the USB +interrupt endpoint and serio), and the status path is not gated on force +feedback being present, so a malicious or counterfeit device can set or +clear a bit at an attacker-chosen offset past the object. + +Reject an out-of-range index instead of indexing with it. Bound against +the array dimension IFORCE_EFFECTS_MAX rather than dev->ff->max_effects so +the check guarantees memory safety regardless of how many effects the +device registered. A legitimate "effect started/stopped" status always +carries an index below IFORCE_EFFECTS_MAX, so well-formed devices are +unaffected; the neighbouring mark_core_as_ready() loop is already bounded +and is left untouched. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Bryam Vargas +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20260613-b4-disp-4828d263-v1-1-02320e1a89dd@proton.me +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/joystick/iforce/iforce-packets.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +--- a/drivers/input/joystick/iforce/iforce-packets.c ++++ b/drivers/input/joystick/iforce/iforce-packets.c +@@ -192,14 +192,18 @@ void iforce_process_packet(struct iforce + + /* Check if an effect was just started or stopped */ + i = data[1] & 0x7f; +- if (data[1] & 0x80) { +- if (!test_and_set_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) { +- /* Report play event */ +- input_report_ff_status(dev, i, FF_STATUS_PLAYING); ++ if (i < IFORCE_EFFECTS_MAX) { ++ if (data[1] & 0x80) { ++ if (!test_and_set_bit(FF_CORE_IS_PLAYED, ++ iforce->core_effects[i].flags)) { ++ /* Report play event */ ++ input_report_ff_status(dev, i, FF_STATUS_PLAYING); ++ } ++ } else if (test_and_clear_bit(FF_CORE_IS_PLAYED, ++ iforce->core_effects[i].flags)) { ++ /* Report stop event */ ++ input_report_ff_status(dev, i, FF_STATUS_STOPPED); + } +- } else if (test_and_clear_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) { +- /* Report stop event */ +- input_report_ff_status(dev, i, FF_STATUS_STOPPED); + } + + for (j = 3; j < len; j += 2) diff --git a/queue-6.1/input-maple_keyb-set-driver-data-before-registering-input-device.patch b/queue-6.1/input-maple_keyb-set-driver-data-before-registering-input-device.patch new file mode 100644 index 0000000000..08c6da9d8c --- /dev/null +++ b/queue-6.1/input-maple_keyb-set-driver-data-before-registering-input-device.patch @@ -0,0 +1,41 @@ +From 536394ec81419b67d9f4f0028812c4372397be1b Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Mon, 29 Jun 2026 18:44:41 -0700 +Subject: Input: maple_keyb - set driver data before registering input device + +From: Dmitry Torokhov + +commit 536394ec81419b67d9f4f0028812c4372397be1b upstream. + +Set maple driver data before calling input_register_device() to +ensure that it is available if the device is opened immediately and +the callback is triggered. + +Cc: stable@vger.kernel.org +Assisted-by: Antigravity:gemini-3.5-flash +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/keyboard/maple_keyb.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/input/keyboard/maple_keyb.c ++++ b/drivers/input/keyboard/maple_keyb.c +@@ -169,6 +169,8 @@ static int probe_maple_kbd(struct device + kbd->dev = idev; + memcpy(kbd->keycode, dc_kbd_keycode, sizeof(kbd->keycode)); + ++ maple_set_drvdata(mdev, kbd); ++ + idev->name = mdev->product_name; + idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + idev->keycode = kbd->keycode; +@@ -193,8 +195,6 @@ static int probe_maple_kbd(struct device + + mdev->driver = mdrv; + +- maple_set_drvdata(mdev, kbd); +- + return error; + + fail_register: diff --git a/queue-6.1/input-maplecontrol-set-driver-data-before-registering-input-device.patch b/queue-6.1/input-maplecontrol-set-driver-data-before-registering-input-device.patch new file mode 100644 index 0000000000..37e62e24db --- /dev/null +++ b/queue-6.1/input-maplecontrol-set-driver-data-before-registering-input-device.patch @@ -0,0 +1,42 @@ +From fe938ee497d58c644f6910cfe6ae155f6fb3e523 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Mon, 29 Jun 2026 22:49:15 -0700 +Subject: Input: maplecontrol - set driver data before registering input device + +From: Dmitry Torokhov + +commit fe938ee497d58c644f6910cfe6ae155f6fb3e523 upstream. + +Set maple driver data before calling input_register_device() to +ensure that it is available if the device is opened immediately and +the callback is triggered. + +Cc: stable@vger.kernel.org +Assisted-by: Antigravity:gemini-3.5-flash +Tested-by: Florian Fuchs +Link: https://patch.msgid.link/akNYib9hQFNN1fA9@google.com +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/joystick/maplecontrol.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/input/joystick/maplecontrol.c ++++ b/drivers/input/joystick/maplecontrol.c +@@ -112,6 +112,8 @@ static int probe_maple_controller(struct + pad->dev = idev; + pad->mdev = mdev; + ++ maple_set_drvdata(mdev, pad); ++ + idev->open = dc_pad_open; + idev->close = dc_pad_close; + +@@ -146,7 +148,6 @@ static int probe_maple_controller(struct + goto fail; + + mdev->driver = mdrv; +- maple_set_drvdata(mdev, pad); + + return 0; + diff --git a/queue-6.1/input-maplemouse-fix-null-pointer-dereference-in-open.patch b/queue-6.1/input-maplemouse-fix-null-pointer-dereference-in-open.patch new file mode 100644 index 0000000000..695fe059c1 --- /dev/null +++ b/queue-6.1/input-maplemouse-fix-null-pointer-dereference-in-open.patch @@ -0,0 +1,62 @@ +From ee89db004238bd0b034f2a6176e175561658750b Mon Sep 17 00:00:00 2001 +From: Florian Fuchs +Date: Mon, 29 Jun 2026 18:33:42 -0700 +Subject: Input: maplemouse - fix NULL pointer dereference in open() + +From: Florian Fuchs + +commit ee89db004238bd0b034f2a6176e175561658750b upstream. + +Commit 555c765b0cc2 ("Input: mouse - drop unnecessary calls to +input_set_drvdata") dropped the input_set_drvdata() call in probe +because the data appeared to be unused. However, dc_mouse_open() and +dc_mouse_close() were using maple_get_drvdata(to_maple_dev(&dev->dev)). +This appears to be accessing the data attached to an instance of +maple_device structure, while in reality this actually retrieves driver +data from the input device's embedded struct device (doing invalid +conversion of input device structure to maple device). After +input_set_drvdata() was removed, that lookup started returning NULL and +opening the input device dereferences mse->mdev. + +Restore input_set_drvdata() and convert open() and close() to use +input_get_drvdata() so the dependency is no longer hidden. + +Fixes: 6b3480855aad ("maple: input: fix up maple mouse driver") +Fixes: 555c765b0cc2 ("Input: mouse - drop unnecessary calls to input_set_drvdata") +Signed-off-by: Florian Fuchs +Link: https://patch.msgid.link/20260628230715.2982552-1-fuchsfl@gmail.com +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/mouse/maplemouse.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/input/mouse/maplemouse.c ++++ b/drivers/input/mouse/maplemouse.c +@@ -48,7 +48,7 @@ static void dc_mouse_callback(struct map + + static int dc_mouse_open(struct input_dev *dev) + { +- struct dc_mouse *mse = maple_get_drvdata(to_maple_dev(&dev->dev)); ++ struct dc_mouse *mse = input_get_drvdata(dev); + + maple_getcond_callback(mse->mdev, dc_mouse_callback, HZ/50, + MAPLE_FUNC_MOUSE); +@@ -58,7 +58,7 @@ static int dc_mouse_open(struct input_de + + static void dc_mouse_close(struct input_dev *dev) + { +- struct dc_mouse *mse = maple_get_drvdata(to_maple_dev(&dev->dev)); ++ struct dc_mouse *mse = input_get_drvdata(dev); + + maple_getcond_callback(mse->mdev, dc_mouse_callback, 0, + MAPLE_FUNC_MOUSE); +@@ -88,6 +88,7 @@ static int probe_maple_mouse(struct devi + mse->dev = input_dev; + mse->mdev = mdev; + ++ input_set_drvdata(input_dev, mse); + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); + input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | + BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); diff --git a/queue-6.1/input-maplemouse-set-driver-data-before-registering-input-device.patch b/queue-6.1/input-maplemouse-set-driver-data-before-registering-input-device.patch new file mode 100644 index 0000000000..895e7a344f --- /dev/null +++ b/queue-6.1/input-maplemouse-set-driver-data-before-registering-input-device.patch @@ -0,0 +1,48 @@ +From 738f24bbbc95dd50cb4229d1ed62a05f29db2bda Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Mon, 29 Jun 2026 22:47:34 -0700 +Subject: Input: maplemouse - set driver data before registering input device + +From: Dmitry Torokhov + +commit 738f24bbbc95dd50cb4229d1ed62a05f29db2bda upstream. + +Set maple driver data before calling input_register_device() to +ensure that it is available if the device is opened immediately and +the callback is triggered. + +Cc: stable@vger.kernel.org +Assisted-by: Antigravity:gemini-3.5-flash +Tested-by: Florian Fuchs +Link: https://patch.msgid.link/akNXw45L_8bxD6QV@google.com +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/mouse/maplemouse.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/input/mouse/maplemouse.c ++++ b/drivers/input/mouse/maplemouse.c +@@ -88,6 +88,8 @@ static int probe_maple_mouse(struct devi + mse->dev = input_dev; + mse->mdev = mdev; + ++ maple_set_drvdata(mdev, mse); ++ + input_set_drvdata(input_dev, mse); + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); + input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | +@@ -103,12 +105,12 @@ static int probe_maple_mouse(struct devi + goto fail_register; + + mdev->driver = mdrv; +- maple_set_drvdata(mdev, mse); + + return error; + + fail_register: + input_free_device(input_dev); ++ maple_set_drvdata(mdev, NULL); + fail_nomem: + kfree(mse); + fail: diff --git a/queue-6.1/input-mms114-fix-multi-touch-slot-corruption.patch b/queue-6.1/input-mms114-fix-multi-touch-slot-corruption.patch new file mode 100644 index 0000000000..7fff1262d2 --- /dev/null +++ b/queue-6.1/input-mms114-fix-multi-touch-slot-corruption.patch @@ -0,0 +1,41 @@ +From adea84ee6cdea611146c4251d3c1616f5a09feca Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Fri, 3 Jul 2026 23:01:12 -0700 +Subject: Input: mms114 - fix multi-touch slot corruption + +From: Dmitry Torokhov + +commit adea84ee6cdea611146c4251d3c1616f5a09feca upstream. + +If the touchscreen controller reports a touch ID of 0, the driver +calculates the slot ID as touch->id - 1, which underflows to UINT_MAX. +This is passed to input_mt_slot() as -1. + +Since the input core ignores negative slot values, the active slot remains +unchanged. The driver then reports the touch coordinates for the previously +active slot, corrupting its state. + +Fix this by rejecting touch reports with ID 0. + +Fixes: 07b8481d4aff ("Input: add MELFAS mms114 touchscreen driver") +Cc: stable@vger.kernel.org +Reported-by: sashiko-bot@kernel.org +Assisted-by: Antigravity:gemini-3.5-flash +Link: https://patch.msgid.link/20260704060115.353049-1-dmitry.torokhov@gmail.com +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/touchscreen/mms114.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/input/touchscreen/mms114.c ++++ b/drivers/input/touchscreen/mms114.c +@@ -162,7 +162,7 @@ static void mms114_process_mt(struct mms + unsigned int x; + unsigned int y; + +- if (touch->id > MMS114_MAX_TOUCH) { ++ if (touch->id == 0 || touch->id > MMS114_MAX_TOUCH) { + dev_err(&client->dev, "Wrong touch id (%d)\n", touch->id); + return; + } diff --git a/queue-6.1/input-synaptics-rmi4-bound-the-f30-keymap-to-the-gpio-led-count.patch b/queue-6.1/input-synaptics-rmi4-bound-the-f30-keymap-to-the-gpio-led-count.patch new file mode 100644 index 0000000000..41d07d9114 --- /dev/null +++ b/queue-6.1/input-synaptics-rmi4-bound-the-f30-keymap-to-the-gpio-led-count.patch @@ -0,0 +1,46 @@ +From d577e46785d45484b2ab7e7309c49b18764bf56c Mon Sep 17 00:00:00 2001 +From: Bryam Vargas +Date: Sun, 14 Jun 2026 00:36:12 -0500 +Subject: Input: synaptics-rmi4 - bound the F30 keymap to the GPIO/LED count + +From: Bryam Vargas + +commit d577e46785d45484b2ab7e7309c49b18764bf56c upstream. + +rmi_f30_map_gpios() allocates gpioled_key_map with +min(gpioled_count, TRACKSTICK_RANGE_END) == at most 6 entries, but +rmi_f30_attention() iterates the full f30->gpioled_count (device query +register, range 0..31) and dereferences gpioled_key_map[i], and +input->keycodemax is set to the full gpioled_count while input->keycode +points at the 6-entry allocation. + +A device that reports gpioled_count > 6 with GPIO support enabled +therefore causes an out-of-bounds read on the attention interrupt and +out-of-bounds read/write through the EVIOCGKEYCODE/EVIOCSKEYCODE ioctls, +which bound the index only against keycodemax. This is the same defect +as the F3A handler, which was copied from F30. + +Size the keymap for the full gpioled_count; the mapping loop still +assigns only the first min(gpioled_count, TRACKSTICK_RANGE_END) entries. + +Fixes: 3e64fcbdbd10 ("Input: synaptics-rmi4 - limit the range of what GPIOs are buttons") +Cc: stable@vger.kernel.org +Signed-off-by: Bryam Vargas +Link: https://patch.msgid.link/20260614-b4-disp-818d6bda-v1-2-cf39a3615085@proton.me +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/rmi4/rmi_f30.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/input/rmi4/rmi_f30.c ++++ b/drivers/input/rmi4/rmi_f30.c +@@ -233,7 +233,7 @@ static int rmi_f30_map_gpios(struct rmi_ + int button_count = min_t(u8, f30->gpioled_count, TRACKSTICK_RANGE_END); + + f30->gpioled_key_map = devm_kcalloc(&fn->dev, +- button_count, ++ f30->gpioled_count, + sizeof(f30->gpioled_key_map[0]), + GFP_KERNEL); + if (!f30->gpioled_key_map) { diff --git a/queue-6.1/input-synaptics-rmi4-bound-the-f3a-keymap-to-the-gpio-count.patch b/queue-6.1/input-synaptics-rmi4-bound-the-f3a-keymap-to-the-gpio-count.patch new file mode 100644 index 0000000000..b061132c7a --- /dev/null +++ b/queue-6.1/input-synaptics-rmi4-bound-the-f3a-keymap-to-the-gpio-count.patch @@ -0,0 +1,51 @@ +From 57c10915f2c16c90e0d46ad00876bf39ece40fc2 Mon Sep 17 00:00:00 2001 +From: Bryam Vargas +Date: Sun, 14 Jun 2026 00:36:11 -0500 +Subject: Input: synaptics-rmi4 - bound the F3A keymap to the GPIO count + +From: Bryam Vargas + +commit 57c10915f2c16c90e0d46ad00876bf39ece40fc2 upstream. + +rmi_f3a_initialize() takes the GPIO count from the device query register +(f3a->gpio_count = buf & RMI_F3A_GPIO_COUNT, range 0..127). +rmi_f3a_map_gpios() then allocates gpio_key_map with +min(gpio_count, TRACKSTICK_RANGE_END) == at most 6 entries, but +rmi_f3a_attention() iterates the full gpio_count and dereferences +gpio_key_map[i], and input->keycodemax is set to the full gpio_count +while input->keycode points at the 6-entry allocation. + +A device that reports gpio_count > 6 therefore causes an out-of-bounds +read of gpio_key_map[] on every attention interrupt, and out-of-bounds +accesses through the input core's default keymap ioctls: EVIOCGKEYCODE +reads past the buffer (leaking adjacent slab memory to user space) and +EVIOCSKEYCODE writes a caller-controlled value past it, for any process +able to open the evdev node, since input_default_getkeycode() and +input_default_setkeycode() only bound the index against keycodemax. + +Size the keymap for the full gpio_count. The mapping loop is unchanged: +it still assigns only the first min(gpio_count, TRACKSTICK_RANGE_END) +entries; the remaining slots stay KEY_RESERVED (devm_kcalloc zero-fills) +and are skipped when reporting. + +Fixes: 9e4c596bfd00 ("Input: synaptics-rmi4 - add support for F3A") +Cc: stable@vger.kernel.org +Signed-off-by: Bryam Vargas +Link: https://patch.msgid.link/20260614-b4-disp-818d6bda-v1-1-cf39a3615085@proton.me +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/rmi4/rmi_f3a.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/input/rmi4/rmi_f3a.c ++++ b/drivers/input/rmi4/rmi_f3a.c +@@ -132,7 +132,7 @@ static int rmi_f3a_map_gpios(struct rmi_ + int button_count = min_t(u8, f3a->gpio_count, TRACKSTICK_RANGE_END); + + f3a->gpio_key_map = devm_kcalloc(&fn->dev, +- button_count, ++ f3a->gpio_count, + sizeof(f3a->gpio_key_map[0]), + GFP_KERNEL); + if (!f3a->gpio_key_map) { diff --git a/queue-6.1/input-synaptics-rmi4-unregister-function-handlers-on-physical-driver-registration-failure.patch b/queue-6.1/input-synaptics-rmi4-unregister-function-handlers-on-physical-driver-registration-failure.patch new file mode 100644 index 0000000000..1eb7ff6b20 --- /dev/null +++ b/queue-6.1/input-synaptics-rmi4-unregister-function-handlers-on-physical-driver-registration-failure.patch @@ -0,0 +1,43 @@ +From 6251f7d3472c0409e30f8d6a24f10d33d12e3f9a Mon Sep 17 00:00:00 2001 +From: Haoxiang Li +Date: Wed, 10 Jun 2026 16:41:16 -0700 +Subject: Input: synaptics-rmi4 - unregister function handlers on physical driver registration failure + +From: Haoxiang Li + +commit 6251f7d3472c0409e30f8d6a24f10d33d12e3f9a upstream. + +If rmi_register_physical_driver() fails, the current error path +unregisters only the RMI bus. The function handlers registered +earlier remain registered with the driver core. + +Add a separate error path to unregister the function handlers +before unregistering the bus in this failure case. + +Fixes: 2b6a321da9a2 ("Input: synaptics-rmi4 - add support for Synaptics RMI4 devices") +Signed-off-by: Haoxiang Li +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20260610064633.2837084-1-haoxiang_li2024@163.com +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/rmi4/rmi_bus.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/input/rmi4/rmi_bus.c ++++ b/drivers/input/rmi4/rmi_bus.c +@@ -448,11 +448,13 @@ static int __init rmi_bus_init(void) + if (error) { + pr_err("%s: error registering the RMI physical driver: %d\n", + __func__, error); +- goto err_unregister_bus; ++ goto err_unregister_function_handlers; + } + + return 0; + ++err_unregister_function_handlers: ++ rmi_unregister_function_handlers(); + err_unregister_bus: + bus_unregister(&rmi_bus_type); + return error; diff --git a/queue-6.1/input-touchwin-reset-the-packet-index-on-every-complete-packet.patch b/queue-6.1/input-touchwin-reset-the-packet-index-on-every-complete-packet.patch new file mode 100644 index 0000000000..53d5b9b200 --- /dev/null +++ b/queue-6.1/input-touchwin-reset-the-packet-index-on-every-complete-packet.patch @@ -0,0 +1,64 @@ +From 478cdd736f2ce3114f90e775d7358136d3977b94 Mon Sep 17 00:00:00 2001 +From: Bryam Vargas +Date: Sat, 13 Jun 2026 20:07:20 -0500 +Subject: Input: touchwin - reset the packet index on every complete packet + +From: Bryam Vargas + +commit 478cdd736f2ce3114f90e775d7358136d3977b94 upstream. + +tw_interrupt() accumulates each non-zero serial byte into a fixed +three-byte buffer with a running index that is only reset once a full +packet has been received *and* the device's two Y bytes agree: + + tw->data[tw->idx++] = data; + if (tw->idx == TW_LENGTH && tw->data[1] == tw->data[2]) { + ... + tw->idx = 0; + } + +The reset is gated on tw->data[1] == tw->data[2], a value the device +controls. A malicious, malfunctioning or counterfeit Touchwindow +peripheral can stream non-zero bytes whose 2nd and 3rd bytes differ: the +index reaches TW_LENGTH without the equality holding, is never reset, and +keeps growing, so tw->data[tw->idx++] walks off the end of the three-byte +array and the rest of the heap-allocated struct tw, one attacker-chosen +byte at a time -- an unbounded, device-driven heap out-of-bounds write. + +Reset the index on every completed packet and report an event only when +the two Y bytes match, like the other serio touchscreen drivers do. + +Fixes: 11ea3173d5f2 ("Input: add driver for Touchwin serial touchscreens") +Cc: stable@vger.kernel.org +Signed-off-by: Bryam Vargas +Link: https://patch.msgid.link/20260613-b4-disp-69921bfd-v1-1-82c036899959@proton.me +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/touchscreen/touchwin.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +--- a/drivers/input/touchscreen/touchwin.c ++++ b/drivers/input/touchscreen/touchwin.c +@@ -63,12 +63,15 @@ static irqreturn_t tw_interrupt(struct s + if (data) { /* touch */ + tw->touched = 1; + tw->data[tw->idx++] = data; +- /* verify length and that the two Y's are the same */ +- if (tw->idx == TW_LENGTH && tw->data[1] == tw->data[2]) { +- input_report_abs(dev, ABS_X, tw->data[0]); +- input_report_abs(dev, ABS_Y, tw->data[1]); +- input_report_key(dev, BTN_TOUCH, 1); +- input_sync(dev); ++ /* a full packet ends the accumulation, valid or not */ ++ if (tw->idx == TW_LENGTH) { ++ /* report only if the two Y's are the same */ ++ if (tw->data[1] == tw->data[2]) { ++ input_report_abs(dev, ABS_X, tw->data[0]); ++ input_report_abs(dev, ABS_Y, tw->data[1]); ++ input_report_key(dev, BTN_TOUCH, 1); ++ input_sync(dev); ++ } + tw->idx = 0; + } + } else if (tw->touched) { /* untouch */ diff --git a/queue-6.1/rdma-rtrs-srv-bound-rdma-write-length-to-chunk-size-in-rdma_write_sg.patch b/queue-6.1/rdma-rtrs-srv-bound-rdma-write-length-to-chunk-size-in-rdma_write_sg.patch new file mode 100644 index 0000000000..f6b2d167d6 --- /dev/null +++ b/queue-6.1/rdma-rtrs-srv-bound-rdma-write-length-to-chunk-size-in-rdma_write_sg.patch @@ -0,0 +1,66 @@ +From 963af8d97a8c6a117134a8d0db1415e0489200b1 Mon Sep 17 00:00:00 2001 +From: Zhenhao Wan +Date: Fri, 12 Jun 2026 01:15:54 +0800 +Subject: RDMA/rtrs-srv: Bound RDMA-Write length to chunk size in rdma_write_sg + +From: Zhenhao Wan + +commit 963af8d97a8c6a117134a8d0db1415e0489200b1 upstream. + +When the server answers an RTRS READ, rdma_write_sg() builds the source +scatter/gather entry for the IB_WR_RDMA_WRITE that returns data to the +peer. Its length is taken directly from the wire descriptor: + + plist->length = le32_to_cpu(id->rd_msg->desc[0].len); + +rd_msg points into the chunk buffer that the remote peer filled via +RDMA-WRITE-WITH-IMM (rtrs_srv_rdma_done() -> process_io_req() -> +process_read()), so desc[0].len is attacker-controlled and, before this +change, was only rejected when zero. The source address is the fixed +chunk start (dma_addr[msg_id]) and the source lkey is the PD-wide +local_dma_lkey, which is not tied to the chunk's MR mapping, so the verbs +layer does not constrain the transfer length to max_chunk_size. msg_id +and off are bounded against queue_depth and max_chunk_size in +rtrs_srv_rdma_done(), but desc[0].len is a separate field that was not +checked against the chunk size. + +A peer that advertises desc[0].len larger than max_chunk_size can make +the posted RDMA write read past the chunk's mapped region. The resulting +behaviour depends on the IOMMU configuration: with no IOMMU or in +passthrough mode the read may extend into memory adjacent to the chunk +and be returned to the peer, which can disclose host memory; with a +translating IOMMU the out-of-range access is expected to fault and abort +the connection. In either case the transfer exceeds what the protocol +permits and is driven by a remote peer. + +Reject a descriptor length above max_chunk_size, mirroring the existing +off >= max_chunk_size bound in rtrs_srv_rdma_done(). Legitimate clients +do not exceed it: the client sets desc[0].len to its MR length, which is +capped at the negotiated max_io_size (max_chunk_size - MAX_HDR_SIZE). + +Fixes: 9cb837480424 ("RDMA/rtrs: server: main functionality") +Link: https://patch.msgid.link/r/20260612-master-v1-1-70cde5c6fdc9@gmail.com +Reported-by: Yuhao Jiang +Cc: stable@vger.kernel.org +Signed-off-by: Zhenhao Wan +Reviewed-by: Md Haris Iqbal +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman +--- + drivers/infiniband/ulp/rtrs/rtrs-srv.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +@@ -222,8 +222,9 @@ static int rdma_write_sg(struct rtrs_srv + /* WR will fail with length error + * if this is 0 + */ +- if (plist->length == 0) { +- rtrs_err(s, "Invalid RDMA-Write sg list length 0\n"); ++ if (plist->length == 0 || plist->length > max_chunk_size) { ++ rtrs_err(s, "Invalid RDMA-Write sg list length %u\n", ++ plist->length); + return -EINVAL; + } + diff --git a/queue-6.1/rdma-siw-bound-read-response-placement-to-the-rread-length.patch b/queue-6.1/rdma-siw-bound-read-response-placement-to-the-rread-length.patch new file mode 100644 index 0000000000..bc5fc498db --- /dev/null +++ b/queue-6.1/rdma-siw-bound-read-response-placement-to-the-rread-length.patch @@ -0,0 +1,65 @@ +From 7d29f7e9dbd844cae4d3e559cf78324b9642fd6b Mon Sep 17 00:00:00 2001 +From: Michael Bommarito +Date: Tue, 2 Jun 2026 15:47:00 -0400 +Subject: RDMA/siw: bound Read Response placement to the RREAD length + +From: Michael Bommarito + +commit 7d29f7e9dbd844cae4d3e559cf78324b9642fd6b upstream. + +In drivers/infiniband/sw/siw/siw_qp_rx.c, siw_proc_rresp() places each +inbound Read Response DDP segment at sge->laddr + wqe->processed and then +accumulates wqe->processed, but it never checks the running total against +the sink buffer length on continuation segments. siw_check_sge() resolves +and validates the sink memory only on the first fragment (the if (!*mem) +branch), and siw_rresp_check_ntoh() compares the cumulative length against +wqe->bytes only on the final segment (the !frx->more_ddp_segs guard). + +A connected siw peer that answers an outstanding RREAD with Read Response +segments that keep the DDP Last flag clear, carrying more total payload +than the RREAD requested, drives wqe->processed past the validated sink +buffer; the next siw_rx_data() call writes out of bounds at +sge->laddr + wqe->processed. siw runs iWARP over ordinary routable TCP, +so the peer is the remote end of an established RDMA connection and needs +no local privilege. + +Bound every segment before placement, exactly as siw_proc_send() and +siw_proc_write() already do for their tagged and untagged paths, and +terminate the connection with a base-or-bounds DDP error when the +Read Response would overrun the sink buffer. + +This is the second receive-path length fix for this file. A separate +change rejects an MPA FPDU length that underflows the per-fragment +remainder in the header decode; that guard does not cover this case, +because here each individual segment length is self-consistent and only +the accumulated placement offset overruns the buffer. + +Fixes: 8b6a361b8c48 ("rdma/siw: receive path") +Link: https://patch.msgid.link/r/20260602194700.2273758-1-michael.bommarito@gmail.com +Cc: stable@vger.kernel.org +Assisted-by: Claude:claude-opus-4-8 +Signed-off-by: Michael Bommarito +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman +--- + drivers/infiniband/sw/siw/siw_qp_rx.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/infiniband/sw/siw/siw_qp_rx.c ++++ b/drivers/infiniband/sw/siw/siw_qp_rx.c +@@ -848,6 +848,15 @@ int siw_proc_rresp(struct siw_qp *qp) + } + mem_p = *mem; + ++ if (unlikely(wqe->processed + srx->fpdu_part_rem > wqe->bytes)) { ++ siw_dbg_qp(qp, "rresp len: %d + %d > %d\n", ++ wqe->processed, srx->fpdu_part_rem, wqe->bytes); ++ wqe->wc_status = SIW_WC_LOC_LEN_ERR; ++ siw_init_terminate(qp, TERM_ERROR_LAYER_DDP, ++ DDP_ETYPE_TAGGED_BUF, ++ DDP_ECODE_T_BASE_BOUNDS, 0); ++ return -EINVAL; ++ } + bytes = min(srx->fpdu_part_rem, srx->skb_new); + + if (mem_p->mem_obj == NULL) diff --git a/queue-6.1/series b/queue-6.1/series index 0b5afc52b6..c1ff660649 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -230,3 +230,21 @@ riscv-mm-define-direct_map_physmem_end.patch kvm-vmx-refresh-guest_pending_dbg_exceptions.bs-on-all-injected-dbs.patch kvm-vmx-grab-vmcs12-on-cr8-interception-update-iff-vcpu-is-in-guest-mode.patch udmabuf-fix-dma-direction-mismatch-in-release_udmabuf.patch +i2c-core-fix-adapter-deregistration-race.patch +i2c-stm32f7-truncate-clock-period-instead-of-rounding-it.patch +input-synaptics-rmi4-unregister-function-handlers-on-physical-driver-registration-failure.patch +input-synaptics-rmi4-bound-the-f3a-keymap-to-the-gpio-count.patch +input-synaptics-rmi4-bound-the-f30-keymap-to-the-gpio-led-count.patch +input-elan_i2c-prevent-division-by-zero-and-arithmetic-underflow.patch +input-goodix-clamp-the-device-reported-contact-count.patch +input-iforce-bound-the-device-reported-force-feedback-effect-index.patch +input-touchwin-reset-the-packet-index-on-every-complete-packet.patch +input-maplemouse-fix-null-pointer-dereference-in-open.patch +input-mms114-fix-multi-touch-slot-corruption.patch +input-maple_keyb-set-driver-data-before-registering-input-device.patch +input-maplemouse-set-driver-data-before-registering-input-device.patch +input-maplecontrol-set-driver-data-before-registering-input-device.patch +rdma-rtrs-srv-bound-rdma-write-length-to-chunk-size-in-rdma_write_sg.patch +rdma-siw-bound-read-response-placement-to-the-rread-length.patch +fuse-fix-device-node-leak-in-cuse_process_init_reply.patch +fuse-re-lock-request-before-returning-from-fuse_ref_folio.patch