From ecfdfdbfe7d74872594df5828005c0eaf951aaa8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 27 Nov 2025 15:02:26 +0100 Subject: [PATCH] 5.10-stable patches added patches: alsa-usb-audio-fix-potential-overflow-of-pcm-transfer-buffer.patch ata-libata-scsi-fix-system-suspend-for-a-security-locked-drive.patch dt-bindings-pinctrl-toshiba-visconti-fix-number-of-items-in-groups.patch input-pegasus-notetaker-fix-potential-out-of-bounds-access.patch input-remove-third-argument-of-usb_maxpacket.patch makefile.compiler-replace-cc-ifversion-with-compiler-specific-macros.patch mm-mempool-fix-poisoning-order-0-pages-with-highmem.patch mm-mempool-replace-kmap_atomic-with-kmap_local_page.patch mm-mprotect-delete-pmd_none_or_clear_bad_unless_trans_huge.patch mm-mprotect-use-long-for-page-accountings-and-retval.patch mptcp-do-not-fallback-when-ooo-is-present.patch mptcp-fix-a-race-in-mptcp_pm_del_add_timer.patch mptcp-fix-proto-fallback-detection-with-bpf.patch mptcp-fix-race-condition-in-mptcp_schedule_work.patch mptcp-introduce-mptcp_schedule_work.patch net-netpoll-fix-incorrect-refcount-handling-causing-incorrect-cleanup.patch net-qede-initialize-qede_ll_ops-with-designated-initializer.patch pmdomain-arm-scmi-fix-genpd-leak-on-provider-registration-failure.patch pmdomain-imx-fix-reference-count-leak-in-imx_gpc_remove.patch revert-nfs-don-t-set-nfs_ino_reval_pagecache-in-the-inode-cache-validity.patch uio_hv_generic-set-event-for-all-channels-on-the-device.patch usb-deprecate-the-third-argument-of-usb_maxpacket.patch --- ...tial-overflow-of-pcm-transfer-buffer.patch | 58 +++++ ...-suspend-for-a-security-locked-drive.patch | 82 ++++++ ...sconti-fix-number-of-items-in-groups.patch | 67 +++++ ...r-fix-potential-out-of-bounds-access.patch | 58 +++++ ...move-third-argument-of-usb_maxpacket.patch | 106 ++++++++ ...ersion-with-compiler-specific-macros.patch | 214 ++++++++++++++++ ...poisoning-order-0-pages-with-highmem.patch | 110 ++++++++ ...ace-kmap_atomic-with-kmap_local_page.patch | 71 +++++ ..._none_or_clear_bad_unless_trans_huge.patch | 242 ++++++++++++++++++ ...long-for-page-accountings-and-retval.patch | 226 ++++++++++++++++ ...-do-not-fallback-when-ooo-is-present.patch | 50 ++++ ...fix-a-race-in-mptcp_pm_del_add_timer.patch | 199 ++++++++++++++ ...ix-proto-fallback-detection-with-bpf.patch | 101 ++++++++ ...ace-condition-in-mptcp_schedule_work.patch | 100 ++++++++ .../mptcp-introduce-mptcp_schedule_work.patch | 123 +++++++++ ...t-handling-causing-incorrect-cleanup.patch | 85 ++++++ ...e_ll_ops-with-designated-initializer.patch | 43 ++++ ...eak-on-provider-registration-failure.patch | 82 ++++++ ...ference-count-leak-in-imx_gpc_remove.patch | 38 +++ ...agecache-in-the-inode-cache-validity.patch | 75 ++++++ queue-5.10/series | 22 ++ ...event-for-all-channels-on-the-device.patch | 74 ++++++ ...-the-third-argument-of-usb_maxpacket.patch | 85 ++++++ 23 files changed, 2311 insertions(+) create mode 100644 queue-5.10/alsa-usb-audio-fix-potential-overflow-of-pcm-transfer-buffer.patch create mode 100644 queue-5.10/ata-libata-scsi-fix-system-suspend-for-a-security-locked-drive.patch create mode 100644 queue-5.10/dt-bindings-pinctrl-toshiba-visconti-fix-number-of-items-in-groups.patch create mode 100644 queue-5.10/input-pegasus-notetaker-fix-potential-out-of-bounds-access.patch create mode 100644 queue-5.10/input-remove-third-argument-of-usb_maxpacket.patch create mode 100644 queue-5.10/makefile.compiler-replace-cc-ifversion-with-compiler-specific-macros.patch create mode 100644 queue-5.10/mm-mempool-fix-poisoning-order-0-pages-with-highmem.patch create mode 100644 queue-5.10/mm-mempool-replace-kmap_atomic-with-kmap_local_page.patch create mode 100644 queue-5.10/mm-mprotect-delete-pmd_none_or_clear_bad_unless_trans_huge.patch create mode 100644 queue-5.10/mm-mprotect-use-long-for-page-accountings-and-retval.patch create mode 100644 queue-5.10/mptcp-do-not-fallback-when-ooo-is-present.patch create mode 100644 queue-5.10/mptcp-fix-a-race-in-mptcp_pm_del_add_timer.patch create mode 100644 queue-5.10/mptcp-fix-proto-fallback-detection-with-bpf.patch create mode 100644 queue-5.10/mptcp-fix-race-condition-in-mptcp_schedule_work.patch create mode 100644 queue-5.10/mptcp-introduce-mptcp_schedule_work.patch create mode 100644 queue-5.10/net-netpoll-fix-incorrect-refcount-handling-causing-incorrect-cleanup.patch create mode 100644 queue-5.10/net-qede-initialize-qede_ll_ops-with-designated-initializer.patch create mode 100644 queue-5.10/pmdomain-arm-scmi-fix-genpd-leak-on-provider-registration-failure.patch create mode 100644 queue-5.10/pmdomain-imx-fix-reference-count-leak-in-imx_gpc_remove.patch create mode 100644 queue-5.10/revert-nfs-don-t-set-nfs_ino_reval_pagecache-in-the-inode-cache-validity.patch create mode 100644 queue-5.10/uio_hv_generic-set-event-for-all-channels-on-the-device.patch create mode 100644 queue-5.10/usb-deprecate-the-third-argument-of-usb_maxpacket.patch diff --git a/queue-5.10/alsa-usb-audio-fix-potential-overflow-of-pcm-transfer-buffer.patch b/queue-5.10/alsa-usb-audio-fix-potential-overflow-of-pcm-transfer-buffer.patch new file mode 100644 index 0000000000..0e1226594a --- /dev/null +++ b/queue-5.10/alsa-usb-audio-fix-potential-overflow-of-pcm-transfer-buffer.patch @@ -0,0 +1,58 @@ +From stable+bounces-196501-greg=kroah.com@vger.kernel.org Fri Nov 21 16:20:18 2025 +From: Sasha Levin +Date: Fri, 21 Nov 2025 10:12:56 -0500 +Subject: ALSA: usb-audio: Fix potential overflow of PCM transfer buffer +To: stable@vger.kernel.org +Cc: Takashi Iwai , syzbot+bfd77469c8966de076f7@syzkaller.appspotmail.com, Lizhi Xu , Sasha Levin +Message-ID: <20251121151256.2561194-1-sashal@kernel.org> + +From: Takashi Iwai + +[ Upstream commit 05a1fc5efdd8560f34a3af39c9cf1e1526cc3ddf ] + +The PCM stream data in USB-audio driver is transferred over USB URB +packet buffers, and each packet size is determined dynamically. The +packet sizes are limited by some factors such as wMaxPacketSize USB +descriptor. OTOH, in the current code, the actually used packet sizes +are determined only by the rate and the PPS, which may be bigger than +the size limit above. This results in a buffer overflow, as reported +by syzbot. + +Basically when the limit is smaller than the calculated packet size, +it implies that something is wrong, most likely a weird USB +descriptor. So the best option would be just to return an error at +the parameter setup time before doing any further operations. + +This patch introduces such a sanity check, and returns -EINVAL when +the packet size is greater than maxpacksize. The comparison with +ep->packsize[1] alone should suffice since it's always equal or +greater than ep->packsize[0]. + +Reported-by: syzbot+bfd77469c8966de076f7@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=bfd77469c8966de076f7 +Link: https://lore.kernel.org/690b6b46.050a0220.3d0d33.0054.GAE@google.com +Cc: Lizhi Xu +Cc: +Link: https://patch.msgid.link/20251109091211.12739-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +[ changed ep->cur_rate to rate parameter and chip to ep->chip ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + sound/usb/endpoint.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/sound/usb/endpoint.c ++++ b/sound/usb/endpoint.c +@@ -1093,6 +1093,11 @@ int snd_usb_endpoint_set_params(struct s + ep->sample_rem = rate % ep->pps; + ep->packsize[0] = rate / ep->pps; + ep->packsize[1] = (rate + (ep->pps - 1)) / ep->pps; ++ if (ep->packsize[1] > ep->maxpacksize) { ++ usb_audio_dbg(ep->chip, "Too small maxpacksize %u for rate %u / pps %u\n", ++ ep->maxpacksize, rate, ep->pps); ++ return -EINVAL; ++ } + + /* calculate the frequency in 16.16 format */ + ep->freqm = ep->freqn; diff --git a/queue-5.10/ata-libata-scsi-fix-system-suspend-for-a-security-locked-drive.patch b/queue-5.10/ata-libata-scsi-fix-system-suspend-for-a-security-locked-drive.patch new file mode 100644 index 0000000000..b67e1b3c2c --- /dev/null +++ b/queue-5.10/ata-libata-scsi-fix-system-suspend-for-a-security-locked-drive.patch @@ -0,0 +1,82 @@ +From stable+bounces-196787-greg=kroah.com@vger.kernel.org Mon Nov 24 20:08:49 2025 +From: Sasha Levin +Date: Mon, 24 Nov 2025 14:04:57 -0500 +Subject: ata: libata-scsi: Fix system suspend for a security locked drive +To: stable@vger.kernel.org +Cc: Niklas Cassel , Ilia Baryshnikov , Hannes Reinecke , "Martin K. Petersen" , Damien Le Moal , Sasha Levin +Message-ID: <20251124190457.4193878-1-sashal@kernel.org> + +From: Niklas Cassel + +[ Upstream commit b11890683380a36b8488229f818d5e76e8204587 ] + +Commit cf3fc037623c ("ata: libata-scsi: Fix ata_to_sense_error() status +handling") fixed ata_to_sense_error() to properly generate sense key +ABORTED COMMAND (without any additional sense code), instead of the +previous bogus sense key ILLEGAL REQUEST with the additional sense code +UNALIGNED WRITE COMMAND, for a failed command. + +However, this broke suspend for Security locked drives (drives that have +Security enabled, and have not been Security unlocked by boot firmware). + +The reason for this is that the SCSI disk driver, for the Synchronize +Cache command only, treats any sense data with sense key ILLEGAL REQUEST +as a successful command (regardless of ASC / ASCQ). + +After commit cf3fc037623c ("ata: libata-scsi: Fix ata_to_sense_error() +status handling") the code that treats any sense data with sense key +ILLEGAL REQUEST as a successful command is no longer applicable, so the +command fails, which causes the system suspend to be aborted: + + sd 1:0:0:0: PM: dpm_run_callback(): scsi_bus_suspend returns -5 + sd 1:0:0:0: PM: failed to suspend async: error -5 + PM: Some devices failed to suspend, or early wake event detected + +To make suspend work once again, for a Security locked device only, +return sense data LOGICAL UNIT ACCESS NOT AUTHORIZED, the actual sense +data which a real SCSI device would have returned if locked. +The SCSI disk driver treats this sense data as a successful command. + +Cc: stable@vger.kernel.org +Reported-by: Ilia Baryshnikov +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220704 +Fixes: cf3fc037623c ("ata: libata-scsi: Fix ata_to_sense_error() status handling") +Reviewed-by: Hannes Reinecke +Reviewed-by: Martin K. Petersen +Reviewed-by: Damien Le Moal +Signed-off-by: Niklas Cassel +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ata/libata-scsi.c | 8 ++++++++ + include/linux/ata.h | 1 + + 2 files changed, 9 insertions(+) + +--- a/drivers/ata/libata-scsi.c ++++ b/drivers/ata/libata-scsi.c +@@ -961,6 +961,14 @@ static void ata_gen_ata_sense(struct ata + ata_scsi_set_sense(dev, cmd, NOT_READY, 0x04, 0x21); + return; + } ++ ++ if (ata_id_is_locked(dev->id)) { ++ /* Security locked */ ++ /* LOGICAL UNIT ACCESS NOT AUTHORIZED */ ++ ata_scsi_set_sense(dev, cmd, DATA_PROTECT, 0x74, 0x71); ++ return; ++ } ++ + /* Use ata_to_sense_error() to map status register bits + * onto sense key, asc & ascq. + */ +--- a/include/linux/ata.h ++++ b/include/linux/ata.h +@@ -557,6 +557,7 @@ struct ata_bmdma_prd { + #define ata_id_has_ncq(id) ((id)[ATA_ID_SATA_CAPABILITY] & (1 << 8)) + #define ata_id_queue_depth(id) (((id)[ATA_ID_QUEUE_DEPTH] & 0x1f) + 1) + #define ata_id_removable(id) ((id)[ATA_ID_CONFIG] & (1 << 7)) ++#define ata_id_is_locked(id) (((id)[ATA_ID_DLF] & 0x7) == 0x7) + #define ata_id_has_atapi_AN(id) \ + ((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \ + ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \ diff --git a/queue-5.10/dt-bindings-pinctrl-toshiba-visconti-fix-number-of-items-in-groups.patch b/queue-5.10/dt-bindings-pinctrl-toshiba-visconti-fix-number-of-items-in-groups.patch new file mode 100644 index 0000000000..0e65758446 --- /dev/null +++ b/queue-5.10/dt-bindings-pinctrl-toshiba-visconti-fix-number-of-items-in-groups.patch @@ -0,0 +1,67 @@ +From stable+bounces-196806-greg=kroah.com@vger.kernel.org Mon Nov 24 22:33:34 2025 +From: Sasha Levin +Date: Mon, 24 Nov 2025 16:33:27 -0500 +Subject: dt-bindings: pinctrl: toshiba,visconti: Fix number of items in groups +To: stable@vger.kernel.org +Cc: Krzysztof Kozlowski , Conor Dooley , Linus Walleij , Sasha Levin +Message-ID: <20251124213327.39691-1-sashal@kernel.org> + +From: Krzysztof Kozlowski + +[ Upstream commit 316e361b5d2cdeb8d778983794a1c6eadcb26814 ] + +The "groups" property can hold multiple entries (e.g. +toshiba/tmpv7708-rm-mbrc.dts file), so allow that by dropping incorrect +type (pinmux-node.yaml schema already defines that as string-array) and +adding constraints for items. This fixes dtbs_check warnings like: + + toshiba/tmpv7708-rm-mbrc.dtb: pinctrl@24190000 (toshiba,tmpv7708-pinctrl): + pwm-pins:groups: ['pwm0_gpio16_grp', 'pwm1_gpio17_grp', 'pwm2_gpio18_grp', 'pwm3_gpio19_grp'] is too long + +Fixes: 1825c1fe0057 ("pinctrl: Add DT bindings for Toshiba Visconti TMPV7700 SoC") +Cc: stable@vger.kernel.org +Signed-off-by: Krzysztof Kozlowski +Acked-by: Conor Dooley +Signed-off-by: Linus Walleij +[ adjusted $ref context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml | 26 +++++----- + 1 file changed, 14 insertions(+), 12 deletions(-) + +--- a/Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml ++++ b/Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml +@@ -46,18 +46,20 @@ patternProperties: + groups: + description: + Name of the pin group to use for the functions. +- $ref: "/schemas/types.yaml#/definitions/string" +- enum: [i2c0_grp, i2c1_grp, i2c2_grp, i2c3_grp, i2c4_grp, +- i2c5_grp, i2c6_grp, i2c7_grp, i2c8_grp, +- spi0_grp, spi0_cs0_grp, spi0_cs1_grp, spi0_cs2_grp, +- spi1_grp, spi2_grp, spi3_grp, spi4_grp, spi5_grp, spi6_grp, +- uart0_grp, uart1_grp, uart2_grp, uart3_grp, +- pwm0_gpio4_grp, pwm0_gpio8_grp, pwm0_gpio12_grp, +- pwm0_gpio16_grp, pwm1_gpio5_grp, pwm1_gpio9_grp, +- pwm1_gpio13_grp, pwm1_gpio17_grp, pwm2_gpio6_grp, +- pwm2_gpio10_grp, pwm2_gpio14_grp, pwm2_gpio18_grp, +- pwm3_gpio7_grp, pwm3_gpio11_grp, pwm3_gpio15_grp, +- pwm3_gpio19_grp, pcmif_out_grp, pcmif_in_grp] ++ items: ++ enum: [i2c0_grp, i2c1_grp, i2c2_grp, i2c3_grp, i2c4_grp, ++ i2c5_grp, i2c6_grp, i2c7_grp, i2c8_grp, ++ spi0_grp, spi0_cs0_grp, spi0_cs1_grp, spi0_cs2_grp, ++ spi1_grp, spi2_grp, spi3_grp, spi4_grp, spi5_grp, spi6_grp, ++ uart0_grp, uart1_grp, uart2_grp, uart3_grp, ++ pwm0_gpio4_grp, pwm0_gpio8_grp, pwm0_gpio12_grp, ++ pwm0_gpio16_grp, pwm1_gpio5_grp, pwm1_gpio9_grp, ++ pwm1_gpio13_grp, pwm1_gpio17_grp, pwm2_gpio6_grp, ++ pwm2_gpio10_grp, pwm2_gpio14_grp, pwm2_gpio18_grp, ++ pwm3_gpio7_grp, pwm3_gpio11_grp, pwm3_gpio15_grp, ++ pwm3_gpio19_grp, pcmif_out_grp, pcmif_in_grp] ++ minItems: 1 ++ maxItems: 8 + + drive-strength: + enum: [2, 4, 6, 8, 16, 24, 32] diff --git a/queue-5.10/input-pegasus-notetaker-fix-potential-out-of-bounds-access.patch b/queue-5.10/input-pegasus-notetaker-fix-potential-out-of-bounds-access.patch new file mode 100644 index 0000000000..efda64e026 --- /dev/null +++ b/queue-5.10/input-pegasus-notetaker-fix-potential-out-of-bounds-access.patch @@ -0,0 +1,58 @@ +From stable+bounces-196786-greg=kroah.com@vger.kernel.org Mon Nov 24 20:01:19 2025 +From: Sasha Levin +Date: Mon, 24 Nov 2025 13:57:18 -0500 +Subject: Input: pegasus-notetaker - fix potential out-of-bounds access +To: stable@vger.kernel.org +Cc: Seungjin Bae , Dmitry Torokhov , Sasha Levin +Message-ID: <20251124185718.4192041-3-sashal@kernel.org> + +From: Seungjin Bae + +[ Upstream commit 69aeb507312306f73495598a055293fa749d454e ] + +In the pegasus_notetaker driver, the pegasus_probe() function allocates +the URB transfer buffer using the wMaxPacketSize value from +the endpoint descriptor. An attacker can use a malicious USB descriptor +to force the allocation of a very small buffer. + +Subsequently, if the device sends an interrupt packet with a specific +pattern (e.g., where the first byte is 0x80 or 0x42), +the pegasus_parse_packet() function parses the packet without checking +the allocated buffer size. This leads to an out-of-bounds memory access. + +Fixes: 1afca2b66aac ("Input: add Pegasus Notetaker tablet driver") +Signed-off-by: Seungjin Bae +Link: https://lore.kernel.org/r/20251007214131.3737115-2-eeodqql09@gmail.com +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Torokhov +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/tablet/pegasus_notetaker.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/input/tablet/pegasus_notetaker.c ++++ b/drivers/input/tablet/pegasus_notetaker.c +@@ -63,6 +63,9 @@ + #define BUTTON_PRESSED 0xb5 + #define COMMAND_VERSION 0xa9 + ++/* 1 Status + 1 Color + 2 X + 2 Y = 6 bytes */ ++#define NOTETAKER_PACKET_SIZE 6 ++ + /* in xy data packet */ + #define BATTERY_NO_REPORT 0x40 + #define BATTERY_LOW 0x41 +@@ -297,6 +300,12 @@ static int pegasus_probe(struct usb_inte + + pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); + pegasus->data_len = usb_maxpacket(dev, pipe); ++ if (pegasus->data_len < NOTETAKER_PACKET_SIZE) { ++ dev_err(&intf->dev, "packet size is too small (%d)\n", ++ pegasus->data_len); ++ error = -EINVAL; ++ goto err_free_mem; ++ } + + pegasus->data = usb_alloc_coherent(dev, pegasus->data_len, GFP_KERNEL, + &pegasus->data_dma); diff --git a/queue-5.10/input-remove-third-argument-of-usb_maxpacket.patch b/queue-5.10/input-remove-third-argument-of-usb_maxpacket.patch new file mode 100644 index 0000000000..9b51198497 --- /dev/null +++ b/queue-5.10/input-remove-third-argument-of-usb_maxpacket.patch @@ -0,0 +1,106 @@ +From stable+bounces-196785-greg=kroah.com@vger.kernel.org Mon Nov 24 20:01:18 2025 +From: Sasha Levin +Date: Mon, 24 Nov 2025 13:57:17 -0500 +Subject: Input: remove third argument of usb_maxpacket() +To: stable@vger.kernel.org +Cc: Vincent Mailhol , Ville Syrjala , Dmitry Torokhov , Henk Vergonet , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251124185718.4192041-2-sashal@kernel.org> + +From: Vincent Mailhol + +[ Upstream commit 948bf187694fc1f4c20cf972fa18b1a6fb3d7603 ] + +The third argument of usb_maxpacket(): in_out has been deprecated +because it could be derived from the second argument (e.g. using +usb_pipeout(pipe)). + +N.B. function usb_maxpacket() was made variadic to accommodate the +transition from the old prototype with three arguments to the new one +with only two arguments (so that no renaming is needed). The variadic +argument is to be removed once all users of usb_maxpacket() get +migrated. + +CC: Ville Syrjala +CC: Dmitry Torokhov +CC: Henk Vergonet +Signed-off-by: Vincent Mailhol +Link: https://lore.kernel.org/r/20220317035514.6378-4-mailhol.vincent@wanadoo.fr +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 69aeb5073123 ("Input: pegasus-notetaker - fix potential out-of-bounds access") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/misc/ati_remote2.c | 2 +- + drivers/input/misc/cm109.c | 2 +- + drivers/input/misc/powermate.c | 2 +- + drivers/input/misc/yealink.c | 2 +- + drivers/input/tablet/acecad.c | 2 +- + drivers/input/tablet/pegasus_notetaker.c | 2 +- + 6 files changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/input/misc/ati_remote2.c ++++ b/drivers/input/misc/ati_remote2.c +@@ -639,7 +639,7 @@ static int ati_remote2_urb_init(struct a + return -ENOMEM; + + pipe = usb_rcvintpipe(udev, ar2->ep[i]->bEndpointAddress); +- maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); ++ maxp = usb_maxpacket(udev, pipe); + maxp = maxp > 4 ? 4 : maxp; + + usb_fill_int_urb(ar2->urb[i], udev, pipe, ar2->buf[i], maxp, +--- a/drivers/input/misc/cm109.c ++++ b/drivers/input/misc/cm109.c +@@ -745,7 +745,7 @@ static int cm109_usb_probe(struct usb_in + + /* get a handle to the interrupt data pipe */ + pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress); +- ret = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); ++ ret = usb_maxpacket(udev, pipe); + if (ret != USB_PKT_LEN) + dev_err(&intf->dev, "invalid payload size %d, expected %d\n", + ret, USB_PKT_LEN); +--- a/drivers/input/misc/powermate.c ++++ b/drivers/input/misc/powermate.c +@@ -374,7 +374,7 @@ static int powermate_probe(struct usb_in + + /* get a handle to the interrupt data pipe */ + pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress); +- maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); ++ maxp = usb_maxpacket(udev, pipe); + + if (maxp < POWERMATE_PAYLOAD_SIZE_MIN || maxp > POWERMATE_PAYLOAD_SIZE_MAX) { + printk(KERN_WARNING "powermate: Expected payload of %d--%d bytes, found %d bytes!\n", +--- a/drivers/input/misc/yealink.c ++++ b/drivers/input/misc/yealink.c +@@ -905,7 +905,7 @@ static int usb_probe(struct usb_interfac + + /* get a handle to the interrupt data pipe */ + pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress); +- ret = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); ++ ret = usb_maxpacket(udev, pipe); + if (ret != USB_PKT_LEN) + dev_err(&intf->dev, "invalid payload size %d, expected %zd\n", + ret, USB_PKT_LEN); +--- a/drivers/input/tablet/acecad.c ++++ b/drivers/input/tablet/acecad.c +@@ -130,7 +130,7 @@ static int usb_acecad_probe(struct usb_i + return -ENODEV; + + pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); +- maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); ++ maxp = usb_maxpacket(dev, pipe); + + acecad = kzalloc(sizeof(struct usb_acecad), GFP_KERNEL); + input_dev = input_allocate_device(); +--- a/drivers/input/tablet/pegasus_notetaker.c ++++ b/drivers/input/tablet/pegasus_notetaker.c +@@ -296,7 +296,7 @@ static int pegasus_probe(struct usb_inte + pegasus->intf = intf; + + pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); +- pegasus->data_len = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); ++ pegasus->data_len = usb_maxpacket(dev, pipe); + + pegasus->data = usb_alloc_coherent(dev, pegasus->data_len, GFP_KERNEL, + &pegasus->data_dma); diff --git a/queue-5.10/makefile.compiler-replace-cc-ifversion-with-compiler-specific-macros.patch b/queue-5.10/makefile.compiler-replace-cc-ifversion-with-compiler-specific-macros.patch new file mode 100644 index 0000000000..04bc92bc75 --- /dev/null +++ b/queue-5.10/makefile.compiler-replace-cc-ifversion-with-compiler-specific-macros.patch @@ -0,0 +1,214 @@ +From 88b61e3bff93f99712718db785b4aa0c1165f35c Mon Sep 17 00:00:00 2001 +From: Nick Desaulniers +Date: Mon, 19 Sep 2022 10:08:28 -0700 +Subject: Makefile.compiler: replace cc-ifversion with compiler-specific macros + +From: Nick Desaulniers + +commit 88b61e3bff93f99712718db785b4aa0c1165f35c upstream. + +cc-ifversion is GCC specific. Replace it with compiler specific +variants. Update the users of cc-ifversion to use these new macros. + +Link: https://github.com/ClangBuiltLinux/linux/issues/350 +Link: https://lore.kernel.org/llvm/CAGG=3QWSAUakO42kubrCap8fp-gm1ERJJAYXTnP1iHk_wrH=BQ@mail.gmail.com/ +Suggested-by: Bill Wendling +Reviewed-by: Nathan Chancellor +Signed-off-by: Nick Desaulniers +Signed-off-by: Masahiro Yamada +[nathan: Backport to 5.10 and eliminate instances of cc-ifversion that + did not exist upstream when this change was original created] +Signed-off-by: Nathan Chancellor +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/kbuild/makefiles.rst | 29 +++++++++++++++----------- + Makefile | 4 ++- + arch/mips/loongson64/Platform | 2 - + arch/powerpc/Makefile | 4 ++- + arch/s390/Makefile | 4 +-- + drivers/gpu/drm/amd/display/dc/calcs/Makefile | 2 - + drivers/gpu/drm/amd/display/dc/dcn20/Makefile | 2 - + drivers/gpu/drm/amd/display/dc/dcn21/Makefile | 2 - + drivers/gpu/drm/amd/display/dc/dcn30/Makefile | 2 - + drivers/gpu/drm/amd/display/dc/dml/Makefile | 2 - + drivers/gpu/drm/amd/display/dc/dsc/Makefile | 2 - + scripts/Kbuild.include | 10 ++++++-- + 12 files changed, 39 insertions(+), 26 deletions(-) + +--- a/Documentation/kbuild/makefiles.rst ++++ b/Documentation/kbuild/makefiles.rst +@@ -552,22 +552,27 @@ more details, with real examples. + In the above example, -Wno-unused-but-set-variable will be added to + KBUILD_CFLAGS only if gcc really accepts it. + +- cc-ifversion +- cc-ifversion tests the version of $(CC) and equals the fourth parameter +- if version expression is true, or the fifth (if given) if the version +- expression is false. ++ gcc-min-version ++ gcc-min-version tests if the value of $(CONFIG_GCC_VERSION) is greater than ++ or equal to the provided value and evaluates to y if so. + + Example:: + +- #fs/reiserfs/Makefile +- ccflags-y := $(call cc-ifversion, -lt, 0402, -O1) ++ cflags-$(call gcc-min-version, 70100) := -foo + +- In this example, ccflags-y will be assigned the value -O1 if the +- $(CC) version is less than 4.2. +- cc-ifversion takes all the shell operators: +- -eq, -ne, -lt, -le, -gt, and -ge +- The third parameter may be a text as in this example, but it may also +- be an expanded variable or a macro. ++ In this example, cflags-y will be assigned the value -foo if $(CC) is gcc and ++ $(CONFIG_GCC_VERSION) is >= 7.1. ++ ++ clang-min-version ++ clang-min-version tests if the value of $(CONFIG_CLANG_VERSION) is greater ++ than or equal to the provided value and evaluates to y if so. ++ ++ Example:: ++ ++ cflags-$(call clang-min-version, 110000) := -foo ++ ++ In this example, cflags-y will be assigned the value -foo if $(CC) is clang ++ and $(CONFIG_CLANG_VERSION) is >= 11.0.0. + + cc-cross-prefix + cc-cross-prefix is used to check if there exists a $(CC) in path with +--- a/Makefile ++++ b/Makefile +@@ -855,7 +855,9 @@ DEBUG_CFLAGS := + # Workaround for GCC versions < 5.0 + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61801 + ifdef CONFIG_CC_IS_GCC +-DEBUG_CFLAGS += $(call cc-ifversion, -lt, 0500, $(call cc-option, -fno-var-tracking-assignments)) ++ifneq ($(call gcc-min-version, 50000),y) ++DEBUG_CFLAGS += $(call cc-option, -fno-var-tracking-assignments) ++endif + endif + + ifdef CONFIG_DEBUG_INFO +--- a/arch/mips/loongson64/Platform ++++ b/arch/mips/loongson64/Platform +@@ -12,7 +12,7 @@ cflags-$(CONFIG_CPU_LOONGSON64) += -Wa,- + # by GAS. The cc-option can't probe for this behaviour so -march=loongson3a + # can't easily be used safely within the kbuild framework. + # +-ifeq ($(call cc-ifversion, -ge, 0409, y), y) ++ifeq ($(call gcc-min-version, 40900), y) + ifeq ($(call ld-ifversion, -ge, 225000000, y), y) + cflags-$(CONFIG_CPU_LOONGSON64) += \ + $(call cc-option,-march=loongson3a -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) +--- a/arch/powerpc/Makefile ++++ b/arch/powerpc/Makefile +@@ -168,7 +168,9 @@ endif + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=44199 + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52828 + ifndef CONFIG_CC_IS_CLANG +-CC_FLAGS_FTRACE += $(call cc-ifversion, -lt, 0409, -mno-sched-epilog) ++ifneq ($(call gcc-min-version, 40900),y) ++CC_FLAGS_FTRACE += -mno-sched-epilog ++endif + endif + endif + +--- a/arch/s390/Makefile ++++ b/arch/s390/Makefile +@@ -35,8 +35,8 @@ KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CON + KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO_DWARF4), $(call cc-option, -gdwarf-4,)) + + ifdef CONFIG_CC_IS_GCC +- ifeq ($(call cc-ifversion, -ge, 1200, y), y) +- ifeq ($(call cc-ifversion, -lt, 1300, y), y) ++ ifeq ($(call gcc-min-version, 120000), y) ++ ifneq ($(call gcc-min-version, 130000), y) + KBUILD_CFLAGS += $(call cc-disable-warning, array-bounds) + KBUILD_CFLAGS_DECOMPRESSOR += $(call cc-disable-warning, array-bounds) + endif +--- a/drivers/gpu/drm/amd/display/dc/calcs/Makefile ++++ b/drivers/gpu/drm/amd/display/dc/calcs/Makefile +@@ -34,7 +34,7 @@ calcs_ccflags := -mhard-float -maltivec + endif + + ifdef CONFIG_CC_IS_GCC +-ifeq ($(call cc-ifversion, -lt, 0701, y), y) ++ifneq ($(call gcc-min-version, 70100),y) + IS_OLD_GCC = 1 + endif + endif +--- a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile +@@ -18,7 +18,7 @@ CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_reso + endif + + ifdef CONFIG_CC_IS_GCC +-ifeq ($(call cc-ifversion, -lt, 0701, y), y) ++ifneq ($(call gcc-min-version, 70100),y) + IS_OLD_GCC = 1 + endif + endif +--- a/drivers/gpu/drm/amd/display/dc/dcn21/Makefile ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/Makefile +@@ -14,7 +14,7 @@ CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_reso + endif + + ifdef CONFIG_CC_IS_GCC +-ifeq ($(call cc-ifversion, -lt, 0701, y), y) ++ifneq ($(call gcc-min-version, 70100),y) + IS_OLD_GCC = 1 + endif + endif +--- a/drivers/gpu/drm/amd/display/dc/dcn30/Makefile ++++ b/drivers/gpu/drm/amd/display/dc/dcn30/Makefile +@@ -47,7 +47,7 @@ CFLAGS_REMOVE_$(AMDDALPATH)/dc/dcn30/dcn + endif + + ifdef CONFIG_CC_IS_GCC +-ifeq ($(call cc-ifversion, -lt, 0701, y), y) ++ifneq ($(call gcc-min-version, 70100),y) + IS_OLD_GCC = 1 + endif + endif +--- a/drivers/gpu/drm/amd/display/dc/dml/Makefile ++++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile +@@ -35,7 +35,7 @@ dml_ccflags := -mhard-float -maltivec + endif + + ifdef CONFIG_CC_IS_GCC +-ifeq ($(call cc-ifversion, -lt, 0701, y), y) ++ifneq ($(call gcc-min-version, 70100),y) + IS_OLD_GCC = 1 + endif + endif +--- a/drivers/gpu/drm/amd/display/dc/dsc/Makefile ++++ b/drivers/gpu/drm/amd/display/dc/dsc/Makefile +@@ -11,7 +11,7 @@ dsc_ccflags := -mhard-float -maltivec + endif + + ifdef CONFIG_CC_IS_GCC +-ifeq ($(call cc-ifversion, -lt, 0701, y), y) ++ifneq ($(call gcc-min-version, 70100),y) + IS_OLD_GCC = 1 + endif + endif +--- a/scripts/Kbuild.include ++++ b/scripts/Kbuild.include +@@ -133,9 +133,13 @@ cc-option-yn = $(call try-run,\ + cc-disable-warning = $(call try-run,\ + $(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1))) + +-# cc-ifversion +-# Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) +-cc-ifversion = $(shell [ $(CONFIG_GCC_VERSION)0 $(1) $(2)000 ] && echo $(3) || echo $(4)) ++# gcc-min-version ++# Usage: cflags-$(call gcc-min-version, 70100) += -foo ++gcc-min-version = $(shell [ $(CONFIG_GCC_VERSION)0 -ge $(1)0 ] && echo y) ++ ++# clang-min-version ++# Usage: cflags-$(call clang-min-version, 110000) += -foo ++clang-min-version = $(shell [ $(CONFIG_CLANG_VERSION)0 -ge $(1)0 ] && echo y) + + # ld-option + # Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y) diff --git a/queue-5.10/mm-mempool-fix-poisoning-order-0-pages-with-highmem.patch b/queue-5.10/mm-mempool-fix-poisoning-order-0-pages-with-highmem.patch new file mode 100644 index 0000000000..7e1645b869 --- /dev/null +++ b/queue-5.10/mm-mempool-fix-poisoning-order-0-pages-with-highmem.patch @@ -0,0 +1,110 @@ +From stable+bounces-196810-greg=kroah.com@vger.kernel.org Mon Nov 24 22:38:44 2025 +From: Sasha Levin +Date: Mon, 24 Nov 2025 16:38:34 -0500 +Subject: mm/mempool: fix poisoning order>0 pages with HIGHMEM +To: stable@vger.kernel.org +Cc: Vlastimil Babka , kernel test robot , Christoph Hellwig , Sasha Levin +Message-ID: <20251124213835.42484-2-sashal@kernel.org> + +From: Vlastimil Babka + +[ Upstream commit ec33b59542d96830e3c89845ff833cf7b25ef172 ] + +The kernel test has reported: + + BUG: unable to handle page fault for address: fffba000 + #PF: supervisor write access in kernel mode + #PF: error_code(0x0002) - not-present page + *pde = 03171067 *pte = 00000000 + Oops: Oops: 0002 [#1] + CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Tainted: G T 6.18.0-rc2-00031-gec7f31b2a2d3 #1 NONE a1d066dfe789f54bc7645c7989957d2bdee593ca + Tainted: [T]=RANDSTRUCT + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 + EIP: memset (arch/x86/include/asm/string_32.h:168 arch/x86/lib/memcpy_32.c:17) + Code: a5 8b 4d f4 83 e1 03 74 02 f3 a4 83 c4 04 5e 5f 5d 2e e9 73 41 01 00 90 90 90 3e 8d 74 26 00 55 89 e5 57 56 89 c6 89 d0 89 f7 aa 89 f0 5e 5f 5d 2e e9 53 41 01 00 cc cc cc 55 89 e5 53 57 56 + EAX: 0000006b EBX: 00000015 ECX: 001fefff EDX: 0000006b + ESI: fffb9000 EDI: fffba000 EBP: c611fbf0 ESP: c611fbe8 + DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068 EFLAGS: 00010287 + CR0: 80050033 CR2: fffba000 CR3: 0316e000 CR4: 00040690 + Call Trace: + poison_element (mm/mempool.c:83 mm/mempool.c:102) + mempool_init_node (mm/mempool.c:142 mm/mempool.c:226) + mempool_init_noprof (mm/mempool.c:250 (discriminator 1)) + ? mempool_alloc_pages (mm/mempool.c:640) + bio_integrity_initfn (block/bio-integrity.c:483 (discriminator 8)) + ? mempool_alloc_pages (mm/mempool.c:640) + do_one_initcall (init/main.c:1283) + +Christoph found out this is due to the poisoning code not dealing +properly with CONFIG_HIGHMEM because only the first page is mapped but +then the whole potentially high-order page is accessed. + +We could give up on HIGHMEM here, but it's straightforward to fix this +with a loop that's mapping, poisoning or checking and unmapping +individual pages. + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-lkp/202511111411.9ebfa1ba-lkp@intel.com +Analyzed-by: Christoph Hellwig +Fixes: bdfedb76f4f5 ("mm, mempool: poison elements backed by slab allocator") +Cc: stable@vger.kernel.org +Tested-by: kernel test robot +Reviewed-by: Christoph Hellwig +Link: https://patch.msgid.link/20251113-mempool-poison-v1-1-233b3ef984c3@suse.cz +Signed-off-by: Vlastimil Babka +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + mm/mempool.c | 32 ++++++++++++++++++++++++++------ + 1 file changed, 26 insertions(+), 6 deletions(-) + +--- a/mm/mempool.c ++++ b/mm/mempool.c +@@ -63,10 +63,20 @@ static void check_element(mempool_t *poo + } else if (pool->free == mempool_free_pages) { + /* Mempools backed by page allocator */ + int order = (int)(long)pool->pool_data; +- void *addr = kmap_local_page((struct page *)element); + +- __check_element(pool, addr, 1UL << (PAGE_SHIFT + order)); +- kunmap_local(addr); ++#ifdef CONFIG_HIGHMEM ++ for (int i = 0; i < (1 << order); i++) { ++ struct page *page = (struct page *)element; ++ void *addr = kmap_local_page(page + i); ++ ++ __check_element(pool, addr, PAGE_SIZE); ++ kunmap_local(addr); ++ } ++#else ++ void *addr = page_address((struct page *)element); ++ ++ __check_element(pool, addr, PAGE_SIZE << order); ++#endif + } + } + +@@ -86,10 +96,20 @@ static void poison_element(mempool_t *po + } else if (pool->alloc == mempool_alloc_pages) { + /* Mempools backed by page allocator */ + int order = (int)(long)pool->pool_data; +- void *addr = kmap_local_page((struct page *)element); + +- __poison_element(addr, 1UL << (PAGE_SHIFT + order)); +- kunmap_local(addr); ++#ifdef CONFIG_HIGHMEM ++ for (int i = 0; i < (1 << order); i++) { ++ struct page *page = (struct page *)element; ++ void *addr = kmap_local_page(page + i); ++ ++ __poison_element(addr, PAGE_SIZE); ++ kunmap_local(addr); ++ } ++#else ++ void *addr = page_address((struct page *)element); ++ ++ __poison_element(addr, PAGE_SIZE << order); ++#endif + } + } + #else /* CONFIG_DEBUG_SLAB || CONFIG_SLUB_DEBUG_ON */ diff --git a/queue-5.10/mm-mempool-replace-kmap_atomic-with-kmap_local_page.patch b/queue-5.10/mm-mempool-replace-kmap_atomic-with-kmap_local_page.patch new file mode 100644 index 0000000000..10a9b64ddb --- /dev/null +++ b/queue-5.10/mm-mempool-replace-kmap_atomic-with-kmap_local_page.patch @@ -0,0 +1,71 @@ +From stable+bounces-196809-greg=kroah.com@vger.kernel.org Mon Nov 24 22:38:42 2025 +From: Sasha Levin +Date: Mon, 24 Nov 2025 16:38:33 -0500 +Subject: mm/mempool: replace kmap_atomic() with kmap_local_page() +To: stable@vger.kernel.org +Cc: "Fabio M. De Francesco" , Ira Weiny , Andrew Morton , Sasha Levin +Message-ID: <20251124213835.42484-1-sashal@kernel.org> + +From: "Fabio M. De Francesco" + +[ Upstream commit f2bcc99a5e901a13b754648d1dbab60f4adf9375 ] + +kmap_atomic() has been deprecated in favor of kmap_local_page(). + +Therefore, replace kmap_atomic() with kmap_local_page(). + +kmap_atomic() is implemented like a kmap_local_page() which also disables +page-faults and preemption (the latter only in !PREEMPT_RT kernels). The +kernel virtual addresses returned by these two API are only valid in the +context of the callers (i.e., they cannot be handed to other threads). + +With kmap_local_page() the mappings are per thread and CPU local like in +kmap_atomic(); however, they can handle page-faults and can be called from +any context (including interrupts). The tasks that call kmap_local_page() +can be preempted and, when they are scheduled to run again, the kernel +virtual addresses are restored and are still valid. + +The code blocks between the mappings and un-mappings don't rely on the +above-mentioned side effects of kmap_atomic(), so that mere replacements +of the old API with the new one is all that they require (i.e., there is +no need to explicitly call pagefault_disable() and/or preempt_disable()). + +Link: https://lkml.kernel.org/r/20231120142640.7077-1-fabio.maria.de.francesco@linux.intel.com +Signed-off-by: Fabio M. De Francesco +Cc: Ira Weiny +Signed-off-by: Andrew Morton +Stable-dep-of: ec33b59542d9 ("mm/mempool: fix poisoning order>0 pages with HIGHMEM") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + mm/mempool.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/mm/mempool.c ++++ b/mm/mempool.c +@@ -63,10 +63,10 @@ static void check_element(mempool_t *poo + } else if (pool->free == mempool_free_pages) { + /* Mempools backed by page allocator */ + int order = (int)(long)pool->pool_data; +- void *addr = kmap_atomic((struct page *)element); ++ void *addr = kmap_local_page((struct page *)element); + + __check_element(pool, addr, 1UL << (PAGE_SHIFT + order)); +- kunmap_atomic(addr); ++ kunmap_local(addr); + } + } + +@@ -86,10 +86,10 @@ static void poison_element(mempool_t *po + } else if (pool->alloc == mempool_alloc_pages) { + /* Mempools backed by page allocator */ + int order = (int)(long)pool->pool_data; +- void *addr = kmap_atomic((struct page *)element); ++ void *addr = kmap_local_page((struct page *)element); + + __poison_element(addr, 1UL << (PAGE_SHIFT + order)); +- kunmap_atomic(addr); ++ kunmap_local(addr); + } + } + #else /* CONFIG_DEBUG_SLAB || CONFIG_SLUB_DEBUG_ON */ diff --git a/queue-5.10/mm-mprotect-delete-pmd_none_or_clear_bad_unless_trans_huge.patch b/queue-5.10/mm-mprotect-delete-pmd_none_or_clear_bad_unless_trans_huge.patch new file mode 100644 index 0000000000..e5b759f794 --- /dev/null +++ b/queue-5.10/mm-mprotect-delete-pmd_none_or_clear_bad_unless_trans_huge.patch @@ -0,0 +1,242 @@ +From stable+bounces-196858-greg=kroah.com@vger.kernel.org Tue Nov 25 05:56:26 2025 +From: Harry Yoo +Date: Tue, 25 Nov 2025 13:54:42 +0900 +Subject: mm/mprotect: delete pmd_none_or_clear_bad_unless_trans_huge() +To: stable@vger.kernel.org +Cc: Liam.Howlett@oracle.com, akpm@linux-foundation.org, baohua@kernel.org, baolin.wang@linux.alibaba.com, david@kernel.org, dev.jain@arm.com, hughd@google.com, jane.chu@oracle.com, jannh@google.com, kas@kernel.org, lance.yang@linux.dev, linux-mm@kvack.org, lorenzo.stoakes@oracle.com, npache@redhat.com, pfalcato@suse.de, ryan.roberts@arm.com, vbabka@suse.cz, ziy@nvidia.com, "Alistair Popple" , "Anshuman Khandual" , "Axel Rasmussen" , "Christophe Leroy" , "Christoph Hellwig" , "David Hildenbrand" , "Huang, Ying" , "Ira Weiny" , "Jason Gunthorpe" , "Kirill A . Shutemov" , "Lorenzo Stoakes" , "Matthew Wilcox" , "Mel Gorman" , "Miaohe Lin" , "Mike Kravetz" , "Mike Rapoport" , "Minchan Kim" , "Naoya Horiguchi" , "Pavel Tatashin" , "Peter Xu" , "Peter Zijlstra" , "Qi Zheng" , "Ralph Campbell" , "SeongJae Park" , "Song Liu" , "Steven Price" , "Suren Baghdasaryan" , "Thomas Hellström" , "Will Deacon" , "Yang Shi" , "Yu Zhao" , "Zack Rusin" +Message-ID: <20251125045442.1084815-3-harry.yoo@oracle.com> + +From: Hugh Dickins + +commit 670ddd8cdcbd1d07a4571266ae3517f821728c3a upstream. + +change_pmd_range() had special pmd_none_or_clear_bad_unless_trans_huge(), +required to avoid "bad" choices when setting automatic NUMA hinting under +mmap_read_lock(); but most of that is already covered in pte_offset_map() +now. change_pmd_range() just wants a pmd_none() check before wasting time +on MMU notifiers, then checks on the read-once _pmd value to work out +what's needed for huge cases. If change_pte_range() returns -EAGAIN to +retry if pte_offset_map_lock() fails, nothing more special is needed. + +Link: https://lkml.kernel.org/r/725a42a9-91e9-c868-925-e3a5fd40bb4f@google.com +Signed-off-by: Hugh Dickins +Cc: Alistair Popple +Cc: Anshuman Khandual +Cc: Axel Rasmussen +Cc: Christophe Leroy +Cc: Christoph Hellwig +Cc: David Hildenbrand +Cc: "Huang, Ying" +Cc: Ira Weiny +Cc: Jason Gunthorpe +Cc: Kirill A. Shutemov +Cc: Lorenzo Stoakes +Cc: Matthew Wilcox +Cc: Mel Gorman +Cc: Miaohe Lin +Cc: Mike Kravetz +Cc: Mike Rapoport (IBM) +Cc: Minchan Kim +Cc: Naoya Horiguchi +Cc: Pavel Tatashin +Cc: Peter Xu +Cc: Peter Zijlstra +Cc: Qi Zheng +Cc: Ralph Campbell +Cc: Ryan Roberts +Cc: SeongJae Park +Cc: Song Liu +Cc: Steven Price +Cc: Suren Baghdasaryan +Cc: Thomas Hellström +Cc: Will Deacon +Cc: Yang Shi +Cc: Yu Zhao +Cc: Zack Rusin +Signed-off-by: Andrew Morton +[ Background: It was reported that a bad pmd is seen when automatic NUMA + balancing is marking page table entries as prot_numa: + + [2437548.196018] mm/pgtable-generic.c:50: bad pmd 00000000af22fc02(dffffffe71fbfe02) + [2437548.235022] Call Trace: + [2437548.238234] + [2437548.241060] dump_stack_lvl+0x46/0x61 + [2437548.245689] panic+0x106/0x2e5 + [2437548.249497] pmd_clear_bad+0x3c/0x3c + [2437548.253967] change_pmd_range.isra.0+0x34d/0x3a7 + [2437548.259537] change_p4d_range+0x156/0x20e + [2437548.264392] change_protection_range+0x116/0x1a9 + [2437548.269976] change_prot_numa+0x15/0x37 + [2437548.274774] task_numa_work+0x1b8/0x302 + [2437548.279512] task_work_run+0x62/0x95 + [2437548.283882] exit_to_user_mode_loop+0x1a4/0x1a9 + [2437548.289277] exit_to_user_mode_prepare+0xf4/0xfc + [2437548.294751] ? sysvec_apic_timer_interrupt+0x34/0x81 + [2437548.300677] irqentry_exit_to_user_mode+0x5/0x25 + [2437548.306153] asm_sysvec_apic_timer_interrupt+0x16/0x1b + + This is due to a race condition between change_prot_numa() and + THP migration because the kernel doesn't check is_swap_pmd() and + pmd_trans_huge() atomically: + + change_prot_numa() THP migration + ====================================================================== + - change_pmd_range() + -> is_swap_pmd() returns false, + meaning it's not a PMD migration + entry. + - do_huge_pmd_numa_page() + -> migrate_misplaced_page() sets + migration entries for the THP. + - change_pmd_range() + -> pmd_none_or_clear_bad_unless_trans_huge() + -> pmd_none() and pmd_trans_huge() returns false + - pmd_none_or_clear_bad_unless_trans_huge() + -> pmd_bad() returns true for the migration entry! + + The upstream commit 670ddd8cdcbd ("mm/mprotect: delete + pmd_none_or_clear_bad_unless_trans_huge()") closes this race condition + by checking is_swap_pmd() and pmd_trans_huge() atomically. + + Backporting note: + Unlike the mainline, pte_offset_map_lock() does not check if the pmd + entry is a migration entry or a hugepage; acquires PTL unconditionally + instead of returning failure. Therefore, it is necessary to keep the + !is_swap_pmd() && !pmd_trans_huge() && !pmd_devmap() check before + acquiring the PTL. + + After acquiring the lock, open-code the semantics of + pte_offset_map_lock() in the mainline kernel; change_pte_range() fails + if the pmd value has changed. This requires adding one more parameter + (to pass pmd value that is read before calling the function) to + change_pte_range(). ] +Signed-off-by: Greg Kroah-Hartman +--- + mm/mprotect.c | 75 ++++++++++++++++++++++++++++++++-------------------------- + 1 file changed, 42 insertions(+), 33 deletions(-) + +--- a/mm/mprotect.c ++++ b/mm/mprotect.c +@@ -36,10 +36,11 @@ + #include "internal.h" + + static long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd, +- unsigned long addr, unsigned long end, pgprot_t newprot, +- unsigned long cp_flags) ++ pmd_t pmd_old, unsigned long addr, unsigned long end, ++ pgprot_t newprot, unsigned long cp_flags) + { + pte_t *pte, oldpte; ++ pmd_t pmd_val; + spinlock_t *ptl; + long pages = 0; + int target_node = NUMA_NO_NODE; +@@ -48,21 +49,15 @@ static long change_pte_range(struct vm_a + bool uffd_wp = cp_flags & MM_CP_UFFD_WP; + bool uffd_wp_resolve = cp_flags & MM_CP_UFFD_WP_RESOLVE; + +- /* +- * Can be called with only the mmap_lock for reading by +- * prot_numa so we must check the pmd isn't constantly +- * changing from under us from pmd_none to pmd_trans_huge +- * and/or the other way around. +- */ +- if (pmd_trans_unstable(pmd)) +- return 0; +- +- /* +- * The pmd points to a regular pte so the pmd can't change +- * from under us even if the mmap_lock is only hold for +- * reading. +- */ + pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); ++ /* Make sure pmd didn't change after acquiring ptl */ ++ pmd_val = pmd_read_atomic(pmd); ++ /* See pmd_none_or_trans_huge_or_clear_bad for info on barrier */ ++ barrier(); ++ if (!pmd_same(pmd_old, pmd_val)) { ++ pte_unmap_unlock(pte, ptl); ++ return -EAGAIN; ++ } + + /* Get target node for single threaded private VMAs */ + if (prot_numa && !(vma->vm_flags & VM_SHARED) && +@@ -223,21 +218,33 @@ static inline long change_pmd_range(stru + + pmd = pmd_offset(pud, addr); + do { +- long this_pages; +- ++ long ret; ++ pmd_t _pmd; ++again: + next = pmd_addr_end(addr, end); ++ _pmd = pmd_read_atomic(pmd); ++ /* See pmd_none_or_trans_huge_or_clear_bad for info on barrier */ ++#ifdef CONFIG_TRANSPARENT_HUGEPAGE ++ barrier(); ++#endif + + /* + * Automatic NUMA balancing walks the tables with mmap_lock + * held for read. It's possible a parallel update to occur +- * between pmd_trans_huge() and a pmd_none_or_clear_bad() +- * check leading to a false positive and clearing. +- * Hence, it's necessary to atomically read the PMD value +- * for all the checks. ++ * between pmd_trans_huge(), is_swap_pmd(), and ++ * a pmd_none_or_clear_bad() check leading to a false positive ++ * and clearing. Hence, it's necessary to atomically read ++ * the PMD value for all the checks. + */ +- if (!is_swap_pmd(*pmd) && !pmd_devmap(*pmd) && +- pmd_none_or_clear_bad_unless_trans_huge(pmd)) +- goto next; ++ if (!is_swap_pmd(_pmd) && !pmd_devmap(_pmd) && !pmd_trans_huge(_pmd)) { ++ if (pmd_none(_pmd)) ++ goto next; ++ ++ if (pmd_bad(_pmd)) { ++ pmd_clear_bad(pmd); ++ goto next; ++ } ++ } + + /* invoke the mmu notifier if the pmd is populated */ + if (!range.start) { +@@ -247,15 +254,15 @@ static inline long change_pmd_range(stru + mmu_notifier_invalidate_range_start(&range); + } + +- if (is_swap_pmd(*pmd) || pmd_trans_huge(*pmd) || pmd_devmap(*pmd)) { ++ if (is_swap_pmd(_pmd) || pmd_trans_huge(_pmd) || pmd_devmap(_pmd)) { + if (next - addr != HPAGE_PMD_SIZE) { + __split_huge_pmd(vma, pmd, addr, false, NULL); + } else { +- int nr_ptes = change_huge_pmd(vma, pmd, addr, +- newprot, cp_flags); ++ ret = change_huge_pmd(vma, pmd, addr, newprot, ++ cp_flags); + +- if (nr_ptes) { +- if (nr_ptes == HPAGE_PMD_NR) { ++ if (ret) { ++ if (ret == HPAGE_PMD_NR) { + pages += HPAGE_PMD_NR; + nr_huge_updates++; + } +@@ -266,9 +273,11 @@ static inline long change_pmd_range(stru + } + /* fall through, the trans huge pmd just split */ + } +- this_pages = change_pte_range(vma, pmd, addr, next, newprot, +- cp_flags); +- pages += this_pages; ++ ret = change_pte_range(vma, pmd, _pmd, addr, next, newprot, ++ cp_flags); ++ if (ret < 0) ++ goto again; ++ pages += ret; + next: + cond_resched(); + } while (pmd++, addr = next, addr != end); diff --git a/queue-5.10/mm-mprotect-use-long-for-page-accountings-and-retval.patch b/queue-5.10/mm-mprotect-use-long-for-page-accountings-and-retval.patch new file mode 100644 index 0000000000..22cfe2b873 --- /dev/null +++ b/queue-5.10/mm-mprotect-use-long-for-page-accountings-and-retval.patch @@ -0,0 +1,226 @@ +From stable+bounces-196859-greg=kroah.com@vger.kernel.org Tue Nov 25 05:56:33 2025 +From: Harry Yoo +Date: Tue, 25 Nov 2025 13:54:41 +0900 +Subject: mm/mprotect: use long for page accountings and retval +To: stable@vger.kernel.org +Cc: Liam.Howlett@oracle.com, akpm@linux-foundation.org, baohua@kernel.org, baolin.wang@linux.alibaba.com, david@kernel.org, dev.jain@arm.com, hughd@google.com, jane.chu@oracle.com, jannh@google.com, kas@kernel.org, lance.yang@linux.dev, linux-mm@kvack.org, lorenzo.stoakes@oracle.com, npache@redhat.com, pfalcato@suse.de, ryan.roberts@arm.com, vbabka@suse.cz, ziy@nvidia.com, Peter Xu , Mike Kravetz , James Houghton , Andrea Arcangeli , Axel Rasmussen , David Hildenbrand , Muchun Song , Nadav Amit , Harry Yoo +Message-ID: <20251125045442.1084815-2-harry.yoo@oracle.com> + +From: Peter Xu + +commit a79390f5d6a78647fd70856bd42b22d994de0ba2 upstream. + +Switch to use type "long" for page accountings and retval across the whole +procedure of change_protection(). + +The change should have shrinked the possible maximum page number to be +half comparing to previous (ULONG_MAX / 2), but it shouldn't overflow on +any system either because the maximum possible pages touched by change +protection should be ULONG_MAX / PAGE_SIZE. + +Two reasons to switch from "unsigned long" to "long": + + 1. It suites better on count_vm_numa_events(), whose 2nd parameter takes + a long type. + + 2. It paves way for returning negative (error) values in the future. + +Currently the only caller that consumes this retval is change_prot_numa(), +where the unsigned long was converted to an int. Since at it, touching up +the numa code to also take a long, so it'll avoid any possible overflow +too during the int-size convertion. + +Link: https://lkml.kernel.org/r/20230104225207.1066932-3-peterx@redhat.com +Signed-off-by: Peter Xu +Acked-by: Mike Kravetz +Acked-by: James Houghton +Cc: Andrea Arcangeli +Cc: Axel Rasmussen +Cc: David Hildenbrand +Cc: Muchun Song +Cc: Nadav Amit +Signed-off-by: Andrew Morton +[ Adjust context ] +Signed-off-by: Harry Yoo +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/hugetlb.h | 4 ++-- + include/linux/mm.h | 2 +- + mm/hugetlb.c | 4 ++-- + mm/mempolicy.c | 2 +- + mm/mprotect.c | 34 +++++++++++++++++----------------- + 5 files changed, 23 insertions(+), 23 deletions(-) + +--- a/include/linux/hugetlb.h ++++ b/include/linux/hugetlb.h +@@ -184,7 +184,7 @@ struct page *follow_huge_pgd(struct mm_s + + int pmd_huge(pmd_t pmd); + int pud_huge(pud_t pud); +-unsigned long hugetlb_change_protection(struct vm_area_struct *vma, ++long hugetlb_change_protection(struct vm_area_struct *vma, + unsigned long address, unsigned long end, pgprot_t newprot); + + bool is_hugetlb_entry_migration(pte_t pte); +@@ -342,7 +342,7 @@ static inline void move_hugetlb_state(st + { + } + +-static inline unsigned long hugetlb_change_protection( ++static inline long hugetlb_change_protection( + struct vm_area_struct *vma, unsigned long address, + unsigned long end, pgprot_t newprot) + { +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -1876,7 +1876,7 @@ extern unsigned long move_page_tables(st + #define MM_CP_UFFD_WP_ALL (MM_CP_UFFD_WP | \ + MM_CP_UFFD_WP_RESOLVE) + +-extern unsigned long change_protection(struct vm_area_struct *vma, unsigned long start, ++extern long change_protection(struct vm_area_struct *vma, unsigned long start, + unsigned long end, pgprot_t newprot, + unsigned long cp_flags); + extern int mprotect_fixup(struct vm_area_struct *vma, +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -5051,7 +5051,7 @@ same_page: + #define flush_hugetlb_tlb_range(vma, addr, end) flush_tlb_range(vma, addr, end) + #endif + +-unsigned long hugetlb_change_protection(struct vm_area_struct *vma, ++long hugetlb_change_protection(struct vm_area_struct *vma, + unsigned long address, unsigned long end, pgprot_t newprot) + { + struct mm_struct *mm = vma->vm_mm; +@@ -5059,7 +5059,7 @@ unsigned long hugetlb_change_protection( + pte_t *ptep; + pte_t pte; + struct hstate *h = hstate_vma(vma); +- unsigned long pages = 0; ++ long pages = 0; + bool shared_pmd = false; + struct mmu_notifier_range range; + +--- a/mm/mempolicy.c ++++ b/mm/mempolicy.c +@@ -653,7 +653,7 @@ unlock: + unsigned long change_prot_numa(struct vm_area_struct *vma, + unsigned long addr, unsigned long end) + { +- int nr_updated; ++ long nr_updated; + + nr_updated = change_protection(vma, addr, end, PAGE_NONE, MM_CP_PROT_NUMA); + if (nr_updated) +--- a/mm/mprotect.c ++++ b/mm/mprotect.c +@@ -35,13 +35,13 @@ + + #include "internal.h" + +-static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd, ++static long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd, + unsigned long addr, unsigned long end, pgprot_t newprot, + unsigned long cp_flags) + { + pte_t *pte, oldpte; + spinlock_t *ptl; +- unsigned long pages = 0; ++ long pages = 0; + int target_node = NUMA_NO_NODE; + bool dirty_accountable = cp_flags & MM_CP_DIRTY_ACCT; + bool prot_numa = cp_flags & MM_CP_PROT_NUMA; +@@ -209,13 +209,13 @@ static inline int pmd_none_or_clear_bad_ + return 0; + } + +-static inline unsigned long change_pmd_range(struct vm_area_struct *vma, ++static inline long change_pmd_range(struct vm_area_struct *vma, + pud_t *pud, unsigned long addr, unsigned long end, + pgprot_t newprot, unsigned long cp_flags) + { + pmd_t *pmd; + unsigned long next; +- unsigned long pages = 0; ++ long pages = 0; + unsigned long nr_huge_updates = 0; + struct mmu_notifier_range range; + +@@ -223,7 +223,7 @@ static inline unsigned long change_pmd_r + + pmd = pmd_offset(pud, addr); + do { +- unsigned long this_pages; ++ long this_pages; + + next = pmd_addr_end(addr, end); + +@@ -281,13 +281,13 @@ next: + return pages; + } + +-static inline unsigned long change_pud_range(struct vm_area_struct *vma, +- p4d_t *p4d, unsigned long addr, unsigned long end, +- pgprot_t newprot, unsigned long cp_flags) ++static inline long change_pud_range(struct vm_area_struct *vma, p4d_t *p4d, ++ unsigned long addr, unsigned long end, pgprot_t newprot, ++ unsigned long cp_flags) + { + pud_t *pud; + unsigned long next; +- unsigned long pages = 0; ++ long pages = 0; + + pud = pud_offset(p4d, addr); + do { +@@ -301,13 +301,13 @@ static inline unsigned long change_pud_r + return pages; + } + +-static inline unsigned long change_p4d_range(struct vm_area_struct *vma, +- pgd_t *pgd, unsigned long addr, unsigned long end, +- pgprot_t newprot, unsigned long cp_flags) ++static inline long change_p4d_range(struct vm_area_struct *vma, pgd_t *pgd, ++ unsigned long addr, unsigned long end, pgprot_t newprot, ++ unsigned long cp_flags) + { + p4d_t *p4d; + unsigned long next; +- unsigned long pages = 0; ++ long pages = 0; + + p4d = p4d_offset(pgd, addr); + do { +@@ -321,7 +321,7 @@ static inline unsigned long change_p4d_r + return pages; + } + +-static unsigned long change_protection_range(struct vm_area_struct *vma, ++static long change_protection_range(struct vm_area_struct *vma, + unsigned long addr, unsigned long end, pgprot_t newprot, + unsigned long cp_flags) + { +@@ -329,7 +329,7 @@ static unsigned long change_protection_r + pgd_t *pgd; + unsigned long next; + unsigned long start = addr; +- unsigned long pages = 0; ++ long pages = 0; + + BUG_ON(addr >= end); + pgd = pgd_offset(mm, addr); +@@ -351,11 +351,11 @@ static unsigned long change_protection_r + return pages; + } + +-unsigned long change_protection(struct vm_area_struct *vma, unsigned long start, ++long change_protection(struct vm_area_struct *vma, unsigned long start, + unsigned long end, pgprot_t newprot, + unsigned long cp_flags) + { +- unsigned long pages; ++ long pages; + + BUG_ON((cp_flags & MM_CP_UFFD_WP_ALL) == MM_CP_UFFD_WP_ALL); + diff --git a/queue-5.10/mptcp-do-not-fallback-when-ooo-is-present.patch b/queue-5.10/mptcp-do-not-fallback-when-ooo-is-present.patch new file mode 100644 index 0000000000..dc61bccbaa --- /dev/null +++ b/queue-5.10/mptcp-do-not-fallback-when-ooo-is-present.patch @@ -0,0 +1,50 @@ +From stable+bounces-196847-greg=kroah.com@vger.kernel.org Tue Nov 25 04:27:16 2025 +From: Sasha Levin +Date: Mon, 24 Nov 2025 22:27:07 -0500 +Subject: mptcp: do not fallback when OoO is present +To: stable@vger.kernel.org +Cc: Paolo Abeni , "Matthieu Baerts (NGI0)" , Jakub Kicinski , Sasha Levin +Message-ID: <20251125032707.340833-1-sashal@kernel.org> + +From: Paolo Abeni + +[ Upstream commit 1bba3f219c5e8c29e63afa3c1fc24f875ebec119 ] + +In case of DSS corruption, the MPTCP protocol tries to avoid the subflow +reset if fallback is possible. Such corruptions happen in the receive +path; to ensure fallback is possible the stack additionally needs to +check for OoO data, otherwise the fallback will break the data stream. + +Fixes: e32d262c89e2 ("mptcp: handle consistently DSS corruption") +Cc: stable@vger.kernel.org +Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/598 +Signed-off-by: Paolo Abeni +Reviewed-by: Matthieu Baerts (NGI0) +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20251118-net-mptcp-misc-fixes-6-18-rc6-v1-4-806d3781c95f@kernel.org +Signed-off-by: Jakub Kicinski +[ patch mptcp_dss_corruption() ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + net/mptcp/protocol.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -478,6 +478,15 @@ static void mptcp_check_data_fin(struct + static void mptcp_dss_corruption(struct mptcp_sock *msk, struct sock *ssk) + { + if (READ_ONCE(msk->allow_infinite_fallback)) { ++ /* The caller possibly is not holding the msk socket lock, but ++ * in the fallback case only the current subflow is touching ++ * the OoO queue. ++ */ ++ if (!RB_EMPTY_ROOT(&msk->out_of_order_queue)) { ++ MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_DSSCORRUPTIONRESET); ++ mptcp_subflow_reset(ssk); ++ return; ++ } + MPTCP_INC_STATS(sock_net(ssk), + MPTCP_MIB_DSSCORRUPTIONFALLBACK); + mptcp_do_fallback(ssk); diff --git a/queue-5.10/mptcp-fix-a-race-in-mptcp_pm_del_add_timer.patch b/queue-5.10/mptcp-fix-a-race-in-mptcp_pm_del_add_timer.patch new file mode 100644 index 0000000000..3f75fc595a --- /dev/null +++ b/queue-5.10/mptcp-fix-a-race-in-mptcp_pm_del_add_timer.patch @@ -0,0 +1,199 @@ +From stable+bounces-196841-greg=kroah.com@vger.kernel.org Tue Nov 25 03:59:01 2025 +From: Sasha Levin +Date: Mon, 24 Nov 2025 21:58:41 -0500 +Subject: mptcp: fix a race in mptcp_pm_del_add_timer() +To: stable@vger.kernel.org +Cc: Eric Dumazet , syzbot+2a6fbf0f0530375968df@syzkaller.appspotmail.com, Geliang Tang , "Matthieu Baerts (NGI0)" , Jakub Kicinski , Sasha Levin +Message-ID: <20251125025841.314477-1-sashal@kernel.org> + +From: Eric Dumazet + +[ Upstream commit 426358d9be7ce3518966422f87b96f1bad27295f ] + +mptcp_pm_del_add_timer() can call sk_stop_timer_sync(sk, &entry->add_timer) +while another might have free entry already, as reported by syzbot. + +Add RCU protection to fix this issue. + +Also change confusing add_timer variable with stop_timer boolean. + +syzbot report: + +BUG: KASAN: slab-use-after-free in __timer_delete_sync+0x372/0x3f0 kernel/time/timer.c:1616 +Read of size 4 at addr ffff8880311e4150 by task kworker/1:1/44 + +CPU: 1 UID: 0 PID: 44 Comm: kworker/1:1 Not tainted syzkaller #0 PREEMPT_{RT,(full)} +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/02/2025 +Workqueue: events mptcp_worker +Call Trace: + + dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 + print_address_description mm/kasan/report.c:378 [inline] + print_report+0xca/0x240 mm/kasan/report.c:482 + kasan_report+0x118/0x150 mm/kasan/report.c:595 + __timer_delete_sync+0x372/0x3f0 kernel/time/timer.c:1616 + sk_stop_timer_sync+0x1b/0x90 net/core/sock.c:3631 + mptcp_pm_del_add_timer+0x283/0x310 net/mptcp/pm.c:362 + mptcp_incoming_options+0x1357/0x1f60 net/mptcp/options.c:1174 + tcp_data_queue+0xca/0x6450 net/ipv4/tcp_input.c:5361 + tcp_rcv_established+0x1335/0x2670 net/ipv4/tcp_input.c:6441 + tcp_v4_do_rcv+0x98b/0xbf0 net/ipv4/tcp_ipv4.c:1931 + tcp_v4_rcv+0x252a/0x2dc0 net/ipv4/tcp_ipv4.c:2374 + ip_protocol_deliver_rcu+0x221/0x440 net/ipv4/ip_input.c:205 + ip_local_deliver_finish+0x3bb/0x6f0 net/ipv4/ip_input.c:239 + NF_HOOK+0x30c/0x3a0 include/linux/netfilter.h:318 + NF_HOOK+0x30c/0x3a0 include/linux/netfilter.h:318 + __netif_receive_skb_one_core net/core/dev.c:6079 [inline] + __netif_receive_skb+0x143/0x380 net/core/dev.c:6192 + process_backlog+0x31e/0x900 net/core/dev.c:6544 + __napi_poll+0xb6/0x540 net/core/dev.c:7594 + napi_poll net/core/dev.c:7657 [inline] + net_rx_action+0x5f7/0xda0 net/core/dev.c:7784 + handle_softirqs+0x22f/0x710 kernel/softirq.c:622 + __do_softirq kernel/softirq.c:656 [inline] + __local_bh_enable_ip+0x1a0/0x2e0 kernel/softirq.c:302 + mptcp_pm_send_ack net/mptcp/pm.c:210 [inline] + mptcp_pm_addr_send_ack+0x41f/0x500 net/mptcp/pm.c:-1 + mptcp_pm_worker+0x174/0x320 net/mptcp/pm.c:1002 + mptcp_worker+0xd5/0x1170 net/mptcp/protocol.c:2762 + process_one_work kernel/workqueue.c:3263 [inline] + process_scheduled_works+0xae1/0x17b0 kernel/workqueue.c:3346 + worker_thread+0x8a0/0xda0 kernel/workqueue.c:3427 + kthread+0x711/0x8a0 kernel/kthread.c:463 + ret_from_fork+0x4bc/0x870 arch/x86/kernel/process.c:158 + ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 + + +Allocated by task 44: + kasan_save_stack mm/kasan/common.c:56 [inline] + kasan_save_track+0x3e/0x80 mm/kasan/common.c:77 + poison_kmalloc_redzone mm/kasan/common.c:400 [inline] + __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:417 + kasan_kmalloc include/linux/kasan.h:262 [inline] + __kmalloc_cache_noprof+0x1ef/0x6c0 mm/slub.c:5748 + kmalloc_noprof include/linux/slab.h:957 [inline] + mptcp_pm_alloc_anno_list+0x104/0x460 net/mptcp/pm.c:385 + mptcp_pm_create_subflow_or_signal_addr+0xf9d/0x1360 net/mptcp/pm_kernel.c:355 + mptcp_pm_nl_fully_established net/mptcp/pm_kernel.c:409 [inline] + __mptcp_pm_kernel_worker+0x417/0x1ef0 net/mptcp/pm_kernel.c:1529 + mptcp_pm_worker+0x1ee/0x320 net/mptcp/pm.c:1008 + mptcp_worker+0xd5/0x1170 net/mptcp/protocol.c:2762 + process_one_work kernel/workqueue.c:3263 [inline] + process_scheduled_works+0xae1/0x17b0 kernel/workqueue.c:3346 + worker_thread+0x8a0/0xda0 kernel/workqueue.c:3427 + kthread+0x711/0x8a0 kernel/kthread.c:463 + ret_from_fork+0x4bc/0x870 arch/x86/kernel/process.c:158 + ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 + +Freed by task 6630: + kasan_save_stack mm/kasan/common.c:56 [inline] + kasan_save_track+0x3e/0x80 mm/kasan/common.c:77 + __kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:587 + kasan_save_free_info mm/kasan/kasan.h:406 [inline] + poison_slab_object mm/kasan/common.c:252 [inline] + __kasan_slab_free+0x5c/0x80 mm/kasan/common.c:284 + kasan_slab_free include/linux/kasan.h:234 [inline] + slab_free_hook mm/slub.c:2523 [inline] + slab_free mm/slub.c:6611 [inline] + kfree+0x197/0x950 mm/slub.c:6818 + mptcp_remove_anno_list_by_saddr+0x2d/0x40 net/mptcp/pm.c:158 + mptcp_pm_flush_addrs_and_subflows net/mptcp/pm_kernel.c:1209 [inline] + mptcp_nl_flush_addrs_list net/mptcp/pm_kernel.c:1240 [inline] + mptcp_pm_nl_flush_addrs_doit+0x593/0xbb0 net/mptcp/pm_kernel.c:1281 + genl_family_rcv_msg_doit+0x215/0x300 net/netlink/genetlink.c:1115 + genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline] + genl_rcv_msg+0x60e/0x790 net/netlink/genetlink.c:1210 + netlink_rcv_skb+0x208/0x470 net/netlink/af_netlink.c:2552 + genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219 + netlink_unicast_kernel net/netlink/af_netlink.c:1320 [inline] + netlink_unicast+0x846/0xa10 net/netlink/af_netlink.c:1346 + netlink_sendmsg+0x805/0xb30 net/netlink/af_netlink.c:1896 + sock_sendmsg_nosec net/socket.c:727 [inline] + __sock_sendmsg+0x21c/0x270 net/socket.c:742 + ____sys_sendmsg+0x508/0x820 net/socket.c:2630 + ___sys_sendmsg+0x21f/0x2a0 net/socket.c:2684 + __sys_sendmsg net/socket.c:2716 [inline] + __do_sys_sendmsg net/socket.c:2721 [inline] + __se_sys_sendmsg net/socket.c:2719 [inline] + __x64_sys_sendmsg+0x1a1/0x260 net/socket.c:2719 + do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] + do_syscall_64+0xfa/0xfa0 arch/x86/entry/syscall_64.c:94 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Cc: stable@vger.kernel.org +Fixes: 00cfd77b9063 ("mptcp: retransmit ADD_ADDR when timeout") +Reported-by: syzbot+2a6fbf0f0530375968df@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/691ad3c3.a70a0220.f6df1.0004.GAE@google.com +Signed-off-by: Eric Dumazet +Cc: Geliang Tang +Reviewed-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20251117100745.1913963-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +[ applied changes to pm_netlink.c instead of pm.c ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + net/mptcp/pm_netlink.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +--- a/net/mptcp/pm_netlink.c ++++ b/net/mptcp/pm_netlink.c +@@ -34,6 +34,7 @@ struct mptcp_pm_add_entry { + struct timer_list add_timer; + struct mptcp_sock *sock; + u8 retrans_times; ++ struct rcu_head rcu; + }; + + struct pm_nl_pernet { +@@ -253,22 +254,27 @@ mptcp_pm_del_add_timer(struct mptcp_sock + { + struct mptcp_pm_add_entry *entry; + struct sock *sk = (struct sock *)msk; +- struct timer_list *add_timer = NULL; ++ bool stop_timer = false; ++ ++ rcu_read_lock(); + + spin_lock_bh(&msk->pm.lock); + entry = mptcp_lookup_anno_list_by_saddr(msk, addr); + if (entry && (!check_id || entry->addr.id == addr->id)) { + entry->retrans_times = ADD_ADDR_RETRANS_MAX; +- add_timer = &entry->add_timer; ++ stop_timer = true; + } + if (!check_id && entry) + list_del(&entry->list); + spin_unlock_bh(&msk->pm.lock); + +- /* no lock, because sk_stop_timer_sync() is calling del_timer_sync() */ +- if (add_timer) +- sk_stop_timer_sync(sk, add_timer); ++ /* Note: entry might have been removed by another thread. ++ * We hold rcu_read_lock() to ensure it is not freed under us. ++ */ ++ if (stop_timer) ++ sk_stop_timer_sync(sk, &entry->add_timer); + ++ rcu_read_unlock(); + return entry; + } + +@@ -311,7 +317,7 @@ void mptcp_pm_free_anno_list(struct mptc + + list_for_each_entry_safe(entry, tmp, &free_list, list) { + sk_stop_timer_sync(sk, &entry->add_timer); +- kfree(entry); ++ kfree_rcu(entry, rcu); + } + } + +@@ -772,7 +778,7 @@ static bool remove_anno_list_by_saddr(st + + entry = mptcp_pm_del_add_timer(msk, addr, false); + if (entry) { +- kfree(entry); ++ kfree_rcu(entry, rcu); + return true; + } + diff --git a/queue-5.10/mptcp-fix-proto-fallback-detection-with-bpf.patch b/queue-5.10/mptcp-fix-proto-fallback-detection-with-bpf.patch new file mode 100644 index 0000000000..e164ebfab8 --- /dev/null +++ b/queue-5.10/mptcp-fix-proto-fallback-detection-with-bpf.patch @@ -0,0 +1,101 @@ +From stable+bounces-196774-greg=kroah.com@vger.kernel.org Mon Nov 24 18:39:05 2025 +From: Sasha Levin +Date: Mon, 24 Nov 2025 12:38:21 -0500 +Subject: mptcp: Fix proto fallback detection with BPF +To: stable@vger.kernel.org +Cc: Jiayuan Chen , Martin KaFai Lau , Jakub Sitnicki , "Matthieu Baerts (NGI0)" , Sasha Levin +Message-ID: <20251124173821.4165452-1-sashal@kernel.org> + +From: Jiayuan Chen + +[ Upstream commit c77b3b79a92e3345aa1ee296180d1af4e7031f8f ] + +The sockmap feature allows bpf syscall from userspace, or based +on bpf sockops, replacing the sk_prot of sockets during protocol stack +processing with sockmap's custom read/write interfaces. +''' +tcp_rcv_state_process() + syn_recv_sock()/subflow_syn_recv_sock() + tcp_init_transfer(BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB) + bpf_skops_established <== sockops + bpf_sock_map_update(sk) <== call bpf helper + tcp_bpf_update_proto() <== update sk_prot +''' + +When the server has MPTCP enabled but the client sends a TCP SYN +without MPTCP, subflow_syn_recv_sock() performs a fallback on the +subflow, replacing the subflow sk's sk_prot with the native sk_prot. +''' +subflow_syn_recv_sock() + subflow_ulp_fallback() + subflow_drop_ctx() + mptcp_subflow_ops_undo_override() +''' + +Then, this subflow can be normally used by sockmap, which replaces the +native sk_prot with sockmap's custom sk_prot. The issue occurs when the +user executes accept::mptcp_stream_accept::mptcp_fallback_tcp_ops(). +Here, it uses sk->sk_prot to compare with the native sk_prot, but this +is incorrect when sockmap is used, as we may incorrectly set +sk->sk_socket->ops. + +This fix uses the more generic sk_family for the comparison instead. + +Additionally, this also prevents a WARNING from occurring: + +result from ./scripts/decode_stacktrace.sh: +------------[ cut here ]------------ +WARNING: CPU: 0 PID: 337 at net/mptcp/protocol.c:68 mptcp_stream_accept \ +(net/mptcp/protocol.c:4005) +Modules linked in: +... + +PKRU: 55555554 +Call Trace: + +do_accept (net/socket.c:1989) +__sys_accept4 (net/socket.c:2028 net/socket.c:2057) +__x64_sys_accept (net/socket.c:2067) +x64_sys_call (arch/x86/entry/syscall_64.c:41) +do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) +entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) +RIP: 0033:0x7f87ac92b83d + +---[ end trace 0000000000000000 ]--- + +Fixes: 0b4f33def7bb ("mptcp: fix tcp fallback crash") +Signed-off-by: Jiayuan Chen +Signed-off-by: Martin KaFai Lau +Reviewed-by: Jakub Sitnicki +Reviewed-by: Matthieu Baerts (NGI0) +Cc: +Link: https://patch.msgid.link/20251111060307.194196-3-jiayuan.chen@linux.dev +[ applied fix to mptcp_is_tcpsk() instead of mptcp_fallback_tcp_ops() ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + net/mptcp/protocol.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -56,8 +56,9 @@ static struct socket *__mptcp_nmpc_socke + static bool mptcp_is_tcpsk(struct sock *sk) + { + struct socket *sock = sk->sk_socket; ++ unsigned short family = READ_ONCE(sk->sk_family); + +- if (unlikely(sk->sk_prot == &tcp_prot)) { ++ if (unlikely(family == AF_INET)) { + /* we are being invoked after mptcp_accept() has + * accepted a non-mp-capable flow: sk is a tcp_sk, + * not an mptcp one. +@@ -68,7 +69,7 @@ static bool mptcp_is_tcpsk(struct sock * + sock->ops = &inet_stream_ops; + return true; + #if IS_ENABLED(CONFIG_MPTCP_IPV6) +- } else if (unlikely(sk->sk_prot == &tcpv6_prot)) { ++ } else if (unlikely(family == AF_INET6)) { + sock->ops = &inet6_stream_ops; + return true; + #endif diff --git a/queue-5.10/mptcp-fix-race-condition-in-mptcp_schedule_work.patch b/queue-5.10/mptcp-fix-race-condition-in-mptcp_schedule_work.patch new file mode 100644 index 0000000000..e63e273464 --- /dev/null +++ b/queue-5.10/mptcp-fix-race-condition-in-mptcp_schedule_work.patch @@ -0,0 +1,100 @@ +From stable+bounces-196799-greg=kroah.com@vger.kernel.org Mon Nov 24 21:59:27 2025 +From: Sasha Levin +Date: Mon, 24 Nov 2025 15:59:17 -0500 +Subject: mptcp: fix race condition in mptcp_schedule_work() +To: stable@vger.kernel.org +Cc: Eric Dumazet , syzbot+355158e7e301548a1424@syzkaller.appspotmail.com, "Matthieu Baerts (NGI0)" , Jakub Kicinski , Sasha Levin +Message-ID: <20251124205917.27437-2-sashal@kernel.org> + +From: Eric Dumazet + +[ Upstream commit 035bca3f017ee9dea3a5a756e77a6f7138cc6eea ] + +syzbot reported use-after-free in mptcp_schedule_work() [1] + +Issue here is that mptcp_schedule_work() schedules a work, +then gets a refcount on sk->sk_refcnt if the work was scheduled. +This refcount will be released by mptcp_worker(). + +[A] if (schedule_work(...)) { +[B] sock_hold(sk); + return true; + } + +Problem is that mptcp_worker() can run immediately and complete before [B] + +We need instead : + + sock_hold(sk); + if (schedule_work(...)) + return true; + sock_put(sk); + +[1] +refcount_t: addition on 0; use-after-free. + WARNING: CPU: 1 PID: 29 at lib/refcount.c:25 refcount_warn_saturate+0xfa/0x1d0 lib/refcount.c:25 +Call Trace: + + __refcount_add include/linux/refcount.h:-1 [inline] + __refcount_inc include/linux/refcount.h:366 [inline] + refcount_inc include/linux/refcount.h:383 [inline] + sock_hold include/net/sock.h:816 [inline] + mptcp_schedule_work+0x164/0x1a0 net/mptcp/protocol.c:943 + mptcp_tout_timer+0x21/0xa0 net/mptcp/protocol.c:2316 + call_timer_fn+0x17e/0x5f0 kernel/time/timer.c:1747 + expire_timers kernel/time/timer.c:1798 [inline] + __run_timers kernel/time/timer.c:2372 [inline] + __run_timer_base+0x648/0x970 kernel/time/timer.c:2384 + run_timer_base kernel/time/timer.c:2393 [inline] + run_timer_softirq+0xb7/0x180 kernel/time/timer.c:2403 + handle_softirqs+0x22f/0x710 kernel/softirq.c:622 + __do_softirq kernel/softirq.c:656 [inline] + run_ktimerd+0xcf/0x190 kernel/softirq.c:1138 + smpboot_thread_fn+0x542/0xa60 kernel/smpboot.c:160 + kthread+0x711/0x8a0 kernel/kthread.c:463 + ret_from_fork+0x4bc/0x870 arch/x86/kernel/process.c:158 + ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 + +Cc: stable@vger.kernel.org +Fixes: 3b1d6210a957 ("mptcp: implement and use MPTCP-level retransmission") +Reported-by: syzbot+355158e7e301548a1424@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/netdev/6915b46f.050a0220.3565dc.0028.GAE@google.com/T/#u +Signed-off-by: Eric Dumazet +Reviewed-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20251113103924.3737425-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + net/mptcp/protocol.c | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -717,14 +717,19 @@ static void mptcp_reset_timer(struct soc + + bool mptcp_schedule_work(struct sock *sk) + { +- if (inet_sk_state_load(sk) != TCP_CLOSE && +- schedule_work(&mptcp_sk(sk)->work)) { +- /* each subflow already holds a reference to the sk, and the +- * workqueue is invoked by a subflow, so sk can't go away here. +- */ +- sock_hold(sk); ++ if (inet_sk_state_load(sk) == TCP_CLOSE) ++ return false; ++ ++ /* Get a reference on this socket, mptcp_worker() will release it. ++ * As mptcp_worker() might complete before us, we can not avoid ++ * a sock_hold()/sock_put() if schedule_work() returns false. ++ */ ++ sock_hold(sk); ++ ++ if (schedule_work(&mptcp_sk(sk)->work)) + return true; +- } ++ ++ sock_put(sk); + return false; + } + diff --git a/queue-5.10/mptcp-introduce-mptcp_schedule_work.patch b/queue-5.10/mptcp-introduce-mptcp_schedule_work.patch new file mode 100644 index 0000000000..eeb10a71de --- /dev/null +++ b/queue-5.10/mptcp-introduce-mptcp_schedule_work.patch @@ -0,0 +1,123 @@ +From stable+bounces-196798-greg=kroah.com@vger.kernel.org Mon Nov 24 21:59:26 2025 +From: Sasha Levin +Date: Mon, 24 Nov 2025 15:59:16 -0500 +Subject: mptcp: introduce mptcp_schedule_work +To: stable@vger.kernel.org +Cc: Paolo Abeni , Jakub Kicinski , Sasha Levin +Message-ID: <20251124205917.27437-1-sashal@kernel.org> + +From: Paolo Abeni + +[ Upstream commit ba8f48f7a4d79352b764ace585b5f602ef940be0 ] + +remove some of code duplications an allow preventing +rescheduling on close. + +Signed-off-by: Paolo Abeni +Signed-off-by: Jakub Kicinski +Stable-dep-of: 035bca3f017e ("mptcp: fix race condition in mptcp_schedule_work()") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + net/mptcp/pm.c | 3 +-- + net/mptcp/protocol.c | 36 ++++++++++++++++++++++-------------- + net/mptcp/protocol.h | 1 + + 3 files changed, 24 insertions(+), 16 deletions(-) + +--- a/net/mptcp/pm.c ++++ b/net/mptcp/pm.c +@@ -89,8 +89,7 @@ static bool mptcp_pm_schedule_work(struc + return false; + + msk->pm.status |= BIT(new_status); +- if (schedule_work(&msk->work)) +- sock_hold((struct sock *)msk); ++ mptcp_schedule_work((struct sock *)msk); + return true; + } + +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -642,9 +642,8 @@ static bool move_skbs_to_msk(struct mptc + * this is not a good place to change state. Let the workqueue + * do it. + */ +- if (mptcp_pending_data_fin(sk, NULL) && +- schedule_work(&msk->work)) +- sock_hold(sk); ++ if (mptcp_pending_data_fin(sk, NULL)) ++ mptcp_schedule_work(sk); + } + + spin_unlock_bh(&sk->sk_lock.slock); +@@ -716,23 +715,32 @@ static void mptcp_reset_timer(struct soc + sk_reset_timer(sk, &icsk->icsk_retransmit_timer, jiffies + tout); + } + ++bool mptcp_schedule_work(struct sock *sk) ++{ ++ if (inet_sk_state_load(sk) != TCP_CLOSE && ++ schedule_work(&mptcp_sk(sk)->work)) { ++ /* each subflow already holds a reference to the sk, and the ++ * workqueue is invoked by a subflow, so sk can't go away here. ++ */ ++ sock_hold(sk); ++ return true; ++ } ++ return false; ++} ++ + void mptcp_data_acked(struct sock *sk) + { + mptcp_reset_timer(sk); + + if ((!test_bit(MPTCP_SEND_SPACE, &mptcp_sk(sk)->flags) || +- (inet_sk_state_load(sk) != TCP_ESTABLISHED)) && +- schedule_work(&mptcp_sk(sk)->work)) +- sock_hold(sk); ++ (inet_sk_state_load(sk) != TCP_ESTABLISHED))) ++ mptcp_schedule_work(sk); + } + + void mptcp_subflow_eof(struct sock *sk) + { +- struct mptcp_sock *msk = mptcp_sk(sk); +- +- if (!test_and_set_bit(MPTCP_WORK_EOF, &msk->flags) && +- schedule_work(&msk->work)) +- sock_hold(sk); ++ if (!test_and_set_bit(MPTCP_WORK_EOF, &mptcp_sk(sk)->flags)) ++ mptcp_schedule_work(sk); + } + + static void mptcp_check_for_eof(struct mptcp_sock *msk) +@@ -1644,8 +1652,7 @@ static void mptcp_retransmit_handler(str + mptcp_stop_timer(sk); + } else { + set_bit(MPTCP_WORK_RTX, &msk->flags); +- if (schedule_work(&msk->work)) +- sock_hold(sk); ++ mptcp_schedule_work(sk); + } + } + +@@ -2504,7 +2511,8 @@ static void mptcp_release_cb(struct sock + struct sock *ssk; + + ssk = mptcp_subflow_recv_lookup(msk); +- if (!ssk || !schedule_work(&msk->work)) ++ if (!ssk || sk->sk_state == TCP_CLOSE || ++ !schedule_work(&msk->work)) + __sock_put(sk); + } + +--- a/net/mptcp/protocol.h ++++ b/net/mptcp/protocol.h +@@ -410,6 +410,7 @@ static inline bool mptcp_is_fully_establ + void mptcp_rcv_space_init(struct mptcp_sock *msk, const struct sock *ssk); + void mptcp_data_ready(struct sock *sk, struct sock *ssk); + bool mptcp_finish_join(struct sock *sk); ++bool mptcp_schedule_work(struct sock *sk); + void mptcp_data_acked(struct sock *sk); + void mptcp_subflow_eof(struct sock *sk); + bool mptcp_update_rcv_data_fin(struct mptcp_sock *msk, u64 data_fin_seq, bool use_64bit); diff --git a/queue-5.10/net-netpoll-fix-incorrect-refcount-handling-causing-incorrect-cleanup.patch b/queue-5.10/net-netpoll-fix-incorrect-refcount-handling-causing-incorrect-cleanup.patch new file mode 100644 index 0000000000..bc96262aa4 --- /dev/null +++ b/queue-5.10/net-netpoll-fix-incorrect-refcount-handling-causing-incorrect-cleanup.patch @@ -0,0 +1,85 @@ +From stable+bounces-195442-greg=kroah.com@vger.kernel.org Fri Nov 21 03:04:38 2025 +From: Sasha Levin +Date: Thu, 20 Nov 2025 20:59:38 -0500 +Subject: net: netpoll: fix incorrect refcount handling causing incorrect cleanup +To: stable@vger.kernel.org +Cc: Breno Leitao , Jay Vosburgh , Simon Horman , Jakub Kicinski , Sasha Levin +Message-ID: <20251121015938.2338360-1-sashal@kernel.org> + +From: Breno Leitao + +[ Upstream commit 49c8d2c1f94cc2f4d1a108530d7ba52614b874c2 ] + +commit efa95b01da18 ("netpoll: fix use after free") incorrectly +ignored the refcount and prematurely set dev->npinfo to NULL during +netpoll cleanup, leading to improper behavior and memory leaks. + +Scenario causing lack of proper cleanup: + +1) A netpoll is associated with a NIC (e.g., eth0) and netdev->npinfo is + allocated, and refcnt = 1 + - Keep in mind that npinfo is shared among all netpoll instances. In + this case, there is just one. + +2) Another netpoll is also associated with the same NIC and + npinfo->refcnt += 1. + - Now dev->npinfo->refcnt = 2; + - There is just one npinfo associated to the netdev. + +3) When the first netpolls goes to clean up: + - The first cleanup succeeds and clears np->dev->npinfo, ignoring + refcnt. + - It basically calls `RCU_INIT_POINTER(np->dev->npinfo, NULL);` + - Set dev->npinfo = NULL, without proper cleanup + - No ->ndo_netpoll_cleanup() is either called + +4) Now the second target tries to clean up + - The second cleanup fails because np->dev->npinfo is already NULL. + * In this case, ops->ndo_netpoll_cleanup() was never called, and + the skb pool is not cleaned as well (for the second netpoll + instance) + - This leaks npinfo and skbpool skbs, which is clearly reported by + kmemleak. + +Revert commit efa95b01da18 ("netpoll: fix use after free") and adds +clarifying comments emphasizing that npinfo cleanup should only happen +once the refcount reaches zero, ensuring stable and correct netpoll +behavior. + +Cc: # 3.17.x +Cc: Jay Vosburgh +Fixes: efa95b01da18 ("netpoll: fix use after free") +Signed-off-by: Breno Leitao +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20251107-netconsole_torture-v10-1-749227b55f63@debian.org +Signed-off-by: Jakub Kicinski +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + net/core/netpoll.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/net/core/netpoll.c ++++ b/net/core/netpoll.c +@@ -863,6 +863,10 @@ void __netpoll_cleanup(struct netpoll *n + + synchronize_srcu(&netpoll_srcu); + ++ /* At this point, there is a single npinfo instance per netdevice, and ++ * its refcnt tracks how many netpoll structures are linked to it. We ++ * only perform npinfo cleanup when the refcnt decrements to zero. ++ */ + if (refcount_dec_and_test(&npinfo->refcnt)) { + const struct net_device_ops *ops; + +@@ -872,8 +876,7 @@ void __netpoll_cleanup(struct netpoll *n + + RCU_INIT_POINTER(np->dev->npinfo, NULL); + call_rcu(&npinfo->rcu, rcu_cleanup_netpoll_info); +- } else +- RCU_INIT_POINTER(np->dev->npinfo, NULL); ++ } + } + EXPORT_SYMBOL_GPL(__netpoll_cleanup); + diff --git a/queue-5.10/net-qede-initialize-qede_ll_ops-with-designated-initializer.patch b/queue-5.10/net-qede-initialize-qede_ll_ops-with-designated-initializer.patch new file mode 100644 index 0000000000..25b8ee08ab --- /dev/null +++ b/queue-5.10/net-qede-initialize-qede_ll_ops-with-designated-initializer.patch @@ -0,0 +1,43 @@ +From 6b3ab7f2cbfaeb6580709cd8ef4d72cfd01bfde4 Mon Sep 17 00:00:00 2001 +From: Nathan Chancellor +Date: Wed, 7 May 2025 21:47:45 +0100 +Subject: net: qede: Initialize qede_ll_ops with designated initializer + +From: Nathan Chancellor + +commit 6b3ab7f2cbfaeb6580709cd8ef4d72cfd01bfde4 upstream. + +After a recent change [1] in clang's randstruct implementation to +randomize structures that only contain function pointers, there is an +error because qede_ll_ops get randomized but does not use a designated +initializer for the first member: + + drivers/net/ethernet/qlogic/qede/qede_main.c:206:2: error: a randomized struct can only be initialized with a designated initializer + 206 | { + | ^ + +Explicitly initialize the common member using a designated initializer +to fix the build. + +Cc: stable@vger.kernel.org +Fixes: 035f7f87b729 ("randstruct: Enable Clang support") +Link: https://github.com/llvm/llvm-project/commit/04364fb888eea6db9811510607bed4b200bcb082 [1] +Signed-off-by: Nathan Chancellor +Link: https://patch.msgid.link/20250507-qede-fix-clang-randstruct-v1-1-5ccc15626fba@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/qlogic/qede/qede_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/qlogic/qede/qede_main.c ++++ b/drivers/net/ethernet/qlogic/qede/qede_main.c +@@ -199,7 +199,7 @@ static struct pci_driver qede_pci_driver + }; + + static struct qed_eth_cb_ops qede_ll_ops = { +- { ++ .common = { + #ifdef CONFIG_RFS_ACCEL + .arfs_filter_op = qede_arfs_filter_op, + #endif diff --git a/queue-5.10/pmdomain-arm-scmi-fix-genpd-leak-on-provider-registration-failure.patch b/queue-5.10/pmdomain-arm-scmi-fix-genpd-leak-on-provider-registration-failure.patch new file mode 100644 index 0000000000..964524b774 --- /dev/null +++ b/queue-5.10/pmdomain-arm-scmi-fix-genpd-leak-on-provider-registration-failure.patch @@ -0,0 +1,82 @@ +From stable+bounces-196536-greg=kroah.com@vger.kernel.org Fri Nov 21 18:02:17 2025 +From: Sasha Levin +Date: Fri, 21 Nov 2025 11:57:51 -0500 +Subject: pmdomain: arm: scmi: Fix genpd leak on provider registration failure +To: stable@vger.kernel.org +Cc: Sudeep Holla , Peng Fan , Ulf Hansson , Sasha Levin +Message-ID: <20251121165751.2605860-1-sashal@kernel.org> + +From: Sudeep Holla + +[ Upstream commit 7458f72cc28f9eb0de811effcb5376d0ec19094a ] + +If of_genpd_add_provider_onecell() fails during probe, the previously +created generic power domains are not removed, leading to a memory leak +and potential kernel crash later in genpd_debug_add(). + +Add proper error handling to unwind the initialized domains before +returning from probe to ensure all resources are correctly released on +failure. + +Example crash trace observed without this fix: + + | Unable to handle kernel paging request at virtual address fffffffffffffc70 + | CPU: 1 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.18.0-rc1 #405 PREEMPT + | Hardware name: ARM LTD ARM Juno Development Platform/ARM Juno Development Platform + | pstate: 00000005 (nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) + | pc : genpd_debug_add+0x2c/0x160 + | lr : genpd_debug_init+0x74/0x98 + | Call trace: + | genpd_debug_add+0x2c/0x160 (P) + | genpd_debug_init+0x74/0x98 + | do_one_initcall+0xd0/0x2d8 + | do_initcall_level+0xa0/0x140 + | do_initcalls+0x60/0xa8 + | do_basic_setup+0x28/0x40 + | kernel_init_freeable+0xe8/0x170 + | kernel_init+0x2c/0x140 + | ret_from_fork+0x10/0x20 + +Fixes: 898216c97ed2 ("firmware: arm_scmi: add device power domain support using genpd") +Signed-off-by: Sudeep Holla +Reviewed-by: Peng Fan +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +[ drivers/pmdomain/arm/scmi_pm_domain.c -> drivers/firmware/arm_scmi/scmi_pm_domain.c ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/firmware/arm_scmi/scmi_pm_domain.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/drivers/firmware/arm_scmi/scmi_pm_domain.c ++++ b/drivers/firmware/arm_scmi/scmi_pm_domain.c +@@ -53,7 +53,7 @@ static int scmi_pd_power_off(struct gene + + static int scmi_pm_domain_probe(struct scmi_device *sdev) + { +- int num_domains, i; ++ int num_domains, i, ret; + struct device *dev = &sdev->dev; + struct device_node *np = dev->of_node; + struct scmi_pm_domain *scmi_pd; +@@ -106,9 +106,18 @@ static int scmi_pm_domain_probe(struct s + scmi_pd_data->domains = domains; + scmi_pd_data->num_domains = num_domains; + ++ ret = of_genpd_add_provider_onecell(np, scmi_pd_data); ++ if (ret) ++ goto err_rm_genpds; ++ + dev_set_drvdata(dev, scmi_pd_data); + +- return of_genpd_add_provider_onecell(np, scmi_pd_data); ++ return 0; ++err_rm_genpds: ++ for (i = num_domains - 1; i >= 0; i--) ++ pm_genpd_remove(domains[i]); ++ ++ return ret; + } + + static void scmi_pm_domain_remove(struct scmi_device *sdev) diff --git a/queue-5.10/pmdomain-imx-fix-reference-count-leak-in-imx_gpc_remove.patch b/queue-5.10/pmdomain-imx-fix-reference-count-leak-in-imx_gpc_remove.patch new file mode 100644 index 0000000000..92b5338c87 --- /dev/null +++ b/queue-5.10/pmdomain-imx-fix-reference-count-leak-in-imx_gpc_remove.patch @@ -0,0 +1,38 @@ +From stable+bounces-196535-greg=kroah.com@vger.kernel.org Fri Nov 21 17:58:04 2025 +From: Sasha Levin +Date: Fri, 21 Nov 2025 11:57:48 -0500 +Subject: pmdomain: imx: Fix reference count leak in imx_gpc_remove +To: stable@vger.kernel.org +Cc: Miaoqian Lin , Ulf Hansson , Sasha Levin +Message-ID: <20251121165748.2605755-1-sashal@kernel.org> + +From: Miaoqian Lin + +[ Upstream commit bbde14682eba21d86f5f3d6fe2d371b1f97f1e61 ] + +of_get_child_by_name() returns a node pointer with refcount incremented, we +should use of_node_put() on it when not needed anymore. Add the missing +of_node_put() to avoid refcount leak. + +Fixes: 721cabf6c660 ("soc: imx: move PGC handling to a new GPC driver") +Cc: stable@vger.kernel.org +Signed-off-by: Miaoqian Lin +Signed-off-by: Ulf Hansson +[ drivers/pmdomain/imx/gpc.c -> drivers/soc/imx/gpc.c ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/soc/imx/gpc.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/soc/imx/gpc.c ++++ b/drivers/soc/imx/gpc.c +@@ -540,6 +540,8 @@ static int imx_gpc_remove(struct platfor + return ret; + } + ++ of_node_put(pgc_node); ++ + return 0; + } + diff --git a/queue-5.10/revert-nfs-don-t-set-nfs_ino_reval_pagecache-in-the-inode-cache-validity.patch b/queue-5.10/revert-nfs-don-t-set-nfs_ino_reval_pagecache-in-the-inode-cache-validity.patch new file mode 100644 index 0000000000..b9b594e494 --- /dev/null +++ b/queue-5.10/revert-nfs-don-t-set-nfs_ino_reval_pagecache-in-the-inode-cache-validity.patch @@ -0,0 +1,75 @@ +From 3ae48f4eccfe9dcfeb9b3ff3670cadaed7b35c9e Mon Sep 17 00:00:00 2001 +Message-ID: <3ae48f4eccfe9dcfeb9b3ff3670cadaed7b35c9e.1763918082.git.trond.myklebust@hammerspace.com> +From: Trond Myklebust +Date: Sat, 22 Nov 2025 10:28:09 -0500 +Subject: Revert "NFS: Don't set NFS_INO_REVAL_PAGECACHE in the inode cache validity" + +From: Trond Myklebust + +This reverts commit 36a9346c225270262d9f34e66c91aa1723fa903f. + +The above commit was incorrectly labelled as a dependency for commit +b01f21cacde9 ("NFS: Fix the setting of capabilities when automounting a +new filesystem") +A revert is needed, since the incorrectly applied commit depends upon a +series of other patches that were merged into Linux 5.13, but have not +been applied to the 5.10 stable series. + +Reported-by: "Ahmed, Aaron" +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfs/inode.c | 6 ++++-- + fs/nfs/nfs4proc.c | 1 + + 2 files changed, 5 insertions(+), 2 deletions(-) + +--- a/fs/nfs/inode.c ++++ b/fs/nfs/inode.c +@@ -217,12 +217,11 @@ static void nfs_set_cache_invalid(struct + flags &= ~NFS_INO_INVALID_OTHER; + flags &= ~(NFS_INO_INVALID_CHANGE + | NFS_INO_INVALID_SIZE ++ | NFS_INO_REVAL_PAGECACHE + | NFS_INO_INVALID_XATTR); + } else if (flags & NFS_INO_REVAL_PAGECACHE) + flags |= NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_SIZE; + +- flags &= ~NFS_INO_REVAL_PAGECACHE; +- + if (!nfs_has_xattr_cache(nfsi)) + flags &= ~NFS_INO_INVALID_XATTR; + if (inode->i_mapping->nrpages == 0) +@@ -1901,6 +1900,7 @@ static int nfs_update_inode(struct inode + nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR + | NFS_INO_INVALID_ATIME + | NFS_INO_REVAL_FORCED ++ | NFS_INO_REVAL_PAGECACHE + | NFS_INO_INVALID_BLOCKS); + + /* Do atomic weak cache consistency updates */ +@@ -1942,6 +1942,7 @@ static int nfs_update_inode(struct inode + } else { + nfsi->cache_validity |= save_cache_validity & + (NFS_INO_INVALID_CHANGE ++ | NFS_INO_REVAL_PAGECACHE + | NFS_INO_REVAL_FORCED); + cache_revalidated = false; + } +@@ -1987,6 +1988,7 @@ static int nfs_update_inode(struct inode + } else { + nfsi->cache_validity |= save_cache_validity & + (NFS_INO_INVALID_SIZE ++ | NFS_INO_REVAL_PAGECACHE + | NFS_INO_REVAL_FORCED); + cache_revalidated = false; + } +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -1212,6 +1212,7 @@ nfs4_update_changeattr_locked(struct ino + | cache_validity; + + if (cinfo->atomic && cinfo->before == inode_peek_iversion_raw(inode)) { ++ nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; + nfsi->attrtimeo_timestamp = jiffies; + } else { + if (S_ISDIR(inode->i_mode)) { diff --git a/queue-5.10/series b/queue-5.10/series index c13a107660..7469d9d379 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -235,3 +235,25 @@ kconfig-nconf-initialize-the-default-locale-at-start.patch mm-mm_init-fix-hash-table-order-logging-in-alloc_lar.patch alsa-usb-audio-fix-uac2-clock-source-at-terminal-par.patch net-ethernet-ti-netcp-standardize-knav_dma_open_chan.patch +uio_hv_generic-set-event-for-all-channels-on-the-device.patch +net-qede-initialize-qede_ll_ops-with-designated-initializer.patch +makefile.compiler-replace-cc-ifversion-with-compiler-specific-macros.patch +revert-nfs-don-t-set-nfs_ino_reval_pagecache-in-the-inode-cache-validity.patch +net-netpoll-fix-incorrect-refcount-handling-causing-incorrect-cleanup.patch +alsa-usb-audio-fix-potential-overflow-of-pcm-transfer-buffer.patch +pmdomain-imx-fix-reference-count-leak-in-imx_gpc_remove.patch +pmdomain-arm-scmi-fix-genpd-leak-on-provider-registration-failure.patch +mptcp-fix-proto-fallback-detection-with-bpf.patch +ata-libata-scsi-fix-system-suspend-for-a-security-locked-drive.patch +mptcp-introduce-mptcp_schedule_work.patch +mptcp-fix-race-condition-in-mptcp_schedule_work.patch +dt-bindings-pinctrl-toshiba-visconti-fix-number-of-items-in-groups.patch +mm-mempool-replace-kmap_atomic-with-kmap_local_page.patch +mm-mempool-fix-poisoning-order-0-pages-with-highmem.patch +mptcp-fix-a-race-in-mptcp_pm_del_add_timer.patch +mptcp-do-not-fallback-when-ooo-is-present.patch +mm-mprotect-use-long-for-page-accountings-and-retval.patch +mm-mprotect-delete-pmd_none_or_clear_bad_unless_trans_huge.patch +usb-deprecate-the-third-argument-of-usb_maxpacket.patch +input-remove-third-argument-of-usb_maxpacket.patch +input-pegasus-notetaker-fix-potential-out-of-bounds-access.patch diff --git a/queue-5.10/uio_hv_generic-set-event-for-all-channels-on-the-device.patch b/queue-5.10/uio_hv_generic-set-event-for-all-channels-on-the-device.patch new file mode 100644 index 0000000000..7152ae9abe --- /dev/null +++ b/queue-5.10/uio_hv_generic-set-event-for-all-channels-on-the-device.patch @@ -0,0 +1,74 @@ +From d062463edf1770427dc2d637df4088df4835aa47 Mon Sep 17 00:00:00 2001 +From: Long Li +Date: Mon, 10 Mar 2025 15:12:01 -0700 +Subject: uio_hv_generic: Set event for all channels on the device + +From: Long Li + +commit d062463edf1770427dc2d637df4088df4835aa47 upstream. + +Hyper-V may offer a non latency sensitive device with subchannels without +monitor bit enabled. The decision is entirely on the Hyper-V host not +configurable within guest. + +When a device has subchannels, also signal events for the subchannel +if its monitor bit is disabled. + +This patch also removes the memory barrier when monitor bit is enabled +as it is not necessary. The memory barrier is only needed between +setting up interrupt mask and calling vmbus_set_event() when monitor +bit is disabled. + +Signed-off-by: Long Li +Reviewed-by: Michael Kelley +Reviewed-by: Saurabh Sengar +Link: https://lore.kernel.org/r/1741644721-20389-1-git-send-email-longli@linuxonhyperv.com +Fixes: b15b7d2a1b09 ("uio_hv_generic: Let userspace take care of interrupt mask") +Closes: https://bugs.debian.org/1120602 +Signed-off-by: Naman Jain +Signed-off-by: Greg Kroah-Hartman +--- + drivers/uio/uio_hv_generic.c | 21 +++++++++++++++++---- + 1 file changed, 17 insertions(+), 4 deletions(-) + +--- a/drivers/uio/uio_hv_generic.c ++++ b/drivers/uio/uio_hv_generic.c +@@ -80,9 +80,15 @@ hv_uio_irqcontrol(struct uio_info *info, + { + struct hv_uio_private_data *pdata = info->priv; + struct hv_device *dev = pdata->device; ++ struct vmbus_channel *primary, *sc; + +- dev->channel->inbound.ring_buffer->interrupt_mask = !irq_state; +- virt_mb(); ++ primary = dev->channel; ++ primary->inbound.ring_buffer->interrupt_mask = !irq_state; ++ ++ mutex_lock(&vmbus_connection.channel_mutex); ++ list_for_each_entry(sc, &primary->sc_list, sc_list) ++ sc->inbound.ring_buffer->interrupt_mask = !irq_state; ++ mutex_unlock(&vmbus_connection.channel_mutex); + + return 0; + } +@@ -93,11 +99,18 @@ hv_uio_irqcontrol(struct uio_info *info, + static void hv_uio_channel_cb(void *context) + { + struct vmbus_channel *chan = context; +- struct hv_device *hv_dev = chan->device_obj; +- struct hv_uio_private_data *pdata = hv_get_drvdata(hv_dev); ++ struct hv_device *hv_dev; ++ struct hv_uio_private_data *pdata; + + virt_mb(); + ++ /* ++ * The callback may come from a subchannel, in which case look ++ * for the hv device in the primary channel ++ */ ++ hv_dev = chan->primary_channel ? ++ chan->primary_channel->device_obj : chan->device_obj; ++ pdata = hv_get_drvdata(hv_dev); + uio_event_notify(&pdata->info); + } + diff --git a/queue-5.10/usb-deprecate-the-third-argument-of-usb_maxpacket.patch b/queue-5.10/usb-deprecate-the-third-argument-of-usb_maxpacket.patch new file mode 100644 index 0000000000..96a231c139 --- /dev/null +++ b/queue-5.10/usb-deprecate-the-third-argument-of-usb_maxpacket.patch @@ -0,0 +1,85 @@ +From stable+bounces-196784-greg=kroah.com@vger.kernel.org Mon Nov 24 20:01:17 2025 +From: Sasha Levin +Date: Mon, 24 Nov 2025 13:57:16 -0500 +Subject: usb: deprecate the third argument of usb_maxpacket() +To: stable@vger.kernel.org +Cc: Vincent Mailhol , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251124185718.4192041-1-sashal@kernel.org> + +From: Vincent Mailhol + +[ Upstream commit 0f08c2e7458e25c967d844170f8ad1aac3b57a02 ] + +This is a transitional patch with the ultimate goal of changing the +prototype of usb_maxpacket() from: +| static inline __u16 +| usb_maxpacket(struct usb_device *udev, int pipe, int is_out) + +into: +| static inline u16 usb_maxpacket(struct usb_device *udev, int pipe) + +The third argument of usb_maxpacket(): is_out gets removed because it +can be derived from its second argument: pipe using +usb_pipeout(pipe). Furthermore, in the current version, +ubs_pipeout(pipe) is called regardless in order to sanitize the is_out +parameter. + +In order to make a smooth change, we first deprecate the is_out +parameter by simply ignoring it (using a variadic function) and will +remove it later, once all the callers get updated. + +The body of the function is reworked accordingly and is_out is +replaced by usb_pipeout(pipe). The WARN_ON() calls become unnecessary +and get removed. + +Finally, the return type is changed from __u16 to u16 because this is +not a UAPI function. + +Signed-off-by: Vincent Mailhol +Link: https://lore.kernel.org/r/20220317035514.6378-2-mailhol.vincent@wanadoo.fr +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 69aeb5073123 ("Input: pegasus-notetaker - fix potential out-of-bounds access") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/usb.h | 16 +++++----------- + 1 file changed, 5 insertions(+), 11 deletions(-) + +--- a/include/linux/usb.h ++++ b/include/linux/usb.h +@@ -1980,21 +1980,17 @@ usb_pipe_endpoint(struct usb_device *dev + return eps[usb_pipeendpoint(pipe)]; + } + +-/*-------------------------------------------------------------------------*/ +- +-static inline __u16 +-usb_maxpacket(struct usb_device *udev, int pipe, int is_out) ++static inline u16 usb_maxpacket(struct usb_device *udev, int pipe, ++ /* int is_out deprecated */ ...) + { + struct usb_host_endpoint *ep; + unsigned epnum = usb_pipeendpoint(pipe); + +- if (is_out) { +- WARN_ON(usb_pipein(pipe)); ++ if (usb_pipeout(pipe)) + ep = udev->ep_out[epnum]; +- } else { +- WARN_ON(usb_pipeout(pipe)); ++ else + ep = udev->ep_in[epnum]; +- } ++ + if (!ep) + return 0; + +@@ -2002,8 +1998,6 @@ usb_maxpacket(struct usb_device *udev, i + return usb_endpoint_maxp(&ep->desc); + } + +-/* ----------------------------------------------------------------------- */ +- + /* translate USB error codes to codes user space understands */ + static inline int usb_translate_errors(int error_code) + { -- 2.47.3