]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for all trees
authorSasha Levin <sashal@kernel.org>
Mon, 3 Aug 2026 20:46:32 +0000 (16:46 -0400)
committerSasha Levin <sashal@kernel.org>
Mon, 3 Aug 2026 20:46:32 +0000 (16:46 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
34 files changed:
queue-5.10/hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch [new file with mode: 0644]
queue-5.10/hid-logitech-dj-prevent-report_id_dj_short-related-u.patch [new file with mode: 0644]
queue-5.10/hid-logitech-dj-standardise-hid_report_enum-variable.patch [new file with mode: 0644]
queue-5.10/net-qrtr-ns-limit-the-maximum-server-registration-pe.patch [new file with mode: 0644]
queue-5.10/net-qrtr-ns-raise-node-count-limit-to-512.patch [new file with mode: 0644]
queue-5.10/series
queue-5.15/hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch [new file with mode: 0644]
queue-5.15/hid-logitech-dj-prevent-report_id_dj_short-related-u.patch [new file with mode: 0644]
queue-5.15/hid-logitech-dj-standardise-hid_report_enum-variable.patch [new file with mode: 0644]
queue-5.15/net-qrtr-ns-limit-the-maximum-server-registration-pe.patch [new file with mode: 0644]
queue-5.15/net-qrtr-ns-raise-node-count-limit-to-512.patch [new file with mode: 0644]
queue-5.15/series
queue-6.1/hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch [new file with mode: 0644]
queue-6.1/hid-logitech-dj-prevent-report_id_dj_short-related-u.patch [new file with mode: 0644]
queue-6.1/hid-logitech-dj-standardise-hid_report_enum-variable.patch [new file with mode: 0644]
queue-6.1/net-qrtr-ns-limit-the-maximum-server-registration-pe.patch [new file with mode: 0644]
queue-6.1/net-qrtr-ns-raise-node-count-limit-to-512.patch [new file with mode: 0644]
queue-6.1/series
queue-6.12/bpf-reset-register-bounds-before-narrowing-retval-ra.patch [new file with mode: 0644]
queue-6.12/hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch [new file with mode: 0644]
queue-6.12/hid-logitech-dj-prevent-report_id_dj_short-related-u.patch [new file with mode: 0644]
queue-6.12/hid-logitech-dj-standardise-hid_report_enum-variable.patch [new file with mode: 0644]
queue-6.12/series
queue-6.18/hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch [new file with mode: 0644]
queue-6.18/hid-logitech-dj-prevent-report_id_dj_short-related-u.patch [new file with mode: 0644]
queue-6.18/hid-logitech-dj-standardise-hid_report_enum-variable.patch [new file with mode: 0644]
queue-6.18/lib-alloc_tag-introduce-mem_alloc_profiling_permanen.patch [new file with mode: 0644]
queue-6.18/mm-slab-prevent-unbounded-recursion-in-free-path-wit.patch [new file with mode: 0644]
queue-6.18/series
queue-6.6/hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch [new file with mode: 0644]
queue-6.6/hid-logitech-dj-prevent-report_id_dj_short-related-u.patch [new file with mode: 0644]
queue-6.6/hid-logitech-dj-standardise-hid_report_enum-variable.patch [new file with mode: 0644]
queue-6.6/series
queue-6.6/soc-qcom-ice-allow-explicit-votes-on-iface-clock-for.patch [new file with mode: 0644]

diff --git a/queue-5.10/hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch b/queue-5.10/hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch
new file mode 100644 (file)
index 0000000..8d275df
--- /dev/null
@@ -0,0 +1,45 @@
+From 638ad3e9919dac6bbeab70501fb0dd6f0a9b1acd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Apr 2026 16:03:07 +0200
+Subject: HID: logitech-dj: fix wrong detection of bad DJ_SHORT output report
+
+From: Benjamin Tissoires <bentiss@kernel.org>
+
+[ Upstream commit 8b9a097eb2fc37b486afd81388c693bf3ab44466 ]
+
+commit b6a57912854e ("HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT
+related user initiated OOB write") assumed that all HID devices attached
+to the logitech-dj driver was having an output report of DJ_SHORT.
+
+However, on the receiver itself, we have 2 other HID device we attach
+here: the mouse emulation and the keyboard emulation. For those devices
+the value of rep is NULL and we are triggered a segfault here.
+
+This is doubly required because logitech-dj also handles non DJ devices
+that might not have the DJ collection.
+
+Fixes: b6a57912854e ("HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT related user initiated OOB write")
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-dj.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index d3f63bac518ae..4bb324b73629e 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1715,7 +1715,8 @@ static int logi_dj_probe(struct hid_device *hdev,
+       output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
+       rep = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
+-      if (rep->maxfield < 1 || rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1) {
++      if (rep && (rep->maxfield < 1 ||
++                  rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1)) {
+               hid_err(hdev, "Expected size of DJ short report is %d, but got %d",
+                       DJREPORT_SHORT_LENGTH - 1, rep->field[0]->report_count);
+               return -EINVAL;
+-- 
+2.53.0
+
diff --git a/queue-5.10/hid-logitech-dj-prevent-report_id_dj_short-related-u.patch b/queue-5.10/hid-logitech-dj-prevent-report_id_dj_short-related-u.patch
new file mode 100644 (file)
index 0000000..92785aa
--- /dev/null
@@ -0,0 +1,56 @@
+From 8b3be89fa8e28f0dd9a954a319b9e31d610e6a39 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Mar 2026 14:36:44 +0000
+Subject: HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT related user initiated
+ OOB write
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit b6a57912854e7ea36f3b270032661140cc4209cd ]
+
+logi_dj_recv_send_report() assumes that all incoming REPORT_ID_DJ_SHORT
+reports are 14 Bytes (DJREPORT_SHORT_LENGTH - 1) long.  It uses that
+assumption to load the associated field's 'value' array with 14 Bytes of
+data.  However, if a malicious user only sends say 1 Byte of data,
+'report_count' will be 1 and only 1 Byte of memory will be allocated to
+the 'value' Byte array.  When we come to populate 'value[1-13]' we will
+experience an OOB write.
+
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-dj.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index 91804ebabc69a..d3f63bac518ae 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1669,6 +1669,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+                        const struct hid_device_id *id)
+ {
+       struct hid_report_enum *input_report_enum;
++      struct hid_report_enum *output_report_enum;
+       struct hid_report *rep;
+       struct dj_receiver_dev *djrcv_dev;
+       struct usb_interface *intf;
+@@ -1711,6 +1712,15 @@ static int logi_dj_probe(struct hid_device *hdev,
+               }
+       }
++      output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
++      rep = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
++
++      if (rep->maxfield < 1 || rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1) {
++              hid_err(hdev, "Expected size of DJ short report is %d, but got %d",
++                      DJREPORT_SHORT_LENGTH - 1, rep->field[0]->report_count);
++              return -EINVAL;
++      }
++
+       input_report_enum = &hdev->report_enum[HID_INPUT_REPORT];
+       /* no input reports, bail out */
+-- 
+2.53.0
+
diff --git a/queue-5.10/hid-logitech-dj-standardise-hid_report_enum-variable.patch b/queue-5.10/hid-logitech-dj-standardise-hid_report_enum-variable.patch
new file mode 100644 (file)
index 0000000..38a81e4
--- /dev/null
@@ -0,0 +1,78 @@
+From 97ddf36d9465ff2795c739f9585e142254f7ce6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Mar 2026 14:36:43 +0000
+Subject: HID: logitech-dj: Standardise hid_report_enum variable nomenclature
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit a940aee176437046598dfc786b719bd96db3c74c ]
+
+Since we will need to differentiate between the two report_enum types
+soon, let's unify the naming conventions now to save confusion and/or
+unnecessary/unrelated changes in upcoming commits.
+
+{input,output}_report_enum is used in other places to let's conform.
+
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-dj.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index bd31315fdaf5e..91804ebabc69a 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1668,7 +1668,7 @@ static int logi_dj_raw_event(struct hid_device *hdev,
+ static int logi_dj_probe(struct hid_device *hdev,
+                        const struct hid_device_id *id)
+ {
+-      struct hid_report_enum *rep_enum;
++      struct hid_report_enum *input_report_enum;
+       struct hid_report *rep;
+       struct dj_receiver_dev *djrcv_dev;
+       struct usb_interface *intf;
+@@ -1711,10 +1711,10 @@ static int logi_dj_probe(struct hid_device *hdev,
+               }
+       }
+-      rep_enum = &hdev->report_enum[HID_INPUT_REPORT];
++      input_report_enum = &hdev->report_enum[HID_INPUT_REPORT];
+       /* no input reports, bail out */
+-      if (list_empty(&rep_enum->report_list))
++      if (list_empty(&input_report_enum->report_list))
+               return -ENODEV;
+       /*
+@@ -1722,7 +1722,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+        * Note: we should theoretically check for HID++ and DJ
+        * collections, but this will do.
+        */
+-      list_for_each_entry(rep, &rep_enum->report_list, list) {
++      list_for_each_entry(rep, &input_report_enum->report_list, list) {
+               if (rep->application == 0xff000001)
+                       has_hidpp = true;
+       }
+@@ -1735,7 +1735,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+               return -ENODEV;
+       /* get the current application attached to the node */
+-      rep = list_first_entry(&rep_enum->report_list, struct hid_report, list);
++      rep = list_first_entry(&input_report_enum->report_list, struct hid_report, list);
+       djrcv_dev = dj_get_receiver_dev(hdev, id->driver_data,
+                                       rep->application, has_hidpp);
+       if (!djrcv_dev) {
+@@ -1743,7 +1743,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+               return -ENOMEM;
+       }
+-      if (!rep_enum->numbered)
++      if (!input_report_enum->numbered)
+               djrcv_dev->unnumbered_application = rep->application;
+       /* Starts the usb device and connects to upper interfaces hiddev and
+-- 
+2.53.0
+
diff --git a/queue-5.10/net-qrtr-ns-limit-the-maximum-server-registration-pe.patch b/queue-5.10/net-qrtr-ns-limit-the-maximum-server-registration-pe.patch
new file mode 100644 (file)
index 0000000..dec975c
--- /dev/null
@@ -0,0 +1,111 @@
+From 7bd488e577cc406fda56d8a7511ab7d9c687941c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 Aug 2026 22:21:06 +0200
+Subject: net: qrtr: ns: Limit the maximum server registration per node
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
+
+[ Upstream commit d5ee2ff98322337951c56398e79d51815acbf955 ]
+
+Current code does no bound checking on the number of servers added per
+node. A malicious client can flood NEW_SERVER messages and exhaust memory.
+
+Fix this issue by limiting the maximum number of server registrations to
+256 per node. If the NEW_SERVER message is received for an old port, then
+don't restrict it as it will get replaced. While at it, also rate limit
+the error messages in the failure path of qrtr_ns_worker().
+
+Note that the limit of 256 is chosen based on the current platform
+requirements. If requirement changes in the future, this limit can be
+increased.
+
+Cc: stable@vger.kernel.org
+Fixes: 0c2204a4ad71 ("net: qrtr: Migrate nameservice to kernel from userspace")
+Reported-by: Yiming Qian <yimingqian591@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260409-qrtr-fix-v3-1-00a8a5ff2b51@oss.qualcomm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/qrtr/ns.c | 26 ++++++++++++++++----------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/net/qrtr/ns.c b/net/qrtr/ns.c
+index 36a7a9ad6b503..440e68601e251 100644
+--- a/net/qrtr/ns.c
++++ b/net/qrtr/ns.c
+@@ -68,13 +68,9 @@ struct qrtr_server {
+ struct qrtr_node {
+       unsigned int id;
+       struct xarray servers;
++      u32 server_count;
+ };
+-/* Max lookup limit is chosen based on the current platform requirements. If the
+- * requirement changes in the future, this value can be increased.
+- */
+-#define QRTR_NS_MAX_LOOKUPS 64
+-
+ /* Max nodes, server, lookup limits are chosen based on the current platform
+  * requirements. If the requirement changes in the future, these values can be
+  * increased.
+@@ -249,6 +245,17 @@ static struct qrtr_server *server_add(unsigned int service,
+       if (!service || !port)
+               return NULL;
++      node = node_get(node_id);
++      if (!node)
++              return NULL;
++
++      /* Make sure the new servers per port are capped at the maximum value */
++      old = xa_load(&node->servers, port);
++      if (!old && node->server_count >= QRTR_NS_MAX_SERVERS) {
++              pr_err_ratelimited("QRTR client node %u exceeds max server limit!\n", node_id);
++              return NULL;
++      }
++
+       srv = kzalloc(sizeof(*srv), GFP_KERNEL);
+       if (!srv)
+               return NULL;
+@@ -258,10 +265,6 @@ static struct qrtr_server *server_add(unsigned int service,
+       srv->node = node_id;
+       srv->port = port;
+-      node = node_get(node_id);
+-      if (!node)
+-              goto err;
+-
+       /* Delete the old server on the same port */
+       old = xa_store(&node->servers, port, srv, GFP_KERNEL);
+       if (old) {
+@@ -272,6 +275,8 @@ static struct qrtr_server *server_add(unsigned int service,
+               } else {
+                       kfree(old);
+               }
++      } else {
++              node->server_count++;
+       }
+       trace_qrtr_ns_server_add(srv->service, srv->instance,
+@@ -312,6 +317,7 @@ static int server_del(struct qrtr_node *node, unsigned int port, bool bcast)
+       }
+       kfree(srv);
++      node->server_count--;
+       return 0;
+ }
+@@ -716,7 +722,7 @@ static void qrtr_ns_worker(struct work_struct *work)
+               }
+               if (ret < 0)
+-                      pr_err("failed while handling packet from %d:%d",
++                      pr_err_ratelimited("failed while handling packet from %d:%d",
+                              sq.sq_node, sq.sq_port);
+       }
+-- 
+2.53.0
+
diff --git a/queue-5.10/net-qrtr-ns-raise-node-count-limit-to-512.patch b/queue-5.10/net-qrtr-ns-raise-node-count-limit-to-512.patch
new file mode 100644 (file)
index 0000000..779a1bb
--- /dev/null
@@ -0,0 +1,56 @@
+From e593be74e085cf6e386701414f00ec5e3df14e5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 Aug 2026 23:33:52 +0200
+Subject: net: qrtr: ns: Raise node count limit to 512
+
+From: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com>
+
+[ Upstream commit ff194cffd586cbd4cc49eccb002c65f2a902a277 ]
+
+The current node limit of 64 breaks the functionality for a number of AI200
+deployments that have up to 384 nodes. Raise the limit to 512.
+
+Also, the backport of commit 27d5e84e810b ("net: qrtr: ns: Limit the total
+number of nodes") to 5.10, 5.15 and 6.1 dropped the node_count-- hunk in
+ctrl_cmd_bye(). Add it back.
+
+Fixes: 27d5e84e810b ("net: qrtr: ns: Limit the total number of nodes")
+Cc: stable@vger.kernel.org
+Signed-off-by: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260713145901.212396-1-youssef.abdulrahman@oss.qualcomm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/qrtr/ns.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/qrtr/ns.c b/net/qrtr/ns.c
+index 440e68601e251..3ebb5d39e153f 100644
+--- a/net/qrtr/ns.c
++++ b/net/qrtr/ns.c
+@@ -75,11 +75,11 @@ struct qrtr_node {
+  * requirements. If the requirement changes in the future, these values can be
+  * increased.
+  */
+-#define QRTR_NS_MAX_NODES   64
++#define QRTR_NS_MAX_NODES   512
+ #define QRTR_NS_MAX_SERVERS 256
+ #define QRTR_NS_MAX_LOOKUPS 64
+-static u8 node_count;
++static u16 node_count;
+ static struct qrtr_node *node_get(unsigned int node_id)
+ {
+@@ -412,6 +412,7 @@ static int ctrl_cmd_bye(struct sockaddr_qrtr *from)
+ delete_node:
+       xa_erase(&nodes, from->sq_node);
+       kfree(node);
++      node_count--;
+       return ret;
+ }
+-- 
+2.53.0
+
index e2e855f699457d7e7ff21889a7e7db485edf9b77..f7bfe5c1ca5348c16c109cf45988aa3a8299e36b 100644 (file)
@@ -194,3 +194,8 @@ net-bridge-vlan-fix-global-vlan-option-range-dumping.patch
 net-mpls-initialize-rtm_tos-in-mpls_getroute.patch
 media-uvcvideo-implement-dual-stream-quirk-to-fix-lo.patch
 media-uvcvideo-fix-sequence-number-when-no-eof.patch
+hid-logitech-dj-standardise-hid_report_enum-variable.patch
+hid-logitech-dj-prevent-report_id_dj_short-related-u.patch
+hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch
+net-qrtr-ns-limit-the-maximum-server-registration-pe.patch
+net-qrtr-ns-raise-node-count-limit-to-512.patch
diff --git a/queue-5.15/hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch b/queue-5.15/hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch
new file mode 100644 (file)
index 0000000..5b63d08
--- /dev/null
@@ -0,0 +1,45 @@
+From 3b1cdda168ef4a580461eb7eb77d0879372cac0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Apr 2026 16:03:07 +0200
+Subject: HID: logitech-dj: fix wrong detection of bad DJ_SHORT output report
+
+From: Benjamin Tissoires <bentiss@kernel.org>
+
+[ Upstream commit 8b9a097eb2fc37b486afd81388c693bf3ab44466 ]
+
+commit b6a57912854e ("HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT
+related user initiated OOB write") assumed that all HID devices attached
+to the logitech-dj driver was having an output report of DJ_SHORT.
+
+However, on the receiver itself, we have 2 other HID device we attach
+here: the mouse emulation and the keyboard emulation. For those devices
+the value of rep is NULL and we are triggered a segfault here.
+
+This is doubly required because logitech-dj also handles non DJ devices
+that might not have the DJ collection.
+
+Fixes: b6a57912854e ("HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT related user initiated OOB write")
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-dj.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index 591a8f56ad2e9..8b11aade46c4d 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1797,7 +1797,8 @@ static int logi_dj_probe(struct hid_device *hdev,
+       output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
+       rep = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
+-      if (rep->maxfield < 1 || rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1) {
++      if (rep && (rep->maxfield < 1 ||
++                  rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1)) {
+               hid_err(hdev, "Expected size of DJ short report is %d, but got %d",
+                       DJREPORT_SHORT_LENGTH - 1, rep->field[0]->report_count);
+               return -EINVAL;
+-- 
+2.53.0
+
diff --git a/queue-5.15/hid-logitech-dj-prevent-report_id_dj_short-related-u.patch b/queue-5.15/hid-logitech-dj-prevent-report_id_dj_short-related-u.patch
new file mode 100644 (file)
index 0000000..06f08ff
--- /dev/null
@@ -0,0 +1,56 @@
+From e110716b1dcc4e4cf089643b504caf30a9c1df4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Mar 2026 14:36:44 +0000
+Subject: HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT related user initiated
+ OOB write
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit b6a57912854e7ea36f3b270032661140cc4209cd ]
+
+logi_dj_recv_send_report() assumes that all incoming REPORT_ID_DJ_SHORT
+reports are 14 Bytes (DJREPORT_SHORT_LENGTH - 1) long.  It uses that
+assumption to load the associated field's 'value' array with 14 Bytes of
+data.  However, if a malicious user only sends say 1 Byte of data,
+'report_count' will be 1 and only 1 Byte of memory will be allocated to
+the 'value' Byte array.  When we come to populate 'value[1-13]' we will
+experience an OOB write.
+
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-dj.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index 97b679e4cdbe3..591a8f56ad2e9 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1750,6 +1750,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+                        const struct hid_device_id *id)
+ {
+       struct hid_report_enum *input_report_enum;
++      struct hid_report_enum *output_report_enum;
+       struct hid_report *rep;
+       struct dj_receiver_dev *djrcv_dev;
+       struct usb_interface *intf;
+@@ -1793,6 +1794,15 @@ static int logi_dj_probe(struct hid_device *hdev,
+               }
+       }
++      output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
++      rep = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
++
++      if (rep->maxfield < 1 || rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1) {
++              hid_err(hdev, "Expected size of DJ short report is %d, but got %d",
++                      DJREPORT_SHORT_LENGTH - 1, rep->field[0]->report_count);
++              return -EINVAL;
++      }
++
+       input_report_enum = &hdev->report_enum[HID_INPUT_REPORT];
+       /* no input reports, bail out */
+-- 
+2.53.0
+
diff --git a/queue-5.15/hid-logitech-dj-standardise-hid_report_enum-variable.patch b/queue-5.15/hid-logitech-dj-standardise-hid_report_enum-variable.patch
new file mode 100644 (file)
index 0000000..067eaf4
--- /dev/null
@@ -0,0 +1,78 @@
+From 9a80fd84857e2b72d13144bddb2189bbcb7426b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Mar 2026 14:36:43 +0000
+Subject: HID: logitech-dj: Standardise hid_report_enum variable nomenclature
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit a940aee176437046598dfc786b719bd96db3c74c ]
+
+Since we will need to differentiate between the two report_enum types
+soon, let's unify the naming conventions now to save confusion and/or
+unnecessary/unrelated changes in upcoming commits.
+
+{input,output}_report_enum is used in other places to let's conform.
+
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-dj.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index be9fbf14f1371..97b679e4cdbe3 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1749,7 +1749,7 @@ static int logi_dj_raw_event(struct hid_device *hdev,
+ static int logi_dj_probe(struct hid_device *hdev,
+                        const struct hid_device_id *id)
+ {
+-      struct hid_report_enum *rep_enum;
++      struct hid_report_enum *input_report_enum;
+       struct hid_report *rep;
+       struct dj_receiver_dev *djrcv_dev;
+       struct usb_interface *intf;
+@@ -1793,10 +1793,10 @@ static int logi_dj_probe(struct hid_device *hdev,
+               }
+       }
+-      rep_enum = &hdev->report_enum[HID_INPUT_REPORT];
++      input_report_enum = &hdev->report_enum[HID_INPUT_REPORT];
+       /* no input reports, bail out */
+-      if (list_empty(&rep_enum->report_list))
++      if (list_empty(&input_report_enum->report_list))
+               return -ENODEV;
+       /*
+@@ -1804,7 +1804,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+        * Note: we should theoretically check for HID++ and DJ
+        * collections, but this will do.
+        */
+-      list_for_each_entry(rep, &rep_enum->report_list, list) {
++      list_for_each_entry(rep, &input_report_enum->report_list, list) {
+               if (rep->application == 0xff000001)
+                       has_hidpp = true;
+       }
+@@ -1817,7 +1817,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+               return -ENODEV;
+       /* get the current application attached to the node */
+-      rep = list_first_entry(&rep_enum->report_list, struct hid_report, list);
++      rep = list_first_entry(&input_report_enum->report_list, struct hid_report, list);
+       djrcv_dev = dj_get_receiver_dev(hdev, id->driver_data,
+                                       rep->application, has_hidpp);
+       if (!djrcv_dev) {
+@@ -1825,7 +1825,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+               return -ENOMEM;
+       }
+-      if (!rep_enum->numbered)
++      if (!input_report_enum->numbered)
+               djrcv_dev->unnumbered_application = rep->application;
+       /* Starts the usb device and connects to upper interfaces hiddev and
+-- 
+2.53.0
+
diff --git a/queue-5.15/net-qrtr-ns-limit-the-maximum-server-registration-pe.patch b/queue-5.15/net-qrtr-ns-limit-the-maximum-server-registration-pe.patch
new file mode 100644 (file)
index 0000000..48a61cc
--- /dev/null
@@ -0,0 +1,111 @@
+From 7b867e2f3b19e46b2693a9cb5680b97ab42748a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 Aug 2026 22:20:04 +0200
+Subject: net: qrtr: ns: Limit the maximum server registration per node
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
+
+[ Upstream commit d5ee2ff98322337951c56398e79d51815acbf955 ]
+
+Current code does no bound checking on the number of servers added per
+node. A malicious client can flood NEW_SERVER messages and exhaust memory.
+
+Fix this issue by limiting the maximum number of server registrations to
+256 per node. If the NEW_SERVER message is received for an old port, then
+don't restrict it as it will get replaced. While at it, also rate limit
+the error messages in the failure path of qrtr_ns_worker().
+
+Note that the limit of 256 is chosen based on the current platform
+requirements. If requirement changes in the future, this limit can be
+increased.
+
+Cc: stable@vger.kernel.org
+Fixes: 0c2204a4ad71 ("net: qrtr: Migrate nameservice to kernel from userspace")
+Reported-by: Yiming Qian <yimingqian591@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260409-qrtr-fix-v3-1-00a8a5ff2b51@oss.qualcomm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/qrtr/ns.c | 26 ++++++++++++++++----------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/net/qrtr/ns.c b/net/qrtr/ns.c
+index 559aad0e36215..91e43b0fd5669 100644
+--- a/net/qrtr/ns.c
++++ b/net/qrtr/ns.c
+@@ -68,13 +68,9 @@ struct qrtr_server {
+ struct qrtr_node {
+       unsigned int id;
+       struct xarray servers;
++      u32 server_count;
+ };
+-/* Max lookup limit is chosen based on the current platform requirements. If the
+- * requirement changes in the future, this value can be increased.
+- */
+-#define QRTR_NS_MAX_LOOKUPS 64
+-
+ /* Max nodes, server, lookup limits are chosen based on the current platform
+  * requirements. If the requirement changes in the future, these values can be
+  * increased.
+@@ -249,6 +245,17 @@ static struct qrtr_server *server_add(unsigned int service,
+       if (!service || !port)
+               return NULL;
++      node = node_get(node_id);
++      if (!node)
++              return NULL;
++
++      /* Make sure the new servers per port are capped at the maximum value */
++      old = xa_load(&node->servers, port);
++      if (!old && node->server_count >= QRTR_NS_MAX_SERVERS) {
++              pr_err_ratelimited("QRTR client node %u exceeds max server limit!\n", node_id);
++              return NULL;
++      }
++
+       srv = kzalloc(sizeof(*srv), GFP_KERNEL);
+       if (!srv)
+               return NULL;
+@@ -258,10 +265,6 @@ static struct qrtr_server *server_add(unsigned int service,
+       srv->node = node_id;
+       srv->port = port;
+-      node = node_get(node_id);
+-      if (!node)
+-              goto err;
+-
+       /* Delete the old server on the same port */
+       old = xa_store(&node->servers, port, srv, GFP_KERNEL);
+       if (old) {
+@@ -272,6 +275,8 @@ static struct qrtr_server *server_add(unsigned int service,
+               } else {
+                       kfree(old);
+               }
++      } else {
++              node->server_count++;
+       }
+       trace_qrtr_ns_server_add(srv->service, srv->instance,
+@@ -312,6 +317,7 @@ static int server_del(struct qrtr_node *node, unsigned int port, bool bcast)
+       }
+       kfree(srv);
++      node->server_count--;
+       return 0;
+ }
+@@ -708,7 +714,7 @@ static void qrtr_ns_worker(struct work_struct *work)
+               }
+               if (ret < 0)
+-                      pr_err("failed while handling packet from %d:%d",
++                      pr_err_ratelimited("failed while handling packet from %d:%d",
+                              sq.sq_node, sq.sq_port);
+       }
+-- 
+2.53.0
+
diff --git a/queue-5.15/net-qrtr-ns-raise-node-count-limit-to-512.patch b/queue-5.15/net-qrtr-ns-raise-node-count-limit-to-512.patch
new file mode 100644 (file)
index 0000000..eae02ba
--- /dev/null
@@ -0,0 +1,56 @@
+From a96d1069f1f40b2a0e14a2b432cfc8af9cf26dad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 Aug 2026 23:33:52 +0200
+Subject: net: qrtr: ns: Raise node count limit to 512
+
+From: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com>
+
+[ Upstream commit ff194cffd586cbd4cc49eccb002c65f2a902a277 ]
+
+The current node limit of 64 breaks the functionality for a number of AI200
+deployments that have up to 384 nodes. Raise the limit to 512.
+
+Also, the backport of commit 27d5e84e810b ("net: qrtr: ns: Limit the total
+number of nodes") to 5.10, 5.15 and 6.1 dropped the node_count-- hunk in
+ctrl_cmd_bye(). Add it back.
+
+Fixes: 27d5e84e810b ("net: qrtr: ns: Limit the total number of nodes")
+Cc: stable@vger.kernel.org
+Signed-off-by: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260713145901.212396-1-youssef.abdulrahman@oss.qualcomm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/qrtr/ns.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/qrtr/ns.c b/net/qrtr/ns.c
+index 91e43b0fd5669..5220529a4c62d 100644
+--- a/net/qrtr/ns.c
++++ b/net/qrtr/ns.c
+@@ -75,11 +75,11 @@ struct qrtr_node {
+  * requirements. If the requirement changes in the future, these values can be
+  * increased.
+  */
+-#define QRTR_NS_MAX_NODES   64
++#define QRTR_NS_MAX_NODES   512
+ #define QRTR_NS_MAX_SERVERS 256
+ #define QRTR_NS_MAX_LOOKUPS 64
+-static u8 node_count;
++static u16 node_count;
+ static struct qrtr_node *node_get(unsigned int node_id)
+ {
+@@ -412,6 +412,7 @@ static int ctrl_cmd_bye(struct sockaddr_qrtr *from)
+ delete_node:
+       xa_erase(&nodes, from->sq_node);
+       kfree(node);
++      node_count--;
+       return ret;
+ }
+-- 
+2.53.0
+
index 868b3b4ec3c2bdb24c2a0cf32bc891f4a3afd655..825d3fff9ed03535484652bbba22478018dcaf2f 100644 (file)
@@ -237,3 +237,8 @@ net-mpls-initialize-rtm_tos-in-mpls_getroute.patch
 media-uvcvideo-implement-dual-stream-quirk-to-fix-lo.patch
 media-uvcvideo-fix-sequence-number-when-no-eof.patch
 gve-fix-rx-queue-stall-on-alloc-failure.patch
+hid-logitech-dj-standardise-hid_report_enum-variable.patch
+hid-logitech-dj-prevent-report_id_dj_short-related-u.patch
+hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch
+net-qrtr-ns-limit-the-maximum-server-registration-pe.patch
+net-qrtr-ns-raise-node-count-limit-to-512.patch
diff --git a/queue-6.1/hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch b/queue-6.1/hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch
new file mode 100644 (file)
index 0000000..6006a10
--- /dev/null
@@ -0,0 +1,45 @@
+From 7ad2b475c1176699f4742e835bb9e88f5b53dc28 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Apr 2026 16:03:07 +0200
+Subject: HID: logitech-dj: fix wrong detection of bad DJ_SHORT output report
+
+From: Benjamin Tissoires <bentiss@kernel.org>
+
+[ Upstream commit 8b9a097eb2fc37b486afd81388c693bf3ab44466 ]
+
+commit b6a57912854e ("HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT
+related user initiated OOB write") assumed that all HID devices attached
+to the logitech-dj driver was having an output report of DJ_SHORT.
+
+However, on the receiver itself, we have 2 other HID device we attach
+here: the mouse emulation and the keyboard emulation. For those devices
+the value of rep is NULL and we are triggered a segfault here.
+
+This is doubly required because logitech-dj also handles non DJ devices
+that might not have the DJ collection.
+
+Fixes: b6a57912854e ("HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT related user initiated OOB write")
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-dj.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index 591a8f56ad2e9..8b11aade46c4d 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1797,7 +1797,8 @@ static int logi_dj_probe(struct hid_device *hdev,
+       output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
+       rep = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
+-      if (rep->maxfield < 1 || rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1) {
++      if (rep && (rep->maxfield < 1 ||
++                  rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1)) {
+               hid_err(hdev, "Expected size of DJ short report is %d, but got %d",
+                       DJREPORT_SHORT_LENGTH - 1, rep->field[0]->report_count);
+               return -EINVAL;
+-- 
+2.53.0
+
diff --git a/queue-6.1/hid-logitech-dj-prevent-report_id_dj_short-related-u.patch b/queue-6.1/hid-logitech-dj-prevent-report_id_dj_short-related-u.patch
new file mode 100644 (file)
index 0000000..82ce2dc
--- /dev/null
@@ -0,0 +1,56 @@
+From c5ef7c3f3e92ac5e188e5be6d9449a668984ced9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Mar 2026 14:36:44 +0000
+Subject: HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT related user initiated
+ OOB write
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit b6a57912854e7ea36f3b270032661140cc4209cd ]
+
+logi_dj_recv_send_report() assumes that all incoming REPORT_ID_DJ_SHORT
+reports are 14 Bytes (DJREPORT_SHORT_LENGTH - 1) long.  It uses that
+assumption to load the associated field's 'value' array with 14 Bytes of
+data.  However, if a malicious user only sends say 1 Byte of data,
+'report_count' will be 1 and only 1 Byte of memory will be allocated to
+the 'value' Byte array.  When we come to populate 'value[1-13]' we will
+experience an OOB write.
+
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-dj.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index 97b679e4cdbe3..591a8f56ad2e9 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1750,6 +1750,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+                        const struct hid_device_id *id)
+ {
+       struct hid_report_enum *input_report_enum;
++      struct hid_report_enum *output_report_enum;
+       struct hid_report *rep;
+       struct dj_receiver_dev *djrcv_dev;
+       struct usb_interface *intf;
+@@ -1793,6 +1794,15 @@ static int logi_dj_probe(struct hid_device *hdev,
+               }
+       }
++      output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
++      rep = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
++
++      if (rep->maxfield < 1 || rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1) {
++              hid_err(hdev, "Expected size of DJ short report is %d, but got %d",
++                      DJREPORT_SHORT_LENGTH - 1, rep->field[0]->report_count);
++              return -EINVAL;
++      }
++
+       input_report_enum = &hdev->report_enum[HID_INPUT_REPORT];
+       /* no input reports, bail out */
+-- 
+2.53.0
+
diff --git a/queue-6.1/hid-logitech-dj-standardise-hid_report_enum-variable.patch b/queue-6.1/hid-logitech-dj-standardise-hid_report_enum-variable.patch
new file mode 100644 (file)
index 0000000..bed871c
--- /dev/null
@@ -0,0 +1,78 @@
+From 4ee36d38b2011b3b1203262f77fda766df1b429c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Mar 2026 14:36:43 +0000
+Subject: HID: logitech-dj: Standardise hid_report_enum variable nomenclature
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit a940aee176437046598dfc786b719bd96db3c74c ]
+
+Since we will need to differentiate between the two report_enum types
+soon, let's unify the naming conventions now to save confusion and/or
+unnecessary/unrelated changes in upcoming commits.
+
+{input,output}_report_enum is used in other places to let's conform.
+
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-dj.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index be9fbf14f1371..97b679e4cdbe3 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1749,7 +1749,7 @@ static int logi_dj_raw_event(struct hid_device *hdev,
+ static int logi_dj_probe(struct hid_device *hdev,
+                        const struct hid_device_id *id)
+ {
+-      struct hid_report_enum *rep_enum;
++      struct hid_report_enum *input_report_enum;
+       struct hid_report *rep;
+       struct dj_receiver_dev *djrcv_dev;
+       struct usb_interface *intf;
+@@ -1793,10 +1793,10 @@ static int logi_dj_probe(struct hid_device *hdev,
+               }
+       }
+-      rep_enum = &hdev->report_enum[HID_INPUT_REPORT];
++      input_report_enum = &hdev->report_enum[HID_INPUT_REPORT];
+       /* no input reports, bail out */
+-      if (list_empty(&rep_enum->report_list))
++      if (list_empty(&input_report_enum->report_list))
+               return -ENODEV;
+       /*
+@@ -1804,7 +1804,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+        * Note: we should theoretically check for HID++ and DJ
+        * collections, but this will do.
+        */
+-      list_for_each_entry(rep, &rep_enum->report_list, list) {
++      list_for_each_entry(rep, &input_report_enum->report_list, list) {
+               if (rep->application == 0xff000001)
+                       has_hidpp = true;
+       }
+@@ -1817,7 +1817,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+               return -ENODEV;
+       /* get the current application attached to the node */
+-      rep = list_first_entry(&rep_enum->report_list, struct hid_report, list);
++      rep = list_first_entry(&input_report_enum->report_list, struct hid_report, list);
+       djrcv_dev = dj_get_receiver_dev(hdev, id->driver_data,
+                                       rep->application, has_hidpp);
+       if (!djrcv_dev) {
+@@ -1825,7 +1825,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+               return -ENOMEM;
+       }
+-      if (!rep_enum->numbered)
++      if (!input_report_enum->numbered)
+               djrcv_dev->unnumbered_application = rep->application;
+       /* Starts the usb device and connects to upper interfaces hiddev and
+-- 
+2.53.0
+
diff --git a/queue-6.1/net-qrtr-ns-limit-the-maximum-server-registration-pe.patch b/queue-6.1/net-qrtr-ns-limit-the-maximum-server-registration-pe.patch
new file mode 100644 (file)
index 0000000..1d37253
--- /dev/null
@@ -0,0 +1,111 @@
+From 5aa16a1d25c6280c0680a3948be2072cda1bb8b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 Aug 2026 22:18:25 +0200
+Subject: net: qrtr: ns: Limit the maximum server registration per node
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
+
+[ Upstream commit d5ee2ff98322337951c56398e79d51815acbf955 ]
+
+Current code does no bound checking on the number of servers added per
+node. A malicious client can flood NEW_SERVER messages and exhaust memory.
+
+Fix this issue by limiting the maximum number of server registrations to
+256 per node. If the NEW_SERVER message is received for an old port, then
+don't restrict it as it will get replaced. While at it, also rate limit
+the error messages in the failure path of qrtr_ns_worker().
+
+Note that the limit of 256 is chosen based on the current platform
+requirements. If requirement changes in the future, this limit can be
+increased.
+
+Cc: stable@vger.kernel.org
+Fixes: 0c2204a4ad71 ("net: qrtr: Migrate nameservice to kernel from userspace")
+Reported-by: Yiming Qian <yimingqian591@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260409-qrtr-fix-v3-1-00a8a5ff2b51@oss.qualcomm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/qrtr/ns.c | 26 ++++++++++++++++----------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/net/qrtr/ns.c b/net/qrtr/ns.c
+index 559aad0e36215..91e43b0fd5669 100644
+--- a/net/qrtr/ns.c
++++ b/net/qrtr/ns.c
+@@ -68,13 +68,9 @@ struct qrtr_server {
+ struct qrtr_node {
+       unsigned int id;
+       struct xarray servers;
++      u32 server_count;
+ };
+-/* Max lookup limit is chosen based on the current platform requirements. If the
+- * requirement changes in the future, this value can be increased.
+- */
+-#define QRTR_NS_MAX_LOOKUPS 64
+-
+ /* Max nodes, server, lookup limits are chosen based on the current platform
+  * requirements. If the requirement changes in the future, these values can be
+  * increased.
+@@ -249,6 +245,17 @@ static struct qrtr_server *server_add(unsigned int service,
+       if (!service || !port)
+               return NULL;
++      node = node_get(node_id);
++      if (!node)
++              return NULL;
++
++      /* Make sure the new servers per port are capped at the maximum value */
++      old = xa_load(&node->servers, port);
++      if (!old && node->server_count >= QRTR_NS_MAX_SERVERS) {
++              pr_err_ratelimited("QRTR client node %u exceeds max server limit!\n", node_id);
++              return NULL;
++      }
++
+       srv = kzalloc(sizeof(*srv), GFP_KERNEL);
+       if (!srv)
+               return NULL;
+@@ -258,10 +265,6 @@ static struct qrtr_server *server_add(unsigned int service,
+       srv->node = node_id;
+       srv->port = port;
+-      node = node_get(node_id);
+-      if (!node)
+-              goto err;
+-
+       /* Delete the old server on the same port */
+       old = xa_store(&node->servers, port, srv, GFP_KERNEL);
+       if (old) {
+@@ -272,6 +275,8 @@ static struct qrtr_server *server_add(unsigned int service,
+               } else {
+                       kfree(old);
+               }
++      } else {
++              node->server_count++;
+       }
+       trace_qrtr_ns_server_add(srv->service, srv->instance,
+@@ -312,6 +317,7 @@ static int server_del(struct qrtr_node *node, unsigned int port, bool bcast)
+       }
+       kfree(srv);
++      node->server_count--;
+       return 0;
+ }
+@@ -708,7 +714,7 @@ static void qrtr_ns_worker(struct work_struct *work)
+               }
+               if (ret < 0)
+-                      pr_err("failed while handling packet from %d:%d",
++                      pr_err_ratelimited("failed while handling packet from %d:%d",
+                              sq.sq_node, sq.sq_port);
+       }
+-- 
+2.53.0
+
diff --git a/queue-6.1/net-qrtr-ns-raise-node-count-limit-to-512.patch b/queue-6.1/net-qrtr-ns-raise-node-count-limit-to-512.patch
new file mode 100644 (file)
index 0000000..adbbb1e
--- /dev/null
@@ -0,0 +1,56 @@
+From 0b83a435d8842d551f7b3df0757bd59c153561b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 Aug 2026 23:33:52 +0200
+Subject: net: qrtr: ns: Raise node count limit to 512
+
+From: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com>
+
+[ Upstream commit ff194cffd586cbd4cc49eccb002c65f2a902a277 ]
+
+The current node limit of 64 breaks the functionality for a number of AI200
+deployments that have up to 384 nodes. Raise the limit to 512.
+
+Also, the backport of commit 27d5e84e810b ("net: qrtr: ns: Limit the total
+number of nodes") to 5.10, 5.15 and 6.1 dropped the node_count-- hunk in
+ctrl_cmd_bye(). Add it back.
+
+Fixes: 27d5e84e810b ("net: qrtr: ns: Limit the total number of nodes")
+Cc: stable@vger.kernel.org
+Signed-off-by: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260713145901.212396-1-youssef.abdulrahman@oss.qualcomm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/qrtr/ns.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/qrtr/ns.c b/net/qrtr/ns.c
+index 91e43b0fd5669..5220529a4c62d 100644
+--- a/net/qrtr/ns.c
++++ b/net/qrtr/ns.c
+@@ -75,11 +75,11 @@ struct qrtr_node {
+  * requirements. If the requirement changes in the future, these values can be
+  * increased.
+  */
+-#define QRTR_NS_MAX_NODES   64
++#define QRTR_NS_MAX_NODES   512
+ #define QRTR_NS_MAX_SERVERS 256
+ #define QRTR_NS_MAX_LOOKUPS 64
+-static u8 node_count;
++static u16 node_count;
+ static struct qrtr_node *node_get(unsigned int node_id)
+ {
+@@ -412,6 +412,7 @@ static int ctrl_cmd_bye(struct sockaddr_qrtr *from)
+ delete_node:
+       xa_erase(&nodes, from->sq_node);
+       kfree(node);
++      node_count--;
+       return ret;
+ }
+-- 
+2.53.0
+
index 94f646b9826bdc4a940471490c5d8f792eb9dbc3..8124209bec3ced01e759236785dea38771c79b54 100644 (file)
@@ -301,3 +301,8 @@ net-mpls-initialize-rtm_tos-in-mpls_getroute.patch
 media-uvcvideo-implement-dual-stream-quirk-to-fix-lo.patch
 media-uvcvideo-fix-sequence-number-when-no-eof.patch
 gve-fix-rx-queue-stall-on-alloc-failure.patch
+hid-logitech-dj-standardise-hid_report_enum-variable.patch
+hid-logitech-dj-prevent-report_id_dj_short-related-u.patch
+hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch
+net-qrtr-ns-limit-the-maximum-server-registration-pe.patch
+net-qrtr-ns-raise-node-count-limit-to-512.patch
diff --git a/queue-6.12/bpf-reset-register-bounds-before-narrowing-retval-ra.patch b/queue-6.12/bpf-reset-register-bounds-before-narrowing-retval-ra.patch
new file mode 100644 (file)
index 0000000..c31f86b
--- /dev/null
@@ -0,0 +1,53 @@
+From 52fc8cff0b7af347b9224c4463fc7dd440f7aa66 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jun 2026 23:01:22 +0000
+Subject: bpf: Reset register bounds before narrowing retval range in
+ check_mem_access()
+
+From: Tristan Madani <tristan@talencesecurity.com>
+
+[ Upstream commit 5e0b273e0a62cc04ec338c7b502797c66c2ed42a ]
+
+When the BPF verifier processes a context load of an LSM hook return
+value, it calls __mark_reg_s32_range() to narrow the register to the
+hook's valid range. However, __mark_reg_s32_range() intersects the new
+range with the register's existing bounds using max_t()/min_t() rather
+than replacing them.
+
+If the destination register carries stale bounds from a prior instruction
+(e.g. BPF_MOV64_IMM), the intersection can produce a range narrower than
+reality. The verifier then believes it knows the register's exact value,
+while at runtime the actual hook return value is loaded, creating a
+verifier/runtime mismatch that can be used to bypass BPF memory safety
+checks.
+
+The else branch already calls mark_reg_unknown() to reset register state
+before any narrowing. Apply the same reset in the is_retval path so
+stale bounds are cleared before __mark_reg_s32_range() intersects.
+
+Fixes: 5d99e198be27 ("bpf, lsm: Add check for BPF LSM return value")
+Cc: stable@vger.kernel.org
+Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
+Acked-by: Eduard Zingerman <eddyz87@gmail.com>
+Link: https://lore.kernel.org/r/20260622230123.3695446-2-tristmd@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 8c3c4ab989a05..77183b436da5e 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -7234,6 +7234,7 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
+                        */
+                       if (reg_type == SCALAR_VALUE) {
+                               if (is_retval && get_func_retval_range(env->prog, &range)) {
++                                      mark_reg_unknown(env, regs, value_regno);
+                                       err = __mark_reg_s32_range(env, regs, value_regno,
+                                                                  range.minval, range.maxval);
+                                       if (err)
+-- 
+2.53.0
+
diff --git a/queue-6.12/hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch b/queue-6.12/hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch
new file mode 100644 (file)
index 0000000..52d73d0
--- /dev/null
@@ -0,0 +1,45 @@
+From d75f6abd34a9c4869d1460c2c89f5fdcf2a400e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Apr 2026 16:03:07 +0200
+Subject: HID: logitech-dj: fix wrong detection of bad DJ_SHORT output report
+
+From: Benjamin Tissoires <bentiss@kernel.org>
+
+[ Upstream commit 8b9a097eb2fc37b486afd81388c693bf3ab44466 ]
+
+commit b6a57912854e ("HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT
+related user initiated OOB write") assumed that all HID devices attached
+to the logitech-dj driver was having an output report of DJ_SHORT.
+
+However, on the receiver itself, we have 2 other HID device we attach
+here: the mouse emulation and the keyboard emulation. For those devices
+the value of rep is NULL and we are triggered a segfault here.
+
+This is doubly required because logitech-dj also handles non DJ devices
+that might not have the DJ collection.
+
+Fixes: b6a57912854e ("HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT related user initiated OOB write")
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-dj.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index 3a37d61616293..f1e923ed9d1c5 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1797,7 +1797,8 @@ static int logi_dj_probe(struct hid_device *hdev,
+       output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
+       rep = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
+-      if (rep->maxfield < 1 || rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1) {
++      if (rep && (rep->maxfield < 1 ||
++                  rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1)) {
+               hid_err(hdev, "Expected size of DJ short report is %d, but got %d",
+                       DJREPORT_SHORT_LENGTH - 1, rep->field[0]->report_count);
+               return -EINVAL;
+-- 
+2.53.0
+
diff --git a/queue-6.12/hid-logitech-dj-prevent-report_id_dj_short-related-u.patch b/queue-6.12/hid-logitech-dj-prevent-report_id_dj_short-related-u.patch
new file mode 100644 (file)
index 0000000..8c52517
--- /dev/null
@@ -0,0 +1,56 @@
+From a80e23c37e2d91de5a333d0b5e196bbf4612c535 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Mar 2026 14:36:44 +0000
+Subject: HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT related user initiated
+ OOB write
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit b6a57912854e7ea36f3b270032661140cc4209cd ]
+
+logi_dj_recv_send_report() assumes that all incoming REPORT_ID_DJ_SHORT
+reports are 14 Bytes (DJREPORT_SHORT_LENGTH - 1) long.  It uses that
+assumption to load the associated field's 'value' array with 14 Bytes of
+data.  However, if a malicious user only sends say 1 Byte of data,
+'report_count' will be 1 and only 1 Byte of memory will be allocated to
+the 'value' Byte array.  When we come to populate 'value[1-13]' we will
+experience an OOB write.
+
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-dj.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index d6fb7015f0d77..3a37d61616293 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1750,6 +1750,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+                        const struct hid_device_id *id)
+ {
+       struct hid_report_enum *input_report_enum;
++      struct hid_report_enum *output_report_enum;
+       struct hid_report *rep;
+       struct dj_receiver_dev *djrcv_dev;
+       struct usb_interface *intf;
+@@ -1793,6 +1794,15 @@ static int logi_dj_probe(struct hid_device *hdev,
+               }
+       }
++      output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
++      rep = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
++
++      if (rep->maxfield < 1 || rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1) {
++              hid_err(hdev, "Expected size of DJ short report is %d, but got %d",
++                      DJREPORT_SHORT_LENGTH - 1, rep->field[0]->report_count);
++              return -EINVAL;
++      }
++
+       input_report_enum = &hdev->report_enum[HID_INPUT_REPORT];
+       /* no input reports, bail out */
+-- 
+2.53.0
+
diff --git a/queue-6.12/hid-logitech-dj-standardise-hid_report_enum-variable.patch b/queue-6.12/hid-logitech-dj-standardise-hid_report_enum-variable.patch
new file mode 100644 (file)
index 0000000..17f2d12
--- /dev/null
@@ -0,0 +1,78 @@
+From 3a52e2a64369a845f434ac2eb131f1fce5f707b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Mar 2026 14:36:43 +0000
+Subject: HID: logitech-dj: Standardise hid_report_enum variable nomenclature
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit a940aee176437046598dfc786b719bd96db3c74c ]
+
+Since we will need to differentiate between the two report_enum types
+soon, let's unify the naming conventions now to save confusion and/or
+unnecessary/unrelated changes in upcoming commits.
+
+{input,output}_report_enum is used in other places to let's conform.
+
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-dj.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index 3b5412541c925..d6fb7015f0d77 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1749,7 +1749,7 @@ static int logi_dj_raw_event(struct hid_device *hdev,
+ static int logi_dj_probe(struct hid_device *hdev,
+                        const struct hid_device_id *id)
+ {
+-      struct hid_report_enum *rep_enum;
++      struct hid_report_enum *input_report_enum;
+       struct hid_report *rep;
+       struct dj_receiver_dev *djrcv_dev;
+       struct usb_interface *intf;
+@@ -1793,10 +1793,10 @@ static int logi_dj_probe(struct hid_device *hdev,
+               }
+       }
+-      rep_enum = &hdev->report_enum[HID_INPUT_REPORT];
++      input_report_enum = &hdev->report_enum[HID_INPUT_REPORT];
+       /* no input reports, bail out */
+-      if (list_empty(&rep_enum->report_list))
++      if (list_empty(&input_report_enum->report_list))
+               return -ENODEV;
+       /*
+@@ -1804,7 +1804,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+        * Note: we should theoretically check for HID++ and DJ
+        * collections, but this will do.
+        */
+-      list_for_each_entry(rep, &rep_enum->report_list, list) {
++      list_for_each_entry(rep, &input_report_enum->report_list, list) {
+               if (rep->application == 0xff000001)
+                       has_hidpp = true;
+       }
+@@ -1817,7 +1817,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+               return -ENODEV;
+       /* get the current application attached to the node */
+-      rep = list_first_entry(&rep_enum->report_list, struct hid_report, list);
++      rep = list_first_entry(&input_report_enum->report_list, struct hid_report, list);
+       djrcv_dev = dj_get_receiver_dev(hdev, id->driver_data,
+                                       rep->application, has_hidpp);
+       if (!djrcv_dev) {
+@@ -1825,7 +1825,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+               return -ENOMEM;
+       }
+-      if (!rep_enum->numbered)
++      if (!input_report_enum->numbered)
+               djrcv_dev->unnumbered_application = rep->application;
+       /* Starts the usb device and connects to upper interfaces hiddev and
+-- 
+2.53.0
+
index ab6e78e7a294b54587d2385c76f9c8bd39f5270d..4065f68f20c326c010cc8614c84a9d6a6009f30b 100644 (file)
@@ -11,3 +11,7 @@ um-preserve-errno-within-signal-handler.patch
 netfilter-br_netfilter-reallocate-headroom-if-necess.patch
 net-airoha-fix-register-index-for-tx-fwd-counter-con.patch
 net-mpls-initialize-rtm_tos-in-mpls_getroute.patch
+hid-logitech-dj-standardise-hid_report_enum-variable.patch
+hid-logitech-dj-prevent-report_id_dj_short-related-u.patch
+hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch
+bpf-reset-register-bounds-before-narrowing-retval-ra.patch
diff --git a/queue-6.18/hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch b/queue-6.18/hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch
new file mode 100644 (file)
index 0000000..9551083
--- /dev/null
@@ -0,0 +1,45 @@
+From d0e76b38d261fa5f81eaf56eaaaeb7faa830cf72 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Apr 2026 16:03:07 +0200
+Subject: HID: logitech-dj: fix wrong detection of bad DJ_SHORT output report
+
+From: Benjamin Tissoires <bentiss@kernel.org>
+
+[ Upstream commit 8b9a097eb2fc37b486afd81388c693bf3ab44466 ]
+
+commit b6a57912854e ("HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT
+related user initiated OOB write") assumed that all HID devices attached
+to the logitech-dj driver was having an output report of DJ_SHORT.
+
+However, on the receiver itself, we have 2 other HID device we attach
+here: the mouse emulation and the keyboard emulation. For those devices
+the value of rep is NULL and we are triggered a segfault here.
+
+This is doubly required because logitech-dj also handles non DJ devices
+that might not have the DJ collection.
+
+Fixes: b6a57912854e ("HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT related user initiated OOB write")
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-dj.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index 3a37d61616293..f1e923ed9d1c5 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1797,7 +1797,8 @@ static int logi_dj_probe(struct hid_device *hdev,
+       output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
+       rep = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
+-      if (rep->maxfield < 1 || rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1) {
++      if (rep && (rep->maxfield < 1 ||
++                  rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1)) {
+               hid_err(hdev, "Expected size of DJ short report is %d, but got %d",
+                       DJREPORT_SHORT_LENGTH - 1, rep->field[0]->report_count);
+               return -EINVAL;
+-- 
+2.53.0
+
diff --git a/queue-6.18/hid-logitech-dj-prevent-report_id_dj_short-related-u.patch b/queue-6.18/hid-logitech-dj-prevent-report_id_dj_short-related-u.patch
new file mode 100644 (file)
index 0000000..2123e93
--- /dev/null
@@ -0,0 +1,56 @@
+From b809ec91217abe5e0d246ec07e0a2aa25e9a513c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Mar 2026 14:36:44 +0000
+Subject: HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT related user initiated
+ OOB write
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit b6a57912854e7ea36f3b270032661140cc4209cd ]
+
+logi_dj_recv_send_report() assumes that all incoming REPORT_ID_DJ_SHORT
+reports are 14 Bytes (DJREPORT_SHORT_LENGTH - 1) long.  It uses that
+assumption to load the associated field's 'value' array with 14 Bytes of
+data.  However, if a malicious user only sends say 1 Byte of data,
+'report_count' will be 1 and only 1 Byte of memory will be allocated to
+the 'value' Byte array.  When we come to populate 'value[1-13]' we will
+experience an OOB write.
+
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-dj.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index d6fb7015f0d77..3a37d61616293 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1750,6 +1750,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+                        const struct hid_device_id *id)
+ {
+       struct hid_report_enum *input_report_enum;
++      struct hid_report_enum *output_report_enum;
+       struct hid_report *rep;
+       struct dj_receiver_dev *djrcv_dev;
+       struct usb_interface *intf;
+@@ -1793,6 +1794,15 @@ static int logi_dj_probe(struct hid_device *hdev,
+               }
+       }
++      output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
++      rep = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
++
++      if (rep->maxfield < 1 || rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1) {
++              hid_err(hdev, "Expected size of DJ short report is %d, but got %d",
++                      DJREPORT_SHORT_LENGTH - 1, rep->field[0]->report_count);
++              return -EINVAL;
++      }
++
+       input_report_enum = &hdev->report_enum[HID_INPUT_REPORT];
+       /* no input reports, bail out */
+-- 
+2.53.0
+
diff --git a/queue-6.18/hid-logitech-dj-standardise-hid_report_enum-variable.patch b/queue-6.18/hid-logitech-dj-standardise-hid_report_enum-variable.patch
new file mode 100644 (file)
index 0000000..9f86c96
--- /dev/null
@@ -0,0 +1,78 @@
+From 6d59139f5c5a499fafe011db0173c9e57f1d189b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Mar 2026 14:36:43 +0000
+Subject: HID: logitech-dj: Standardise hid_report_enum variable nomenclature
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit a940aee176437046598dfc786b719bd96db3c74c ]
+
+Since we will need to differentiate between the two report_enum types
+soon, let's unify the naming conventions now to save confusion and/or
+unnecessary/unrelated changes in upcoming commits.
+
+{input,output}_report_enum is used in other places to let's conform.
+
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-dj.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index 3b5412541c925..d6fb7015f0d77 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1749,7 +1749,7 @@ static int logi_dj_raw_event(struct hid_device *hdev,
+ static int logi_dj_probe(struct hid_device *hdev,
+                        const struct hid_device_id *id)
+ {
+-      struct hid_report_enum *rep_enum;
++      struct hid_report_enum *input_report_enum;
+       struct hid_report *rep;
+       struct dj_receiver_dev *djrcv_dev;
+       struct usb_interface *intf;
+@@ -1793,10 +1793,10 @@ static int logi_dj_probe(struct hid_device *hdev,
+               }
+       }
+-      rep_enum = &hdev->report_enum[HID_INPUT_REPORT];
++      input_report_enum = &hdev->report_enum[HID_INPUT_REPORT];
+       /* no input reports, bail out */
+-      if (list_empty(&rep_enum->report_list))
++      if (list_empty(&input_report_enum->report_list))
+               return -ENODEV;
+       /*
+@@ -1804,7 +1804,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+        * Note: we should theoretically check for HID++ and DJ
+        * collections, but this will do.
+        */
+-      list_for_each_entry(rep, &rep_enum->report_list, list) {
++      list_for_each_entry(rep, &input_report_enum->report_list, list) {
+               if (rep->application == 0xff000001)
+                       has_hidpp = true;
+       }
+@@ -1817,7 +1817,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+               return -ENODEV;
+       /* get the current application attached to the node */
+-      rep = list_first_entry(&rep_enum->report_list, struct hid_report, list);
++      rep = list_first_entry(&input_report_enum->report_list, struct hid_report, list);
+       djrcv_dev = dj_get_receiver_dev(hdev, id->driver_data,
+                                       rep->application, has_hidpp);
+       if (!djrcv_dev) {
+@@ -1825,7 +1825,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+               return -ENOMEM;
+       }
+-      if (!rep_enum->numbered)
++      if (!input_report_enum->numbered)
+               djrcv_dev->unnumbered_application = rep->application;
+       /* Starts the usb device and connects to upper interfaces hiddev and
+-- 
+2.53.0
+
diff --git a/queue-6.18/lib-alloc_tag-introduce-mem_alloc_profiling_permanen.patch b/queue-6.18/lib-alloc_tag-introduce-mem_alloc_profiling_permanen.patch
new file mode 100644 (file)
index 0000000..ff5d718
--- /dev/null
@@ -0,0 +1,76 @@
+From d4dbc617c3b8ba03a2d575c12854ce83084b80fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Aug 2026 07:15:10 +0000
+Subject: lib/alloc_tag: introduce mem_alloc_profiling_permanently_disabled()
+
+From: Harry Yoo (Oracle) <harry@kernel.org>
+
+commit a37b0066a10aabf3c968b4566706fb866eaf9a85 upstream.
+
+mem_alloc_profiling_enabled() tells whether memalloc profiling is
+currently enabled. However, even when this function returns false,
+it can be enabled later.
+
+However, this is not enough. Some optimizations can be applied only when
+memalloc profiling is permanently disabled. For example, to skip the
+creation of KMALLOC_NO_OBJ_EXT caches at boot time, mem_profiling must
+be set to "never", "0" w/ debugging on, or have been shutdown so that
+it can no longer be enabled.
+
+Introduce mem_alloc_profiling_permanently_disabled() for this purpose.
+
+Signed-off-by: Harry Yoo (Oracle) <harry@kernel.org>
+Acked-by: Suren Baghdasaryan <surenb@google.com>
+Link: https://patch.msgid.link/20260713-kmalloc-no-objext-v3-3-47c7bd138de7@kernel.org
+Signed-off-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
+Signed-off-by: Harry Yoo <harry@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/alloc_tag.h | 3 +++
+ lib/alloc_tag.c           | 9 +++++++++
+ 2 files changed, 12 insertions(+)
+
+diff --git a/include/linux/alloc_tag.h b/include/linux/alloc_tag.h
+index 02de2ede560f3..7e7cdc7612bed 100644
+--- a/include/linux/alloc_tag.h
++++ b/include/linux/alloc_tag.h
+@@ -134,6 +134,8 @@ static inline bool mem_alloc_profiling_enabled(void)
+                                  &mem_alloc_profiling_key);
+ }
++bool mem_alloc_profiling_permanently_disabled(void);
++
+ static inline struct alloc_tag_counters alloc_tag_read(struct alloc_tag *tag)
+ {
+       struct alloc_tag_counters v = { 0, 0 };
+@@ -239,6 +241,7 @@ static inline bool alloc_tag_is_inaccurate(struct alloc_tag *tag)
+ #define DEFINE_ALLOC_TAG(_alloc_tag)
+ static inline bool mem_alloc_profiling_enabled(void) { return false; }
++static inline bool mem_alloc_profiling_permanently_disabled(void) { return true; }
+ static inline void alloc_tag_add(union codetag_ref *ref, struct alloc_tag *tag,
+                                size_t bytes) {}
+ static inline void alloc_tag_sub(union codetag_ref *ref, size_t bytes) {}
+diff --git a/lib/alloc_tag.c b/lib/alloc_tag.c
+index 3082d977efaae..7c6d3a086fdc4 100644
+--- a/lib/alloc_tag.c
++++ b/lib/alloc_tag.c
+@@ -26,6 +26,15 @@ static bool mem_profiling_support = true;
+ static bool mem_profiling_support;
+ #endif
++/*
++ * Memory allocation profiling is permanently disabled and cannot be enabled.
++ * Must be called after setup_early_mem_profiling().
++ */
++bool mem_alloc_profiling_permanently_disabled(void)
++{
++      return !mem_profiling_support;
++}
++
+ static struct codetag_type *alloc_tag_cttype;
+ #ifdef CONFIG_ARCH_MODULE_NEEDS_WEAK_PER_CPU
+-- 
+2.53.0
+
diff --git a/queue-6.18/mm-slab-prevent-unbounded-recursion-in-free-path-wit.patch b/queue-6.18/mm-slab-prevent-unbounded-recursion-in-free-path-wit.patch
new file mode 100644 (file)
index 0000000..8e90ac6
--- /dev/null
@@ -0,0 +1,387 @@
+From 34dcda1699b4a6e0c983ffb0983fc875fb41f4b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Aug 2026 07:15:11 +0000
+Subject: mm/slab: prevent unbounded recursion in free path with new kmalloc
+ type
+
+From: Harry Yoo (Oracle) <harry@kernel.org>
+
+commit d9e6a7623938968e3752b67e37eaff097e559a54 upstream.
+
+Commit 280ea9c3154b ("mm/slab: avoid allocating slabobj_ext array from
+its own slab") avoided recursive allocation of obj_exts from kmalloc
+caches of the same size, by bumping the obj_exts array's allocation
+size whenever the array size equals the size of the object being
+allocated.
+
+However, as reported by Danielle Costantino and Shakeel Butt,
+even slabs from kmalloc caches of different sizes can form a cycle
+by allocating obj_exts arrays from each other [1]:
+
+  What happened: a KMALLOC_NORMAL slab's obj_exts array (used by
+  allocation profiling / memcg accounting) is itself kmalloc()'d from a
+  KMALLOC_NORMAL cache, so the "slab holds another slab's obj_exts array"
+  relation can form cycles. With sizeof(struct slabobj_ext) == 16 and
+  the host's geometry:
+
+  - kmalloc-512 has 64 objects/slab -> array is 64*16 == 1024 bytes,
+    served from kmalloc-1k;
+  - kmalloc-1k  has 32 objects/slab -> array is 32*16 ==  512 bytes,
+    served from kmalloc-512.
+
+  A kmalloc-512 slab and a kmalloc-1k slab therefore hold each other's
+  obj_exts array.  Discarding one frees the other's array, which empties
+  and discards that slab, which frees the first's array, and so on:
+  __free_slab() -> free_slab_obj_exts() -> kfree() -> discard_slab() ->
+  __free_slab() recurses along the cycle until the stack is exhausted.
+
+With memory allocation profiling, this allows unbounded recursion
+in the free path and led to a stack overflow on a production host in
+the Meta fleet [1]:
+
+  BUG: TASK stack guard page was hit
+  Oops: stack guard page
+  RIP: 0010:kfree+0x8/0x5d0
+  Call Trace:
+   __free_slab+0x66/0xc0
+   kfree+0x3f0/0x5d0
+   ... ( ~125x __free_slab <-> kfree ) ...
+   <kernel driver freeing a resource>
+   do_syscall_64
+
+It is proposed [1] to resolve this issue by always serving the obj_exts
+array allocation from kmalloc caches (or large kmalloc) of sizes larger
+than the object size. However, as pointed out by Vlastimil Babka [2],
+this can waste an excessive amount of memory as slabs from large
+kmalloc sizes (e.g. kmalloc-8k) generally need obj_exts arrays much
+smaller than the object size.
+
+Therefore, rather than bumping the size, let us take a different
+approach; disallow formation of cycles between kmalloc types when
+allocating obj_exts arrays. Currently, all obj_exts arrays are served
+from normal kmalloc caches. Cycles cannot be created if obj_exts arrays
+of normal kmalloc caches are served from a special kmalloc type that can
+never have obj_exts arrays.
+
+To achieve this, create a new kmalloc type called KMALLOC_NO_OBJ_EXT.
+KMALLOC_NO_OBJ_EXT caches are created with SLAB_NO_OBJ_EXT flag when
+either 1) memory allocation profiling is not permanently disabled,
+or 2) kmalloc types with a priority higher than KMALLOC_CGROUP are
+aliased with KMALLOC_NORMAL.
+
+Sheaf bootstrapping for KMALLOC_NO_OBJ_EXT caches now must be deferred
+because allocation of a barn can trigger obj_exts array allocation of
+normal kmalloc caches when the KMALLOC_NO_OBJ_EXT cache for that size
+is not ready yet. For simplicity, perform bootstrapping of sheaves for
+all kmalloc caches later.
+
+Introduce a new slab alloc flag, SLAB_ALLOC_NO_OBJ_EXT, to prevent
+allocation of obj_exts arrays, and let kmalloc_slab() override the type
+to KMALLOC_NO_OBJ_EXT when specified. Note that kmalloc_type() remains
+unchanged because kmalloc_flags() bypasses the kmalloc fastpath.
+
+Do not pass SLAB_ALLOC_NO_RECURSE to kmalloc_flags() in
+alloc_slab_obj_exts() and instead use SLAB_ALLOC_NO_OBJ_EXT only when
+the objects are allocated from normal kmalloc caches. While this
+prevents unbounded recursive allocation of obj_exts, it allows
+KMALLOC_NO_OBJ_EXT caches to have sheaves.
+
+Since sheaf allocations specify SLAB_ALLOC_NO_RECURSE that prevents
+allocation of both sheaves and obj_exts arrays, the recursion depth
+is bounded.
+
+obj_exts arrays for non-kmalloc-normal caches can now have a valid tag.
+Do not call mark_obj_codetag_empty() when freeing an obj_exts array to
+avoid false warnings. KMALLOC_NO_OBJ_EXT don't need this as they never
+allocate those arrays.
+
+Reported-by: Danielle Costantino <dcostantino@meta.com>
+Reported-by: Shakeel Butt <shakeel.butt@linux.dev>
+Closes: https://lore.kernel.org/linux-mm/20260625230029.703750-1-shakeel.butt@linux.dev [1]
+Fixes: 4b8736964640 ("mm/slab: add allocation accounting into slab allocation and free paths")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/linux-mm/c5c4208d-a6f0-413e-bad9-49be12f12d55@kernel.org [2]
+Signed-off-by: Harry Yoo (Oracle) <harry@kernel.org>
+Reviewed-by: Suren Baghdasaryan <surenb@google.com>
+Link: https://patch.msgid.link/20260713-kmalloc-no-objext-v3-4-47c7bd138de7@kernel.org
+Signed-off-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
+[harry@kernel.org: Backport notes:
+ - Fix a minor conflict due to missing partitioned
+   kmalloc caches in 6.18.
+
+ - Use __GFP_NO_OBJ_EXT instead of SLAB_ALLOC_NO_OBJ_EXT
+   since slab's internal alloc_flags do not exist in 6.18.
+
+ - Deferring sheaf bootstrapping for kmalloc caches is not applied
+   as they don't have sheaves in 6.18.
+
+ - Adjust the comment for SLAB_NO_OBJ_EXT, like in the commit
+   982e31382d9a ("mm/slab: decouple SLAB_NO_SHEAVES from
+   SLAB_NO_OBJ_EXT"). The rest of that commit is a no-op in 6.18 as
+   kmalloc caches don't have sheaves and thus only adjust the comment.
+
+ - Apply the __GFP_NO_OBJ_EXT flag to the !allow_spin path in
+   alloc_slab_obj_exts(). ]
+Signed-off-by: Harry Yoo <harry@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/slab.h |  8 ++++-
+ mm/slab.h            | 28 ++++++++++++++--
+ mm/slab_common.c     | 13 ++++++++
+ mm/slub.c            | 76 ++++++++++++++------------------------------
+ 4 files changed, 70 insertions(+), 55 deletions(-)
+
+diff --git a/include/linux/slab.h b/include/linux/slab.h
+index 22daf3f34a76f..a12601cc93a1b 100644
+--- a/include/linux/slab.h
++++ b/include/linux/slab.h
+@@ -238,7 +238,7 @@ enum _slab_flag_bits {
+ #endif
+ #define SLAB_TEMPORARY                SLAB_RECLAIM_ACCOUNT    /* Objects are short-lived */
+-/* Slab created using create_boot_cache */
++/* Slab caches without obj_exts array */
+ #ifdef CONFIG_SLAB_OBJ_EXT
+ #define SLAB_NO_OBJ_EXT               __SLAB_FLAG_BIT(_SLAB_NO_OBJ_EXT)
+ #else
+@@ -641,6 +641,9 @@ enum kmalloc_cache_type {
+ #endif
+ #ifndef CONFIG_MEMCG
+       KMALLOC_CGROUP = KMALLOC_NORMAL,
++#endif
++#ifndef CONFIG_SLAB_OBJ_EXT
++      KMALLOC_NO_OBJ_EXT = KMALLOC_NORMAL,
+ #endif
+       KMALLOC_RANDOM_START = KMALLOC_NORMAL,
+       KMALLOC_RANDOM_END = KMALLOC_RANDOM_START + RANDOM_KMALLOC_CACHES_NR,
+@@ -654,6 +657,9 @@ enum kmalloc_cache_type {
+ #endif
+ #ifdef CONFIG_MEMCG
+       KMALLOC_CGROUP,
++#endif
++#ifdef CONFIG_SLAB_OBJ_EXT
++      KMALLOC_NO_OBJ_EXT,
+ #endif
+       NR_KMALLOC_TYPES
+ };
+diff --git a/mm/slab.h b/mm/slab.h
+index 36893299fa67c..c452f2a32c801 100644
+--- a/mm/slab.h
++++ b/mm/slab.h
+@@ -394,9 +394,13 @@ static inline struct kmem_cache *
+ kmalloc_slab(size_t size, kmem_buckets *b, gfp_t flags, unsigned long caller)
+ {
+       unsigned int index;
++      enum kmalloc_cache_type type = kmalloc_type(flags, caller);
++
++      if (flags & __GFP_NO_OBJ_EXT)
++              type = KMALLOC_NO_OBJ_EXT;
+       if (!b)
+-              b = &kmalloc_caches[kmalloc_type(flags, caller)];
++              b = &kmalloc_caches[type];
+       if (size <= 192)
+               index = kmalloc_size_index[size_index_elem(size)];
+       else
+@@ -435,7 +439,8 @@ static inline bool is_kmalloc_normal(struct kmem_cache *s)
+ {
+       if (!is_kmalloc_cache(s))
+               return false;
+-      return !(s->flags & (SLAB_CACHE_DMA|SLAB_ACCOUNT|SLAB_RECLAIM_ACCOUNT));
++
++      return !(s->flags & (SLAB_CACHE_DMA|SLAB_ACCOUNT|SLAB_RECLAIM_ACCOUNT|SLAB_NO_OBJ_EXT));
+ }
+ bool __kfree_rcu_sheaf(struct kmem_cache *s, void *obj);
+@@ -520,6 +525,25 @@ bool slab_in_kunit_test(void);
+ static inline bool slab_in_kunit_test(void) { return false; }
+ #endif
++/*
++ * Return true if KMALLOC_NORMAL caches may need obj_exts arrays.
++ *
++ * Memory allocation profiling requires obj_exts for all caches.
++ * Memcg usually doesn't need them for normal kmalloc caches, but kmalloc types
++ * with a priority higher than KMALLOC_CGROUP can be aliased with KMALLOC_NORMAL.
++ */
++static inline bool need_kmalloc_no_objext(void)
++{
++      if (!mem_alloc_profiling_permanently_disabled())
++              return true;
++
++      if (!mem_cgroup_kmem_disabled() &&
++                      (KMALLOC_NORMAL == KMALLOC_RECLAIM))
++              return true;
++
++      return false;
++}
++
+ #ifdef CONFIG_SLAB_OBJ_EXT
+ /*
+diff --git a/mm/slab_common.c b/mm/slab_common.c
+index 04583044a2bf0..085af9a96fd92 100644
+--- a/mm/slab_common.c
++++ b/mm/slab_common.c
+@@ -803,6 +803,12 @@ EXPORT_SYMBOL(kmalloc_size_roundup);
+ #define KMALLOC_RANDOM_NAME(N, sz)
+ #endif
++#ifdef CONFIG_SLAB_OBJ_EXT
++#define KMALLOC_NO_OBJ_EXT_NAME(sz) .name[KMALLOC_NO_OBJ_EXT] = "kmalloc-no-objext-" #sz,
++#else
++#define KMALLOC_NO_OBJ_EXT_NAME(sz)
++#endif
++
+ #define INIT_KMALLOC_INFO(__size, __short_size)                       \
+ {                                                             \
+       .name[KMALLOC_NORMAL]  = "kmalloc-" #__short_size,      \
+@@ -810,6 +816,7 @@ EXPORT_SYMBOL(kmalloc_size_roundup);
+       KMALLOC_CGROUP_NAME(__short_size)                       \
+       KMALLOC_DMA_NAME(__short_size)                          \
+       KMALLOC_RANDOM_NAME(RANDOM_KMALLOC_CACHES_NR, __short_size)     \
++      KMALLOC_NO_OBJ_EXT_NAME(__short_size)                   \
+       .size = __size,                                         \
+ }
+@@ -917,6 +924,12 @@ new_kmalloc_cache(int idx, enum kmalloc_cache_type type)
+                       return;
+               }
+               flags |= SLAB_ACCOUNT;
++      } else if (IS_ENABLED(CONFIG_SLAB_OBJ_EXT) && type == KMALLOC_NO_OBJ_EXT) {
++              if (!need_kmalloc_no_objext()) {
++                      kmalloc_caches[type][idx] = kmalloc_caches[KMALLOC_NORMAL][idx];
++                      return;
++              }
++              flags |= SLAB_NO_OBJ_EXT | SLAB_NO_MERGE;
+       } else if (IS_ENABLED(CONFIG_ZONE_DMA) && (type == KMALLOC_DMA)) {
+               flags |= SLAB_CACHE_DMA;
+       }
+diff --git a/mm/slub.c b/mm/slub.c
+index 71e09c675047d..5ddd2a5c9e79b 100644
+--- a/mm/slub.c
++++ b/mm/slub.c
+@@ -2096,42 +2096,6 @@ static inline void init_slab_obj_exts(struct slab *slab)
+       slab->obj_exts = 0;
+ }
+-/*
+- * Calculate the allocation size for slabobj_ext array.
+- *
+- * When memory allocation profiling is enabled, the obj_exts array
+- * could be allocated from the same slab cache it's being allocated for.
+- * This would prevent the slab from ever being freed because it would
+- * always contain at least one allocated object (its own obj_exts array).
+- *
+- * To avoid this, increase the allocation size when we detect the array
+- * may come from the same cache, forcing it to use a different cache.
+- */
+-static inline size_t obj_exts_alloc_size(struct kmem_cache *s,
+-                                       struct slab *slab, gfp_t gfp)
+-{
+-      size_t sz = sizeof(struct slabobj_ext) * slab->objects;
+-      struct kmem_cache *obj_exts_cache;
+-
+-      if (sz > KMALLOC_MAX_CACHE_SIZE)
+-              return sz;
+-
+-      if (!is_kmalloc_normal(s))
+-              return sz;
+-
+-      obj_exts_cache = kmalloc_slab(sz, NULL, gfp, 0);
+-      /*
+-       * We can't simply compare s with obj_exts_cache, because random kmalloc
+-       * caches have multiple caches per size, selected by caller address.
+-       * Since caller address may differ between kmalloc_slab() and actual
+-       * allocation, bump size when sizes are equal.
+-       */
+-      if (s->object_size == obj_exts_cache->object_size)
+-              return obj_exts_cache->object_size + 1;
+-
+-      return sz;
+-}
+-
+ int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s,
+                       gfp_t gfp, bool new_slab)
+ {
+@@ -2140,13 +2104,17 @@ int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s,
+       unsigned long new_exts;
+       unsigned long old_exts;
+       struct slabobj_ext *vec;
+-      size_t sz;
++      size_t sz = sizeof(struct slabobj_ext) * slab->objects;
+       gfp &= ~OBJCGS_CLEAR_MASK;
+-      /* Prevent recursive extension vector allocation */
+-      gfp |= __GFP_NO_OBJ_EXT;
+-      sz = obj_exts_alloc_size(s, slab, gfp);
++      /*
++       * In most cases, obj_exts arrays are allocated from normal kmalloc.
++       * However, normal kmalloc caches must allocate them from
++       * KMALLOC_NO_OBJ_EXT caches to prevent recursion.
++       */
++      if (is_kmalloc_normal(s))
++              gfp |= __GFP_NO_OBJ_EXT;
+       /*
+        * Note that allow_spin may be false during early boot and its
+@@ -2155,7 +2123,7 @@ int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s,
+        * very early allocations on those.
+        */
+       if (unlikely(!allow_spin))
+-              vec = kmalloc_nolock(sz, __GFP_ZERO | __GFP_NO_OBJ_EXT,
++              vec = kmalloc_nolock(sz, __GFP_ZERO | (gfp & __GFP_NO_OBJ_EXT),
+                                    slab_nid(slab));
+       else
+               vec = kmalloc_node(sz, gfp | __GFP_ZERO, slab_nid(slab));
+@@ -2173,8 +2141,21 @@ int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s,
+               return -ENOMEM;
+       }
+-      VM_WARN_ON_ONCE(virt_to_slab(vec) != NULL &&
+-                      virt_to_slab(vec)->slab_cache == s);
++      if (IS_ENABLED(CONFIG_DEBUG_VM)) {
++              struct kmem_cache *exts_cache;
++              struct slab *exts_slab;
++
++              exts_slab = virt_to_slab(vec);
++              if (exts_slab) {
++                      /*
++                       * The vector must be allocated from either normal or
++                       * KMALLOC_NO_OBJ_EXT kmalloc caches to avoid cycles.
++                       */
++                      exts_cache = exts_slab->slab_cache;
++                      WARN_ON_ONCE(!is_kmalloc_normal(exts_cache) &&
++                                      !(exts_cache->flags & SLAB_NO_OBJ_EXT));
++              }
++      }
+       new_exts = (unsigned long)vec;
+       if (unlikely(!allow_spin))
+@@ -2198,7 +2179,6 @@ int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s,
+                * assign slabobj_exts in parallel. In this case the existing
+                * objcg vector should be reused.
+                */
+-              mark_objexts_empty(vec);
+               if (unlikely(!allow_spin))
+                       kfree_nolock(vec);
+               else
+@@ -2229,14 +2209,6 @@ static inline void free_slab_obj_exts(struct slab *slab)
+               return;
+       }
+-      /*
+-       * obj_exts was created with __GFP_NO_OBJ_EXT flag, therefore its
+-       * corresponding extension will be NULL. alloc_tag_sub() will throw a
+-       * warning if slab has extensions but the extension of an object is
+-       * NULL, therefore replace NULL with CODETAG_EMPTY to indicate that
+-       * the extension for obj_exts is expected to be NULL.
+-       */
+-      mark_objexts_empty(obj_exts);
+       if (unlikely(READ_ONCE(slab->obj_exts) & OBJEXTS_NOSPIN_ALLOC))
+               kfree_nolock(obj_exts);
+       else
+-- 
+2.53.0
+
index f4d8d3fb1c9e432524f27a2bb325945f90c2c25d..f19915941179f160847b09473517a0b76b755fb4 100644 (file)
@@ -5,3 +5,8 @@ netfilter-br_netfilter-reallocate-headroom-if-necess.patch
 net-mpls-initialize-rtm_tos-in-mpls_getroute.patch
 drm-gpusvm-publish-dpagemap-early-to-avoid-device-ma.patch
 alsa-hda-realtek-add-quirk-for-hp-dragonfly-folio-g3.patch
+hid-logitech-dj-standardise-hid_report_enum-variable.patch
+hid-logitech-dj-prevent-report_id_dj_short-related-u.patch
+hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch
+lib-alloc_tag-introduce-mem_alloc_profiling_permanen.patch
+mm-slab-prevent-unbounded-recursion-in-free-path-wit.patch
diff --git a/queue-6.6/hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch b/queue-6.6/hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch
new file mode 100644 (file)
index 0000000..143e7d4
--- /dev/null
@@ -0,0 +1,45 @@
+From c3237696fdc9e7161d3e93a03611348bd8695af0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Apr 2026 16:03:07 +0200
+Subject: HID: logitech-dj: fix wrong detection of bad DJ_SHORT output report
+
+From: Benjamin Tissoires <bentiss@kernel.org>
+
+[ Upstream commit 8b9a097eb2fc37b486afd81388c693bf3ab44466 ]
+
+commit b6a57912854e ("HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT
+related user initiated OOB write") assumed that all HID devices attached
+to the logitech-dj driver was having an output report of DJ_SHORT.
+
+However, on the receiver itself, we have 2 other HID device we attach
+here: the mouse emulation and the keyboard emulation. For those devices
+the value of rep is NULL and we are triggered a segfault here.
+
+This is doubly required because logitech-dj also handles non DJ devices
+that might not have the DJ collection.
+
+Fixes: b6a57912854e ("HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT related user initiated OOB write")
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-dj.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index 3529fb55689a1..5ab415939da0f 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1797,7 +1797,8 @@ static int logi_dj_probe(struct hid_device *hdev,
+       output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
+       rep = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
+-      if (rep->maxfield < 1 || rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1) {
++      if (rep && (rep->maxfield < 1 ||
++                  rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1)) {
+               hid_err(hdev, "Expected size of DJ short report is %d, but got %d",
+                       DJREPORT_SHORT_LENGTH - 1, rep->field[0]->report_count);
+               return -EINVAL;
+-- 
+2.53.0
+
diff --git a/queue-6.6/hid-logitech-dj-prevent-report_id_dj_short-related-u.patch b/queue-6.6/hid-logitech-dj-prevent-report_id_dj_short-related-u.patch
new file mode 100644 (file)
index 0000000..39824f0
--- /dev/null
@@ -0,0 +1,56 @@
+From a0666095694a93acbfb27236469ac017abe79be7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Mar 2026 14:36:44 +0000
+Subject: HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT related user initiated
+ OOB write
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit b6a57912854e7ea36f3b270032661140cc4209cd ]
+
+logi_dj_recv_send_report() assumes that all incoming REPORT_ID_DJ_SHORT
+reports are 14 Bytes (DJREPORT_SHORT_LENGTH - 1) long.  It uses that
+assumption to load the associated field's 'value' array with 14 Bytes of
+data.  However, if a malicious user only sends say 1 Byte of data,
+'report_count' will be 1 and only 1 Byte of memory will be allocated to
+the 'value' Byte array.  When we come to populate 'value[1-13]' we will
+experience an OOB write.
+
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-dj.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index 8b14a6062d181..3529fb55689a1 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1750,6 +1750,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+                        const struct hid_device_id *id)
+ {
+       struct hid_report_enum *input_report_enum;
++      struct hid_report_enum *output_report_enum;
+       struct hid_report *rep;
+       struct dj_receiver_dev *djrcv_dev;
+       struct usb_interface *intf;
+@@ -1793,6 +1794,15 @@ static int logi_dj_probe(struct hid_device *hdev,
+               }
+       }
++      output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
++      rep = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
++
++      if (rep->maxfield < 1 || rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1) {
++              hid_err(hdev, "Expected size of DJ short report is %d, but got %d",
++                      DJREPORT_SHORT_LENGTH - 1, rep->field[0]->report_count);
++              return -EINVAL;
++      }
++
+       input_report_enum = &hdev->report_enum[HID_INPUT_REPORT];
+       /* no input reports, bail out */
+-- 
+2.53.0
+
diff --git a/queue-6.6/hid-logitech-dj-standardise-hid_report_enum-variable.patch b/queue-6.6/hid-logitech-dj-standardise-hid_report_enum-variable.patch
new file mode 100644 (file)
index 0000000..dbf08e9
--- /dev/null
@@ -0,0 +1,78 @@
+From f17a309ce10913e688ef1cacb7ae6da4cd92a57b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Mar 2026 14:36:43 +0000
+Subject: HID: logitech-dj: Standardise hid_report_enum variable nomenclature
+
+From: Lee Jones <lee@kernel.org>
+
+[ Upstream commit a940aee176437046598dfc786b719bd96db3c74c ]
+
+Since we will need to differentiate between the two report_enum types
+soon, let's unify the naming conventions now to save confusion and/or
+unnecessary/unrelated changes in upcoming commits.
+
+{input,output}_report_enum is used in other places to let's conform.
+
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-dj.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index 84ad70c9d0383..8b14a6062d181 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -1749,7 +1749,7 @@ static int logi_dj_raw_event(struct hid_device *hdev,
+ static int logi_dj_probe(struct hid_device *hdev,
+                        const struct hid_device_id *id)
+ {
+-      struct hid_report_enum *rep_enum;
++      struct hid_report_enum *input_report_enum;
+       struct hid_report *rep;
+       struct dj_receiver_dev *djrcv_dev;
+       struct usb_interface *intf;
+@@ -1793,10 +1793,10 @@ static int logi_dj_probe(struct hid_device *hdev,
+               }
+       }
+-      rep_enum = &hdev->report_enum[HID_INPUT_REPORT];
++      input_report_enum = &hdev->report_enum[HID_INPUT_REPORT];
+       /* no input reports, bail out */
+-      if (list_empty(&rep_enum->report_list))
++      if (list_empty(&input_report_enum->report_list))
+               return -ENODEV;
+       /*
+@@ -1804,7 +1804,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+        * Note: we should theoretically check for HID++ and DJ
+        * collections, but this will do.
+        */
+-      list_for_each_entry(rep, &rep_enum->report_list, list) {
++      list_for_each_entry(rep, &input_report_enum->report_list, list) {
+               if (rep->application == 0xff000001)
+                       has_hidpp = true;
+       }
+@@ -1817,7 +1817,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+               return -ENODEV;
+       /* get the current application attached to the node */
+-      rep = list_first_entry(&rep_enum->report_list, struct hid_report, list);
++      rep = list_first_entry(&input_report_enum->report_list, struct hid_report, list);
+       djrcv_dev = dj_get_receiver_dev(hdev, id->driver_data,
+                                       rep->application, has_hidpp);
+       if (!djrcv_dev) {
+@@ -1825,7 +1825,7 @@ static int logi_dj_probe(struct hid_device *hdev,
+               return -ENOMEM;
+       }
+-      if (!rep_enum->numbered)
++      if (!input_report_enum->numbered)
+               djrcv_dev->unnumbered_application = rep->application;
+       /* Starts the usb device and connects to upper interfaces hiddev and
+-- 
+2.53.0
+
index e69d2a50065a5c09412138bfdf27bcde35a2a1db..6542c4811d0a5f974f3843843c51475df24d6555 100644 (file)
@@ -2,3 +2,7 @@ netfilter-nf_conntrack_expect-restore-helper-propaga.patch
 netfilter-br_netfilter-reallocate-headroom-if-necess.patch
 net-mpls-initialize-rtm_tos-in-mpls_getroute.patch
 gve-fix-rx-queue-stall-on-alloc-failure.patch
+hid-logitech-dj-standardise-hid_report_enum-variable.patch
+hid-logitech-dj-prevent-report_id_dj_short-related-u.patch
+hid-logitech-dj-fix-wrong-detection-of-bad-dj_short-.patch
+soc-qcom-ice-allow-explicit-votes-on-iface-clock-for.patch
diff --git a/queue-6.6/soc-qcom-ice-allow-explicit-votes-on-iface-clock-for.patch b/queue-6.6/soc-qcom-ice-allow-explicit-votes-on-iface-clock-for.patch
new file mode 100644 (file)
index 0000000..5847379
--- /dev/null
@@ -0,0 +1,87 @@
+From 99d8af7cf74840aa93ef05e972c633d7c3dc452b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Apr 2026 17:29:19 +0530
+Subject: soc: qcom: ice: Allow explicit votes on 'iface' clock for ICE
+
+From: Harshal Dev <harshal.dev@oss.qualcomm.com>
+
+[ Upstream commit 0d5dc5818191b55e4364d04b1b898a14a2ccac38 ]
+
+Since Qualcomm inline-crypto engine (ICE) is now a dedicated driver
+de-coupled from the QCOM UFS driver, it explicitly votes for its required
+clocks during probe. For scenarios where the 'clk_ignore_unused' flag is
+not passed on the kernel command line, to avoid potential unclocked ICE
+hardware register access during probe the ICE driver should additionally
+vote on the 'iface' clock.
+Also update the suspend and resume callbacks to handle un-voting and voting
+on the 'iface' clock.
+
+Fixes: 2afbf43a4aec6 ("soc: qcom: Make the Qualcomm UFS/SDCC ICE a dedicated driver")
+Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
+Reviewed-by: Kuldeep Singh <kuldeep.singh@oss.qualcomm.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Signed-off-by: Harshal Dev <harshal.dev@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20260416-qcom_ice_power_and_clk_vote-v5-2-5ccf5d7e2846@oss.qualcomm.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/ice.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/soc/qcom/ice.c b/drivers/soc/qcom/ice.c
+index 94e91835062b2..b20214027fc26 100644
+--- a/drivers/soc/qcom/ice.c
++++ b/drivers/soc/qcom/ice.c
+@@ -48,6 +48,7 @@ struct qcom_ice {
+       struct device_link *link;
+       struct clk *core_clk;
++      struct clk *iface_clk;
+ };
+ static DEFINE_XARRAY(ice_handles);
+@@ -149,8 +150,13 @@ int qcom_ice_resume(struct qcom_ice *ice)
+       err = clk_prepare_enable(ice->core_clk);
+       if (err) {
+-              dev_err(dev, "failed to enable core clock (%d)\n",
+-                      err);
++              dev_err(dev, "Failed to enable core clock: %d\n", err);
++              return err;
++      }
++
++      err = clk_prepare_enable(ice->iface_clk);
++      if (err) {
++              dev_err(dev, "Failed to enable iface clock: %d\n", err);
+               return err;
+       }
+@@ -160,6 +166,7 @@ EXPORT_SYMBOL_GPL(qcom_ice_resume);
+ int qcom_ice_suspend(struct qcom_ice *ice)
+ {
++      clk_disable_unprepare(ice->iface_clk);
+       clk_disable_unprepare(ice->core_clk);
+       return 0;
+@@ -240,11 +247,17 @@ static struct qcom_ice *qcom_ice_create(struct device *dev,
+       engine->core_clk = devm_clk_get_optional_enabled(dev, "ice_core_clk");
+       if (!engine->core_clk)
+               engine->core_clk = devm_clk_get_optional_enabled(dev, "ice");
++      if (!engine->core_clk)
++              engine->core_clk = devm_clk_get_optional_enabled(dev, "core");
+       if (!engine->core_clk)
+               engine->core_clk = devm_clk_get_enabled(dev, NULL);
+       if (IS_ERR(engine->core_clk))
+               return ERR_CAST(engine->core_clk);
++      engine->iface_clk = devm_clk_get_optional_enabled(dev, "iface");
++      if (IS_ERR(engine->iface_clk))
++              return ERR_CAST(engine->iface_clk);
++
+       if (!qcom_ice_check_supported(engine))
+               return ERR_PTR(-EOPNOTSUPP);
+-- 
+2.53.0
+