* [PATCH 6.12 001/877] Revert "hwmon: (emc1403) Drop hysteresis for low limit temperature"
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 002/877] Revert "hwmon: (emc1403) Rely on subsystem locking" Greg Kroah-Hartman
` (883 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
This reverts commit 5cc075ffa1c986474c1f56ba6f869dcc41a363d4.
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/hwmon/emc1403.rst | 8 ++++----
drivers/hwmon/emc1403.c | 27 ++++++++++++++++-----------
2 files changed, 20 insertions(+), 15 deletions(-)
diff --git a/Documentation/hwmon/emc1403.rst b/Documentation/hwmon/emc1403.rst
index ebf2435a76a62..57f833b1a800e 100644
--- a/Documentation/hwmon/emc1403.rst
+++ b/Documentation/hwmon/emc1403.rst
@@ -71,10 +71,10 @@ and EMC14x8 support eight sensors (one internal, seven external).
The chips implement three limits for each sensor: low (tempX_min), high
(tempX_max) and critical (tempX_crit.) The chips also implement an
-hysteresis mechanism which applies to high and critical limits. The relative
-difference is stored in a single register on the chip, which means that the
-relative difference between the limit and its hysteresis is always the same
-for high and critical limits.
+hysteresis mechanism which applies to all limits. The relative difference
+is stored in a single register on the chip, which means that the relative
+difference between the limit and its hysteresis is always the same for
+all three limits.
This implementation detail implies the following:
diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c
index 39f69adb88c25..ccce948a4306e 100644
--- a/drivers/hwmon/emc1403.c
+++ b/drivers/hwmon/emc1403.c
@@ -305,9 +305,10 @@ static int emc1403_get_hyst(struct thermal_data *data, int channel,
ret = regmap_read(data->regmap, 0x21, &hyst);
if (ret < 0)
return ret;
-
- *val = limit - hyst * 1000;
-
+ if (map == temp_min)
+ *val = limit + hyst * 1000;
+ else
+ *val = limit - hyst * 1000;
return 0;
}
@@ -323,6 +324,9 @@ static int emc1403_temp_read(struct thermal_data *data, u32 attr, int channel, l
case hwmon_temp_input:
ret = emc1403_get_temp(data, channel, ema1403_temp_map[attr], val);
break;
+ case hwmon_temp_min_hyst:
+ ret = emc1403_get_hyst(data, channel, temp_min, val);
+ break;
case hwmon_temp_max_hyst:
ret = emc1403_get_hyst(data, channel, temp_max, val);
break;
@@ -544,6 +548,7 @@ static umode_t emc1403_temp_is_visible(const void *_data, u32 attr, int channel)
case hwmon_temp_max_alarm:
case hwmon_temp_crit_alarm:
case hwmon_temp_fault:
+ case hwmon_temp_min_hyst:
case hwmon_temp_max_hyst:
return 0444;
case hwmon_temp_min:
@@ -586,35 +591,35 @@ static const struct hwmon_channel_info * const emc1403_info[] = {
HWMON_CHANNEL_INFO(chip, HWMON_C_UPDATE_INTERVAL),
HWMON_CHANNEL_INFO(temp,
HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
- HWMON_T_CRIT | HWMON_T_MAX_HYST |
+ HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |
HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM,
HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
- HWMON_T_CRIT | HWMON_T_MAX_HYST |
+ HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |
HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT,
HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
- HWMON_T_CRIT | HWMON_T_MAX_HYST |
+ HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |
HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT,
HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
- HWMON_T_CRIT | HWMON_T_MAX_HYST |
+ HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |
HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT,
HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
- HWMON_T_CRIT | HWMON_T_MAX_HYST |
+ HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |
HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT,
HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
- HWMON_T_CRIT | HWMON_T_MAX_HYST |
+ HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |
HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT,
HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
- HWMON_T_CRIT | HWMON_T_MAX_HYST |
+ HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |
HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT,
HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
- HWMON_T_CRIT | HWMON_T_MAX_HYST |
+ HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |
HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT
),
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 002/877] Revert "hwmon: (emc1403) Rely on subsystem locking"
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 001/877] Revert "hwmon: (emc1403) Drop hysteresis for low limit temperature" Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 003/877] landlock: Fix TCP Fast Open connection bypass Greg Kroah-Hartman
` (882 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
This reverts commit 52dfb8be29d9918c40b512f3d65529f88304afe4.
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/emc1403.c | 46 ++++++++++++++++++++++++++++++++---------
1 file changed, 36 insertions(+), 10 deletions(-)
diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c
index ccce948a4306e..eca33220d34a0 100644
--- a/drivers/hwmon/emc1403.c
+++ b/drivers/hwmon/emc1403.c
@@ -17,6 +17,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/sysfs.h>
+#include <linux/mutex.h>
#include <linux/regmap.h>
#include <linux/util_macros.h>
@@ -29,6 +30,7 @@ enum emc1403_chip { emc1402, emc1403, emc1404, emc1428 };
struct thermal_data {
enum emc1403_chip chip;
struct regmap *regmap;
+ struct mutex mutex;
};
static ssize_t power_state_show(struct device *dev, struct device_attribute *attr, char *buf)
@@ -266,8 +268,8 @@ static s8 emc1403_temp_regs_low[][4] = {
},
};
-static int emc1403_get_temp(struct thermal_data *data, int channel,
- enum emc1403_reg_map map, long *val)
+static int __emc1403_get_temp(struct thermal_data *data, int channel,
+ enum emc1403_reg_map map, long *val)
{
unsigned int regvalh;
unsigned int regvall = 0;
@@ -293,23 +295,38 @@ static int emc1403_get_temp(struct thermal_data *data, int channel,
return 0;
}
+static int emc1403_get_temp(struct thermal_data *data, int channel,
+ enum emc1403_reg_map map, long *val)
+{
+ int ret;
+
+ mutex_lock(&data->mutex);
+ ret = __emc1403_get_temp(data, channel, map, val);
+ mutex_unlock(&data->mutex);
+
+ return ret;
+}
+
static int emc1403_get_hyst(struct thermal_data *data, int channel,
enum emc1403_reg_map map, long *val)
{
int hyst, ret;
long limit;
- ret = emc1403_get_temp(data, channel, map, &limit);
+ mutex_lock(&data->mutex);
+ ret = __emc1403_get_temp(data, channel, map, &limit);
if (ret < 0)
- return ret;
+ goto unlock;
ret = regmap_read(data->regmap, 0x21, &hyst);
if (ret < 0)
- return ret;
+ goto unlock;
if (map == temp_min)
*val = limit + hyst * 1000;
else
*val = limit - hyst * 1000;
- return 0;
+unlock:
+ mutex_unlock(&data->mutex);
+ return ret;
}
static int emc1403_temp_read(struct thermal_data *data, u32 attr, int channel, long *val)
@@ -434,16 +451,20 @@ static int emc1403_set_hyst(struct thermal_data *data, long val)
else
val = clamp_val(val, 0, 255000);
- ret = emc1403_get_temp(data, 0, temp_crit, &limit);
+ mutex_lock(&data->mutex);
+ ret = __emc1403_get_temp(data, 0, temp_crit, &limit);
if (ret < 0)
- return ret;
+ goto unlock;
hyst = limit - val;
if (data->chip == emc1428)
hyst = clamp_val(DIV_ROUND_CLOSEST(hyst, 1000), 0, 127);
else
hyst = clamp_val(DIV_ROUND_CLOSEST(hyst, 1000), 0, 255);
- return regmap_write(data->regmap, 0x21, hyst);
+ ret = regmap_write(data->regmap, 0x21, hyst);
+unlock:
+ mutex_unlock(&data->mutex);
+ return ret;
}
static int emc1403_set_temp(struct thermal_data *data, int channel,
@@ -457,6 +478,7 @@ static int emc1403_set_temp(struct thermal_data *data, int channel,
regh = emc1403_temp_regs[channel][map];
regl = emc1403_temp_regs_low[channel][map];
+ mutex_lock(&data->mutex);
if (regl >= 0) {
if (data->chip == emc1428)
val = clamp_val(val, -128000, 127875);
@@ -465,7 +487,7 @@ static int emc1403_set_temp(struct thermal_data *data, int channel,
regval = DIV_ROUND_CLOSEST(val, 125);
ret = regmap_write(data->regmap, regh, (regval >> 3) & 0xff);
if (ret < 0)
- return ret;
+ goto unlock;
ret = regmap_write(data->regmap, regl, (regval & 0x07) << 5);
} else {
if (data->chip == emc1428)
@@ -475,6 +497,8 @@ static int emc1403_set_temp(struct thermal_data *data, int channel,
regval = DIV_ROUND_CLOSEST(val, 1000);
ret = regmap_write(data->regmap, regh, regval);
}
+unlock:
+ mutex_unlock(&data->mutex);
return ret;
}
@@ -671,6 +695,8 @@ static int emc1403_probe(struct i2c_client *client)
if (IS_ERR(data->regmap))
return PTR_ERR(data->regmap);
+ mutex_init(&data->mutex);
+
hwmon_dev = devm_hwmon_device_register_with_info(&client->dev,
client->name, data,
&emc1403_chip_info,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 003/877] landlock: Fix TCP Fast Open connection bypass
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 001/877] Revert "hwmon: (emc1403) Drop hysteresis for low limit temperature" Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 002/877] Revert "hwmon: (emc1403) Rely on subsystem locking" Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 004/877] selftests/landlock: Add test for TCP fast open Greg Kroah-Hartman
` (881 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Matthieu Buffet,
Mickaël Salaün, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Buffet <matthieu@buffet.re>
[ Upstream commit 33cb713db0161b54f04fe830e062c9e102c29a04 ]
The documentation of the socket_connect() LSM hook states that it
controls connecting a socket to a remote address. It has not been the
case since the addition of TCP Fast Open (RFC 7413) support, which
allows opening a TCP connection (thus, setting a socket's destination
address) via the MSG_FASTOPEN flag passed to
sendto()/sendmsg()/sendmmsg(). The problem then got duplicated into
MPTCP.
Landlock did not take it into account when its TCP support was added,
leaving a bypass of TCP connect policy.
Ideally a call to the LSM hook would be added in the fastopen code path,
in order to fix this generically. But connect() hooks are designed to
run with the socket locked, unlike sendmsg() hooks.
Closes: https://github.com/landlock-lsm/linux/issues/41
Fixes: fff69fb03dde ("landlock: Support network rules with TCP bind and connect")
Signed-off-by: Matthieu Buffet <matthieu@buffet.re>
Link: https://patch.msgid.link/20260701214628.33319-1-matthieu@buffet.re
Cc: stable@vger.kernel.org
[mic: Wrap commit message]
Signed-off-by: Mickaël Salaün <mic@digikod.net>
[mic: Backport: adapt the TCP Fast Open check to the TCP-only network
hooks]
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
security/landlock/net.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/security/landlock/net.c b/security/landlock/net.c
index 9c9608924fbdb..c5c26e9029924 100644
--- a/security/landlock/net.c
+++ b/security/landlock/net.c
@@ -193,9 +193,23 @@ static int hook_socket_connect(struct socket *const sock,
LANDLOCK_ACCESS_NET_CONNECT_TCP);
}
+static int hook_socket_sendmsg(struct socket *const sock,
+ struct msghdr *const msg, const int size)
+{
+ struct sockaddr *const address = msg->msg_name;
+
+ if ((msg->msg_flags & MSG_FASTOPEN) && address)
+ return current_check_access_socket(
+ sock, address, msg->msg_namelen,
+ LANDLOCK_ACCESS_NET_CONNECT_TCP);
+
+ return 0;
+}
+
static struct security_hook_list landlock_hooks[] __ro_after_init = {
LSM_HOOK_INIT(socket_bind, hook_socket_bind),
LSM_HOOK_INIT(socket_connect, hook_socket_connect),
+ LSM_HOOK_INIT(socket_sendmsg, hook_socket_sendmsg),
};
__init void landlock_add_net_hooks(void)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 004/877] selftests/landlock: Add test for TCP fast open
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (2 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 003/877] landlock: Fix TCP Fast Open connection bypass Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 005/877] selftests/landlock: Add missing connect(minimal AF_UNSPEC) test Greg Kroah-Hartman
` (880 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Matthieu Buffet,
Mickaël Salaün, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Buffet <matthieu@buffet.re>
[ Upstream commit f4b30e0b1d488e7ffd8ea28d1365b9ba8e551edb ]
Enforce that TCP Fast Open is controlled by
LANDLOCK_ACCESS_NET_CONNECT_TCP. Semantics of connect() and
sendmsg(MSG_FASTOPEN) should be identical from Landlock's perspective.
Also enforce error code consistency, since UDP sockets ignore the
MSG_FASTOPEN flag while Unix sockets reject it.
Signed-off-by: Matthieu Buffet <matthieu@buffet.re>
Link: https://patch.msgid.link/20260701214628.33319-2-matthieu@buffet.re
Cc: stable@vger.kernel.org
[mic: Fix formatting]
Signed-off-by: Mickaël Salaün <mic@digikod.net>
[mic: Backport: adapt the test to the older network fixture and add the
required send helper]
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/landlock/net_test.c | 155 ++++++++++++++++++++
1 file changed, 155 insertions(+)
diff --git a/tools/testing/selftests/landlock/net_test.c b/tools/testing/selftests/landlock/net_test.c
index 897131bc8a13b..63b1e655afb25 100644
--- a/tools/testing/selftests/landlock/net_test.c
+++ b/tools/testing/selftests/landlock/net_test.c
@@ -257,6 +257,64 @@ static int connect_variant(const int sock_fd,
return connect_variant_addrlen(sock_fd, srv, get_addrlen(srv, false));
}
+static int sendto_variant_addrlen(const int sock_fd,
+ const struct service_fixture *const srv,
+ const socklen_t addrlen, void *buf,
+ size_t len, size_t flags)
+{
+ const struct sockaddr *dst = NULL;
+ ssize_t ret;
+
+ /*
+ * We never want our processes to be killed by SIGPIPE: we check return
+ * codes and errno, so that we have actual error messages.
+ */
+ flags |= MSG_NOSIGNAL;
+
+ if (srv != NULL) {
+ switch (srv->protocol.domain) {
+ case AF_UNSPEC:
+ case AF_INET:
+ dst = (const struct sockaddr *)&srv->ipv4_addr;
+ break;
+
+ case AF_INET6:
+ dst = (const struct sockaddr *)&srv->ipv6_addr;
+ break;
+
+ case AF_UNIX:
+ dst = (const struct sockaddr *)&srv->unix_addr;
+ break;
+
+ default:
+ errno = EAFNOSUPPORT;
+ return -errno;
+ }
+ }
+
+ ret = sendto(sock_fd, buf, len, flags, dst, addrlen);
+ if (ret < 0)
+ return -errno;
+
+ /* errno is not set in cases of partial writes. */
+ if (ret != len)
+ return -EINTR;
+
+ return 0;
+}
+
+static int sendto_variant(const int sock_fd,
+ const struct service_fixture *const srv, void *buf,
+ size_t len, size_t flags)
+{
+ socklen_t addrlen = 0;
+
+ if (srv != NULL)
+ addrlen = get_addrlen(srv, false);
+
+ return sendto_variant_addrlen(sock_fd, srv, addrlen, buf, len, flags);
+}
+
FIXTURE(protocol)
{
struct service_fixture srv0, srv1, srv2, unspec_any0, unspec_srv0;
@@ -937,6 +995,103 @@ TEST_F(protocol, connect_unspec)
EXPECT_EQ(0, close(bind_fd));
}
+TEST_F(protocol, tcp_fastopen)
+{
+ const bool restricted = variant->sandbox == TCP_SANDBOX &&
+ variant->prot.type == SOCK_STREAM &&
+ (variant->prot.protocol == IPPROTO_TCP ||
+ variant->prot.protocol == IPPROTO_IP) &&
+ (variant->prot.domain == AF_INET ||
+ variant->prot.domain == AF_INET6);
+ const struct landlock_ruleset_attr ruleset_attr = {
+ .handled_access_net = LANDLOCK_ACCESS_NET_CONNECT_TCP,
+ };
+ int bind_fd, client_fd, status;
+ char buf;
+ pid_t child;
+
+ bind_fd = socket_variant(&self->srv0);
+ ASSERT_LE(0, bind_fd);
+ EXPECT_EQ(0, bind_variant(bind_fd, &self->srv0));
+ if (self->srv0.protocol.type == SOCK_STREAM)
+ EXPECT_EQ(0, listen(bind_fd, backlog));
+
+ child = fork();
+ ASSERT_LE(0, child);
+ if (child == 0) {
+ int connect_fd, ret;
+
+ /* Closes listening socket for the child. */
+ EXPECT_EQ(0, close(bind_fd));
+
+ connect_fd = socket_variant(&self->srv0);
+ ASSERT_LE(0, connect_fd);
+
+ if (variant->sandbox == TCP_SANDBOX) {
+ const int ruleset_fd = landlock_create_ruleset(
+ &ruleset_attr, sizeof(ruleset_attr), 0);
+ ASSERT_LE(0, ruleset_fd);
+
+ enforce_ruleset(_metadata, ruleset_fd);
+ EXPECT_EQ(0, close(ruleset_fd));
+ }
+
+ /* Fast Open with no address. */
+ ret = sendto_variant(connect_fd, NULL, NULL, 0, MSG_FASTOPEN);
+ if (self->srv0.protocol.domain == AF_UNIX) {
+ EXPECT_EQ(-ENOTCONN, ret);
+ } else if (self->srv0.protocol.type == SOCK_DGRAM) {
+ EXPECT_EQ(-EDESTADDRREQ, ret);
+ } else {
+ EXPECT_EQ(-EINVAL, ret);
+ }
+
+ /* Fast Open to a denied address. */
+ ret = sendto_variant(connect_fd, &self->srv0, "A", 1,
+ MSG_FASTOPEN);
+ if (restricted) {
+ EXPECT_EQ(-EACCES, ret);
+ } else if (self->srv0.protocol.domain == AF_UNIX &&
+ self->srv0.protocol.type == SOCK_STREAM) {
+ EXPECT_EQ(-EOPNOTSUPP, ret);
+ } else {
+ EXPECT_EQ(0, ret);
+ }
+
+ EXPECT_EQ(0, close(connect_fd));
+ _exit(_metadata->exit_code);
+ return;
+ }
+
+ client_fd = bind_fd;
+ if (!restricted && self->srv0.protocol.type == SOCK_STREAM &&
+ self->srv0.protocol.domain != AF_UNIX) {
+ client_fd = accept(bind_fd, NULL, 0);
+ ASSERT_LE(0, client_fd);
+ }
+
+ if (restricted) {
+ EXPECT_EQ(-1, read(client_fd, &buf, 1));
+ EXPECT_EQ(ENOTCONN, errno);
+ } else if (self->srv0.protocol.domain == AF_UNIX &&
+ self->srv0.protocol.type == SOCK_STREAM) {
+ EXPECT_EQ(-1, read(client_fd, &buf, 1));
+ EXPECT_EQ(EINVAL, errno);
+ } else {
+ EXPECT_EQ(1, read(client_fd, &buf, 1));
+ EXPECT_EQ('A', buf);
+ }
+
+ EXPECT_EQ(child, waitpid(child, &status, 0));
+ EXPECT_EQ(1, WIFEXITED(status));
+ EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
+
+ if (client_fd != bind_fd)
+ EXPECT_LE(0, close(client_fd));
+
+ EXPECT_EQ(0, close(bind_fd));
+}
+
FIXTURE(ipv4)
{
struct service_fixture srv0, srv1;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 005/877] selftests/landlock: Add missing connect(minimal AF_UNSPEC) test
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (3 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 004/877] selftests/landlock: Add test for TCP fast open Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 006/877] selftests/landlock: Add tests for access through disconnected paths Greg Kroah-Hartman
` (879 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Matthieu Buffet,
Mickaël Salaün, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Buffet <matthieu@buffet.re>
[ Upstream commit 6685201ebfacff0c889bcd569181fa6e8af5575e ]
connect_variant(unspec_any0) is called twice. Both calls end
up in connect_variant_addrlen() with an address length of
get_addrlen(minimal=false).
However, the connect() syscall and its variants (e.g.
iouring/compat) accept much shorter addresses of 4 bytes
and that behaviour was not tested.
Replace one of these calls with one using a minimal address
length (just a bare sa_family=AF_UNSPEC field with no actual
address). Also add a call using a truncated address for good
measure.
Signed-off-by: Matthieu Buffet <matthieu@buffet.re>
Link: https://lore.kernel.org/r/20251027190726.626244-3-matthieu@buffet.re
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/landlock/net_test.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/landlock/net_test.c b/tools/testing/selftests/landlock/net_test.c
index 63b1e655afb25..0be69fcc4efbe 100644
--- a/tools/testing/selftests/landlock/net_test.c
+++ b/tools/testing/selftests/landlock/net_test.c
@@ -963,7 +963,19 @@ TEST_F(protocol, connect_unspec)
EXPECT_EQ(0, close(ruleset_fd));
}
- ret = connect_variant(connect_fd, &self->unspec_any0);
+ /* Try to re-disconnect with a truncated address struct. */
+ EXPECT_EQ(-EINVAL,
+ connect_variant_addrlen(
+ connect_fd, &self->unspec_any0,
+ get_addrlen(&self->unspec_any0, true) - 1));
+
+ /*
+ * Re-disconnect, with a minimal sockaddr struct (just a
+ * bare af_family=AF_UNSPEC field).
+ */
+ ret = connect_variant_addrlen(connect_fd, &self->unspec_any0,
+ get_addrlen(&self->unspec_any0,
+ true));
if (self->srv0.protocol.domain == AF_UNIX &&
self->srv0.protocol.type == SOCK_STREAM) {
EXPECT_EQ(-EINVAL, ret);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 006/877] selftests/landlock: Add tests for access through disconnected paths
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (4 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 005/877] selftests/landlock: Add missing connect(minimal AF_UNSPEC) test Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 007/877] selftests/landlock: Add disconnected leafs and branch test suites Greg Kroah-Hartman
` (878 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Günther Noack, Song Liu,
Tingmao Wang, Mickaël Salaün, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tingmao Wang <m@maowtm.org>
[ Upstream commit a18ee3f31fd714173a62515d049d77e76ab55649 ]
This adds tests for the edge case discussed in [1], with specific ones
for rename and link operations when the operands are through
disconnected paths, as that go through a separate code path in Landlock.
This has resulted in a warning, due to collect_domain_accesses() not
expecting to reach a different root from path->mnt:
# RUN layout1_bind.path_disconnected ...
# OK layout1_bind.path_disconnected
ok 96 layout1_bind.path_disconnected
# RUN layout1_bind.path_disconnected_rename ...
[..] ------------[ cut here ]------------
[..] WARNING: CPU: 3 PID: 385 at security/landlock/fs.c:1065 collect_domain_accesses
[..] ...
[..] RIP: 0010:collect_domain_accesses (security/landlock/fs.c:1065 (discriminator 2) security/landlock/fs.c:1031 (discriminator 2))
[..] current_check_refer_path (security/landlock/fs.c:1205)
[..] ...
[..] hook_path_rename (security/landlock/fs.c:1526)
[..] security_path_rename (security/security.c:2026 (discriminator 1))
[..] do_renameat2 (fs/namei.c:5264)
# OK layout1_bind.path_disconnected_rename
ok 97 layout1_bind.path_disconnected_rename
Move the const char definitions a bit above so that we can use the path
for s4d1 in cleanup code.
Cc: Günther Noack <gnoack@google.com>
Cc: Song Liu <song@kernel.org>
Link: https://lore.kernel.org/r/027d5190-b37a-40a8-84e9-4ccbc352bcdf@maowtm.org [1]
Signed-off-by: Tingmao Wang <m@maowtm.org>
Link: https://lore.kernel.org/r/20251128172200.760753-4-mic@digikod.net
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/landlock/fs_test.c | 423 ++++++++++++++++++++-
1 file changed, 415 insertions(+), 8 deletions(-)
diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c
index c781014e6a5c6..1109d0e932336 100644
--- a/tools/testing/selftests/landlock/fs_test.c
+++ b/tools/testing/selftests/landlock/fs_test.c
@@ -4363,6 +4363,18 @@ TEST_F_FORK(ioctl, handle_file_access_file)
FIXTURE(layout1_bind) {};
/* clang-format on */
+static const char bind_dir_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3";
+static const char bind_file1_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3/f1";
+
+/* Move targets for disconnected path tests. */
+static const char dir_s4d1[] = TMP_DIR "/s4d1";
+static const char file1_s4d1[] = TMP_DIR "/s4d1/f1";
+static const char file2_s4d1[] = TMP_DIR "/s4d1/f2";
+static const char dir_s4d2[] = TMP_DIR "/s4d1/s4d2";
+static const char file1_s4d2[] = TMP_DIR "/s4d1/s4d2/f1";
+static const char file1_name[] = "f1";
+static const char file2_name[] = "f2";
+
FIXTURE_SETUP(layout1_bind)
{
prepare_layout(_metadata);
@@ -4378,14 +4390,14 @@ FIXTURE_TEARDOWN_PARENT(layout1_bind)
{
/* umount(dir_s2d2)) is handled by namespace lifetime. */
+ remove_path(file1_s4d1);
+ remove_path(file2_s4d1);
+
remove_layout1(_metadata);
cleanup_layout(_metadata);
}
-static const char bind_dir_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3";
-static const char bind_file1_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3/f1";
-
/*
* layout1_bind hierarchy:
*
@@ -4396,20 +4408,25 @@ static const char bind_file1_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3/f1";
* │ └── s1d2
* │ ├── f1
* │ ├── f2
- * │ └── s1d3
+ * │ └── s1d3 [disconnected by path_disconnected]
* │ ├── f1
* │ └── f2
* ├── s2d1
* │ ├── f1
- * │ └── s2d2
+ * │ └── s2d2 [bind mount from s1d2]
* │ ├── f1
* │ ├── f2
* │ └── s1d3
* │ ├── f1
* │ └── f2
- * └── s3d1
- * └── s3d2
- * └── s3d3
+ * ├── s3d1
+ * │ └── s3d2
+ * │ └── s3d3
+ * └── s4d1 [renamed from s1d3 by path_disconnected]
+ * ├── f1
+ * ├── f2
+ * └── s4d2
+ * └── f1
*/
TEST_F_FORK(layout1_bind, no_restriction)
@@ -4608,6 +4625,396 @@ TEST_F_FORK(layout1_bind, reparent_cross_mount)
ASSERT_EQ(0, rename(bind_file1_s1d3, file1_s2d2));
}
+/*
+ * Make sure access to file through a disconnected path works as expected.
+ * This test moves s1d3 to s4d1.
+ */
+TEST_F_FORK(layout1_bind, path_disconnected)
+{
+ const struct rule layer1_allow_all[] = {
+ {
+ .path = TMP_DIR,
+ .access = ACCESS_ALL,
+ },
+ {},
+ };
+ const struct rule layer2_allow_just_f1[] = {
+ {
+ .path = file1_s1d3,
+ .access = LANDLOCK_ACCESS_FS_READ_FILE,
+ },
+ {},
+ };
+ const struct rule layer3_only_s1d2[] = {
+ {
+ .path = dir_s1d2,
+ .access = LANDLOCK_ACCESS_FS_READ_FILE,
+ },
+ {},
+ };
+
+ /* Landlock should not deny access just because it is disconnected. */
+ int ruleset_fd_l1 =
+ create_ruleset(_metadata, ACCESS_ALL, layer1_allow_all);
+
+ /* Creates the new ruleset now before we move the dir containing the file. */
+ int ruleset_fd_l2 =
+ create_ruleset(_metadata, ACCESS_RW, layer2_allow_just_f1);
+ int ruleset_fd_l3 =
+ create_ruleset(_metadata, ACCESS_RW, layer3_only_s1d2);
+ int bind_s1d3_fd;
+
+ ASSERT_LE(0, ruleset_fd_l1);
+ ASSERT_LE(0, ruleset_fd_l2);
+ ASSERT_LE(0, ruleset_fd_l3);
+
+ enforce_ruleset(_metadata, ruleset_fd_l1);
+ EXPECT_EQ(0, close(ruleset_fd_l1));
+
+ bind_s1d3_fd = open(bind_dir_s1d3, O_PATH | O_CLOEXEC);
+ ASSERT_LE(0, bind_s1d3_fd);
+
+ /* Tests access is possible before we move. */
+ EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
+ EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file2_name, O_RDONLY));
+ EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, "..", O_RDONLY | O_DIRECTORY));
+
+ /* Makes it disconnected. */
+ ASSERT_EQ(0, rename(dir_s1d3, dir_s4d1))
+ {
+ TH_LOG("Failed to rename %s to %s: %s", dir_s1d3, dir_s4d1,
+ strerror(errno));
+ }
+
+ /* Tests that access is still possible. */
+ EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
+ EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file2_name, O_RDONLY));
+
+ /*
+ * Tests that ".." is not possible (not because of Landlock, but just
+ * because it's disconnected).
+ */
+ EXPECT_EQ(ENOENT,
+ test_open_rel(bind_s1d3_fd, "..", O_RDONLY | O_DIRECTORY));
+
+ /* This should still work with a narrower rule. */
+ enforce_ruleset(_metadata, ruleset_fd_l2);
+ EXPECT_EQ(0, close(ruleset_fd_l2));
+
+ EXPECT_EQ(0, test_open(file1_s4d1, O_RDONLY));
+ /*
+ * Accessing a file through a disconnected file descriptor can still be
+ * allowed by a rule tied to this file, even if it is no longer visible in
+ * its mount point.
+ */
+ EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
+ EXPECT_EQ(EACCES, test_open_rel(bind_s1d3_fd, file2_name, O_RDONLY));
+
+ enforce_ruleset(_metadata, ruleset_fd_l3);
+ EXPECT_EQ(0, close(ruleset_fd_l3));
+
+ EXPECT_EQ(EACCES, test_open(file1_s4d1, O_RDONLY));
+ /*
+ * Accessing a file through a disconnected file descriptor can still be
+ * allowed by a rule tied to the original mount point, even if it is no
+ * longer visible in its mount point.
+ */
+ EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
+ EXPECT_EQ(EACCES, test_open_rel(bind_s1d3_fd, file2_name, O_RDONLY));
+}
+
+/*
+ * Test that renameat with disconnected paths works under Landlock. This test
+ * moves s1d3 to s4d2, so that we can have a rule allowing refers on the move
+ * target's immediate parent.
+ */
+TEST_F_FORK(layout1_bind, path_disconnected_rename)
+{
+ const struct rule layer1[] = {
+ {
+ .path = dir_s1d2,
+ .access = LANDLOCK_ACCESS_FS_REFER |
+ LANDLOCK_ACCESS_FS_MAKE_DIR |
+ LANDLOCK_ACCESS_FS_REMOVE_DIR |
+ LANDLOCK_ACCESS_FS_MAKE_REG |
+ LANDLOCK_ACCESS_FS_REMOVE_FILE |
+ LANDLOCK_ACCESS_FS_READ_FILE,
+ },
+ {
+ .path = dir_s4d1,
+ .access = LANDLOCK_ACCESS_FS_REFER |
+ LANDLOCK_ACCESS_FS_MAKE_DIR |
+ LANDLOCK_ACCESS_FS_REMOVE_DIR |
+ LANDLOCK_ACCESS_FS_MAKE_REG |
+ LANDLOCK_ACCESS_FS_REMOVE_FILE |
+ LANDLOCK_ACCESS_FS_READ_FILE,
+ },
+ {}
+ };
+
+ /* This layer only handles LANDLOCK_ACCESS_FS_READ_FILE. */
+ const struct rule layer2_only_s1d2[] = {
+ {
+ .path = dir_s1d2,
+ .access = LANDLOCK_ACCESS_FS_READ_FILE,
+ },
+ {},
+ };
+ int ruleset_fd_l1, ruleset_fd_l2;
+ pid_t child_pid;
+ int bind_s1d3_fd, status;
+
+ ASSERT_EQ(0, mkdir(dir_s4d1, 0755))
+ {
+ TH_LOG("Failed to create %s: %s", dir_s4d1, strerror(errno));
+ }
+ ruleset_fd_l1 = create_ruleset(_metadata, ACCESS_ALL, layer1);
+ ruleset_fd_l2 = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE,
+ layer2_only_s1d2);
+ ASSERT_LE(0, ruleset_fd_l1);
+ ASSERT_LE(0, ruleset_fd_l2);
+
+ enforce_ruleset(_metadata, ruleset_fd_l1);
+ EXPECT_EQ(0, close(ruleset_fd_l1));
+
+ bind_s1d3_fd = open(bind_dir_s1d3, O_PATH | O_CLOEXEC);
+ ASSERT_LE(0, bind_s1d3_fd);
+ EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
+
+ /* Tests ENOENT priority over EACCES for disconnected directory. */
+ EXPECT_EQ(EACCES, test_open_rel(bind_s1d3_fd, "..", O_DIRECTORY));
+ ASSERT_EQ(0, rename(dir_s1d3, dir_s4d2))
+ {
+ TH_LOG("Failed to rename %s to %s: %s", dir_s1d3, dir_s4d2,
+ strerror(errno));
+ }
+ EXPECT_EQ(ENOENT, test_open_rel(bind_s1d3_fd, "..", O_DIRECTORY));
+
+ /*
+ * The file is no longer under s1d2 but we should still be able to access it
+ * with layer 2 because its mount point is evaluated as the first valid
+ * directory because it was initially a parent. Do a fork to test this so
+ * we don't prevent ourselves from renaming it back later.
+ */
+ child_pid = fork();
+ ASSERT_LE(0, child_pid);
+ if (child_pid == 0) {
+ enforce_ruleset(_metadata, ruleset_fd_l2);
+ EXPECT_EQ(0, close(ruleset_fd_l2));
+ EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
+ EXPECT_EQ(EACCES, test_open(file1_s4d2, O_RDONLY));
+
+ /*
+ * Tests that access widening checks indeed prevents us from renaming it
+ * back.
+ */
+ EXPECT_EQ(-1, rename(dir_s4d2, dir_s1d3));
+ EXPECT_EQ(EXDEV, errno);
+
+ /*
+ * Including through the now disconnected fd (but it should return
+ * EXDEV).
+ */
+ EXPECT_EQ(-1, renameat(bind_s1d3_fd, file1_name, AT_FDCWD,
+ file1_s2d2));
+ EXPECT_EQ(EXDEV, errno);
+ _exit(_metadata->exit_code);
+ return;
+ }
+
+ EXPECT_EQ(child_pid, waitpid(child_pid, &status, 0));
+ EXPECT_EQ(1, WIFEXITED(status));
+ EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
+
+ ASSERT_EQ(0, rename(dir_s4d2, dir_s1d3))
+ {
+ TH_LOG("Failed to rename %s back to %s: %s", dir_s4d1, dir_s1d3,
+ strerror(errno));
+ }
+
+ /* Now checks that we can access it under l2. */
+ child_pid = fork();
+ ASSERT_LE(0, child_pid);
+ if (child_pid == 0) {
+ enforce_ruleset(_metadata, ruleset_fd_l2);
+ EXPECT_EQ(0, close(ruleset_fd_l2));
+ EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
+ EXPECT_EQ(0, test_open(file1_s1d3, O_RDONLY));
+ _exit(_metadata->exit_code);
+ return;
+ }
+
+ EXPECT_EQ(child_pid, waitpid(child_pid, &status, 0));
+ EXPECT_EQ(1, WIFEXITED(status));
+ EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
+
+ /*
+ * Also test that we can rename via a disconnected path. We move the
+ * dir back to the disconnected place first, then we rename file1 to
+ * file2 through our dir fd.
+ */
+ ASSERT_EQ(0, rename(dir_s1d3, dir_s4d2))
+ {
+ TH_LOG("Failed to rename %s to %s: %s", dir_s1d3, dir_s4d2,
+ strerror(errno));
+ }
+ ASSERT_EQ(0,
+ renameat(bind_s1d3_fd, file1_name, bind_s1d3_fd, file2_name))
+ {
+ TH_LOG("Failed to rename %s to %s within disconnected %s: %s",
+ file1_name, file2_name, bind_dir_s1d3, strerror(errno));
+ }
+ EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file2_name, O_RDONLY));
+ ASSERT_EQ(0, renameat(bind_s1d3_fd, file2_name, AT_FDCWD, file1_s2d2))
+ {
+ TH_LOG("Failed to rename %s to %s through disconnected %s: %s",
+ file2_name, file1_s2d2, bind_dir_s1d3, strerror(errno));
+ }
+ EXPECT_EQ(0, test_open(file1_s2d2, O_RDONLY));
+ EXPECT_EQ(0, test_open(file1_s1d2, O_RDONLY));
+
+ /* Move it back using the disconnected path as the target. */
+ ASSERT_EQ(0, renameat(AT_FDCWD, file1_s2d2, bind_s1d3_fd, file1_name))
+ {
+ TH_LOG("Failed to rename %s to %s through disconnected %s: %s",
+ file1_s1d2, file1_name, bind_dir_s1d3, strerror(errno));
+ }
+
+ /* Now make it connected again. */
+ ASSERT_EQ(0, rename(dir_s4d2, dir_s1d3))
+ {
+ TH_LOG("Failed to rename %s back to %s: %s", dir_s4d2, dir_s1d3,
+ strerror(errno));
+ }
+
+ /* Checks again that we can access it under l2. */
+ enforce_ruleset(_metadata, ruleset_fd_l2);
+ EXPECT_EQ(0, close(ruleset_fd_l2));
+ EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
+ EXPECT_EQ(0, test_open(file1_s1d3, O_RDONLY));
+}
+
+/*
+ * Test that linkat(2) with disconnected paths works under Landlock. This
+ * test moves s1d3 to s4d1.
+ */
+TEST_F_FORK(layout1_bind, path_disconnected_link)
+{
+ /* Ruleset to be applied after renaming s1d3 to s4d1. */
+ const struct rule layer1[] = {
+ {
+ .path = dir_s4d1,
+ .access = LANDLOCK_ACCESS_FS_REFER |
+ LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_MAKE_REG |
+ LANDLOCK_ACCESS_FS_REMOVE_FILE,
+ },
+ {
+ .path = dir_s2d2,
+ .access = LANDLOCK_ACCESS_FS_REFER |
+ LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_MAKE_REG |
+ LANDLOCK_ACCESS_FS_REMOVE_FILE,
+ },
+ {}
+ };
+ int ruleset_fd, bind_s1d3_fd;
+
+ /* Removes unneeded files created by layout1, otherwise it will EEXIST. */
+ ASSERT_EQ(0, unlink(file1_s1d2));
+ ASSERT_EQ(0, unlink(file2_s1d3));
+
+ bind_s1d3_fd = open(bind_dir_s1d3, O_PATH | O_CLOEXEC);
+ ASSERT_LE(0, bind_s1d3_fd);
+ EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
+
+ /* Disconnects bind_s1d3_fd. */
+ ASSERT_EQ(0, rename(dir_s1d3, dir_s4d1))
+ {
+ TH_LOG("Failed to rename %s to %s: %s", dir_s1d3, dir_s4d1,
+ strerror(errno));
+ }
+
+ /* Need this later to test different parent link. */
+ ASSERT_EQ(0, mkdir(dir_s4d2, 0755))
+ {
+ TH_LOG("Failed to create %s: %s", dir_s4d2, strerror(errno));
+ }
+
+ ruleset_fd = create_ruleset(_metadata, ACCESS_ALL, layer1);
+ ASSERT_LE(0, ruleset_fd);
+ enforce_ruleset(_metadata, ruleset_fd);
+ EXPECT_EQ(0, close(ruleset_fd));
+
+ /* From disconnected to connected. */
+ ASSERT_EQ(0, linkat(bind_s1d3_fd, file1_name, AT_FDCWD, file1_s2d2, 0))
+ {
+ TH_LOG("Failed to link %s to %s via disconnected %s: %s",
+ file1_name, file1_s2d2, bind_dir_s1d3, strerror(errno));
+ }
+
+ /* Tests that we can access via the new link... */
+ EXPECT_EQ(0, test_open(file1_s2d2, O_RDONLY))
+ {
+ TH_LOG("Failed to open newly linked %s: %s", file1_s2d2,
+ strerror(errno));
+ }
+
+ /* ...as well as the old one. */
+ EXPECT_EQ(0, test_open(file1_s4d1, O_RDONLY))
+ {
+ TH_LOG("Failed to open original %s: %s", file1_s4d1,
+ strerror(errno));
+ }
+
+ /* From connected to disconnected. */
+ ASSERT_EQ(0, unlink(file1_s4d1));
+ ASSERT_EQ(0, linkat(AT_FDCWD, file1_s2d2, bind_s1d3_fd, file2_name, 0))
+ {
+ TH_LOG("Failed to link %s to %s via disconnected %s: %s",
+ file1_s2d2, file2_name, bind_dir_s1d3, strerror(errno));
+ }
+ EXPECT_EQ(0, test_open(file2_s4d1, O_RDONLY));
+ ASSERT_EQ(0, unlink(file1_s2d2));
+
+ /* From disconnected to disconnected (same parent). */
+ ASSERT_EQ(0,
+ linkat(bind_s1d3_fd, file2_name, bind_s1d3_fd, file1_name, 0))
+ {
+ TH_LOG("Failed to link %s to %s within disconnected %s: %s",
+ file2_name, file1_name, bind_dir_s1d3, strerror(errno));
+ }
+ EXPECT_EQ(0, test_open(file1_s4d1, O_RDONLY))
+ {
+ TH_LOG("Failed to open newly linked %s: %s", file1_s4d1,
+ strerror(errno));
+ }
+ EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY))
+ {
+ TH_LOG("Failed to open %s through newly created link under disconnected path: %s",
+ file1_name, strerror(errno));
+ }
+ ASSERT_EQ(0, unlink(file2_s4d1));
+
+ /* From disconnected to disconnected (different parent). */
+ ASSERT_EQ(0,
+ linkat(bind_s1d3_fd, file1_name, bind_s1d3_fd, "s4d2/f1", 0))
+ {
+ TH_LOG("Failed to link %s to %s within disconnected %s: %s",
+ file1_name, "s4d2/f1", bind_dir_s1d3, strerror(errno));
+ }
+ EXPECT_EQ(0, test_open(file1_s4d2, O_RDONLY))
+ {
+ TH_LOG("Failed to open %s after link: %s", file1_s4d2,
+ strerror(errno));
+ }
+ EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, "s4d2/f1", O_RDONLY))
+ {
+ TH_LOG("Failed to open %s through disconnected path after link: %s",
+ "s4d2/f1", strerror(errno));
+ }
+}
+
#define LOWER_BASE TMP_DIR "/lower"
#define LOWER_DATA LOWER_BASE "/data"
static const char lower_fl1[] = LOWER_DATA "/fl1";
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 007/877] selftests/landlock: Add disconnected leafs and branch test suites
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (5 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 006/877] selftests/landlock: Add tests for access through disconnected paths Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 008/877] s390/boot: Add sized_strscpy() to enable strscpy() usage Greg Kroah-Hartman
` (877 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Günther Noack, Song Liu,
Tingmao Wang, Mickaël Salaün, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mickaël Salaün <mic@digikod.net>
[ Upstream commit 54f9baf537b0a091adad860ec92e3e18e0a0754c ]
Test disconnected directories with two test suites
(layout4_disconnected_leafs and layout5_disconnected_branch) and 43
variants to cover the main corner cases.
These tests are complementary to the previous commit.
Add test_renameat() and test_exchangeat() helpers.
Test coverage for security/landlock is 92.1% of 1927 lines according to
LLVM 20.
Cc: Günther Noack <gnoack@google.com>
Cc: Song Liu <song@kernel.org>
Cc: Tingmao Wang <m@maowtm.org>
Link: https://lore.kernel.org/r/20251128172200.760753-5-mic@digikod.net
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/landlock/fs_test.c | 1051 ++++++++++++++++++++
1 file changed, 1051 insertions(+)
diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c
index 1109d0e932336..732ba5a92df56 100644
--- a/tools/testing/selftests/landlock/fs_test.c
+++ b/tools/testing/selftests/landlock/fs_test.c
@@ -2109,6 +2109,22 @@ static int test_exchange(const char *const oldpath, const char *const newpath)
return 0;
}
+static int test_renameat(int olddirfd, const char *oldpath, int newdirfd,
+ const char *newpath)
+{
+ if (renameat2(olddirfd, oldpath, newdirfd, newpath, 0))
+ return errno;
+ return 0;
+}
+
+static int test_exchangeat(int olddirfd, const char *oldpath, int newdirfd,
+ const char *newpath)
+{
+ if (renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_EXCHANGE))
+ return errno;
+ return 0;
+}
+
TEST_F_FORK(layout1, rename_file)
{
const struct rule rules[] = {
@@ -5015,6 +5031,1041 @@ TEST_F_FORK(layout1_bind, path_disconnected_link)
}
}
+/*
+ * layout4_disconnected_leafs with bind mount and renames:
+ *
+ * tmp
+ * ├── s1d1
+ * │ └── s1d2 [source of the bind mount]
+ * │ ├── s1d31
+ * │ │ └── s1d41 [now renamed beneath s3d1]
+ * │ │ ├── f1
+ * │ │ └── f2
+ * │ └── s1d32
+ * │ └── s1d42 [now renamed beneath s4d1]
+ * │ ├── f3
+ * │ └── f4
+ * ├── s2d1
+ * │ └── s2d2 [bind mount of s1d2]
+ * │ ├── s1d31
+ * │ │ └── s1d41 [opened FD, now renamed beneath s3d1]
+ * │ │ ├── f1
+ * │ │ └── f2
+ * │ └── s1d32
+ * │ └── s1d42 [opened FD, now renamed beneath s4d1]
+ * │ ├── f3
+ * │ └── f4
+ * ├── s3d1
+ * │ └── s1d41 [renamed here]
+ * │ ├── f1
+ * │ └── f2
+ * └── s4d1
+ * └── s1d42 [renamed here]
+ * ├── f3
+ * └── f4
+ */
+/* clang-format off */
+FIXTURE(layout4_disconnected_leafs) {
+ int s2d2_fd;
+};
+/* clang-format on */
+
+FIXTURE_SETUP(layout4_disconnected_leafs)
+{
+ prepare_layout(_metadata);
+
+ create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d31/s1d41/f1");
+ create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d31/s1d41/f2");
+ create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d32/s1d42/f3");
+ create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d32/s1d42/f4");
+ create_directory(_metadata, TMP_DIR "/s2d1/s2d2");
+ create_directory(_metadata, TMP_DIR "/s3d1");
+ create_directory(_metadata, TMP_DIR "/s4d1");
+
+ self->s2d2_fd =
+ open(TMP_DIR "/s2d1/s2d2", O_DIRECTORY | O_PATH | O_CLOEXEC);
+ ASSERT_LE(0, self->s2d2_fd);
+
+ set_cap(_metadata, CAP_SYS_ADMIN);
+ ASSERT_EQ(0, mount(TMP_DIR "/s1d1/s1d2", TMP_DIR "/s2d1/s2d2", NULL,
+ MS_BIND, NULL));
+ clear_cap(_metadata, CAP_SYS_ADMIN);
+}
+
+FIXTURE_TEARDOWN_PARENT(layout4_disconnected_leafs)
+{
+ /* umount(TMP_DIR "/s2d1") is handled by namespace lifetime. */
+
+ /* Removes files after renames. */
+ remove_path(TMP_DIR "/s3d1/s1d41/f1");
+ remove_path(TMP_DIR "/s3d1/s1d41/f2");
+ remove_path(TMP_DIR "/s4d1/s1d42/f1");
+ remove_path(TMP_DIR "/s4d1/s1d42/f3");
+ remove_path(TMP_DIR "/s4d1/s1d42/f4");
+ remove_path(TMP_DIR "/s4d1/s1d42/f5");
+
+ cleanup_layout(_metadata);
+}
+
+FIXTURE_VARIANT(layout4_disconnected_leafs)
+{
+ /*
+ * Parent of the bind mount source. It should always be ignored when
+ * testing against files under the s1d41 or s1d42 disconnected directories.
+ */
+ const __u64 allowed_s1d1;
+ /*
+ * Source of bind mount (to s2d2). It should always be enforced when
+ * testing against files under the s1d41 or s1d42 disconnected directories.
+ */
+ const __u64 allowed_s1d2;
+ /*
+ * Original parent of s1d41. It should always be ignored when testing
+ * against files under the s1d41 disconnected directory.
+ */
+ const __u64 allowed_s1d31;
+ /*
+ * Original parent of s1d42. It should always be ignored when testing
+ * against files under the s1d42 disconnected directory.
+ */
+ const __u64 allowed_s1d32;
+ /*
+ * Opened and disconnected source directory. It should always be enforced
+ * when testing against files under the s1d41 disconnected directory.
+ */
+ const __u64 allowed_s1d41;
+ /*
+ * Opened and disconnected source directory. It should always be enforced
+ * when testing against files under the s1d42 disconnected directory.
+ */
+ const __u64 allowed_s1d42;
+ /*
+ * File in the s1d41 disconnected directory. It should always be enforced
+ * when testing against itself under the s1d41 disconnected directory.
+ */
+ const __u64 allowed_f1;
+ /*
+ * File in the s1d41 disconnected directory. It should always be enforced
+ * when testing against itself under the s1d41 disconnected directory.
+ */
+ const __u64 allowed_f2;
+ /*
+ * File in the s1d42 disconnected directory. It should always be enforced
+ * when testing against itself under the s1d42 disconnected directory.
+ */
+ const __u64 allowed_f3;
+ /*
+ * Parent of the bind mount destination. It should always be enforced when
+ * testing against files under the s1d41 or s1d42 disconnected directories.
+ */
+ const __u64 allowed_s2d1;
+ /*
+ * Directory covered by the bind mount. It should always be ignored when
+ * testing against files under the s1d41 or s1d42 disconnected directories.
+ */
+ const __u64 allowed_s2d2;
+ /*
+ * New parent of the renamed s1d41. It should always be ignored when
+ * testing against files under the s1d41 disconnected directory.
+ */
+ const __u64 allowed_s3d1;
+ /*
+ * New parent of the renamed s1d42. It should always be ignored when
+ * testing against files under the s1d42 disconnected directory.
+ */
+ const __u64 allowed_s4d1;
+
+ /* Expected result of the call to open([fd:s1d41]/f1, O_RDONLY). */
+ const int expected_read_result;
+ /* Expected result of the call to renameat([fd:s1d41]/f1, [fd:s1d42]/f1). */
+ const int expected_rename_result;
+ /*
+ * Expected result of the call to renameat([fd:s1d41]/f2, [fd:s1d42]/f3,
+ * RENAME_EXCHANGE).
+ */
+ const int expected_exchange_result;
+ /* Expected result of the call to renameat([fd:s1d42]/f4, [fd:s1d42]/f5). */
+ const int expected_same_dir_rename_result;
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d1_mount_src_parent) {
+ /* clang-format on */
+ .allowed_s1d1 = LANDLOCK_ACCESS_FS_REFER |
+ LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_EXECUTE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = EACCES,
+ .expected_same_dir_rename_result = EACCES,
+ .expected_rename_result = EACCES,
+ .expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d2_mount_src_refer) {
+ /* clang-format on */
+ .allowed_s1d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = EACCES,
+ .expected_rename_result = EACCES,
+ .expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d2_mount_src_create) {
+ /* clang-format on */
+ .allowed_s1d2 = LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = EXDEV,
+ .expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d2_mount_src_rename) {
+ /* clang-format on */
+ .allowed_s1d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = EACCES,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = 0,
+ .expected_exchange_result = 0,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d31_s1d32_old_parent) {
+ /* clang-format on */
+ .allowed_s1d31 = LANDLOCK_ACCESS_FS_REFER |
+ LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_EXECUTE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .allowed_s1d32 = LANDLOCK_ACCESS_FS_REFER |
+ LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_EXECUTE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = EACCES,
+ .expected_same_dir_rename_result = EACCES,
+ .expected_rename_result = EACCES,
+ .expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d41_s1d42_disconnected_refer) {
+ /* clang-format on */
+ .allowed_s1d41 = LANDLOCK_ACCESS_FS_REFER |
+ LANDLOCK_ACCESS_FS_READ_FILE,
+ .allowed_s1d42 = LANDLOCK_ACCESS_FS_REFER |
+ LANDLOCK_ACCESS_FS_READ_FILE,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = EACCES,
+ .expected_rename_result = EACCES,
+ .expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d41_s1d42_disconnected_create) {
+ /* clang-format on */
+ .allowed_s1d41 = LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .allowed_s1d42 = LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = EXDEV,
+ .expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d41_s1d42_disconnected_rename_even) {
+ /* clang-format on */
+ .allowed_s1d41 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+ .allowed_s1d42 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = EACCES,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = 0,
+ .expected_exchange_result = 0,
+};
+
+/* The destination directory has more access right. */
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d41_s1d42_disconnected_rename_more) {
+ /* clang-format on */
+ .allowed_s1d41 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+ .allowed_s1d42 = LANDLOCK_ACCESS_FS_REFER |
+ LANDLOCK_ACCESS_FS_MAKE_REG |
+ LANDLOCK_ACCESS_FS_EXECUTE,
+ .expected_read_result = EACCES,
+ .expected_same_dir_rename_result = 0,
+ /* Access denied. */
+ .expected_rename_result = EXDEV,
+ .expected_exchange_result = EXDEV,
+};
+
+/* The destination directory has less access right. */
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d41_s1d42_disconnected_rename_less) {
+ /* clang-format on */
+ .allowed_s1d41 = LANDLOCK_ACCESS_FS_REFER |
+ LANDLOCK_ACCESS_FS_MAKE_REG |
+ LANDLOCK_ACCESS_FS_EXECUTE,
+ .allowed_s1d42 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = EACCES,
+ .expected_same_dir_rename_result = 0,
+ /* Access allowed. */
+ .expected_rename_result = 0,
+ .expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s2d1_mount_dst_parent_create) {
+ /* clang-format on */
+ .allowed_s2d1 = LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = EXDEV,
+ .expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s2d1_mount_dst_parent_refer) {
+ /* clang-format on */
+ .allowed_s2d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = EACCES,
+ .expected_rename_result = EACCES,
+ .expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s2d1_mount_dst_parent_mini) {
+ /* clang-format on */
+ .allowed_s2d1 = LANDLOCK_ACCESS_FS_REFER |
+ LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = 0,
+ .expected_exchange_result = 0,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s2d2_covered_by_mount) {
+ /* clang-format on */
+ .allowed_s2d2 = LANDLOCK_ACCESS_FS_REFER |
+ LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_EXECUTE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = EACCES,
+ .expected_same_dir_rename_result = EACCES,
+ .expected_rename_result = EACCES,
+ .expected_exchange_result = EACCES,
+};
+
+/* Tests collect_domain_accesses(). */
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s3d1_s4d1_new_parent_refer) {
+ /* clang-format on */
+ .allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
+ .allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = EACCES,
+ .expected_rename_result = EACCES,
+ .expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s3d1_s4d1_new_parent_create) {
+ /* clang-format on */
+ .allowed_s3d1 = LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .allowed_s4d1 = LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = EXDEV,
+ .expected_exchange_result = EXDEV,
+};
+
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs,
+ s3d1_s4d1_disconnected_rename_even){
+ /* clang-format on */
+ .allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+ .allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = EACCES,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = 0,
+ .expected_exchange_result = 0,
+};
+
+/* The destination directory has more access right. */
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s3d1_s4d1_disconnected_rename_more) {
+ /* clang-format on */
+ .allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+ .allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG |
+ LANDLOCK_ACCESS_FS_EXECUTE,
+ .expected_read_result = EACCES,
+ .expected_same_dir_rename_result = 0,
+ /* Access denied. */
+ .expected_rename_result = EXDEV,
+ .expected_exchange_result = EXDEV,
+};
+
+/* The destination directory has less access right. */
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s3d1_s4d1_disconnected_rename_less) {
+ /* clang-format on */
+ .allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG |
+ LANDLOCK_ACCESS_FS_EXECUTE,
+ .allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = EACCES,
+ .expected_same_dir_rename_result = 0,
+ /* Access allowed. */
+ .expected_rename_result = 0,
+ .expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, f1_f2_f3) {
+ /* clang-format on */
+ .allowed_f1 = LANDLOCK_ACCESS_FS_READ_FILE,
+ .allowed_f2 = LANDLOCK_ACCESS_FS_READ_FILE,
+ .allowed_f3 = LANDLOCK_ACCESS_FS_READ_FILE,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = EACCES,
+ .expected_rename_result = EACCES,
+ .expected_exchange_result = EACCES,
+};
+
+TEST_F_FORK(layout4_disconnected_leafs, read_rename_exchange)
+{
+ const __u64 handled_access =
+ LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_EXECUTE | LANDLOCK_ACCESS_FS_MAKE_REG;
+ const struct rule rules[] = {
+ {
+ .path = TMP_DIR "/s1d1",
+ .access = variant->allowed_s1d1,
+ },
+ {
+ .path = TMP_DIR "/s1d1/s1d2",
+ .access = variant->allowed_s1d2,
+ },
+ {
+ .path = TMP_DIR "/s1d1/s1d2/s1d31",
+ .access = variant->allowed_s1d31,
+ },
+ {
+ .path = TMP_DIR "/s1d1/s1d2/s1d32",
+ .access = variant->allowed_s1d32,
+ },
+ {
+ .path = TMP_DIR "/s1d1/s1d2/s1d31/s1d41",
+ .access = variant->allowed_s1d41,
+ },
+ {
+ .path = TMP_DIR "/s1d1/s1d2/s1d32/s1d42",
+ .access = variant->allowed_s1d42,
+ },
+ {
+ .path = TMP_DIR "/s1d1/s1d2/s1d31/s1d41/f1",
+ .access = variant->allowed_f1,
+ },
+ {
+ .path = TMP_DIR "/s1d1/s1d2/s1d31/s1d41/f2",
+ .access = variant->allowed_f2,
+ },
+ {
+ .path = TMP_DIR "/s1d1/s1d2/s1d32/s1d42/f3",
+ .access = variant->allowed_f3,
+ },
+ {
+ .path = TMP_DIR "/s2d1",
+ .access = variant->allowed_s2d1,
+ },
+ /* s2d2_fd */
+ {
+ .path = TMP_DIR "/s3d1",
+ .access = variant->allowed_s3d1,
+ },
+ {
+ .path = TMP_DIR "/s4d1",
+ .access = variant->allowed_s4d1,
+ },
+ {},
+ };
+ int ruleset_fd, s1d41_bind_fd, s1d42_bind_fd;
+
+ ruleset_fd = create_ruleset(_metadata, handled_access, rules);
+ ASSERT_LE(0, ruleset_fd);
+
+ /* Adds rule for the covered directory. */
+ if (variant->allowed_s2d2) {
+ ASSERT_EQ(0, landlock_add_rule(
+ ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
+ &(struct landlock_path_beneath_attr){
+ .parent_fd = self->s2d2_fd,
+ .allowed_access =
+ variant->allowed_s2d2,
+ },
+ 0));
+ }
+ EXPECT_EQ(0, close(self->s2d2_fd));
+
+ s1d41_bind_fd = open(TMP_DIR "/s2d1/s2d2/s1d31/s1d41",
+ O_DIRECTORY | O_PATH | O_CLOEXEC);
+ ASSERT_LE(0, s1d41_bind_fd);
+ s1d42_bind_fd = open(TMP_DIR "/s2d1/s2d2/s1d32/s1d42",
+ O_DIRECTORY | O_PATH | O_CLOEXEC);
+ ASSERT_LE(0, s1d42_bind_fd);
+
+ /* Disconnects and checks source and destination directories. */
+ EXPECT_EQ(0, test_open_rel(s1d41_bind_fd, "..", O_DIRECTORY));
+ EXPECT_EQ(0, test_open_rel(s1d42_bind_fd, "..", O_DIRECTORY));
+ /* Renames to make it accessible through s3d1/s1d41 */
+ ASSERT_EQ(0, test_renameat(AT_FDCWD, TMP_DIR "/s1d1/s1d2/s1d31/s1d41",
+ AT_FDCWD, TMP_DIR "/s3d1/s1d41"));
+ /* Renames to make it accessible through s4d1/s1d42 */
+ ASSERT_EQ(0, test_renameat(AT_FDCWD, TMP_DIR "/s1d1/s1d2/s1d32/s1d42",
+ AT_FDCWD, TMP_DIR "/s4d1/s1d42"));
+ EXPECT_EQ(ENOENT, test_open_rel(s1d41_bind_fd, "..", O_DIRECTORY));
+ EXPECT_EQ(ENOENT, test_open_rel(s1d42_bind_fd, "..", O_DIRECTORY));
+
+ enforce_ruleset(_metadata, ruleset_fd);
+ EXPECT_EQ(0, close(ruleset_fd));
+
+ EXPECT_EQ(variant->expected_read_result,
+ test_open_rel(s1d41_bind_fd, "f1", O_RDONLY));
+
+ EXPECT_EQ(variant->expected_rename_result,
+ test_renameat(s1d41_bind_fd, "f1", s1d42_bind_fd, "f1"));
+ EXPECT_EQ(variant->expected_exchange_result,
+ test_exchangeat(s1d41_bind_fd, "f2", s1d42_bind_fd, "f3"));
+
+ EXPECT_EQ(variant->expected_same_dir_rename_result,
+ test_renameat(s1d42_bind_fd, "f4", s1d42_bind_fd, "f5"));
+}
+
+/*
+ * layout5_disconnected_branch before rename:
+ *
+ * tmp
+ * ├── s1d1
+ * │ └── s1d2 [source of the first bind mount]
+ * │ └── s1d3
+ * │ ├── s1d41
+ * │ │ ├── f1
+ * │ │ └── f2
+ * │ └── s1d42
+ * │ ├── f3
+ * │ └── f4
+ * ├── s2d1
+ * │ └── s2d2 [source of the second bind mount]
+ * │ └── s2d3
+ * │ └── s2d4 [first s1d2 bind mount]
+ * │ └── s1d3
+ * │ ├── s1d41
+ * │ │ ├── f1
+ * │ │ └── f2
+ * │ └── s1d42
+ * │ ├── f3
+ * │ └── f4
+ * ├── s3d1
+ * │ └── s3d2 [second s2d2 bind mount]
+ * │ └── s2d3
+ * │ └── s2d4 [first s1d2 bind mount]
+ * │ └── s1d3
+ * │ ├── s1d41
+ * │ │ ├── f1
+ * │ │ └── f2
+ * │ └── s1d42
+ * │ ├── f3
+ * │ └── f4
+ * └── s4d1
+ *
+ * After rename:
+ *
+ * tmp
+ * ├── s1d1
+ * │ └── s1d2 [source of the first bind mount]
+ * │ └── s1d3
+ * │ ├── s1d41
+ * │ │ ├── f1
+ * │ │ └── f2
+ * │ └── s1d42
+ * │ ├── f3
+ * │ └── f4
+ * ├── s2d1
+ * │ └── s2d2 [source of the second bind mount]
+ * ├── s3d1
+ * │ └── s3d2 [second s2d2 bind mount]
+ * └── s4d1
+ * └── s2d3 [renamed here]
+ * └── s2d4 [first s1d2 bind mount]
+ * └── s1d3
+ * ├── s1d41
+ * │ ├── f1
+ * │ └── f2
+ * └── s1d42
+ * ├── f3
+ * └── f4
+ *
+ * Decision path for access from the s3d1/s3d2/s2d3/s2d4/s1d3 file descriptor:
+ * 1. first bind mount: s1d3 -> s1d2
+ * 2. second bind mount: s2d3
+ * 3. tmp mount: s4d1 -> tmp [disconnected branch]
+ * 4. second bind mount: s2d2
+ * 5. tmp mount: s3d1 -> tmp
+ * 6. parent mounts: [...] -> /
+ *
+ * The s4d1 directory is evaluated even if it is not in the s2d2 mount.
+ */
+
+/* clang-format off */
+FIXTURE(layout5_disconnected_branch) {
+ int s2d4_fd, s3d2_fd;
+};
+/* clang-format on */
+
+FIXTURE_SETUP(layout5_disconnected_branch)
+{
+ prepare_layout(_metadata);
+
+ create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d3/s1d41/f1");
+ create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d3/s1d41/f2");
+ create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f3");
+ create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f4");
+ create_directory(_metadata, TMP_DIR "/s2d1/s2d2/s2d3/s2d4");
+ create_directory(_metadata, TMP_DIR "/s3d1/s3d2");
+ create_directory(_metadata, TMP_DIR "/s4d1");
+
+ self->s2d4_fd = open(TMP_DIR "/s2d1/s2d2/s2d3/s2d4",
+ O_DIRECTORY | O_PATH | O_CLOEXEC);
+ ASSERT_LE(0, self->s2d4_fd);
+
+ self->s3d2_fd =
+ open(TMP_DIR "/s3d1/s3d2", O_DIRECTORY | O_PATH | O_CLOEXEC);
+ ASSERT_LE(0, self->s3d2_fd);
+
+ set_cap(_metadata, CAP_SYS_ADMIN);
+ ASSERT_EQ(0, mount(TMP_DIR "/s1d1/s1d2", TMP_DIR "/s2d1/s2d2/s2d3/s2d4",
+ NULL, MS_BIND, NULL));
+ ASSERT_EQ(0, mount(TMP_DIR "/s2d1/s2d2", TMP_DIR "/s3d1/s3d2", NULL,
+ MS_BIND | MS_REC, NULL));
+ clear_cap(_metadata, CAP_SYS_ADMIN);
+}
+
+FIXTURE_TEARDOWN_PARENT(layout5_disconnected_branch)
+{
+ /* Bind mounts are handled by namespace lifetime. */
+
+ /* Removes files after renames. */
+ remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d41/f1");
+ remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d41/f2");
+ remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f1");
+ remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f3");
+ remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f4");
+ remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f5");
+
+ cleanup_layout(_metadata);
+}
+
+FIXTURE_VARIANT(layout5_disconnected_branch)
+{
+ /*
+ * Parent of all files. It should always be enforced when testing against
+ * files under the s1d41 or s1d42 disconnected directories.
+ */
+ const __u64 allowed_base;
+ /*
+ * Parent of the first bind mount source. It should always be ignored when
+ * testing against files under the s1d41 or s1d42 disconnected directories.
+ */
+ const __u64 allowed_s1d1;
+ const __u64 allowed_s1d2;
+ const __u64 allowed_s1d3;
+ const __u64 allowed_s2d1;
+ const __u64 allowed_s2d2;
+ const __u64 allowed_s2d3;
+ const __u64 allowed_s2d4;
+ const __u64 allowed_s3d1;
+ const __u64 allowed_s3d2;
+ const __u64 allowed_s4d1;
+
+ /* Expected result of the call to open([fd:s1d3]/s1d41/f1, O_RDONLY). */
+ const int expected_read_result;
+ /*
+ * Expected result of the call to renameat([fd:s1d3]/s1d41/f1,
+ * [fd:s1d3]/s1d42/f1).
+ */
+ const int expected_rename_result;
+ /*
+ * Expected result of the call to renameat([fd:s1d3]/s1d41/f2,
+ * [fd:s1d3]/s1d42/f3, RENAME_EXCHANGE).
+ */
+ const int expected_exchange_result;
+ /*
+ * Expected result of the call to renameat([fd:s1d3]/s1d42/f4,
+ * [fd:s1d3]/s1d42/f5).
+ */
+ const int expected_same_dir_rename_result;
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d1_mount1_src_parent) {
+ /* clang-format on */
+ .allowed_s1d1 = LANDLOCK_ACCESS_FS_REFER |
+ LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_EXECUTE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = EACCES,
+ .expected_same_dir_rename_result = EACCES,
+ .expected_rename_result = EACCES,
+ .expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d2_mount1_src_refer) {
+ /* clang-format on */
+ .allowed_s1d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = EACCES,
+ .expected_rename_result = EACCES,
+ .expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d2_mount1_src_create) {
+ /* clang-format on */
+ .allowed_s1d2 = LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = EXDEV,
+ .expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d2_mount1_src_rename) {
+ /* clang-format on */
+ .allowed_s1d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = EACCES,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = 0,
+ .expected_exchange_result = 0,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d3_fd_refer) {
+ /* clang-format on */
+ .allowed_s1d3 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = EACCES,
+ .expected_rename_result = EACCES,
+ .expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d3_fd_create) {
+ /* clang-format on */
+ .allowed_s1d3 = LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = EXDEV,
+ .expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d3_fd_rename) {
+ /* clang-format on */
+ .allowed_s1d3 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = EACCES,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = 0,
+ .expected_exchange_result = 0,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d3_fd_full) {
+ /* clang-format on */
+ .allowed_s1d3 = LANDLOCK_ACCESS_FS_REFER |
+ LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_EXECUTE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = 0,
+ .expected_exchange_result = 0,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d1_mount2_src_parent) {
+ /* clang-format on */
+ .allowed_s2d1 = LANDLOCK_ACCESS_FS_REFER |
+ LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_EXECUTE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = EACCES,
+ .expected_same_dir_rename_result = EACCES,
+ .expected_rename_result = EACCES,
+ .expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d2_mount2_src_refer) {
+ /* clang-format on */
+ .allowed_s2d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = EACCES,
+ .expected_rename_result = EACCES,
+ .expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d2_mount2_src_create) {
+ /* clang-format on */
+ .allowed_s2d2 = LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = EXDEV,
+ .expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d2_mount2_src_rename) {
+ /* clang-format on */
+ .allowed_s2d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = EACCES,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = 0,
+ .expected_exchange_result = 0,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d3_mount1_dst_parent_refer) {
+ /* clang-format on */
+ .allowed_s2d3 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = EACCES,
+ .expected_rename_result = EACCES,
+ .expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d3_mount1_dst_parent_create) {
+ /* clang-format on */
+ .allowed_s2d3 = LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = EXDEV,
+ .expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d3_mount1_dst_parent_rename) {
+ /* clang-format on */
+ .allowed_s2d3 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = EACCES,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = 0,
+ .expected_exchange_result = 0,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d4_mount1_dst) {
+ /* clang-format on */
+ .allowed_s2d4 = LANDLOCK_ACCESS_FS_REFER |
+ LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_EXECUTE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = EACCES,
+ .expected_same_dir_rename_result = EACCES,
+ .expected_rename_result = EACCES,
+ .expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s3d1_mount2_dst_parent_refer) {
+ /* clang-format on */
+ .allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = EACCES,
+ .expected_rename_result = EACCES,
+ .expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s3d1_mount2_dst_parent_create) {
+ /* clang-format on */
+ .allowed_s3d1 = LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = EXDEV,
+ .expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s3d1_mount2_dst_parent_rename) {
+ /* clang-format on */
+ .allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = EACCES,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = 0,
+ .expected_exchange_result = 0,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s3d2_mount1_dst) {
+ /* clang-format on */
+ .allowed_s3d2 = LANDLOCK_ACCESS_FS_REFER |
+ LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_EXECUTE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = EACCES,
+ .expected_same_dir_rename_result = EACCES,
+ .expected_rename_result = EACCES,
+ .expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s4d1_rename_parent_refer) {
+ /* clang-format on */
+ .allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = EACCES,
+ .expected_rename_result = EACCES,
+ .expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s4d1_rename_parent_create) {
+ /* clang-format on */
+ .allowed_s4d1 = LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = 0,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = EXDEV,
+ .expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s4d1_rename_parent_rename) {
+ /* clang-format on */
+ .allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+ .expected_read_result = EACCES,
+ .expected_same_dir_rename_result = 0,
+ .expected_rename_result = 0,
+ .expected_exchange_result = 0,
+};
+
+TEST_F_FORK(layout5_disconnected_branch, read_rename_exchange)
+{
+ const __u64 handled_access =
+ LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_EXECUTE | LANDLOCK_ACCESS_FS_MAKE_REG;
+ const struct rule rules[] = {
+ {
+ .path = TMP_DIR "/s1d1",
+ .access = variant->allowed_s1d1,
+ },
+ {
+ .path = TMP_DIR "/s1d1/s1d2",
+ .access = variant->allowed_s1d2,
+ },
+ {
+ .path = TMP_DIR "/s1d1/s1d2/s1d3",
+ .access = variant->allowed_s1d3,
+ },
+ {
+ .path = TMP_DIR "/s2d1",
+ .access = variant->allowed_s2d1,
+ },
+ {
+ .path = TMP_DIR "/s2d1/s2d2",
+ .access = variant->allowed_s2d2,
+ },
+ {
+ .path = TMP_DIR "/s2d1/s2d2/s2d3",
+ .access = variant->allowed_s2d3,
+ },
+ /* s2d4_fd */
+ {
+ .path = TMP_DIR "/s3d1",
+ .access = variant->allowed_s3d1,
+ },
+ /* s3d2_fd */
+ {
+ .path = TMP_DIR "/s4d1",
+ .access = variant->allowed_s4d1,
+ },
+ {},
+ };
+ int ruleset_fd, s1d3_bind_fd;
+
+ ruleset_fd = create_ruleset(_metadata, handled_access, rules);
+ ASSERT_LE(0, ruleset_fd);
+
+ /* Adds rules for the covered directories. */
+ if (variant->allowed_s2d4) {
+ ASSERT_EQ(0, landlock_add_rule(
+ ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
+ &(struct landlock_path_beneath_attr){
+ .parent_fd = self->s2d4_fd,
+ .allowed_access =
+ variant->allowed_s2d4,
+ },
+ 0));
+ }
+ EXPECT_EQ(0, close(self->s2d4_fd));
+
+ if (variant->allowed_s3d2) {
+ ASSERT_EQ(0, landlock_add_rule(
+ ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
+ &(struct landlock_path_beneath_attr){
+ .parent_fd = self->s3d2_fd,
+ .allowed_access =
+ variant->allowed_s3d2,
+ },
+ 0));
+ }
+ EXPECT_EQ(0, close(self->s3d2_fd));
+
+ s1d3_bind_fd = open(TMP_DIR "/s3d1/s3d2/s2d3/s2d4/s1d3",
+ O_DIRECTORY | O_PATH | O_CLOEXEC);
+ ASSERT_LE(0, s1d3_bind_fd);
+
+ /* Disconnects and checks source and destination directories. */
+ EXPECT_EQ(0, test_open_rel(s1d3_bind_fd, "..", O_DIRECTORY));
+ EXPECT_EQ(0, test_open_rel(s1d3_bind_fd, "../..", O_DIRECTORY));
+ /* Renames to make it accessible through s3d1/s1d41 */
+ ASSERT_EQ(0, test_renameat(AT_FDCWD, TMP_DIR "/s2d1/s2d2/s2d3",
+ AT_FDCWD, TMP_DIR "/s4d1/s2d3"));
+ EXPECT_EQ(0, test_open_rel(s1d3_bind_fd, "..", O_DIRECTORY));
+ EXPECT_EQ(ENOENT, test_open_rel(s1d3_bind_fd, "../..", O_DIRECTORY));
+
+ enforce_ruleset(_metadata, ruleset_fd);
+ EXPECT_EQ(0, close(ruleset_fd));
+
+ EXPECT_EQ(variant->expected_read_result,
+ test_open_rel(s1d3_bind_fd, "s1d41/f1", O_RDONLY));
+
+ EXPECT_EQ(variant->expected_rename_result,
+ test_renameat(s1d3_bind_fd, "s1d41/f1", s1d3_bind_fd,
+ "s1d42/f1"));
+ EXPECT_EQ(variant->expected_exchange_result,
+ test_exchangeat(s1d3_bind_fd, "s1d41/f2", s1d3_bind_fd,
+ "s1d42/f3"));
+
+ EXPECT_EQ(variant->expected_same_dir_rename_result,
+ test_renameat(s1d3_bind_fd, "s1d42/f4", s1d3_bind_fd,
+ "s1d42/f5"));
+}
+
#define LOWER_BASE TMP_DIR "/lower"
#define LOWER_DATA LOWER_BASE "/data"
static const char lower_fl1[] = LOWER_DATA "/fl1";
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 008/877] s390/boot: Add sized_strscpy() to enable strscpy() usage
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (6 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 007/877] selftests/landlock: Add disconnected leafs and branch test suites Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 009/877] s390/boot: Avoid IPL parameter append past command line Greg Kroah-Hartman
` (876 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vasily Gorbik, Heiko Carstens,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasily Gorbik <gor@linux.ibm.com>
[ Upstream commit f271df9d41c216f6189c40fa1cb83839a6117c3e ]
Add a simple sized_strscpy() implementation to allow the use of strscpy()
in the decompressor.
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/boot/string.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/s390/boot/string.c b/arch/s390/boot/string.c
index f6b9b1df48a82..bd68161434a60 100644
--- a/arch/s390/boot/string.c
+++ b/arch/s390/boot/string.c
@@ -29,6 +29,18 @@ int strncmp(const char *cs, const char *ct, size_t count)
return 0;
}
+ssize_t sized_strscpy(char *dst, const char *src, size_t count)
+{
+ size_t len;
+
+ if (count == 0)
+ return -E2BIG;
+ len = strnlen(src, count - 1);
+ memcpy(dst, src, len);
+ dst[len] = '\0';
+ return src[len] ? -E2BIG : len;
+}
+
void *memset64(uint64_t *s, uint64_t v, size_t count)
{
uint64_t *xs = s;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 009/877] s390/boot: Avoid IPL parameter append past command line
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (7 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 008/877] s390/boot: Add sized_strscpy() to enable strscpy() usage Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 010/877] selftests/landlock: Add tests for whiteout object creation Greg Kroah-Hartman
` (875 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Heiko Carstens, Vasily Gorbik,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasily Gorbik <gor@linux.ibm.com>
[ Upstream commit d76181dfabdaa720703167393704efacba343442 ]
A command line may occupy all but the terminating byte of
COMMAND_LINE_SIZE. In that case append_ipl_block_parm() passes a zero size
to the IPL parameter conversion helpers and points the destination one
byte past early_command_line. The helpers subtract one from the unsigned
size and write the converted parameter outside the command line buffer.
Convert the IPL parameter in the command line parsing buffer first. A
parameter beginning with '=' can then replace the existing command line
regardless of its length, while other parameters are appended only when
space remains.
Fixes: 5ecb2da660ab ("s390: support command lines longer than 896 bytes")
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/boot/ipl_parm.c | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c
index 557462e62cd73..6c77afb3b8a11 100644
--- a/arch/s390/boot/ipl_parm.c
+++ b/arch/s390/boot/ipl_parm.c
@@ -21,6 +21,7 @@ struct parmarea parmarea __section(".parmarea") = {
};
char __bootdata(early_command_line)[COMMAND_LINE_SIZE];
+static char command_line_buf[COMMAND_LINE_SIZE];
unsigned int __bootdata_preserved(zlib_dfltcc_support) = ZLIB_DFLTCC_FULL;
struct ipl_parameter_block __bootdata_preserved(ipl_block);
@@ -148,31 +149,29 @@ static size_t ipl_block_get_ascii_scpdata(char *dest, size_t size,
static void append_ipl_block_parm(void)
{
- char *parm, *delim;
- size_t len, rc = 0;
+ size_t len, extra = 0;
+ char *delim;
len = strlen(early_command_line);
-
- delim = early_command_line + len; /* '\0' character position */
- parm = early_command_line + len + 1; /* append right after '\0' */
+ delim = early_command_line + len; /* '\0' character position */
switch (ipl_block.pb0_hdr.pbt) {
case IPL_PBT_CCW:
- rc = ipl_block_get_ascii_vmparm(
- parm, COMMAND_LINE_SIZE - len - 1, &ipl_block);
+ extra = ipl_block_get_ascii_vmparm(command_line_buf, sizeof(command_line_buf), &ipl_block);
break;
case IPL_PBT_FCP:
case IPL_PBT_NVME:
case IPL_PBT_ECKD:
- rc = ipl_block_get_ascii_scpdata(
- parm, COMMAND_LINE_SIZE - len - 1, &ipl_block);
+ extra = ipl_block_get_ascii_scpdata(command_line_buf, sizeof(command_line_buf), &ipl_block);
break;
}
- if (rc) {
- if (*parm == '=')
- memmove(early_command_line, parm + 1, rc);
- else
+ if (extra) {
+ if (command_line_buf[0] == '=') {
+ memmove(early_command_line, command_line_buf + 1, extra);
+ } else if (len < COMMAND_LINE_SIZE - 2) {
*delim = ' '; /* replace '\0' with space */
+ sized_strscpy(delim + 1, command_line_buf, COMMAND_LINE_SIZE - len - 1);
+ }
}
}
@@ -258,7 +257,6 @@ static void modify_fac_list(char *str)
check_cleared_facilities();
}
-static char command_line_buf[COMMAND_LINE_SIZE];
void parse_boot_command_line(void)
{
char *param, *val;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 010/877] selftests/landlock: Add tests for whiteout object creation
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (8 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 009/877] s390/boot: Avoid IPL parameter append past command line Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 011/877] sunvdc: fix -EIO issue due to lack of retries Greg Kroah-Hartman
` (874 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Günther Noack,
Mickaël Salaün, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Günther Noack <gnoack@google.com>
[ Upstream commit ee890889b30b22f9a21636061def7a04e4f89380 ]
Add tests to check that whiteout object creation is guarded by
LANDLOCK_ACCESS_FS_MAKE_REG, in the cases where these are created from
userspace:
* Conventional creation with mknod()
* Linking or renaming an existing whiteout object
* renameat2() with RENAME_WHITEOUT,
which creates a new whiteout object in the source location
* renameat2() with RENAME_EXCHANGE,
with one of the renamed objects being a whiteout object
Signed-off-by: Günther Noack <gnoack@google.com>
Link: https://patch.msgid.link/20260813093157.1436894-4-gnoack@google.com
[mic: Update commit message as requested]
Signed-off-by: Mickaël Salaün <mic@digikod.net>
[mic: Backport: adapt the tests to the older filesystem fixture and
ruleset helper]
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/landlock/fs_test.c | 205 ++++++++++++++++++++-
1 file changed, 203 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c
index 732ba5a92df56..ae96637ad40e9 100644
--- a/tools/testing/selftests/landlock/fs_test.c
+++ b/tools/testing/selftests/landlock/fs_test.c
@@ -85,6 +85,8 @@ static const char file1_s3d1[] = TMP_DIR "/s3d1/f1";
/* dir_s3d2 is a mount point. */
static const char dir_s3d2[] = TMP_DIR "/s3d1/s3d2";
static const char dir_s3d3[] = TMP_DIR "/s3d1/s3d2/s3d3";
+static const char file1_s3d3[] = TMP_DIR "/s3d1/s3d2/s3d3/f1";
+static const char file1_s3d4[] = TMP_DIR "/s3d1/s3d2/s3d4/f1";
/*
* layout1 hierarchy:
@@ -358,7 +360,8 @@ static void create_layout1(struct __test_metadata *const _metadata)
ASSERT_EQ(0, mount_opt(&mnt_tmp, dir_s3d2));
clear_cap(_metadata, CAP_SYS_ADMIN);
- ASSERT_EQ(0, mkdir(dir_s3d3, 0700));
+ create_file(_metadata, file1_s3d3);
+ create_file(_metadata, file1_s3d4);
}
static void remove_layout1(struct __test_metadata *const _metadata)
@@ -378,7 +381,8 @@ static void remove_layout1(struct __test_metadata *const _metadata)
EXPECT_EQ(0, remove_path(dir_s2d2));
EXPECT_EQ(0, remove_path(file1_s3d1));
- EXPECT_EQ(0, remove_path(dir_s3d3));
+ EXPECT_EQ(0, remove_path(file1_s3d3));
+ EXPECT_EQ(0, remove_path(file1_s3d4));
set_cap(_metadata, CAP_SYS_ADMIN);
umount(dir_s3d2);
clear_cap(_metadata, CAP_SYS_ADMIN);
@@ -772,6 +776,27 @@ static int create_ruleset(struct __test_metadata *const _metadata,
return ruleset_fd;
}
+static void enforce_fs(struct __test_metadata *const _metadata,
+ const __u64 access_fs, const struct rule rules[])
+{
+ int ruleset_fd;
+
+ if (rules) {
+ ruleset_fd = create_ruleset(_metadata, access_fs, rules);
+ } else {
+ const struct landlock_ruleset_attr ruleset_attr = {
+ .handled_access_fs = access_fs,
+ };
+
+ ruleset_fd = landlock_create_ruleset(&ruleset_attr,
+ sizeof(ruleset_attr), 0);
+ ASSERT_LE(0, ruleset_fd);
+ }
+
+ enforce_ruleset(_metadata, ruleset_fd);
+ EXPECT_EQ(0, close(ruleset_fd));
+}
+
TEST_F_FORK(layout0, proc_nsfs)
{
const struct rule rules[] = {
@@ -2207,6 +2232,170 @@ TEST_F_FORK(layout1, rename_file)
RENAME_EXCHANGE));
}
+TEST_F_FORK(layout1, rename_whiteout_denied)
+{
+ /* The affected file is a FIFO. */
+ ASSERT_EQ(0, unlink(file1_s3d3));
+ ASSERT_EQ(0, mknod(file1_s3d3, S_IFIFO | 0600, 0));
+
+ /* Deny MAKE_REG, but allow MAKE_FIFO. */
+ enforce_fs(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, NULL);
+
+ /*
+ * Try to rename a file with RENAME_WHITEOUT.
+ * file1_s3d3 is in dir_s3d2 (tmpfs), so it supports RENAME_WHITEOUT.
+ * Denied, because whiteout creation is guarded with MAKE_REG.
+ */
+ EXPECT_EQ(-1, renameat2(AT_FDCWD, file1_s3d3, AT_FDCWD,
+ TMP_DIR "/s3d1/s3d2/s3d3/f2", RENAME_WHITEOUT));
+ EXPECT_EQ(EACCES, errno);
+}
+
+static bool is_whiteout(const char *const path)
+{
+ struct stat st;
+
+ if (stat(path, &st) == -1)
+ return false;
+
+ return S_ISCHR(st.st_mode) && st.st_rdev == makedev(0, 0);
+}
+
+static bool is_fifo(const char *const path)
+{
+ struct stat st;
+
+ return stat(path, &st) == 0 && S_ISFIFO(st.st_mode);
+}
+
+TEST_F_FORK(layout1, rename_whiteout_allowed)
+{
+ const struct rule rules[] = {
+ {
+ .path = dir_s3d3,
+ .access = LANDLOCK_ACCESS_FS_MAKE_REG,
+ },
+ {},
+ };
+
+ /* The affected file is a FIFO. */
+ ASSERT_EQ(0, unlink(file1_s3d3));
+ ASSERT_EQ(0, mknod(file1_s3d3, S_IFIFO | 0600, 0));
+
+ /* Allow MAKE_REG below dir_s3d3. */
+ enforce_fs(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, rules);
+
+ /*
+ * Rename a file with RENAME_WHITEOUT within the same directory.
+ * Allowed, because MAKE_REG is granted for the whiteout object which
+ * gets created in the source location.
+ */
+ EXPECT_EQ(0, renameat2(AT_FDCWD, file1_s3d3, AT_FDCWD,
+ TMP_DIR "/s3d1/s3d2/s3d3/f2", RENAME_WHITEOUT));
+
+ /* A whiteout object took the place of the moved FIFO. */
+ EXPECT_TRUE(is_whiteout(file1_s3d3));
+ EXPECT_TRUE(is_fifo(TMP_DIR "/s3d1/s3d2/s3d3/f2"));
+}
+
+TEST_F_FORK(layout1, rename_whiteout_reparenting)
+{
+ const struct rule rules[] = {
+ {
+ .path = dir_s3d2,
+ .access = LANDLOCK_ACCESS_FS_REFER,
+ },
+ {
+ .path = dir_s3d3,
+ .access = LANDLOCK_ACCESS_FS_MAKE_REG,
+ },
+ {},
+ };
+
+ /* The moved files are FIFOs. */
+ ASSERT_EQ(0, unlink(file1_s3d3));
+ ASSERT_EQ(0, mknod(file1_s3d3, S_IFIFO | 0600, 0));
+ ASSERT_EQ(0, unlink(file1_s3d4));
+ ASSERT_EQ(0, mknod(file1_s3d4, S_IFIFO | 0600, 0));
+
+ /* Allow REFER below dir_s3d2, but MAKE_REG only below dir_s3d3. */
+ enforce_fs(_metadata,
+ LANDLOCK_ACCESS_FS_MAKE_REG | LANDLOCK_ACCESS_FS_REFER,
+ rules);
+
+ /*
+ * The whiteout object is created in the source directory: Moving the
+ * FIFO out of dir_s3d4 is denied because MAKE_REG is not granted
+ * there, even though it is granted in the destination directory
+ * dir_s3d3.
+ */
+ EXPECT_EQ(-1, renameat2(AT_FDCWD, file1_s3d4, AT_FDCWD,
+ TMP_DIR "/s3d1/s3d2/s3d3/f2", RENAME_WHITEOUT));
+ EXPECT_EQ(EACCES, errno);
+
+ /*
+ * Moving the FIFO out of dir_s3d3 is allowed, because MAKE_REG is
+ * granted there for the created whiteout object.
+ */
+ EXPECT_EQ(0, renameat2(AT_FDCWD, file1_s3d3, AT_FDCWD,
+ TMP_DIR "/s3d1/s3d2/s3d4/f2", RENAME_WHITEOUT));
+
+ /* A whiteout object took the place of the moved FIFO. */
+ EXPECT_TRUE(is_whiteout(file1_s3d3));
+ EXPECT_TRUE(is_fifo(TMP_DIR "/s3d1/s3d2/s3d4/f2"));
+}
+
+TEST_F_FORK(layout1, rename_whiteout_exchange)
+{
+ const char *const whiteout_s3d3 = TMP_DIR "/s3d1/s3d2/s3d3/f2";
+ const struct rule rules[] = {
+ {
+ .path = dir_s3d2,
+ .access = LANDLOCK_ACCESS_FS_REFER,
+ },
+ {
+ .path = dir_s3d3,
+ .access = LANDLOCK_ACCESS_FS_MAKE_REG,
+ },
+ {},
+ };
+
+ /* The exchanged files are FIFOs and an existing whiteout object. */
+ ASSERT_EQ(0, unlink(file1_s3d3));
+ ASSERT_EQ(0, mknod(file1_s3d3, S_IFIFO | 0600, 0));
+ ASSERT_EQ(0, mknod(whiteout_s3d3, S_IFCHR | 0600, makedev(0, 0)));
+ ASSERT_EQ(0, unlink(file1_s3d4));
+ ASSERT_EQ(0, mknod(file1_s3d4, S_IFIFO | 0600, 0));
+
+ /* Allow REFER below dir_s3d2, but MAKE_REG only below dir_s3d3. */
+ enforce_fs(_metadata,
+ LANDLOCK_ACCESS_FS_MAKE_REG | LANDLOCK_ACCESS_FS_REFER,
+ rules);
+
+ /*
+ * With RENAME_EXCHANGE, the whiteout object moves into the source
+ * directory of the rename: Exchanging the FIFO in dir_s3d4 with the
+ * whiteout object is denied because MAKE_REG is not granted in
+ * dir_s3d4, even though it is granted in the whiteout object's own
+ * directory dir_s3d3.
+ */
+ EXPECT_EQ(-1, renameat2(AT_FDCWD, file1_s3d4, AT_FDCWD, whiteout_s3d3,
+ RENAME_EXCHANGE));
+ EXPECT_EQ(EACCES, errno);
+
+ /*
+ * Exchanging the FIFO in dir_s3d3 with the whiteout object is
+ * allowed, because MAKE_REG is granted in the directory into which
+ * the whiteout object moves.
+ */
+ EXPECT_EQ(0, renameat2(AT_FDCWD, file1_s3d3, AT_FDCWD, whiteout_s3d3,
+ RENAME_EXCHANGE));
+
+ /* The FIFO and the whiteout object swapped places. */
+ EXPECT_TRUE(is_whiteout(file1_s3d3));
+ EXPECT_TRUE(is_fifo(whiteout_s3d3));
+}
+
TEST_F_FORK(layout1, rename_dir)
{
const struct rule rules[] = {
@@ -3260,6 +3449,18 @@ TEST_F_FORK(layout1, make_char)
makedev(1, 3));
}
+TEST_F_FORK(layout1, make_whiteout)
+{
+ /*
+ * Creates a whiteout object (creation guarded by MAKE_REG).
+ *
+ * Contrary to the other character devices, this does not require
+ * CAP_MKNOD, cf. vfs_mknod().
+ */
+ test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, S_IFCHR,
+ makedev(0, 0));
+}
+
TEST_F_FORK(layout1, make_block)
{
/* Creates a /dev/loop0 device. */
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 011/877] sunvdc: fix -EIO issue due to lack of retries
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (9 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 010/877] selftests/landlock: Add tests for whiteout object creation Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 012/877] net: cpsw_new: Execute ndo_set_rx_mode callback in a work queue Greg Kroah-Hartman
` (873 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, John Paul Adrian Glaubitz,
Stian Halseth, Jens Axboe, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <axboe@kernel.dk>
[ Upstream commit 5067d4ba713961d8ccea1e06cd4c453793f3121e ]
John reports that since commit:
a11f6ca9aef9 ("sunvdc: Do not spin in an infinite loop when vio_ldc_send() returns EAGAIN")
users of Linux inside Solaris ldom see occasional -EIO errors because
the request send loop now times out. The current loop does 10 retries,
and inside vio_ldc_send() a further 1000 1usec retries are done as well.
Even with 10.5 msec of busy loop retries that's apparently not enough to
always succeed.
Rather than introduce continued busy looping, requeue the request and
have the delayed queue kicking retry the request after another 10ms.
This obviously isn't ideal, but there's seemingly no way to wait for
this type of event. And if 10ms of busy looping was not enough to make
progress, then presumably this is an edge condition and we just need to
guarantee to make forward progress at some later point in time. That's
more suitably done through letting the CPU tend to other work, rather
than sitting in a tight loop retrying.
[stian: rebased on top of the cookie-unmap fix, without which every
requeued attempt leaks LDC map table entries; tested on an
UltraSPARC T4 LDOM where the vdc_tx_trigger failure condition was
reproduced and absorbed by the requeue with no I/O error]
Reported-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Link: https://lore.kernel.org/all/20251006100226.4246-2-glaubitz@physik.fu-berlin.de/
Link: https://lore.kernel.org/all/418310b3-2b77-4534-b2fd-27dcc11e333c@kernel.dk/
Signed-off-by: Stian Halseth <stian@itx.no>
Link: https://patch.msgid.link/20260901173947.3292110-3-stian@itx.no
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/block/sunvdc.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
index 97fe566465d79..16953341e5013 100644
--- a/drivers/block/sunvdc.c
+++ b/drivers/block/sunvdc.c
@@ -557,6 +557,7 @@ static blk_status_t vdc_queue_rq(struct blk_mq_hw_ctx *hctx,
struct vdc_port *port = hctx->queue->queuedata;
struct vio_dring_state *dr;
unsigned long flags;
+ int ret;
dr = &port->vio.drings[VIO_DRIVER_TX_RING];
@@ -578,7 +579,13 @@ static blk_status_t vdc_queue_rq(struct blk_mq_hw_ctx *hctx,
return BLK_STS_DEV_RESOURCE;
}
- if (__send_request(bd->rq) < 0) {
+ ret = __send_request(bd->rq);
+ if (ret == -EAGAIN) {
+ spin_unlock_irqrestore(&port->vio.lock, flags);
+ /* already spun for 10msec, defer 10msec and retry */
+ blk_mq_delay_kick_requeue_list(hctx->queue, 10);
+ return BLK_STS_DEV_RESOURCE;
+ } else if (ret < 0) {
spin_unlock_irqrestore(&port->vio.lock, flags);
return BLK_STS_IOERR;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 012/877] net: cpsw_new: Execute ndo_set_rx_mode callback in a work queue
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (10 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 011/877] sunvdc: fix -EIO issue due to lack of retries Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 013/877] net: cpsw: " Greg Kroah-Hartman
` (872 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Kevin Hao, Jakub Kicinski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kevin Hao <haokexin@gmail.com>
commit c0b5dc73a38f954e780f93a549b8fe225235c07a upstream.
Commit 1767bb2d47b7 ("ipv6: mcast: Don't hold RTNL for
IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP.") removed the RTNL lock for
IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP operations. However, this
change triggered the following call trace on my BeagleBone Black board:
WARNING: net/8021q/vlan_core.c:236 at vlan_for_each+0x120/0x124, CPU#0: rpcbind/496
RTNL: assertion failed at net/8021q/vlan_core.c (236)
Modules linked in:
CPU: 0 UID: 997 PID: 496 Comm: rpcbind Not tainted 6.19.0-rc6-next-20260122-yocto-standard+ #8 PREEMPT
Hardware name: Generic AM33XX (Flattened Device Tree)
Call trace:
unwind_backtrace from show_stack+0x28/0x2c
show_stack from dump_stack_lvl+0x30/0x38
dump_stack_lvl from __warn+0xb8/0x11c
__warn from warn_slowpath_fmt+0x130/0x194
warn_slowpath_fmt from vlan_for_each+0x120/0x124
vlan_for_each from cpsw_add_mc_addr+0x54/0xd8
cpsw_add_mc_addr from __hw_addr_ref_sync_dev+0xc4/0xec
__hw_addr_ref_sync_dev from __dev_mc_add+0x78/0x88
__dev_mc_add from igmp6_group_added+0x84/0xec
igmp6_group_added from __ipv6_dev_mc_inc+0x1fc/0x2f0
__ipv6_dev_mc_inc from __ipv6_sock_mc_join+0x124/0x1b4
__ipv6_sock_mc_join from do_ipv6_setsockopt+0x84c/0x1168
do_ipv6_setsockopt from ipv6_setsockopt+0x88/0xc8
ipv6_setsockopt from do_sock_setsockopt+0xe8/0x19c
do_sock_setsockopt from __sys_setsockopt+0x84/0xac
__sys_setsockopt from ret_fast_syscall+0x0/0x5
This trace occurs because vlan_for_each() is called within
cpsw_ndo_set_rx_mode(), which expects the RTNL lock to be held.
Since modifying vlan_for_each() to operate without the RTNL lock is not
straightforward, and because ndo_set_rx_mode() is invoked both with and
without the RTNL lock across different code paths, simply adding
rtnl_lock() in cpsw_ndo_set_rx_mode() is not a viable solution.
To resolve this issue, we opt to execute the actual processing within
a work queue, following the approach used by the icssg-prueth driver.
Fixes: 1767bb2d47b7 ("ipv6: mcast: Don't hold RTNL for IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP.")
Signed-off-by: Kevin Hao <haokexin@gmail.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260203-bbb-v5-1-ea0ea217a85c@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/ti/cpsw_new.c | 35 ++++++++++++++++++++++++-----
drivers/net/ethernet/ti/cpsw_priv.h | 1 +
2 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpsw_new.c b/drivers/net/ethernet/ti/cpsw_new.c
index 468eaa6f785e6..c2041e46b83d6 100644
--- a/drivers/net/ethernet/ti/cpsw_new.c
+++ b/drivers/net/ethernet/ti/cpsw_new.c
@@ -248,16 +248,22 @@ static int cpsw_purge_all_mc(struct net_device *ndev, const u8 *addr, int num)
return 0;
}
-static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
+static void cpsw_ndo_set_rx_mode_work(struct work_struct *work)
{
- struct cpsw_priv *priv = netdev_priv(ndev);
+ struct cpsw_priv *priv = container_of(work, struct cpsw_priv, rx_mode_work);
struct cpsw_common *cpsw = priv->cpsw;
+ struct net_device *ndev = priv->ndev;
+
+ rtnl_lock();
+ if (!netif_running(ndev))
+ goto unlock_rtnl;
+ netif_addr_lock_bh(ndev);
if (ndev->flags & IFF_PROMISC) {
/* Enable promiscuous mode */
cpsw_set_promiscious(ndev, true);
cpsw_ale_set_allmulti(cpsw->ale, IFF_ALLMULTI, priv->emac_port);
- return;
+ goto unlock_addr;
}
/* Disable promiscuous mode */
@@ -270,6 +276,18 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
/* add/remove mcast address either for real netdev or for vlan */
__hw_addr_ref_sync_dev(&ndev->mc, ndev, cpsw_add_mc_addr,
cpsw_del_mc_addr);
+
+unlock_addr:
+ netif_addr_unlock_bh(ndev);
+unlock_rtnl:
+ rtnl_unlock();
+}
+
+static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
+{
+ struct cpsw_priv *priv = netdev_priv(ndev);
+
+ schedule_work(&priv->rx_mode_work);
}
static unsigned int cpsw_rxbuf_total_len(unsigned int len)
@@ -1391,6 +1409,7 @@ static int cpsw_create_ports(struct cpsw_common *cpsw)
priv->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG);
priv->emac_port = i + 1;
priv->tx_packet_min = CPSW_MIN_PACKET_SIZE;
+ INIT_WORK(&priv->rx_mode_work, cpsw_ndo_set_rx_mode_work);
if (is_valid_ether_addr(slave_data->mac_addr)) {
ether_addr_copy(priv->mac_addr, slave_data->mac_addr);
@@ -1440,14 +1459,18 @@ static int cpsw_create_ports(struct cpsw_common *cpsw)
static void cpsw_unregister_ports(struct cpsw_common *cpsw)
{
+ struct net_device *ndev;
+ struct cpsw_priv *priv;
int i = 0;
for (i = 0; i < cpsw->data.slaves; i++) {
- if (!cpsw->slaves[i].ndev ||
- cpsw->slaves[i].ndev->reg_state != NETREG_REGISTERED)
+ ndev = cpsw->slaves[i].ndev;
+ if (!ndev || ndev->reg_state != NETREG_REGISTERED)
continue;
- unregister_netdev(cpsw->slaves[i].ndev);
+ priv = netdev_priv(ndev);
+ unregister_netdev(ndev);
+ disable_work_sync(&priv->rx_mode_work);
}
}
diff --git a/drivers/net/ethernet/ti/cpsw_priv.h b/drivers/net/ethernet/ti/cpsw_priv.h
index 1f448290b9f4b..bacaa855e6148 100644
--- a/drivers/net/ethernet/ti/cpsw_priv.h
+++ b/drivers/net/ethernet/ti/cpsw_priv.h
@@ -391,6 +391,7 @@ struct cpsw_priv {
u32 tx_packet_min;
struct cpsw_ale_ratelimit ale_bc_ratelimit;
struct cpsw_ale_ratelimit ale_mc_ratelimit;
+ struct work_struct rx_mode_work;
};
#define ndev_to_cpsw(ndev) (((struct cpsw_priv *)netdev_priv(ndev))->cpsw)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 013/877] net: cpsw: Execute ndo_set_rx_mode callback in a work queue
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (11 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 012/877] net: cpsw_new: Execute ndo_set_rx_mode callback in a work queue Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 014/877] ipv6: mcast: Use in6_dev_get() in ipv6_dev_mc_dec() Greg Kroah-Hartman
` (871 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Kevin Hao, Jakub Kicinski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kevin Hao <haokexin@gmail.com>
commit 0b8c878d117319f2be34c8391a77e0f4d5c94d79 upstream.
Commit 1767bb2d47b7 ("ipv6: mcast: Don't hold RTNL for
IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP.") removed the RTNL lock for
IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP operations. However, this
change triggered the following call trace on my BeagleBone Black board:
WARNING: net/8021q/vlan_core.c:236 at vlan_for_each+0x120/0x124, CPU#0: rpcbind/481
RTNL: assertion failed at net/8021q/vlan_core.c (236)
Modules linked in:
CPU: 0 UID: 997 PID: 481 Comm: rpcbind Not tainted 6.19.0-rc7-next-20260130-yocto-standard+ #35 PREEMPT
Hardware name: Generic AM33XX (Flattened Device Tree)
Call trace:
unwind_backtrace from show_stack+0x28/0x2c
show_stack from dump_stack_lvl+0x30/0x38
dump_stack_lvl from __warn+0xb8/0x11c
__warn from warn_slowpath_fmt+0x130/0x194
warn_slowpath_fmt from vlan_for_each+0x120/0x124
vlan_for_each from cpsw_add_mc_addr+0x54/0x98
cpsw_add_mc_addr from __hw_addr_ref_sync_dev+0xc4/0xec
__hw_addr_ref_sync_dev from __dev_mc_add+0x78/0x88
__dev_mc_add from igmp6_group_added+0x84/0xec
igmp6_group_added from __ipv6_dev_mc_inc+0x1fc/0x2f0
__ipv6_dev_mc_inc from __ipv6_sock_mc_join+0x124/0x1b4
__ipv6_sock_mc_join from do_ipv6_setsockopt+0x84c/0x1168
do_ipv6_setsockopt from ipv6_setsockopt+0x88/0xc8
ipv6_setsockopt from do_sock_setsockopt+0xe8/0x19c
do_sock_setsockopt from __sys_setsockopt+0x84/0xac
__sys_setsockopt from ret_fast_syscall+0x0/0x54
This trace occurs because vlan_for_each() is called within
cpsw_ndo_set_rx_mode(), which expects the RTNL lock to be held.
Since modifying vlan_for_each() to operate without the RTNL lock is not
straightforward, and because ndo_set_rx_mode() is invoked both with and
without the RTNL lock across different code paths, simply adding
rtnl_lock() in cpsw_ndo_set_rx_mode() is not a viable solution.
To resolve this issue, we opt to execute the actual processing within
a work queue, following the approach used by the icssg-prueth driver.
Please note: To reproduce this issue, I manually reverted the changes to
am335x-bone-common.dtsi from commit c477358e66a3 ("ARM: dts: am335x-bone:
switch to new cpsw switch drv") in order to revert to the legacy cpsw
driver.
Fixes: 1767bb2d47b7 ("ipv6: mcast: Don't hold RTNL for IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP.")
Signed-off-by: Kevin Hao <haokexin@gmail.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260203-bbb-v5-2-ea0ea217a85c@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/ti/cpsw.c | 41 +++++++++++++++++++++++++++++-----
1 file changed, 35 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index c0a5abd8d9a8e..2968b5fbe428c 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -305,12 +305,19 @@ static int cpsw_purge_all_mc(struct net_device *ndev, const u8 *addr, int num)
return 0;
}
-static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
+static void cpsw_ndo_set_rx_mode_work(struct work_struct *work)
{
- struct cpsw_priv *priv = netdev_priv(ndev);
+ struct cpsw_priv *priv = container_of(work, struct cpsw_priv, rx_mode_work);
struct cpsw_common *cpsw = priv->cpsw;
+ struct net_device *ndev = priv->ndev;
int slave_port = -1;
+ rtnl_lock();
+ if (!netif_running(ndev))
+ goto unlock_rtnl;
+
+ netif_addr_lock_bh(ndev);
+
if (cpsw->data.dual_emac)
slave_port = priv->emac_port + 1;
@@ -318,7 +325,7 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
/* Enable promiscuous mode */
cpsw_set_promiscious(ndev, true);
cpsw_ale_set_allmulti(cpsw->ale, IFF_ALLMULTI, slave_port);
- return;
+ goto unlock_addr;
} else {
/* Disable promiscuous mode */
cpsw_set_promiscious(ndev, false);
@@ -331,6 +338,18 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
/* add/remove mcast address either for real netdev or for vlan */
__hw_addr_ref_sync_dev(&ndev->mc, ndev, cpsw_add_mc_addr,
cpsw_del_mc_addr);
+
+unlock_addr:
+ netif_addr_unlock_bh(ndev);
+unlock_rtnl:
+ rtnl_unlock();
+}
+
+static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
+{
+ struct cpsw_priv *priv = netdev_priv(ndev);
+
+ schedule_work(&priv->rx_mode_work);
}
static unsigned int cpsw_rxbuf_total_len(unsigned int len)
@@ -1444,6 +1463,7 @@ static int cpsw_probe_dual_emac(struct cpsw_priv *priv)
priv_sl2->ndev = ndev;
priv_sl2->dev = &ndev->dev;
priv_sl2->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG);
+ INIT_WORK(&priv_sl2->rx_mode_work, cpsw_ndo_set_rx_mode_work);
if (is_valid_ether_addr(data->slave_data[1].mac_addr)) {
memcpy(priv_sl2->mac_addr, data->slave_data[1].mac_addr,
@@ -1625,6 +1645,7 @@ static int cpsw_probe(struct platform_device *pdev)
priv->dev = dev;
priv->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG);
priv->emac_port = 0;
+ INIT_WORK(&priv->rx_mode_work, cpsw_ndo_set_rx_mode_work);
if (is_valid_ether_addr(data->slave_data[0].mac_addr)) {
memcpy(priv->mac_addr, data->slave_data[0].mac_addr, ETH_ALEN);
@@ -1727,6 +1748,8 @@ static int cpsw_probe(struct platform_device *pdev)
static void cpsw_remove(struct platform_device *pdev)
{
struct cpsw_common *cpsw = platform_get_drvdata(pdev);
+ struct net_device *ndev;
+ struct cpsw_priv *priv;
int i, ret;
ret = pm_runtime_resume_and_get(&pdev->dev);
@@ -1739,9 +1762,15 @@ static void cpsw_remove(struct platform_device *pdev)
return;
}
- for (i = 0; i < cpsw->data.slaves; i++)
- if (cpsw->slaves[i].ndev)
- unregister_netdev(cpsw->slaves[i].ndev);
+ for (i = 0; i < cpsw->data.slaves; i++) {
+ ndev = cpsw->slaves[i].ndev;
+ if (!ndev)
+ continue;
+
+ priv = netdev_priv(ndev);
+ unregister_netdev(ndev);
+ disable_work_sync(&priv->rx_mode_work);
+ }
cpts_release(cpsw->cpts);
cpdma_ctlr_destroy(cpsw->dma);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 014/877] ipv6: mcast: Use in6_dev_get() in ipv6_dev_mc_dec().
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (12 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 013/877] net: cpsw: " Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 015/877] ipv6: mcast: Dont hold RTNL for IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP Greg Kroah-Hartman
` (870 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Eric Dumazet,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit e01b193e0b50ae849bf60067e111446f19ee2f20 ]
As well as __ipv6_dev_mc_inc(), all code in __ipv6_dev_mc_dec() are
protected by inet6_dev->mc_lock, and RTNL is not needed.
Let's use in6_dev_get() in ipv6_dev_mc_dec() and remove ASSERT_RTNL()
in __ipv6_dev_mc_dec().
Now, we can remove the RTNL comment above addrconf_leave_solict() too.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20250702230210.3115355-6-kuni1840@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/addrconf.c | 3 +--
net/ipv6/mcast.c | 14 ++++++--------
2 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index ef938fb1d7549..fb239e8f83593 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2255,12 +2255,11 @@ void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr)
ipv6_dev_mc_inc(dev, &maddr);
}
-/* caller must hold RTNL */
void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr)
{
struct in6_addr maddr;
- if (idev->dev->flags&(IFF_LOOPBACK|IFF_NOARP))
+ if (READ_ONCE(idev->dev->flags) & (IFF_LOOPBACK | IFF_NOARP))
return;
addrconf_addr_solict_mult(addr, &maddr);
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index c060954c52757..212c2d8efe0f5 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -972,9 +972,8 @@ int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr)
{
struct ifmcaddr6 *ma, __rcu **map;
- ASSERT_RTNL();
-
mutex_lock(&idev->mc_lock);
+
for (map = &idev->mc_list;
(ma = mc_dereference(*map, idev));
map = &ma->next) {
@@ -1003,13 +1002,12 @@ int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr)
struct inet6_dev *idev;
int err;
- ASSERT_RTNL();
-
- idev = __in6_dev_get(dev);
+ idev = in6_dev_get(dev);
if (!idev)
- err = -ENODEV;
- else
- err = __ipv6_dev_mc_dec(idev, addr);
+ return -ENODEV;
+
+ err = __ipv6_dev_mc_dec(idev, addr);
+ in6_dev_put(idev);
return err;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 015/877] ipv6: mcast: Dont hold RTNL for IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP.
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (13 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 014/877] ipv6: mcast: Use in6_dev_get() in ipv6_dev_mc_dec() Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 016/877] ipv6: mcast: Dont hold RTNL for IPV6_DROP_MEMBERSHIP and MCAST_LEAVE_GROUP Greg Kroah-Hartman
` (869 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Eric Dumazet,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit 1767bb2d47b715a106287a8f963d9ec6cbab4e69 ]
In __ipv6_sock_mc_join(), per-socket mld data is protected by lock_sock(),
and only __dev_get_by_index() requires RTNL.
Let's use dev_get_by_index() and drop RTNL for IPV6_ADD_MEMBERSHIP and
MCAST_JOIN_GROUP.
Note that we must call rt6_lookup() and dev_hold() under RCU.
If rt6_lookup() returns an entry from the exception table, dst_dev_put()
could change rt->dev.dst to loopback concurrently, and the original device
could lose the refcount before dev_hold() and unblock device registration.
dst_dev_put() is called from NETDEV_UNREGISTER and synchronize_net() follows
it, so as long as rt6_lookup() and dev_hold() are called within the same
RCU critical section, the dev is alive.
Even if the race happens, they are synchronised by idev->dead and mcast
addresses are cleaned up.
For the racy access to rt->dst.dev, we use dst_dev().
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20250702230210.3115355-7-kuni1840@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/ipv6_sockglue.c | 2 --
net/ipv6/mcast.c | 24 +++++++++++++-----------
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index c2ea92c0f9166..385321a43a19b 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -121,11 +121,9 @@ static bool setsockopt_needs_rtnl(int optname)
{
switch (optname) {
case IPV6_ADDRFORM:
- case IPV6_ADD_MEMBERSHIP:
case IPV6_DROP_MEMBERSHIP:
case IPV6_JOIN_ANYCAST:
case IPV6_LEAVE_ANYCAST:
- case MCAST_JOIN_GROUP:
case MCAST_LEAVE_GROUP:
case MCAST_JOIN_SOURCE_GROUP:
case MCAST_LEAVE_SOURCE_GROUP:
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 212c2d8efe0f5..61046543302d4 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -172,14 +172,12 @@ static int unsolicited_report_interval(struct inet6_dev *idev)
static int __ipv6_sock_mc_join(struct sock *sk, int ifindex,
const struct in6_addr *addr, unsigned int mode)
{
- struct net_device *dev = NULL;
- struct ipv6_mc_socklist *mc_lst;
struct ipv6_pinfo *np = inet6_sk(sk);
+ struct ipv6_mc_socklist *mc_lst;
struct net *net = sock_net(sk);
+ struct net_device *dev = NULL;
int err;
- ASSERT_RTNL();
-
if (!ipv6_addr_is_multicast(addr))
return -EINVAL;
@@ -199,13 +197,18 @@ static int __ipv6_sock_mc_join(struct sock *sk, int ifindex,
if (ifindex == 0) {
struct rt6_info *rt;
+
+ rcu_read_lock();
rt = rt6_lookup(net, addr, NULL, 0, NULL, 0);
if (rt) {
- dev = rt->dst.dev;
+ dev = dst_dev(&rt->dst);
+ dev_hold(dev);
ip6_rt_put(rt);
}
- } else
- dev = __dev_get_by_index(net, ifindex);
+ rcu_read_unlock();
+ } else {
+ dev = dev_get_by_index(net, ifindex);
+ }
if (!dev) {
sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
@@ -216,12 +219,11 @@ static int __ipv6_sock_mc_join(struct sock *sk, int ifindex,
mc_lst->sfmode = mode;
RCU_INIT_POINTER(mc_lst->sflist, NULL);
- /*
- * now add/increase the group membership on the device
- */
-
+ /* now add/increase the group membership on the device */
err = __ipv6_dev_mc_inc(dev, addr, mode);
+ dev_put(dev);
+
if (err) {
sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
return err;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 016/877] ipv6: mcast: Dont hold RTNL for IPV6_DROP_MEMBERSHIP and MCAST_LEAVE_GROUP.
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (14 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 015/877] ipv6: mcast: Dont hold RTNL for IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 017/877] ipv6: mcast: Dont hold RTNL for MCAST_ socket options Greg Kroah-Hartman
` (868 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Eric Dumazet,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit 2ceb71ce7d34e751f91bbca9da3513a2bc29089c ]
In __ipv6_sock_mc_drop(), per-socket mld data is protected by lock_sock(),
and only __dev_get_by_index() and __in6_dev_get() require RTNL.
Let's use dev_get_by_index() and in6_dev_get() and drop RTNL for
IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP.
Note that __ipv6_sock_mc_drop() is factorised to reuse in the next patch.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20250702230210.3115355-8-kuni1840@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/ipv6_sockglue.c | 2 --
net/ipv6/mcast.c | 47 +++++++++++++++++++++++-----------------
2 files changed, 27 insertions(+), 22 deletions(-)
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 385321a43a19b..ab6987e72e3a7 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -121,10 +121,8 @@ static bool setsockopt_needs_rtnl(int optname)
{
switch (optname) {
case IPV6_ADDRFORM:
- case IPV6_DROP_MEMBERSHIP:
case IPV6_JOIN_ANYCAST:
case IPV6_LEAVE_ANYCAST:
- case MCAST_LEAVE_GROUP:
case MCAST_JOIN_SOURCE_GROUP:
case MCAST_LEAVE_SOURCE_GROUP:
case MCAST_BLOCK_SOURCE:
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 61046543302d4..2f485e58a7d49 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -250,14 +250,36 @@ int ipv6_sock_mc_join_ssm(struct sock *sk, int ifindex,
/*
* socket leave on multicast group
*/
+static void __ipv6_sock_mc_drop(struct sock *sk, struct ipv6_mc_socklist *mc_lst)
+{
+ struct net *net = sock_net(sk);
+ struct net_device *dev;
+
+ dev = dev_get_by_index(net, mc_lst->ifindex);
+ if (dev) {
+ struct inet6_dev *idev = in6_dev_get(dev);
+
+ ip6_mc_leave_src(sk, mc_lst, idev);
+
+ if (idev) {
+ __ipv6_dev_mc_dec(idev, &mc_lst->addr);
+ in6_dev_put(idev);
+ }
+
+ dev_put(dev);
+ } else {
+ ip6_mc_leave_src(sk, mc_lst, NULL);
+ }
+
+ atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc);
+ kfree_rcu(mc_lst, rcu);
+}
+
int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
{
struct ipv6_pinfo *np = inet6_sk(sk);
- struct ipv6_mc_socklist *mc_lst;
struct ipv6_mc_socklist __rcu **lnk;
- struct net *net = sock_net(sk);
-
- ASSERT_RTNL();
+ struct ipv6_mc_socklist *mc_lst;
if (!ipv6_addr_is_multicast(addr))
return -EINVAL;
@@ -267,23 +289,8 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
lnk = &mc_lst->next) {
if ((ifindex == 0 || mc_lst->ifindex == ifindex) &&
ipv6_addr_equal(&mc_lst->addr, addr)) {
- struct net_device *dev;
-
*lnk = mc_lst->next;
-
- dev = __dev_get_by_index(net, mc_lst->ifindex);
- if (dev) {
- struct inet6_dev *idev = __in6_dev_get(dev);
-
- ip6_mc_leave_src(sk, mc_lst, idev);
- if (idev)
- __ipv6_dev_mc_dec(idev, &mc_lst->addr);
- } else {
- ip6_mc_leave_src(sk, mc_lst, NULL);
- }
-
- atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc);
- kfree_rcu(mc_lst, rcu);
+ __ipv6_sock_mc_drop(sk, mc_lst);
return 0;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 017/877] ipv6: mcast: Dont hold RTNL for MCAST_ socket options.
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (15 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 016/877] ipv6: mcast: Dont hold RTNL for IPV6_DROP_MEMBERSHIP and MCAST_LEAVE_GROUP Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 018/877] ipv6: mcast: use copy-on-write RCU updates in ip6_mc_source() Greg Kroah-Hartman
` (867 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Eric Dumazet,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit e6e14d582dd2cbee362c48a1865f8d03ca0a5611 ]
In ip6_mc_source() and ip6_mc_msfilter(), per-socket mld data is
protected by lock_sock() and inet6_dev->mc_lock is also held for
some per-interface functions.
ip6_mc_find_dev_rtnl() only depends on RTNL. If we want to remove
it, we need to check inet6_dev->dead under mc_lock to close the race
with addrconf_ifdown(), as mentioned earlier.
Let's do that and drop RTNL for the rest of MCAST_ socket options.
Note that ip6_mc_msfilter() has unnecessary lock dances and they
are integrated into one to avoid the last-minute error and simplify
the error handling.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20250702230210.3115355-10-kuni1840@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/ipv6_sockglue.c | 5 ---
net/ipv6/mcast.c | 74 ++++++++++++++++++++++++----------------
2 files changed, 45 insertions(+), 34 deletions(-)
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index ab6987e72e3a7..0f1242138d176 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -123,11 +123,6 @@ static bool setsockopt_needs_rtnl(int optname)
case IPV6_ADDRFORM:
case IPV6_JOIN_ANYCAST:
case IPV6_LEAVE_ANYCAST:
- case MCAST_JOIN_SOURCE_GROUP:
- case MCAST_LEAVE_SOURCE_GROUP:
- case MCAST_BLOCK_SOURCE:
- case MCAST_UNBLOCK_SOURCE:
- case MCAST_MSFILTER:
return true;
}
return false;
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 2f485e58a7d49..02919944d5570 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -299,31 +299,36 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
}
EXPORT_SYMBOL(ipv6_sock_mc_drop);
-static struct inet6_dev *ip6_mc_find_dev_rtnl(struct net *net,
- const struct in6_addr *group,
- int ifindex)
+static struct inet6_dev *ip6_mc_find_dev(struct net *net,
+ const struct in6_addr *group,
+ int ifindex)
{
struct net_device *dev = NULL;
- struct inet6_dev *idev = NULL;
+ struct inet6_dev *idev;
if (ifindex == 0) {
- struct rt6_info *rt = rt6_lookup(net, group, NULL, 0, NULL, 0);
+ struct rt6_info *rt;
+ rcu_read_lock();
+ rt = rt6_lookup(net, group, NULL, 0, NULL, 0);
if (rt) {
- dev = rt->dst.dev;
+ dev = dst_dev(&rt->dst);
+ dev_hold(dev);
ip6_rt_put(rt);
}
+ rcu_read_unlock();
} else {
- dev = __dev_get_by_index(net, ifindex);
+ dev = dev_get_by_index(net, ifindex);
}
-
if (!dev)
return NULL;
- idev = __in6_dev_get(dev);
+
+ idev = in6_dev_get(dev);
+ dev_put(dev);
+
if (!idev)
return NULL;
- if (idev->dead)
- return NULL;
+
return idev;
}
@@ -371,16 +376,16 @@ void ipv6_sock_mc_close(struct sock *sk)
}
int ip6_mc_source(int add, int omode, struct sock *sk,
- struct group_source_req *pgsr)
+ struct group_source_req *pgsr)
{
+ struct ipv6_pinfo *inet6 = inet6_sk(sk);
struct in6_addr *source, *group;
+ struct net *net = sock_net(sk);
struct ipv6_mc_socklist *pmc;
- struct inet6_dev *idev;
- struct ipv6_pinfo *inet6 = inet6_sk(sk);
struct ip6_sf_socklist *psl;
- struct net *net = sock_net(sk);
- int i, j, rv;
+ struct inet6_dev *idev;
int leavegroup = 0;
+ int i, j, rv;
int err;
source = &((struct sockaddr_in6 *)&pgsr->gsr_source)->sin6_addr;
@@ -389,13 +394,19 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
if (!ipv6_addr_is_multicast(group))
return -EINVAL;
- idev = ip6_mc_find_dev_rtnl(net, group, pgsr->gsr_interface);
+ idev = ip6_mc_find_dev(net, group, pgsr->gsr_interface);
if (!idev)
return -ENODEV;
+ mutex_lock(&idev->mc_lock);
+
+ if (idev->dead) {
+ err = -ENODEV;
+ goto done;
+ }
+
err = -EADDRNOTAVAIL;
- mutex_lock(&idev->mc_lock);
for_each_pmc_socklock(inet6, sk, pmc) {
if (pgsr->gsr_interface && pmc->ifindex != pgsr->gsr_interface)
continue;
@@ -492,6 +503,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
ip6_mc_add_src(idev, group, omode, 1, source, 1);
done:
mutex_unlock(&idev->mc_lock);
+ in6_dev_put(idev);
if (leavegroup)
err = ipv6_sock_mc_drop(sk, pgsr->gsr_interface, group);
return err;
@@ -500,12 +512,12 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf,
struct sockaddr_storage *list)
{
- const struct in6_addr *group;
- struct ipv6_mc_socklist *pmc;
- struct inet6_dev *idev;
struct ipv6_pinfo *inet6 = inet6_sk(sk);
struct ip6_sf_socklist *newpsl, *psl;
struct net *net = sock_net(sk);
+ const struct in6_addr *group;
+ struct ipv6_mc_socklist *pmc;
+ struct inet6_dev *idev;
int leavegroup = 0;
int i, err;
@@ -517,10 +529,17 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf,
gsf->gf_fmode != MCAST_EXCLUDE)
return -EINVAL;
- idev = ip6_mc_find_dev_rtnl(net, group, gsf->gf_interface);
+ idev = ip6_mc_find_dev(net, group, gsf->gf_interface);
if (!idev)
return -ENODEV;
+ mutex_lock(&idev->mc_lock);
+
+ if (idev->dead) {
+ err = -ENODEV;
+ goto done;
+ }
+
err = 0;
if (gsf->gf_fmode == MCAST_INCLUDE && gsf->gf_numsrc == 0) {
@@ -553,24 +572,19 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf,
psin6 = (struct sockaddr_in6 *)list;
newpsl->sl_addr[i] = psin6->sin6_addr;
}
- mutex_lock(&idev->mc_lock);
+
err = ip6_mc_add_src(idev, group, gsf->gf_fmode,
newpsl->sl_count, newpsl->sl_addr, 0);
if (err) {
- mutex_unlock(&idev->mc_lock);
sock_kfree_s(sk, newpsl, struct_size(newpsl, sl_addr,
newpsl->sl_max));
goto done;
}
- mutex_unlock(&idev->mc_lock);
} else {
newpsl = NULL;
- mutex_lock(&idev->mc_lock);
ip6_mc_add_src(idev, group, gsf->gf_fmode, 0, NULL, 0);
- mutex_unlock(&idev->mc_lock);
}
- mutex_lock(&idev->mc_lock);
psl = sock_dereference(pmc->sflist, sk);
if (psl) {
ip6_mc_del_src(idev, group, pmc->sfmode,
@@ -580,12 +594,14 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf,
} else {
ip6_mc_del_src(idev, group, pmc->sfmode, 0, NULL, 0);
}
+
rcu_assign_pointer(pmc->sflist, newpsl);
- mutex_unlock(&idev->mc_lock);
kfree_rcu(psl, rcu);
pmc->sfmode = gsf->gf_fmode;
err = 0;
done:
+ mutex_unlock(&idev->mc_lock);
+ in6_dev_put(idev);
if (leavegroup)
err = ipv6_sock_mc_drop(sk, gsf->gf_interface, group);
return err;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 018/877] ipv6: mcast: use copy-on-write RCU updates in ip6_mc_source()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (16 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 017/877] ipv6: mcast: Dont hold RTNL for MCAST_ socket options Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 019/877] media: video-i2c: fix buffer queue ordering Greg Kroah-Hartman
` (866 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Taehee Yoo,
Ido Schimmel, Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit c073d1b070f171d206b19c98d71739a97f15b3f1 ]
pmc->sflist is read locklessly under rcu_read_lock() by
inet6_mc_check() during packet reception in the UDP and RAW
multicast receive paths.
ip6_mc_source() mutated psl->sl_addr and psl->sl_count in-place
when adding or removing a source filter. Additionally, when expanding
the filter buffer, newpsl was published via rcu_assign_pointer()
before writing the new source into the array.
Because 16-byte struct in6_addr writes are not atomic and array
shifting is not synchronized with RCU readers, concurrent readers in
inet6_mc_check() could read torn IPv6 addresses or observe
duplicated/missed source entries.
Fix this by switching ip6_mc_source() to copy-on-write RCU updates:
allocate and fully populate newpsl before publishing it via
rcu_assign_pointer(), and reclaim the old filter via kfree_rcu(),
matching ip6_mc_msfilter().
Also remove the now unused IP6_SFBLOCK macro.
Fixes: 882ba1f73c06 ("mld: convert ipv6_mc_socklist->sflist to RCU")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Taehee Yoo <ap420073@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260828084531.1826790-3-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/if_inet6.h | 2 -
net/ipv6/mcast.c | 98 ++++++++++++++++++++++++------------------
2 files changed, 56 insertions(+), 44 deletions(-)
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 238ad3349456a..795fb41b45f5d 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -88,8 +88,6 @@ struct ip6_sf_socklist {
struct in6_addr sl_addr[] __counted_by(sl_max);
};
-#define IP6_SFBLOCK 10 /* allocate this many at once */
-
struct ipv6_mc_socklist {
struct in6_addr addr;
int ifindex;
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 02919944d5570..d0eefadea5c33 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -380,12 +380,12 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
{
struct ipv6_pinfo *inet6 = inet6_sk(sk);
struct in6_addr *source, *group;
+ struct ip6_sf_socklist *newpsl, *psl;
struct net *net = sock_net(sk);
struct ipv6_mc_socklist *pmc;
- struct ip6_sf_socklist *psl;
struct inet6_dev *idev;
int leavegroup = 0;
- int i, j, rv;
+ int i, j;
int err;
source = &((struct sockaddr_in6 *)&pgsr->gsr_source)->sin6_addr;
@@ -434,13 +434,11 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
if (!add) {
if (!psl)
goto done; /* err = -EADDRNOTAVAIL */
- rv = !0;
for (i = 0; i < psl->sl_count; i++) {
- rv = !ipv6_addr_equal(&psl->sl_addr[i], source);
- if (rv == 0)
+ if (ipv6_addr_equal(&psl->sl_addr[i], source))
break;
}
- if (rv) /* source not found */
+ if (i == psl->sl_count) /* source not found */
goto done; /* err = -EADDRNOTAVAIL */
/* special case - (INCLUDE, empty) == LEAVE_GROUP */
@@ -449,58 +447,74 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
goto done;
}
+ atomic_sub(struct_size(psl, sl_addr, psl->sl_max),
+ &sk->sk_omem_alloc);
+
+ if (psl->sl_count == 1) {
+ newpsl = NULL;
+ } else {
+ newpsl = sock_kmalloc(sk, struct_size(newpsl, sl_addr,
+ psl->sl_count - 1),
+ GFP_KERNEL);
+ if (!newpsl) {
+ atomic_add(struct_size(psl, sl_addr, psl->sl_max),
+ &sk->sk_omem_alloc);
+ err = -ENOBUFS;
+ goto done;
+ }
+ newpsl->sl_max = psl->sl_count - 1;
+ newpsl->sl_count = psl->sl_count - 1;
+ for (j = 0; j < i; j++)
+ newpsl->sl_addr[j] = psl->sl_addr[j];
+ for (j = i + 1; j < psl->sl_count; j++)
+ newpsl->sl_addr[j - 1] = psl->sl_addr[j];
+ }
+
/* update the interface filter */
ip6_mc_del_src(idev, group, omode, 1, source, 1);
- for (j = i+1; j < psl->sl_count; j++)
- psl->sl_addr[j-1] = psl->sl_addr[j];
- psl->sl_count--;
+ rcu_assign_pointer(pmc->sflist, newpsl);
+ kfree_rcu(psl, rcu);
err = 0;
goto done;
}
/* else, add a new source to the filter */
- if (psl && psl->sl_count >= sysctl_mld_max_msf) {
+ if (psl && psl->sl_count >= READ_ONCE(sysctl_mld_max_msf)) {
err = -ENOBUFS;
goto done;
}
- if (!psl || psl->sl_count == psl->sl_max) {
- struct ip6_sf_socklist *newpsl;
- int count = IP6_SFBLOCK;
-
- if (psl)
- count += psl->sl_max;
- newpsl = sock_kmalloc(sk, struct_size(newpsl, sl_addr, count),
- GFP_KERNEL);
- if (!newpsl) {
- err = -ENOBUFS;
- goto done;
- }
- newpsl->sl_max = count;
- newpsl->sl_count = count - IP6_SFBLOCK;
- if (psl) {
- for (i = 0; i < psl->sl_count; i++)
- newpsl->sl_addr[i] = psl->sl_addr[i];
- atomic_sub(struct_size(psl, sl_addr, psl->sl_max),
- &sk->sk_omem_alloc);
+ if (psl) {
+ for (i = 0; i < psl->sl_count; i++) {
+ if (ipv6_addr_equal(&psl->sl_addr[i], source))
+ goto done; /* err = -EADDRNOTAVAIL */
}
- rcu_assign_pointer(pmc->sflist, newpsl);
- kfree_rcu(psl, rcu);
- psl = newpsl;
}
- rv = 1; /* > 0 for insert logic below if sl_count is 0 */
- for (i = 0; i < psl->sl_count; i++) {
- rv = !ipv6_addr_equal(&psl->sl_addr[i], source);
- if (rv == 0) /* There is an error in the address. */
- goto done;
+
+ i = psl ? psl->sl_count + 1 : 1;
+ newpsl = sock_kmalloc(sk, struct_size(newpsl, sl_addr, i),
+ GFP_KERNEL);
+ if (!newpsl) {
+ err = -ENOBUFS;
+ goto done;
}
- for (j = psl->sl_count-1; j >= i; j--)
- psl->sl_addr[j+1] = psl->sl_addr[j];
- psl->sl_addr[i] = *source;
- psl->sl_count++;
- err = 0;
+ newpsl->sl_max = i;
+ newpsl->sl_count = i;
+ if (psl) {
+ for (j = 0; j < psl->sl_count; j++)
+ newpsl->sl_addr[j] = psl->sl_addr[j];
+ }
+ newpsl->sl_addr[i - 1] = *source;
+
/* update the interface list */
ip6_mc_add_src(idev, group, omode, 1, source, 1);
+
+ if (psl)
+ atomic_sub(struct_size(psl, sl_addr, psl->sl_max),
+ &sk->sk_omem_alloc);
+ rcu_assign_pointer(pmc->sflist, newpsl);
+ kfree_rcu(psl, rcu);
+ err = 0;
done:
mutex_unlock(&idev->mc_lock);
in6_dev_put(idev);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 019/877] media: video-i2c: fix buffer queue ordering
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (17 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 018/877] ipv6: mcast: use copy-on-write RCU updates in ip6_mc_source() Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 020/877] ipv6: Select best matching nexthop object in fib6_table_lookup() Greg Kroah-Hartman
` (865 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Arash Golgol, Hans Verkuil,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arash Golgol <arash.golgol@gmail.com>
[ Upstream commit bc4574c265ed738849e46d942617100580fcedd2 ]
Queued buffers are added to the tail of vid_cap_active in
buffer_queue(), but the capture kthread also retrieves buffers from
the tail of the list.
This makes the queue behave as LIFO instead of FIFO when multiple
buffers are queued.
Fix this by retrieving buffers from the head of the list.
Signed-off-by: Arash Golgol <arash.golgol@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/i2c/video-i2c.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/media/i2c/video-i2c.c b/drivers/media/i2c/video-i2c.c
index a091fd6d3e607..a4ddc10c5f22e 100644
--- a/drivers/media/i2c/video-i2c.c
+++ b/drivers/media/i2c/video-i2c.c
@@ -465,8 +465,9 @@ static int video_i2c_thread_vid_cap(void *priv)
spin_lock(&data->slock);
if (!list_empty(&data->vid_cap_active)) {
- vid_cap_buf = list_last_entry(&data->vid_cap_active,
- struct video_i2c_buffer, list);
+ vid_cap_buf = list_first_entry(&data->vid_cap_active,
+ struct video_i2c_buffer,
+ list);
list_del(&vid_cap_buf->list);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 020/877] ipv6: Select best matching nexthop object in fib6_table_lookup()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (18 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 019/877] media: video-i2c: fix buffer queue ordering Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 021/877] ipv6: Honor oif when choosing nexthop for locally generated traffic Greg Kroah-Hartman
` (864 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ido Schimmel, David Ahern,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <idosch@nvidia.com>
[ Upstream commit 484bb9d164df397a53e0f533b262b27b1590efcb ]
Currently, when using multipath routes without nexthop objects,
fib6_table_lookup() selects the nexthop with the highest score. This
means that when both a source address and an oif are specified, the
nexthop that is chosen is the one that matches in terms of oif:
# sysctl -wq net.ipv6.conf.all.forwarding=1
# ip address add 2001:db8:2::1/64 dev lo
# ip route add 2001:db8:10::/64 nexthop via fe80::1 dev dummy1 nexthop via fe80::2 dev dummy2
# perf record -e fib6:fib6_table_lookup -- bash -c "for i in {1..100}; do ip route get 2001:db8:10::${i} from 2001:db8:2::1 oif dummy1; done > /dev/null"
# perf script | grep -o dummy[0-9] | sort | uniq -c
100 dummy1
# perf record -e fib6:fib6_table_lookup -- bash -c "for i in {1..100}; do ip route get 2001:db8:10::${i} from 2001:db8:2::1 oif dummy2; done > /dev/null"
# perf script | grep -o dummy[0-9] | sort | uniq -c
100 dummy2
When using nexthop objects, fib6_table_lookup() selects the first
matching nexthop and not necessarily the one with the highest score:
# ip nexthop add id 1 via fe80::1 dev dummy1
# ip nexthop add id 2 via fe80::2 dev dummy2
# ip nexthop add id 3 group 1/2
# ip route add 2001:db8:20::/64 nhid 3
# perf record -e fib6:fib6_table_lookup -- bash -c "for i in {1..100}; do ip route get 2001:db8:20::${i} from 2001:db8:2::1 oif dummy1; done > /dev/null"
# perf script | grep -o dummy[0-9] | sort | uniq -c
100 dummy1
# perf record -e fib6:fib6_table_lookup -- bash -c "for i in {1..100}; do ip route get 2001:db8:20::${i} from 2001:db8:2::1 oif dummy2; done > /dev/null"
# perf script | grep -o dummy[0-9] | sort | uniq -c
100 dummy1
This is not very significant right now because the nexthop is later
overwritten during path selection in fib6_select_path(). However, the
next patch is going to skip path selection when we have an oif match
during output route lookup.
As a preparation for this change, align the nexthop object behavior with
the legacy one and make sure that fib6_table_lookup() always selects the
best matching nexthop. Do that by always returning 0 from
rt6_nh_find_match() in order not to terminate the loop in
nexthop_for_each_fib6_nh() and storing in arg->nh the best matching
nexthop so far.
Behavior after the change:
# perf record -e fib6:fib6_table_lookup -- bash -c "for i in {1..100}; do ip route get 2001:db8:20::${i} from 2001:db8:2::1 oif dummy1; done > /dev/null"
# perf script | grep -o dummy[0-9] | sort | uniq -c
100 dummy1
# perf record -e fib6:fib6_table_lookup -- bash -c "for i in {1..100}; do ip route get 2001:db8:20::${i} from 2001:db8:2::1 oif dummy2; done > /dev/null"
# perf script | grep -o dummy[0-9] | sort | uniq -c
100 dummy2
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20260611154605.992528-2-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/route.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 19c970978e863..b30cb180009b1 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -820,9 +820,11 @@ static int rt6_nh_find_match(struct fib6_nh *nh, void *_arg)
{
struct fib6_nh_frl_arg *arg = _arg;
- arg->nh = nh;
- return find_match(nh, arg->flags, arg->oif, arg->strict,
- arg->mpri, arg->do_rr);
+ if (find_match(nh, arg->flags, arg->oif, arg->strict, arg->mpri,
+ arg->do_rr))
+ arg->nh = nh;
+
+ return 0;
}
static void __find_rr_leaf(struct fib6_info *f6i_start,
@@ -862,11 +864,10 @@ static void __find_rr_leaf(struct fib6_info *f6i_start,
res->nh = nexthop_fib6_nh(f6i->nh);
return;
}
- if (nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_find_match,
- &arg)) {
- matched = true;
- nh = arg.nh;
- }
+ nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_find_match,
+ &arg);
+ matched = !!arg.nh;
+ nh = arg.nh;
} else {
nh = f6i->fib6_nh;
if (find_match(nh, f6i->fib6_flags, oif, strict,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 021/877] ipv6: Honor oif when choosing nexthop for locally generated traffic
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (19 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 020/877] ipv6: Select best matching nexthop object in fib6_table_lookup() Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 022/877] pidfd: hold exec_update_lock around namespace ioctl Greg Kroah-Hartman
` (863 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Ahern, Ido Schimmel,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <idosch@nvidia.com>
[ Upstream commit d25e7e9d8a6c1e2afb854613e417c6aa1a28ce6f ]
Commit 741a11d9e410 ("net: ipv6: Add RT6_LOOKUP_F_IFACE flag if oif is
set") made the kernel honor the oif parameter when specified as part of
output route lookup:
# ip route add 2001:db8:1::/64 dev dummy1
# ip route add ::/0 dev dummy2
# ip route get 2001:db8:1::1 oif dummy2 fibmatch
default dev dummy2 metric 1024 pref medium
Due to regression reports, the behavior was partially reverted in commit
d46a9d678e4c ("net: ipv6: Dont add RT6_LOOKUP_F_IFACE flag if saddr
set") to only honor the oif if source address is not specified:
# ip route get 2001:db8:1::1 from 2001:db8:2::1 oif dummy2 fibmatch
2001:db8:1::/64 dev dummy1 metric 1024 pref medium
That is, when source address is specified, the kernel will choose the
most specific route even if its nexthop device does not match the
specified oif.
This creates a problem for multipath routes. After looking up a route,
when source address is not specified, the kernel will choose a nexthop
whose nexthop device matches the specified oif:
# sysctl -wq net.ipv6.conf.all.forwarding=1
# ip route add 2001:db8:10::/64 nexthop via fe80::1 dev dummy1 nexthop via fe80::2 dev dummy2
# for i in {1..100}; do ip route get 2001:db8:10::${i} oif dummy2; done | grep -o dummy[0-9] | sort | uniq -c
100 dummy2
But will disregard the oif when source address is specified despite the
fact that a matching nexthop exists:
# for i in {1..100}; do ip route get 2001:db8:10::${i} from 2001:db8:2::1 oif dummy2; done | grep -o dummy[0-9] | sort | uniq -c
53 dummy1
47 dummy2
This behavior differs from IPv4:
# ip address add 192.0.2.1/32 dev lo
# ip route add 198.51.100.0/24 nexthop via inet6 fe80::1 dev dummy1 nexthop via inet6 fe80::2 dev dummy2
# for i in {1..100}; do ip route get 198.51.100.${i} from 192.0.2.1 oif dummy2; done | grep -o dummy[0-9] | sort | uniq -c
100 dummy2
What happens is that fib6_table_lookup() returns a route with a matching
nexthop device (assuming it exists):
# perf record -e fib6:fib6_table_lookup -- bash -c "for i in {1..100}; do ip route get 2001:db8:10::${i} from 2001:db8:2::1 oif dummy2; done > /dev/null"
# perf script | grep -o dummy[0-9] | sort | uniq -c
100 dummy2
But it is later overwritten during path selection in fib6_select_path()
which instead chooses a nexthop according to the calculated hash.
Solve this by telling fib6_select_path() to skip path selection if we
have an oif match during output route lookup (iif being
LOOPBACK_IFINDEX).
Behavior after the change:
# sysctl -wq net.ipv6.conf.all.forwarding=1
# ip route add 2001:db8:10::/64 nexthop via fe80::1 dev dummy1 nexthop via fe80::2 dev dummy2
# for i in {1..100}; do ip route get 2001:db8:10::${i} from 2001:db8:2::1 oif dummy2; done | grep -o dummy[0-9] | sort | uniq -c
100 dummy2
Note that enabling forwarding is only needed because we did not add
neighbor entries for the gateway addresses. When forwarding is disabled
and CONFIG_IPV6_ROUTER_PREF is not enabled in kernel config, the kernel
will treat non-existing neighbor entries as errors and perform
round-robin between the nexthops:
# sysctl -wq net.ipv6.conf.all.forwarding=0
# for i in {1..100}; do ip route get 2001:db8:10::${i} from 2001:db8:2::1 oif dummy2; done | grep -o dummy[0-9] | sort | uniq -c
50 dummy1
50 dummy2
Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260611154605.992528-3-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/route.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index b30cb180009b1..15f02882be040 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2269,6 +2269,7 @@ struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
{
struct fib6_result res = {};
struct rt6_info *rt = NULL;
+ bool have_oif_match;
int strict = 0;
WARN_ON_ONCE((flags & RT6_LOOKUP_F_DST_NOREF) &&
@@ -2285,7 +2286,9 @@ struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
if (res.f6i == net->ipv6.fib6_null_entry)
goto out;
- fib6_select_path(net, &res, fl6, oif, false, skb, strict);
+ have_oif_match = fl6->flowi6_iif == LOOPBACK_IFINDEX &&
+ oif == res.nh->fib_nh_dev->ifindex;
+ fib6_select_path(net, &res, fl6, oif, have_oif_match, skb, strict);
/*Search through exception table */
rt = rt6_find_cached_rt(&res, &fl6->daddr, &fl6->saddr);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 022/877] pidfd: hold exec_update_lock around namespace ioctl
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (20 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 021/877] ipv6: Honor oif when choosing nexthop for locally generated traffic Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 023/877] xfrm: avoid RCU warnings around the per-netns netlink socket Greg Kroah-Hartman
` (862 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chen Linxuan,
Christian Brauner (Amutable), Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Linxuan <me@black-desk.cn>
[ Upstream commit 9688a46802939da28f00cb40e8129615d5d4af39 ]
The PIDFD_GET_*_NAMESPACE ioctls in pidfd_ioctl() perform a filesystem
credentials ptrace access check before handing out a namespace file
descriptor. The accompanying comment states that the code "mirrors nsfs
behavior", but, unlike the corresponding procfs paths, it does so without
holding the target task's exec_update_lock.
proc_ns_get_link() and proc_ns_readlink() both take exec_update_lock for
reading around the ptrace check and the namespace lookup, so that the
credentials used for the access decision match those of the task when its
namespace is read. Without it, a caller can pass the check against the
target's old credentials and then read the namespace after the target has
execve()'d a setuid binary and committed new credentials -- accessing
namespace information it should have been denied.
Hold exec_update_lock for reading around the ptrace check and the
namespace lookup so that pidfd truly mirrors nsfs behavior, as the comment
already claims. open_namespace() itself runs outside the lock: once a
namespace reference is obtained it carries its own refcount and is opened
with the caller's own credentials, so a concurrent execve() on the target
can no longer affect the outcome.
Fixes: 5b08bd408534 ("pidfs: allow retrieval of namespace file descriptors")
Cc: stable@vger.kernel.org
Signed-off-by: Chen Linxuan <me@black-desk.cn>
Link: https://patch.msgid.link/20260731-pidfd-exec-update-lock-v1-1-b388f2f3a8b0@black-desk.cn
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/pidfs.c | 43 +++++++++++++++++++++++++++++++------------
1 file changed, 31 insertions(+), 12 deletions(-)
diff --git a/fs/pidfs.c b/fs/pidfs.c
index 5a8d8eb8df23b..b2dc613a64f6f 100644
--- a/fs/pidfs.c
+++ b/fs/pidfs.c
@@ -122,6 +122,7 @@ static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
struct pid *pid = pidfd_pid(file);
struct ns_common *ns_common = NULL;
struct pid_namespace *pid_ns;
+ int error;
if (arg)
return -EINVAL;
@@ -130,20 +131,33 @@ static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (!task)
return -ESRCH;
+ /*
+ * We're trying to open a file descriptor to the namespace so perform a
+ * filesystem cred ptrace check. Hold @task's exec_update_lock for the
+ * duration of the ptrace check and the namespace lookup so that the
+ * credentials used for the access decision match those of @task at the
+ * time its namespace is read, preventing a concurrent execve() from
+ * swapping the task's credentials in between the check and the use. We
+ * mirror nsfs behavior.
+ */
+ error = down_read_killable(&task->signal->exec_update_lock);
+ if (error)
+ return error;
+
+ if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
+ error = -EACCES;
+ goto out_unlock;
+ }
+
scoped_guard(task_lock, task) {
nsp = task->nsproxy;
if (nsp)
get_nsproxy(nsp);
}
- if (!nsp)
- return -ESRCH; /* just pretend it didn't exist */
-
- /*
- * We're trying to open a file descriptor to the namespace so perform a
- * filesystem cred ptrace check. Also, we mirror nsfs behavior.
- */
- if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
- return -EACCES;
+ if (!nsp) {
+ error = -ESRCH; /* just pretend it didn't exist */
+ goto out_unlock;
+ }
switch (cmd) {
/* Namespaces that hang of nsproxy. */
@@ -211,11 +225,16 @@ static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
break;
default:
- return -ENOIOCTLCMD;
+ error = -ENOIOCTLCMD;
}
- if (!ns_common)
- return -EOPNOTSUPP;
+ if (!error && !ns_common)
+ error = -EOPNOTSUPP;
+
+out_unlock:
+ up_read(&task->signal->exec_update_lock);
+ if (error)
+ return error;
/* open_namespace() unconditionally consumes the reference */
return open_namespace(ns_common);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 023/877] xfrm: avoid RCU warnings around the per-netns netlink socket
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (21 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 022/877] pidfd: hold exec_update_lock around namespace ioctl Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 024/877] xfrm: fix compat ALLOCSPI request use-after-free Greg Kroah-Hartman
` (861 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sabrina Dubroca, Simon Horman,
Steffen Klassert, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sabrina Dubroca <sd@queasysnail.net>
[ Upstream commit d87f8bc47fbf012a7f115e311d0603d97e47c34c ]
net->xfrm.nlsk is used in 2 types of contexts:
- fully under RCU, with rcu_read_lock + rcu_dereference and a NULL check
- in the netlink handlers, with requests coming from a userspace socket
In the 2nd case, net->xfrm.nlsk is guaranteed to stay non-NULL and the
object is alive, since we can't enter the netns destruction path while
the user socket holds a reference on the netns.
After adding the __rcu annotation to netns_xfrm.nlsk (which silences
sparse warnings in the RCU users and __net_init code), we need to tell
sparse that the 2nd case is safe. Add a helper for that.
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Stable-dep-of: d1ebd9081879 ("xfrm: fix compat ALLOCSPI request use-after-free")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/netns/xfrm.h | 2 +-
net/xfrm/xfrm_user.c | 25 +++++++++++++++++--------
2 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 23dd647fe0248..b73983a17e088 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -59,7 +59,7 @@ struct netns_xfrm {
struct list_head inexact_bins;
- struct sock *nlsk;
+ struct sock __rcu *nlsk;
struct sock *nlsk_stash;
u32 sysctl_aevent_etime;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 904c9328852f0..c37f8e518f1e3 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -35,6 +35,15 @@
#endif
#include <linux/unaligned.h>
+static struct sock *xfrm_net_nlsk(const struct net *net, const struct sk_buff *skb)
+{
+ /* get the source of this request, see netlink_unicast_kernel */
+ const struct sock *sk = NETLINK_CB(skb).sk;
+
+ /* sk is refcounted, the netns stays alive and nlsk with it */
+ return rcu_dereference_protected(net->xfrm.nlsk, sk->sk_net_refcnt);
+}
+
static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type,
struct netlink_ext_ack *extack)
{
@@ -1662,7 +1671,7 @@ static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
err = build_spdinfo(r_skb, net, sportid, seq, *flags);
BUG_ON(err < 0);
- return nlmsg_unicast(net->xfrm.nlsk, r_skb, sportid);
+ return nlmsg_unicast(xfrm_net_nlsk(net, skb), r_skb, sportid);
}
static inline unsigned int xfrm_sadinfo_msgsize(void)
@@ -1722,7 +1731,7 @@ static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
err = build_sadinfo(r_skb, net, sportid, seq, *flags);
BUG_ON(err < 0);
- return nlmsg_unicast(net->xfrm.nlsk, r_skb, sportid);
+ return nlmsg_unicast(xfrm_net_nlsk(net, skb), r_skb, sportid);
}
static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -1742,7 +1751,7 @@ static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
if (IS_ERR(resp_skb)) {
err = PTR_ERR(resp_skb);
} else {
- err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).portid);
+ err = nlmsg_unicast(xfrm_net_nlsk(net, skb), resp_skb, NETLINK_CB(skb).portid);
}
xfrm_state_put(x);
out_noput:
@@ -1833,7 +1842,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
}
}
- err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).portid);
+ err = nlmsg_unicast(xfrm_net_nlsk(net, skb), resp_skb, NETLINK_CB(skb).portid);
out:
xfrm_state_put(x);
@@ -2476,7 +2485,7 @@ static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh,
r_up->out = READ_ONCE(net->xfrm.policy_default[XFRM_POLICY_OUT]);
nlmsg_end(r_skb, r_nlh);
- return nlmsg_unicast(net->xfrm.nlsk, r_skb, portid);
+ return nlmsg_unicast(xfrm_net_nlsk(net, skb), r_skb, portid);
}
static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -2542,7 +2551,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
if (IS_ERR(resp_skb)) {
err = PTR_ERR(resp_skb);
} else {
- err = nlmsg_unicast(net->xfrm.nlsk, resp_skb,
+ err = nlmsg_unicast(xfrm_net_nlsk(net, skb), resp_skb,
NETLINK_CB(skb).portid);
}
} else {
@@ -2721,7 +2730,7 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
return err;
}
- err = nlmsg_unicast(net->xfrm.nlsk, r_skb, NETLINK_CB(skb).portid);
+ err = nlmsg_unicast(xfrm_net_nlsk(net, skb), r_skb, NETLINK_CB(skb).portid);
spin_unlock_bh(&x->lock);
xfrm_state_put(x);
return err;
@@ -3393,7 +3402,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
goto err;
}
- err = netlink_dump_start(net->xfrm.nlsk, skb, nlh, &c);
+ err = netlink_dump_start(xfrm_net_nlsk(net, skb), skb, nlh, &c);
goto err;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 024/877] xfrm: fix compat ALLOCSPI request use-after-free
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (22 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 023/877] xfrm: avoid RCU warnings around the per-netns netlink socket Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 025/877] xfrm: add missing rcu_read_lock(), skb_dst_force() and dev_hold() for xfrm_trans_reinject() Greg Kroah-Hartman
` (860 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kyle Zeng, David Lee,
Steffen Klassert, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kyle Zeng <kylebot@openai.com>
[ Upstream commit d1ebd9081879fd9ae9c8fb7e8928f19cc88ae320 ]
xfrm_state_netlink() builds the ALLOCSPI response with
dump_one_state(), which already calls alloc_compat() with the response
skb and header.
xfrm_alloc_userspi() then calls alloc_compat() again, but passes the
original request skb and its header. For a compat request, the
translator therefore interprets the 228-byte compat xfrm_userspi_info
as the 232-byte native layout and reads four bytes past the declared
payload. It also publishes the translated child through the request's
frag_list.
A multicast clone of the request shares skb_shared_info and can observe
that child. xfrm_user_rcv_msg() frees it after the request handler
returns, racing a compat receiver which may still be copying from it and
resulting in a use-after-free.
Remove the redundant conversion. The response keeps its correct compat
translation from dump_one_state(), and no child is attached to the
inbound request.
Fixes: 5f3eea6b7e8f ("xfrm/compat: Attach xfrm dumps to 64=>32 bit translator")
Assisted-by: Codex:gpt-5.6-sol Codex:gpt-5.5-cyber
Signed-off-by: Kyle Zeng <kylebot@openai.com>
Co-developed-by: David Lee <david.lee@trailofbits.com>
Signed-off-by: David Lee <david.lee@trailofbits.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/xfrm/xfrm_user.c | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index c37f8e518f1e3..c1e753d554e75 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1765,7 +1765,6 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
struct net *net = sock_net(skb->sk);
struct xfrm_state *x;
struct xfrm_userspi_info *p;
- struct xfrm_translator *xtr;
struct sk_buff *resp_skb;
xfrm_address_t *daddr;
int family;
@@ -1831,17 +1830,6 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
goto out;
}
- xtr = xfrm_get_translator();
- if (xtr) {
- err = xtr->alloc_compat(skb, nlmsg_hdr(skb));
-
- xfrm_put_translator(xtr);
- if (err) {
- kfree_skb(resp_skb);
- goto out;
- }
- }
-
err = nlmsg_unicast(xfrm_net_nlsk(net, skb), resp_skb, NETLINK_CB(skb).portid);
out:
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 025/877] xfrm: add missing rcu_read_lock(), skb_dst_force() and dev_hold() for xfrm_trans_reinject()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (23 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 024/877] xfrm: fix compat ALLOCSPI request use-after-free Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 026/877] esp: downgrade zerocopy managed frags before mutating skb frags Greg Kroah-Hartman
` (859 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot, Eric Dumazet,
Steffen Klassert, Liu Jian, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit d2f5082f9e84653fa1a9e8aebaaff23e688f5e19 ]
syzbot reported a suspicious RCU usage warning in ip6_pkt_drop():
WARNING: suspicious RCU usage in ip6_pkt_drop
include/net/addrconf.h:389 suspicious rcu_dereference_check() usage!
Call Trace:
__in6_dev_get_safely include/net/addrconf.h:389 [inline]
ip6_pkt_drop+0x596/0x610 net/ipv6/route.c:4620
ip6_pkt_discard+0x1c/0x30 net/ipv6/route.c:4651
xfrm_trans_reinject+0x324/0x630 net/xfrm/xfrm_input.c:806
process_one_work kernel/workqueue.c:3322 [inline]
process_scheduled_works+0xa8e/0x14e0 kernel/workqueue.c:3405
worker_thread+0xa47/0xfb0 kernel/workqueue.c:3486
When commit 4f4920669d21 ("xfrm: Reinject transport-mode packets through
workqueue") converted xfrm_trans_reinject from a tasklet to a workqueue,
the reinjection loop ceased running in softirq context. Workqueue workers
run in process context where local_bh_disable() does not enter an RCU
read-side critical section under CONFIG_PREEMPT_RCU.
Because finish callbacks (such as ip6_rcv_finish) expect to run under an
RCU read lock (performing route lookups, l3mdev lookups, and accessing
RCU-protected data structures), invoking them in workqueue context without
rcu_read_lock() triggers RCU lockdep warnings.
Furthermore, packets queued to the workqueue via xfrm_trans_queue_net()
may carry non-refcounted (noref) dst entries (e.g. from ip_route_input_noref).
Additionally, on netdevice unregistration, dst_dev_put() replaces dst->dev
with blackhole_netdev, so dst entries do not keep skb->dev alive while
queued in the workqueue.
Fix these issues by:
1. Calling skb_dst_force(skb) in xfrm_trans_queue_net() while still in the
caller's RCU section to ensure dst is reference-counted before queuing.
2. Holding a reference on skb->dev via dev_hold()/dev_put() across workqueue
deferral so skb->dev remains valid during finish() callback processing.
3. Acquiring rcu_read_lock() around the finish callback invocation loop in
xfrm_trans_reinject().
Fixes: 4f4920669d21 ("xfrm: Reinject transport-mode packets through workqueue")
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Steffen Klassert <steffen.klassert@secunet.com>
Cc: Liu Jian <liujian56@huawei.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/xfrm/xfrm_input.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 5d3633ce6ba32..1be187b980461 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -778,12 +778,17 @@ static void xfrm_trans_reinject(struct work_struct *work)
spin_unlock_bh(&trans->queue_lock);
local_bh_disable();
+ rcu_read_lock();
while ((skb = __skb_dequeue(&queue))) {
struct net *net = XFRM_TRANS_SKB_CB(skb)->net;
+ struct net_device *dev = skb->dev;
XFRM_TRANS_SKB_CB(skb)->finish(net, NULL, skb);
+ if (dev)
+ dev_put(dev);
put_net(net);
}
+ rcu_read_unlock();
local_bh_enable();
}
@@ -799,12 +804,18 @@ int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
if (skb_queue_len(&trans->queue) >= READ_ONCE(net_hotdata.max_backlog))
return -ENOBUFS;
+ if (skb_dst(skb) && !skb_dst_force(skb))
+ return -EHOSTUNREACH;
+
BUILD_BUG_ON(sizeof(struct xfrm_trans_cb) > sizeof(skb->cb));
hold_net = maybe_get_net(net);
if (!hold_net)
return -ENODEV;
+ if (skb->dev)
+ dev_hold(skb->dev);
+
XFRM_TRANS_SKB_CB(skb)->finish = finish;
XFRM_TRANS_SKB_CB(skb)->net = hold_net;
spin_lock_bh(&trans->queue_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 026/877] esp: downgrade zerocopy managed frags before mutating skb frags
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (24 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 025/877] xfrm: add missing rcu_read_lock(), skb_dst_force() and dev_hold() for xfrm_trans_reinject() Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 027/877] ARM: socfpga: select the PL310 erratum 753970 workaround Greg Kroah-Hartman
` (858 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Maher Azzouzi, Steffen Klassert,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maher Azzouzi <maherazz04@gmail.com>
[ Upstream commit f89416eb3db151170a6f3c6dfc5239d26cdce4d2 ]
On the out-of-place output path (esp->inplace == false) ESP rewrites the
skb frag array: esp_output_head() appends a trailer frag and
esp_output_tail() replaces the frags with a destination page, both
referenced with get_page().
When the skb carries zerocopy managed frags (SKBFL_MANAGED_FRAG_REFS) the
payload frags are owned by the ubuf and must not be referenced or
unreferenced individually, but ESP mutates the frag array without ever
downgrading the skb. This breaks the managed-frag invariant two ways:
- esp_ssg_unref() walks the source scatterlist and drops a page
reference for every frag, including the ubuf-owned payload frags,
pushing their refcount below the GUP pin bias while the pages are
still pinned, i.e. a use-after-free of the zerocopy pages;
- esp_output_tail() installs its destination page as frag 0 with
get_page() but leaves SKBFL_MANAGED_FRAG_REFS set, so
skb_release_data() takes the skip_unref branch and never drops that
reference, leaking the x->xfrag page at packet rate.
Fix this the way every other frag-mutating site does (__ip_append_data(),
__ip6_append_data(), tcp_sendmsg_locked()) and call
skb_zcopy_downgrade_managed() before ESP touches the frag array: it takes
a real reference on each existing frag and clears SKBFL_MANAGED_FRAG_REFS,
so the per-frag unref in esp_ssg_unref() and the frag release in
skb_release_data() are both balanced and no mixed-ownership frag array is
left behind.
Fixes: 753f1ca4e1e5 ("net: introduce managed frags infrastructure")
Signed-off-by: Maher Azzouzi <maherazz04@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/esp4.c | 6 ++++++
net/ipv6/esp6.c | 6 ++++++
2 files changed, 12 insertions(+)
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 6c8c789ded0e4..fb78dc6b7e148 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -438,6 +438,12 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
esp->inplace = false;
+ /* Take real page refs and clear SKBFL_MANAGED_FRAG_REFS before
+ * we mutate the frag array, so the per-frag unref stays balanced
+ * for zerocopy managed frags (see __ip_append_data()).
+ */
+ skb_zcopy_downgrade_managed(skb);
+
allocsize = ALIGN(tailen, L1_CACHE_BYTES);
spin_lock_bh(&x->lock);
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 80981596236ab..7411aac0707b2 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -467,6 +467,12 @@ int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
esp->inplace = false;
+ /* Take real page refs and clear SKBFL_MANAGED_FRAG_REFS before
+ * we mutate the frag array, so the per-frag unref stays balanced
+ * for zerocopy managed frags (see __ip_append_data()).
+ */
+ skb_zcopy_downgrade_managed(skb);
+
allocsize = ALIGN(tailen, L1_CACHE_BYTES);
spin_lock_bh(&x->lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 027/877] ARM: socfpga: select the PL310 erratum 753970 workaround
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (25 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 026/877] esp: downgrade zerocopy managed frags before mutating skb frags Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 028/877] RDMA/siw: Clear association under lock if siw_qp_modify fails in siw_accept Greg Kroah-Hartman
` (857 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Pengpeng Hou, Dinh Nguyen,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <pengpeng@iscas.ac.cn>
[ Upstream commit cfc1e9a543e3589ba200795b6e7fd8ef4314efdf ]
ARCH_INTEL_SOCFPGA selects CACHE_L2X0 and several PL310 erratum
workarounds. The 753970 workaround is still conditioned on PL310, but that
Kconfig symbol no longer exists, so this one selection is always disabled.
Select PL310_ERRATA_753970 directly, consistently with the other PL310
workarounds required by the platform.
Fixes: fbc125afdc50 ("ARM: socfpga: Turn on ARM errata for L2 cache")
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm/mach-socfpga/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig
index eb72c240c2486..528c5c1368c37 100644
--- a/arch/arm/mach-socfpga/Kconfig
+++ b/arch/arm/mach-socfpga/Kconfig
@@ -16,7 +16,7 @@ menuconfig ARCH_INTEL_SOCFPGA
select ARM_ERRATA_775420
select PL310_ERRATA_588369
select PL310_ERRATA_727915
- select PL310_ERRATA_753970 if PL310
+ select PL310_ERRATA_753970
select PL310_ERRATA_769419
select RESET_CONTROLLER
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 028/877] RDMA/siw: Clear association under lock if siw_qp_modify fails in siw_accept
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (26 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 027/877] ARM: socfpga: select the PL310 erratum 753970 workaround Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 029/877] RDMA/rxe: validate access flags before swapping the MRs PD Greg Kroah-Hartman
` (856 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shuangpeng Bai, Guoqing Jiang,
Bernard Metzler, Leon Romanovsky, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guoqing Jiang <guoqing.jiang@linux.dev>
[ Upstream commit 32cd87f54dd1070020e664ccb0312a9f0fea79b4 ]
We need to clear cep before release state_lock as siw_qp_llp_close and
siw_qp_modify->siw_qp_llp_close did.
Otherwise if siw_qp_modify() fails in siw_accept(), the QP's state_lock
is released before the error path cleanup. A concurrent ibv_modify_qp()
transitioning the QP to ERROR can race in this window:
siw_accept() ibv_modify_qp(ERROR)
---------------------- ----------------------
siw_qp_modify() fails
up_write(&qp->state_lock)
down_write(&qp->state_lock)
nextstate_from_idle():
if (qp->cep)
siw_cep_put(qp->cep) <- frees cep
qp->cep = NULL
goto error
cep->qp = NULL <- UAF
Clear qp->cep and drop the association reference taken by siw_cep_get(),
all under the write lock held from the initial down_write(&qp->state_lock).
Thread B therefore sees qp->cep == NULL, skips its own put, and cannot free
the cep before siw_accept() is done with it.
Fixes: 6c52fdc244b5 ("rdma/siw: connection management")
Reported-by: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
Link: https://lore.kernel.org/linux-rdma/d6fbe475-a5c2-f975-99b0-a0bd6b6d10e8@linux.dev/T/#m5876c1ff2de8686a9a1173b8f1aa0ff5363a785c
Signed-off-by: Guoqing Jiang <guoqing.jiang@linux.dev>
Link: https://patch.msgid.link/20260827125553.12831-1-guoqing.jiang@linux.dev
Acked-by: Bernard Metzler <bernard.metzler@linux.dev>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/sw/siw/siw_cm.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/sw/siw/siw_cm.c b/drivers/infiniband/sw/siw/siw_cm.c
index bb7d909639071..04fabab440581 100644
--- a/drivers/infiniband/sw/siw/siw_cm.c
+++ b/drivers/infiniband/sw/siw/siw_cm.c
@@ -1669,9 +1669,12 @@ int siw_accept(struct iw_cm_id *id, struct iw_cm_conn_param *params)
SIW_QP_ATTR_STATE | SIW_QP_ATTR_LLP_HANDLE |
SIW_QP_ATTR_ORD | SIW_QP_ATTR_IRD |
SIW_QP_ATTR_MPA);
+ if (rv) {
+ qp->cep = NULL;
+ siw_cep_put(cep);
+ goto error_unlock;
+ }
up_write(&qp->state_lock);
- if (rv)
- goto error;
siw_dbg_cep(cep, "[QP %u]: send mpa reply, %d byte pdata\n",
qp_id(qp), params->private_data_len);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 029/877] RDMA/rxe: validate access flags before swapping the MRs PD
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (27 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 028/877] RDMA/siw: Clear association under lock if siw_qp_modify fails in siw_accept Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 030/877] RDMA/rxe: Fix integer overflow in mr_check_range() leading to OOB access Greg Kroah-Hartman
` (855 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Norbert Szetei, Zhu Yanjun,
Leon Romanovsky, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Norbert Szetei <norbert@doyensec.com>
[ Upstream commit ae36a5b609ae79f4de966328b78d2584be9719a4 ]
rxe_rereg_user_mr() reassigns mr->ibmr.pd first and only then
validates the IB_MR_REREG_ACCESS argument:
if (flags & IB_MR_REREG_PD) {
rxe_put(old_pd);
rxe_get(pd);
mr->ibmr.pd = ibpd;
}
if (flags & IB_MR_REREG_ACCESS) {
if (access & ~RXE_ACCESS_SUPPORTED_MR)
return ERR_PTR(-EOPNOTSUPP);
mr->access = access;
}
Both flags pass the entry check because RXE_MR_REREG_SUPPORTED is
IB_MR_REREG_PD | IB_MR_REREG_ACCESS, so a caller can reach the access
check with mr->ibmr.pd already reassigned.
mr->ibmr.pd is owned by the core, which adjusts pd->usecnt only on the
success path: ib_uverbs_rereg_mr() jumps to put_new_uobj on a driver error
without undoing the reassignment, so mr->pd == new_pd while the usecnts
still charge the MR to orig_pd. ib_dereg_mr_user() then decrements
new_pd, whose count can reach zero while a memory window still references
it; uverbs_free_pd() frees the PD on that count alone and rxe_mw_cleanup()
writes to freed memory:
BUG: KASAN: slab-use-after-free in __rxe_put+0x31/0xa0
Write of size 4 at addr ffff8881301dd690 by task rxe_poc/591
__rxe_put+0x31/0xa0
rxe_mw_cleanup+0x42/0x200
__rxe_cleanup+0x115/0x370
rxe_dealloc_mw+0x4c/0x80
Allocated by task 591:
ib_uverbs_alloc_pd+0x258/0x540
Freed by task 591:
ib_dealloc_pd_user+0x174/0x210
uverbs_free_pd+0x8d/0xc0
ib_uverbs_dealloc_pd+0x18e/0x1d0
Validate the access flags before mutating any state so the callback either
applies every requested change or none.
Fixes: 544c7f62cf32 ("RDMA/rxe: Implement rereg_user_mr")
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
Link: https://patch.msgid.link/46E1D5C0-24BE-4D01-BDB3-634FE09B22C5@doyensec.com
Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/sw/rxe/rxe_verbs.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c
index 9466fed6726b4..da3bad301efab 100644
--- a/drivers/infiniband/sw/rxe/rxe_verbs.c
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
@@ -1326,19 +1326,20 @@ static struct ib_mr *rxe_rereg_user_mr(struct ib_mr *ibmr, int flags,
if (err)
return ERR_PTR(err);
+ if ((flags & IB_MR_REREG_ACCESS) &&
+ (access & ~RXE_ACCESS_SUPPORTED_MR)) {
+ rxe_err_mr(mr, "access = %#x not supported\n", access);
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+
if (flags & IB_MR_REREG_PD) {
rxe_put(old_pd);
rxe_get(pd);
mr->ibmr.pd = ibpd;
}
- if (flags & IB_MR_REREG_ACCESS) {
- if (access & ~RXE_ACCESS_SUPPORTED_MR) {
- rxe_err_mr(mr, "access = %#x not supported\n", access);
- return ERR_PTR(-EOPNOTSUPP);
- }
+ if (flags & IB_MR_REREG_ACCESS)
mr->access = access;
- }
return NULL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 030/877] RDMA/rxe: Fix integer overflow in mr_check_range() leading to OOB access
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (28 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 029/877] RDMA/rxe: validate access flags before swapping the MRs PD Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 031/877] firmware: arm_scpi: reject DVFS OPP count above MAX_DVFS_OPPS Greg Kroah-Hartman
` (854 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Gang Yan, Zhu Yanjun, Shukai Ni,
Leon Romanovsky, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gang Yan <yangang@kylinos.cn>
[ Upstream commit d10e2a08799e858d3e71ea4169bcd018f216d444 ]
mr_check_range() validates that [iova, iova+length) falls within the
registered MR range using wraparound-prone arithmetic:
if (iova < mr->ibmr.iova ||
iova + length > mr->ibmr.iova + mr->ibmr.length)
A remote peer can craft an RDMA-Write/Read RETH so that iova + length
wraps to 0 (e.g. iova=0xfffffffffffffff8, length=8), bypassing the
check. rxe_mr_iova_to_index() then computes a huge index (int idx, only
guarded by WARN_ON) and rxe_mr_copy_xarray() dereferences
mr->page_info[huge], causing an out-of-bounds read/write and a kernel
oops that is triggerable by an unauthenticated remote peer.
Rewrite the check in overflow-safe form; the first two clauses guarantee
that the subsequent subtractions do not underflow:
if (iova < mr->ibmr.iova ||
length > mr->ibmr.length ||
iova - mr->ibmr.iova > mr->ibmr.length - length)
With the fix, mr_check_range() returns -EINVAL for the crafted iova and
the responder reports REMOTE_ACCESS_ERROR instead of triggering the OOB.
Fixes: 8700e3e7c485 ("Soft RoCE driver")
Signed-off-by: Gang Yan <yangang@kylinos.cn>
Link: https://patch.msgid.link/20260814093740.292954-1-gang.yan@linux.dev
Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev>
Reviewed-by: Shukai Ni <shukai.ni@kuleuven.be>
Tested-by: Shukai Ni <shukai.ni@kuleuven.be>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/sw/rxe/rxe_mr.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c
index da3dee520876a..83e325b76f67d 100644
--- a/drivers/infiniband/sw/rxe/rxe_mr.c
+++ b/drivers/infiniband/sw/rxe/rxe_mr.c
@@ -33,7 +33,8 @@ int mr_check_range(struct rxe_mr *mr, u64 iova, size_t length)
case IB_MR_TYPE_USER:
case IB_MR_TYPE_MEM_REG:
if (iova < mr->ibmr.iova ||
- iova + length > mr->ibmr.iova + mr->ibmr.length) {
+ length > mr->ibmr.length ||
+ iova - mr->ibmr.iova > mr->ibmr.length - length) {
rxe_dbg_mr(mr, "iova/length out of range\n");
return -EINVAL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 031/877] firmware: arm_scpi: reject DVFS OPP count above MAX_DVFS_OPPS
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (29 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 030/877] RDMA/rxe: Fix integer overflow in mr_check_range() leading to OOB access Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 032/877] clk: scpi: bound-check DVFS index in scpi_dvfs_recalc_rate Greg Kroah-Hartman
` (853 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Xixin Liu, Sudeep Holla, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xixin Liu <liuxixin@kylinos.cn>
[ Upstream commit 32471d84a487c7fd74532bc96be56f8028cf4a3f ]
scpi_dvfs_get_info() already rejected a zero opp_count, but still trusted
any larger value from the SCP firmware. The shared-memory reply only holds
MAX_DVFS_OPPS entries in buf.opps[]; a bigger count over-reads that array
and then sizes the allocated OPP table incorrectly (garbage OPPs / OOB).
The missing upper bound dates back to the original SCPI DVFS support.
Reject zero and out-of-range counts in one check and return -EINVAL.
Fixes: 8cb7cf56c9fe ("firmware: add support for ARM System Control and Power Interface(SCPI) protocol")
Signed-off-by: Xixin Liu <liuxixin@kylinos.cn>
Link: https://patch.msgid.link/022802f0b38f.v2.1785200642.git.liuxixin@kylinos.cn
Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/firmware/arm_scpi.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c
index 2d33771917bb4..ec6f3d0cdd6a1 100644
--- a/drivers/firmware/arm_scpi.c
+++ b/drivers/firmware/arm_scpi.c
@@ -631,8 +631,8 @@ static struct scpi_dvfs_info *scpi_dvfs_get_info(u8 domain)
if (ret)
return ERR_PTR(ret);
- if (!buf.opp_count)
- return ERR_PTR(-ENOENT);
+ if (!buf.opp_count || buf.opp_count > MAX_DVFS_OPPS)
+ return ERR_PTR(-EINVAL);
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 032/877] clk: scpi: bound-check DVFS index in scpi_dvfs_recalc_rate
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (30 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 031/877] firmware: arm_scpi: reject DVFS OPP count above MAX_DVFS_OPPS Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 033/877] RDMA/rxe: insert mcg into mcg_tree only after rxe_mcast_add() succeeds Greg Kroah-Hartman
` (852 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Xixin Liu, Sudeep Holla, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xixin Liu <liuxixin@kylinos.cn>
[ Upstream commit 70f4b78d560e592cbf3325b162424737d032fc1d ]
dvfs_get_idx() may return an out-of-range index if the SCP firmware is
buggy or returns a stale value. Only negative indexes were rejected, so a
large index walked past info->opps and could treat garbage as a clock rate
(KASAN OOB / wrong frequency to consumers). The missing upper bound dates
back to the original SCPI clock driver.
Treat indexes >= opp count as invalid and return 0, same as idx < 0.
Fixes: cd52c2a4b5c4 ("clk: add support for clocks provided by SCP(System Control Processor)")
Signed-off-by: Xixin Liu <liuxixin@kylinos.cn>
Link: https://patch.msgid.link/04f9ab766e07.v2.1785200642.git.liuxixin@kylinos.cn
Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/clk/clk-scpi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c
index 50ac1cd255785..598dc1fd99ade 100644
--- a/drivers/clk/clk-scpi.c
+++ b/drivers/clk/clk-scpi.c
@@ -85,7 +85,7 @@ static unsigned long scpi_dvfs_recalc_rate(struct clk_hw *hw,
int idx = clk->scpi_ops->dvfs_get_idx(clk->id);
const struct scpi_opp *opp;
- if (idx < 0)
+ if (idx < 0 || idx >= clk->info->count)
return 0;
opp = clk->info->opps + idx;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 033/877] RDMA/rxe: insert mcg into mcg_tree only after rxe_mcast_add() succeeds
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (31 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 032/877] clk: scpi: bound-check DVFS index in scpi_dvfs_recalc_rate Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 034/877] RDMA/core: Reject unregistering netdevs in ib_get_eth_speed Greg Kroah-Hartman
` (851 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael Bommarito, Zhu Yanjun,
Leon Romanovsky, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <michael.bommarito@gmail.com>
[ Upstream commit 1caceeb2d74bbe88223aea55eb8626b4c5f076fd ]
rxe_get_mcg() publishes a newly allocated multicast group in
rxe->mcg_tree before programming the backing Ethernet multicast address
with rxe_mcast_add(), which runs outside mcg_lock. A local userspace
RDMA client reaches this path with ATTACH_MCAST on a UD QP; if
rxe_mcast_add() then returns an error (for example -ENODEV when the
backing netdev has been removed, or a propagated dev_mc_add() error),
the unwind frees the published group without removing it from the tree.
A later lookup of the same MGID dereferences the freed struct rxe_mcg
from __rxe_lookup_mcg().
Fix this by keeping the new mcg private until rxe_mcast_add() succeeds.
Split the tree publication into __rxe_publish_mcg(), call rxe_mcast_add()
before taking the tree reference, and free the still-private mcg on
failure. Because the group is never visible in mcg_tree until the
multicast address is programmed, no concurrent caller can look it up or
attach a QP to a group that is about to be torn down, so the error path
needs no conditional unwind. If another caller publishes the same MGID
while the address is being programmed, the post-add re-check under
mcg_lock finds the winner; this caller then drops its private object and
balances its own rxe_mcast_add() with rxe_mcast_del() before returning
the winner.
Reproduced by forcing the rxe_mcast_add() error return under KASAN:
without the change the next attach to the same MGID reports a
slab-use-after-free in __rxe_lookup_mcg(); with it the forced failure
returns cleanly. A no-injection attach/detach regression, including a
two-QP shared join/leave and re-attach, stays KASAN- and leak-clean.
Fixes: a926a903b7dc ("RDMA/rxe: Do not call dev_mc_add/del() under a spinlock")
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Link: https://patch.msgid.link/20260617022728.2770116-1-michael.bommarito@gmail.com
Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/sw/rxe/rxe_mcast.c | 50 +++++++++++++++++++--------
1 file changed, 36 insertions(+), 14 deletions(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_mcast.c b/drivers/infiniband/sw/rxe/rxe_mcast.c
index 07ff47bae31df..c14680c9a5362 100644
--- a/drivers/infiniband/sw/rxe/rxe_mcast.c
+++ b/drivers/infiniband/sw/rxe/rxe_mcast.c
@@ -175,7 +175,9 @@ struct rxe_mcg *rxe_lookup_mcg(struct rxe_dev *rxe, union ib_gid *mgid)
* @mgid: multicast address as a gid
* @mcg: new mcg object
*
- * Context: caller should hold rxe->mcg lock
+ * Initializes the mcg fields. The mcg is private and not yet visible in
+ * mcg_tree, so this may run without rxe->mcg_lock; __rxe_publish_mcg()
+ * makes it visible under the lock once it is ready.
*/
static void __rxe_init_mcg(struct rxe_dev *rxe, union ib_gid *mgid,
struct rxe_mcg *mcg)
@@ -184,13 +186,22 @@ static void __rxe_init_mcg(struct rxe_dev *rxe, union ib_gid *mgid,
memcpy(&mcg->mgid, mgid, sizeof(mcg->mgid));
INIT_LIST_HEAD(&mcg->qp_list);
mcg->rxe = rxe;
+}
- /* caller holds a ref on mcg but that will be
- * dropped when mcg goes out of scope. We need to take a ref
- * on the pointer that will be saved in the red-black tree
- * by __rxe_insert_mcg and used to lookup mcg from mgid later.
- * Inserting mcg makes it visible to outside so this should
- * be done last after the object is ready.
+/**
+ * __rxe_publish_mcg - make a fully initialized mcg visible in mcg_tree
+ * @mcg: the mcg object
+ *
+ * Context: caller must hold rxe->mcg_lock and a reference on mcg
+ */
+static void __rxe_publish_mcg(struct rxe_mcg *mcg)
+{
+ /* caller holds a ref on mcg but that will be dropped when mcg goes
+ * out of scope. We need to take a ref on the pointer that will be
+ * saved in the red-black tree by __rxe_insert_mcg and used to lookup
+ * mcg from mgid later. Inserting mcg makes it visible to outside so
+ * this is done last after the object is ready and the multicast
+ * address has been programmed.
*/
kref_get(&mcg->ref_cnt);
__rxe_insert_mcg(mcg);
@@ -228,26 +239,37 @@ static struct rxe_mcg *rxe_get_mcg(struct rxe_dev *rxe, union ib_gid *mgid)
err = -ENOMEM;
goto err_dec;
}
+ __rxe_init_mcg(rxe, mgid, mcg);
+
+ /* program the multicast address while mcg is still private, before
+ * it is inserted into mcg_tree. dev_mc_add() may sleep so this must
+ * run outside mcg_lock. On failure mcg was never published, so a
+ * plain free is correct and the tree is untouched.
+ */
+ err = rxe_mcast_add(rxe, mgid);
+ if (err) {
+ kfree(mcg);
+ goto err_dec;
+ }
spin_lock_bh(&rxe->mcg_lock);
- /* re-check to see if someone else just added it */
+ /* re-check to see if someone else just added it while we were adding
+ * the multicast address; if so use theirs and drop ours
+ */
tmp = __rxe_lookup_mcg(rxe, mgid);
if (tmp) {
spin_unlock_bh(&rxe->mcg_lock);
+ rxe_mcast_del(rxe, mgid);
atomic_dec(&rxe->mcg_num);
kfree(mcg);
return tmp;
}
- __rxe_init_mcg(rxe, mgid, mcg);
+ __rxe_publish_mcg(mcg);
spin_unlock_bh(&rxe->mcg_lock);
- /* add mcast address outside of lock */
- err = rxe_mcast_add(rxe, mgid);
- if (!err)
- return mcg;
+ return mcg;
- kfree(mcg);
err_dec:
atomic_dec(&rxe->mcg_num);
return ERR_PTR(err);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 034/877] RDMA/core: Reject unregistering netdevs in ib_get_eth_speed
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (32 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 033/877] RDMA/rxe: insert mcg into mcg_tree only after rxe_mcast_add() succeeds Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 035/877] IB/iser: reject a remote invalidation of an unregistered direction Greg Kroah-Hartman
` (850 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+5fe14f2ff4ccbace9a26,
Krystian Kaniewski, Leon Romanovsky, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krystian Kaniewski <krystianmkaniewski@gmail.com>
[ Upstream commit ef9fbe1b93f3b617b96e86d5cd76b3fa44514cb5 ]
ib_device_get_netdev() intentionally returns a referenced net_device even
when it is unregistering, so matching and cleanup callers can still find
the association. The reference keeps struct net_device allocated, but does
not guarantee that the device remains operational.
ib_get_eth_speed() uses the returned device operationally by invoking its
ethtool callback. Although that call is made under RTNL, the function does
not verify the registration state first. An asynchronous RDMA port query
can therefore call into a netdev after NETDEV_UNREGISTER and ndo_uninit
have completed.
Check for NETREG_REGISTERED while holding RTNL and return -ENODEV for a
device which is being unregistered. Keeping RTNL across the check and the
ethtool operation prevents unregister from starting between them.
Keep the speed fallback and warning under RTNL as well, so the warning can
safely read netdev->name. Drop the netdev reference before releasing RTNL
once all accesses to the device are complete.
Fixes: d41861942fc5 ("IB/core: Add generic function to extract IB speed from netdev")
Reported-by: syzbot+5fe14f2ff4ccbace9a26@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=5fe14f2ff4ccbace9a26
Signed-off-by: Krystian Kaniewski <krystianmkaniewski@gmail.com>
Link: https://patch.msgid.link/20260812081708.32468-1-krystianmkaniewski@gmail.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/core/verbs.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index d0bd57ac7c6aa..d6fd7db5cbbd7 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -2000,11 +2000,13 @@ int ib_get_eth_speed(struct ib_device *dev, u32 port_num, u16 *speed, u8 *width)
return -ENODEV;
rtnl_lock();
- rc = __ethtool_get_link_ksettings(netdev, &lksettings);
- rtnl_unlock();
-
- dev_put(netdev);
+ if (READ_ONCE(netdev->reg_state) != NETREG_REGISTERED) {
+ dev_put(netdev);
+ rtnl_unlock();
+ return -ENODEV;
+ }
+ rc = __ethtool_get_link_ksettings(netdev, &lksettings);
if (!rc && lksettings.base.speed != (u32)SPEED_UNKNOWN) {
netdev_speed = lksettings.base.speed;
} else {
@@ -2013,6 +2015,8 @@ int ib_get_eth_speed(struct ib_device *dev, u32 port_num, u16 *speed, u8 *width)
pr_warn("%s speed is unknown, defaulting to %u\n",
netdev->name, netdev_speed);
}
+ dev_put(netdev);
+ rtnl_unlock();
ib_get_width_and_speed(netdev_speed, lksettings.lanes,
speed, width);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 035/877] IB/iser: reject a remote invalidation of an unregistered direction
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (33 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 034/877] RDMA/core: Reject unregistering netdevs in ib_get_eth_speed Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 036/877] IB/isert: wait for deferred control PDU completions before releasing the connection Greg Kroah-Hartman
` (849 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yehyeong Lee, Max Gurtovoy,
Leon Romanovsky, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
[ Upstream commit d85f0f0a7c85756fc992c70d869706f19dac9259 ]
A write command whose data is sent entirely as immediate data is not
registered. iser_reg_mem_fastreg() takes the DMA key path and leaves
rdma_reg[ISER_DIR_OUT].desc at NULL, while iser_dma_map_task_data() has
already set dir[ISER_DIR_OUT].
iser_check_remote_inv() looks at dir[] alone and hands the descriptor to
iser_inv_desc(), which reads desc->sig_protected. A target that answers
such a command with IB_WR_SEND_WITH_INV faults the initiator.
Leaving those commands unregistered is deliberate.
The same function already terminates the connection when a target sends
a remote invalidation the initiator did not ask for. A target that
invalidates a direction that was never registered is in the same class,
so give it the same answer.
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000004: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000020-0x0000000000000027]
CPU: 0 UID: 0 PID: 40 Comm: kworker/u8:2 Not tainted 7.2.0-rc5-ISERHOST-gf5098b6bae76-dirty #3 PREEMPT(lazy)
Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Workqueue: rxe_wq do_work
RIP: 0010:iser_task_rsp+0x6d6/0xec0
Code: 48 c1 ea 03 80 3c 02 00 0f 85 ba 06 00 00 48 8b 9b 78 01 00 00 48 b8 00 00 00 00 00 fc ff df 48 8d 7b 20 48 89 fa 48 c1 ea 03 <0f> b6 04 02 84 c0 74 06 0f 8e 76 06 00 00 80 7b 20 00 0f 84 3d 04
RSP: 0018:ffff88811b008db8 EFLAGS: 00010202
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000001848
RDX: 0000000000000004 RSI: 1ffff11021587b12 RDI: 0000000000000020
RBP: ffff88810adc1ae4 R08: ffff888109b7f860 R09: ffffffff90a922c0
R10: ffff88810adc1a1c R11: 000000000000003c R12: ffff888109b7f800
R13: ffff88810adc1acc R14: ffff888109b7f820 R15: 0000000000000000
FS: 0000000000000000(0000) GS:ffff88818a676000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000005afe2b CR3: 000000010af23005 CR4: 0000000000770ef0
PKRU: 55555554
Call Trace:
<IRQ>
__ib_process_cq+0xe1/0x390
ib_poll_handler+0x6e/0x200
irq_poll_softirq+0x1df/0x480
? clockevents_program_event+0x2ba/0x860
? __pfx_irq_poll_softirq+0x10/0x10
handle_softirqs+0x18e/0x590
? __pfx_handle_softirqs+0x10/0x10
? __hrtimer_rearm_deferred+0x156/0x450
do_softirq+0x3b/0x60
</IRQ>
<TASK>
__local_bh_enable_ip+0x61/0x70
__alloc_skb+0x732/0x890
? _raw_spin_lock_irqsave+0x85/0xe0
? __pfx___alloc_skb+0x10/0x10
? _raw_read_unlock_irqrestore+0x16/0x50
rxe_init_packet+0x16b/0x4f0
prepare_ack_packet+0xb8/0x830
rxe_receiver+0x499/0x9980
? __pfx_rxe_receiver+0x10/0x10
? rxe_completer+0x29e5/0x38c0
? hrtimer_start_range_ns_common+0x75f/0x1730
? hrtimer_start_range_ns+0xa6/0x2c0
? __pfx__raw_spin_lock_irqsave+0x10/0x10
? __pfx_rxe_receiver+0x10/0x10
do_work+0x144/0x470
process_one_work+0x633/0x1030
? assign_work+0x11d/0x370
worker_thread+0x45b/0xd10
? __pfx_worker_thread+0x10/0x10
kthread+0x2c6/0x3b0
? recalc_sigpending+0x15c/0x1e0
? __pfx_kthread+0x10/0x10
ret_from_fork+0x36e/0x5a0
? __pfx_ret_from_fork+0x10/0x10
? __switch_to+0x572/0xdd0
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1a/0x30
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
Fixes: 59caaed7a72a ("IB/iser: Support the remote invalidation exception")
Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Link: https://patch.msgid.link/20260819010804.641772-1-yhlee@isslab.korea.ac.kr
Reviewed-by: Max Gurtovoy <mgurtovoy@nvidia.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/ulp/iser/iser_initiator.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
index f5f090dc4f1eb..cf234ddbaaad5 100644
--- a/drivers/infiniband/ulp/iser/iser_initiator.c
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -599,11 +599,8 @@ static int iser_check_remote_inv(struct iser_conn *iser_conn, struct ib_wc *wc,
iser_dbg("conn %p: remote invalidation for rkey %#x\n",
iser_conn, rkey);
- if (unlikely(!iser_conn->snd_w_inv)) {
- iser_err("conn %p: unexpected remote invalidation, terminating connection\n",
- iser_conn);
- return -EPROTO;
- }
+ if (unlikely(!iser_conn->snd_w_inv))
+ goto bad_inv;
task = iscsi_itt_to_ctask(iser_conn->iscsi_conn, hdr->itt);
if (likely(task)) {
@@ -612,12 +609,16 @@ static int iser_check_remote_inv(struct iser_conn *iser_conn, struct ib_wc *wc,
if (iser_task->dir[ISER_DIR_IN]) {
desc = iser_task->rdma_reg[ISER_DIR_IN].desc;
+ if (unlikely(!desc))
+ goto bad_inv;
if (unlikely(iser_inv_desc(desc, rkey)))
return -EINVAL;
}
if (iser_task->dir[ISER_DIR_OUT]) {
desc = iser_task->rdma_reg[ISER_DIR_OUT].desc;
+ if (unlikely(!desc))
+ goto bad_inv;
if (unlikely(iser_inv_desc(desc, rkey)))
return -EINVAL;
}
@@ -628,6 +629,11 @@ static int iser_check_remote_inv(struct iser_conn *iser_conn, struct ib_wc *wc,
}
return 0;
+
+bad_inv:
+ iser_err("conn %p: unexpected remote invalidation, terminating connection\n",
+ iser_conn);
+ return -EPROTO;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 036/877] IB/isert: wait for deferred control PDU completions before releasing the connection
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (34 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 035/877] IB/iser: reject a remote invalidation of an unregistered direction Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 037/877] RDMA/mad: Fix receive buffer leak when PKey enforcement fails Greg Kroah-Hartman
` (848 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yehyeong Lee, Leon Romanovsky,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
[ Upstream commit a8fe3dfce8c0d8a76dc3d8486a5bff5feebe156f ]
isert_send_done() hands ISTATE_SEND_TASKMGTRSP, ISTATE_SEND_REJECT and
ISTATE_SEND_TEXTRSP completions off to isert_comp_wq and returns. The work
item then runs isert_completion_put() -> isert_put_cmd(), which reads
isert_conn->conn and takes conn->cmd_lock.
Nothing orders that work item against teardown. isert_wait_conn() queues
isert_release_work, which frees isert_conn, and iscsit_close_connection()
frees the iscsit_conn right after it returns, so the queued work can run
against freed memory.
Count the deferred control PDU completions per connection and let
isert_wait_conn() wait for them before the release work is queued.
ISTATE_SEND_LOGOUTRSP is deliberately not counted: that branch runs
iscsit_logout_post_handler(), which ends up waiting for
conn->conn_wait_comp, and that completion is only sent by
iscsit_close_connection() after it has called iscsit_wait_conn().
Waiting for it here would deadlock. Its wait stays the existing
isert_wait4logout().
The splat below is from a kernel with tracing printk()s and an msleep(200)
injected into isert_do_control_comp() to widen the window:
BUG: KASAN: slab-use-after-free in isert_put_cmd+0x53d/0x620
Read of size 8 at addr ffff8881054f1038 by task kworker/u17:1/182
CPU: 0 UID: 0 PID: 182 Comm: kworker/u17:1 Tainted: G B 7.2.0-rc5-TWIDE-gb8babf08acc7 #1 PREEMPT(lazy)
Tainted: [B]=BAD_PAGE
Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Workqueue: isert_comp_wq isert_do_control_comp
Call Trace:
<TASK>
dump_stack_lvl+0x53/0x70
print_report+0xd0/0x630
? __pfx__raw_spin_lock_irqsave+0x10/0x10
? _raw_spin_unlock_irqrestore+0x3e/0x70
? isert_put_cmd+0x53d/0x620
kasan_report+0xce/0x100
? isert_put_cmd+0x53d/0x620
isert_put_cmd+0x53d/0x620
? isert_completion_put+0x305/0x330
? isert_do_control_comp+0x2ef/0x310
process_one_work+0x633/0x1030
? assign_work+0x11d/0x370
worker_thread+0x45b/0xd10
? __pfx_worker_thread+0x10/0x10
? __pfx_worker_thread+0x10/0x10
kthread+0x2c6/0x3b0
? recalc_sigpending+0x15c/0x1e0
? __pfx_kthread+0x10/0x10
ret_from_fork+0x36e/0x5a0
? __pfx_ret_from_fork+0x10/0x10
? __switch_to+0x572/0xdd0
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1a/0x30
</TASK>
Allocated by task 48:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
__kasan_kmalloc+0x8f/0xa0
__kmalloc_cache_noprof+0x158/0x370
isert_cma_handler+0x1e3/0x2ae0
cma_cm_event_handler+0x3e/0x240
cma_ib_req_handler+0x17d9/0x4490
cm_process_work+0x41/0x330
cm_work_handler+0x5727/0xc160
process_one_work+0x633/0x1030
worker_thread+0x45b/0xd10
kthread+0x2c6/0x3b0
ret_from_fork+0x36e/0x5a0
ret_from_fork_asm+0x1a/0x30
Freed by task 184:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
kasan_save_free_info+0x3b/0x60
__kasan_slab_free+0x43/0x70
kfree+0x121/0x380
iscsit_close_connection+0x7cf/0x1e60
iscsit_take_action_for_connection_exit+0x1b6/0x360
iscsi_target_tx_thread+0x472/0x690
kthread+0x2c6/0x3b0
ret_from_fork+0x36e/0x5a0
ret_from_fork_asm+0x1a/0x30
Fixes: b8d26b3be8b3 ("iser-target: Add iSCSI Extensions for RDMA (iSER) target driver")
Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Link: https://patch.msgid.link/20260821080620.1694119-1-yhlee@isslab.korea.ac.kr
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/ulp/isert/ib_isert.c | 22 ++++++++++++++++++++++
drivers/infiniband/ulp/isert/ib_isert.h | 2 ++
2 files changed, 24 insertions(+)
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index 6483a55170cd1..b3fc753982a38 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -21,6 +21,7 @@
#include <target/target_core_fabric.h>
#include <target/iscsi/iscsi_transport.h>
#include <linux/semaphore.h>
+#include <linux/wait_bit.h>
#include "ib_isert.h"
@@ -311,6 +312,7 @@ isert_init_conn(struct isert_conn *isert_conn)
init_completion(&isert_conn->login_req_comp);
init_waitqueue_head(&isert_conn->rem_wait);
kref_init(&isert_conn->kref);
+ atomic_set(&isert_conn->ctrl_comp_cnt, 0);
mutex_init(&isert_conn->mutex);
INIT_WORK(&isert_conn->release_work, isert_release_work);
}
@@ -1697,6 +1699,8 @@ isert_do_control_comp(struct work_struct *work)
struct isert_conn *isert_conn = isert_cmd->conn;
struct ib_device *ib_dev = isert_conn->cm_id->device;
struct iscsit_cmd *cmd = isert_cmd->iscsit_cmd;
+ /* The switch below may free isert_cmd. */
+ bool counted = isert_cmd->ctrl_counted;
isert_dbg("Cmd %p i_state %d\n", isert_cmd, cmd->i_state);
@@ -1718,6 +1722,14 @@ isert_do_control_comp(struct work_struct *work)
dump_stack();
break;
}
+
+ /*
+ * The count is what keeps isert_conn alive, so drop it last. The wait
+ * queue lives in the global hash table, not in isert_conn, so this is
+ * safe even if the waiter has already freed the connection.
+ */
+ if (counted && atomic_dec_and_test(&isert_conn->ctrl_comp_cnt))
+ wake_up_var(&isert_conn->ctrl_comp_cnt);
}
static void
@@ -1761,6 +1773,12 @@ isert_send_done(struct ib_cq *cq, struct ib_wc *wc)
case ISTATE_SEND_TEXTRSP:
isert_unmap_tx_desc(tx_desc, ib_dev);
+ /* Paired with the wait in isert_wait_conn(). */
+ isert_cmd->ctrl_counted =
+ isert_cmd->iscsit_cmd->i_state != ISTATE_SEND_LOGOUTRSP;
+ if (isert_cmd->ctrl_counted)
+ atomic_inc(&isert_conn->ctrl_comp_cnt);
+
INIT_WORK(&isert_cmd->comp_work, isert_do_control_comp);
queue_work(isert_comp_wq, &isert_cmd->comp_work);
return;
@@ -2605,6 +2623,10 @@ static void isert_wait_conn(struct iscsit_conn *conn)
isert_wait4cmds(conn);
isert_wait4logout(isert_conn);
+ /* Paired with the count taken in isert_send_done(). */
+ wait_var_event(&isert_conn->ctrl_comp_cnt,
+ !atomic_read(&isert_conn->ctrl_comp_cnt));
+
queue_work(isert_release_wq, &isert_conn->release_work);
}
diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h
index 0bac5aa66c802..519b17e54bd34 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.h
+++ b/drivers/infiniband/ulp/isert/ib_isert.h
@@ -153,6 +153,7 @@ struct isert_cmd {
struct work_struct comp_work;
struct scatterlist sg;
bool ctx_init_done;
+ bool ctrl_counted;
};
static inline struct isert_cmd *tx_desc_to_cmd(struct iser_tx_desc *desc)
@@ -187,6 +188,7 @@ struct isert_conn {
struct mutex mutex;
struct kref kref;
struct work_struct release_work;
+ atomic_t ctrl_comp_cnt;
bool logout_posted;
bool snd_w_inv;
wait_queue_head_t rem_wait;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 037/877] RDMA/mad: Fix receive buffer leak when PKey enforcement fails
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (35 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 036/877] IB/isert: wait for deferred control PDU completions before releasing the connection Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 038/877] RDMA/irdma: Enforce local fence for IB_WR_REG_MR Greg Kroah-Hartman
` (847 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Li RongQing, Leon Romanovsky,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li RongQing <lirongqing@baidu.com>
[ Upstream commit 3476c28c9addfa253f505e6bd87f1f5598b961d0 ]
ib_mad_complete_recv() initializes mad_recv_wc->rmpp_list and then runs
ib_mad_enforce_security() before linking recv_buf onto that list. On
failure it calls ib_free_recv_mad(), which only walks rmpp_list and frees
the ib_mad_private of every buffer found there. As the list is still
empty at that point, nothing is freed at all.
The caller cannot clean up either: ib_mad_recv_done() sets recv to NULL
right after ib_mad_complete_recv() returns, assuming the MAD layer took
ownership of the buffer. Every MAD that fails the PKey check therefore
leaks one ib_mad_private (about 300 bytes per IB port MAD, ~2K for OPA),
and a remote node can trigger this repeatedly by sending MADs with a
wrong PKey.
Link recv_buf onto rmpp_list right after the list is initialized, so the
error path has something to free.
Fixes: 47a2b338fe63 ("IB/core: Enforce security on management datagrams")
Signed-off-by: Li RongQing <lirongqing@baidu.com>
Link: https://patch.msgid.link/20260826073216.2367-1-lirongqing@baidu.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/core/mad.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 96c1fd8039fb5..21f482e0243f2 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -1805,6 +1805,8 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
int ret;
INIT_LIST_HEAD(&mad_recv_wc->rmpp_list);
+ list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list);
+
ret = ib_mad_enforce_security(mad_agent_priv,
mad_recv_wc->wc->pkey_index);
if (ret) {
@@ -1813,7 +1815,6 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
return;
}
- list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list);
if (is_kernel_rmpp_data_response(mad_agent_priv, mad_recv_wc)) {
spin_lock_irqsave(&mad_agent_priv->lock, flags);
mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 038/877] RDMA/irdma: Enforce local fence for IB_WR_REG_MR
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (36 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 037/877] RDMA/mad: Fix receive buffer leak when PKey enforcement fails Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 039/877] RDMA/rtrs-clt: Fix CQ pool leak when connect is interrupted Greg Kroah-Hartman
` (846 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jacob Moroni, Leon Romanovsky,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacob Moroni <jmoroni@google.com>
[ Upstream commit 3fb905f07ea45b31c8f67ba6e4668de46f527e65 ]
Enforce local fence for IB_WR_REG_MR to avoid spurious
FASTREG_VALID_MKEY async events during heavy invalidation
and registration activity.
Commit 69e8e429bca2 ("RDMA/irdma: Enforce local fence for LOCAL_INV WRs")
was very similar, but was not sufficient to prevent all occurrences
of these async events.
Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
Signed-off-by: Jacob Moroni <jmoroni@google.com>
Link: https://patch.msgid.link/20260901160014.2026285-1-jmoroni@google.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/hw/irdma/verbs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
index d8e101fc74ff7..97fa345635524 100644
--- a/drivers/infiniband/hw/irdma/verbs.c
+++ b/drivers/infiniband/hw/irdma/verbs.c
@@ -3571,7 +3571,7 @@ static int irdma_post_send(struct ib_qp *ibqp,
stag_info.total_len = iwmr->ibmr.length;
stag_info.reg_addr_pa = *palloc->level1.addr;
stag_info.first_pm_pbl_index = palloc->level1.idx;
- stag_info.local_fence = ib_wr->send_flags & IB_SEND_FENCE;
+ stag_info.local_fence = true;
if (iwmr->npages > IRDMA_MIN_PAGES_PER_FMR)
stag_info.chunk_size = 1;
err = irdma_sc_mr_fast_register(&iwqp->sc_qp, &stag_info,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 039/877] RDMA/rtrs-clt: Fix CQ pool leak when connect is interrupted
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (37 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 038/877] RDMA/irdma: Enforce local fence for IB_WR_REG_MR Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 040/877] dmaengine: sprd: Fix runtime PM reference leak in probe Greg Kroah-Hartman
` (845 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+d396918a29afb8543e1c,
Quanye Yang, Jack Wang, Leon Romanovsky, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Quanye Yang <quanyeyang@proton.me>
[ Upstream commit 2ae16aaa78b5edc6e6d0904c84fd9cdfb762bcda ]
The client borrows shared CQ credits in the ADDR_RESOLVED handler via
ib_cq_pool_get(), before the peer is connected. create_cm() can return
-ERESTARTSYS from wait_event_interruptible_timeout() without destroying
the CM ID. The init_conns() and stop-and-destroy paths then call
destroy_con_cq_qp() while cq is still NULL (no PUT) and only afterwards
rdma_destroy_id().
CMA serializes the handler against rdma_destroy_id() with handler_mutex,
but that does not order the GET against destroy_con_cq_qp(). If
ADDR_RESOLVED has already passed the DESTROYING check, it can take
con_mutex, GET credits, and then lose the con to kfree. Device
unregister later hits WARN_ON(cq->cqe_used) in ib_cq_pool_cleanup().
Set a per-connection flag under con_mutex before CQ/QP teardown so a
racing ADDR_RESOLVED cannot borrow credits after teardown has begun.
Reported-by: syzbot+d396918a29afb8543e1c@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=d396918a29afb8543e1c
Fixes: 3b89e92c2a95 ("RDMA/rtrs: Use new shared CQ mechanism")
Signed-off-by: Quanye Yang <quanyeyang@proton.me>
Link: https://patch.msgid.link/20260830-rdma-rtrs-clt-cq-pool-leak-v1-1-b169434fd3df@proton.me
Reviewed-by: Jack Wang <jinpu.wang@cloud.ionos.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/ulp/rtrs/rtrs-clt.c | 8 ++++++++
drivers/infiniband/ulp/rtrs/rtrs-clt.h | 2 ++
2 files changed, 10 insertions(+)
diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
index 8fa1d72bd20a4..fea3b17611c50 100644
--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
@@ -1738,6 +1738,8 @@ static void destroy_con_cq_qp(struct rtrs_clt_con *con)
/*
* Be careful here: destroy_con_cq_qp() can be called even
* create_con_cq_qp() failed, see comments there.
+ * Caller must set con->destroyed under this lock first so a
+ * racing ADDR_RESOLVED cannot ib_cq_pool_get() after we PUT/SKIP.
*/
lockdep_assert_held(&con->con_mutex);
rtrs_cq_qp_destroy(&con->c);
@@ -1772,6 +1774,10 @@ static int rtrs_rdma_addr_resolved(struct rtrs_clt_con *con)
int err;
mutex_lock(&con->con_mutex);
+ if (con->destroyed) {
+ mutex_unlock(&con->con_mutex);
+ return -ECONNABORTED;
+ }
err = create_con_cq_qp(con);
mutex_unlock(&con->con_mutex);
if (err) {
@@ -2202,6 +2208,7 @@ static void rtrs_clt_stop_and_destroy_conns(struct rtrs_clt_path *clt_path)
break;
con = to_clt_con(clt_path->s.con[cid]);
mutex_lock(&con->con_mutex);
+ con->destroyed = true;
destroy_con_cq_qp(con);
mutex_unlock(&con->con_mutex);
destroy_cm(con);
@@ -2368,6 +2375,7 @@ static int init_conns(struct rtrs_clt_path *clt_path)
if (con->c.cm_id) {
stop_cm(con);
mutex_lock(&con->con_mutex);
+ con->destroyed = true;
destroy_con_cq_qp(con);
mutex_unlock(&con->con_mutex);
destroy_cm(con);
diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.h b/drivers/infiniband/ulp/rtrs/rtrs-clt.h
index 0f57759b3080f..e1e7c7adc9470 100644
--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.h
+++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.h
@@ -75,6 +75,8 @@ struct rtrs_clt_con {
unsigned int cpu;
struct mutex con_mutex;
int cm_err;
+ /* Set under con_mutex before CQ/QP teardown. */
+ bool destroyed;
};
/**
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 040/877] dmaengine: sprd: Fix runtime PM reference leak in probe
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (38 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 039/877] RDMA/rtrs-clt: Fix CQ pool leak when connect is interrupted Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 041/877] wifi: virt_wifi: free skb when disconnected Greg Kroah-Hartman
` (844 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ruoyu Wang, Frank Li, Baolin Wang,
Vinod Koul, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ruoyu Wang <ruoyuw560@gmail.com>
[ Upstream commit a7df136ec529ee49a789c5029bc37b98b0d4bedd ]
pm_runtime_get_sync() increments a device's usage counter even when it
fails. sprd_dma_probe() currently jumps directly to controller clock
cleanup on that error, bypassing both pm_runtime_put_noidle() and
pm_runtime_disable(). This can happen if the preceding unchecked
pm_runtime_set_active() fails and the following runtime-resume attempt
also returns an error.
Enter the existing runtime-PM unwind path instead. This drops the
reference without idling the partially initialized device, disables
runtime PM, and then releases the controller clocks. The success path
and propagated error code are unchanged.
This issue was found by a static analysis checker and confirmed by manual
source review.
Fixes: 9b3b8171f7f4 ("dmaengine: sprd: Add Spreadtrum DMA driver")
Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Link: https://patch.msgid.link/20260813153149.3953497-1-ruoyuw560@gmail.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/dma/sprd-dma.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/dma/sprd-dma.c b/drivers/dma/sprd-dma.c
index 3f54ff37c5e05..f000d5a5add52 100644
--- a/drivers/dma/sprd-dma.c
+++ b/drivers/dma/sprd-dma.c
@@ -1212,7 +1212,7 @@ static int sprd_dma_probe(struct platform_device *pdev)
ret = pm_runtime_get_sync(&pdev->dev);
if (ret < 0)
- goto err_rpm;
+ goto err_register;
ret = dma_async_device_register(&sdev->dma_dev);
if (ret < 0) {
@@ -1234,7 +1234,6 @@ static int sprd_dma_probe(struct platform_device *pdev)
err_register:
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
-err_rpm:
sprd_dma_disable(sdev);
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 041/877] wifi: virt_wifi: free skb when disconnected
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (39 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 040/877] dmaengine: sprd: Fix runtime PM reference leak in probe Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 042/877] wifi: mwifiex: fix IRQ leak using wrong index in MSI-X error path Greg Kroah-Hartman
` (843 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mariano Baragiola, Johannes Berg,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mariano Baragiola <mbaragiola@linux.com>
[ Upstream commit f9edf7cf63b96d2b776fca8d258d3c5256e40c8e ]
When the simulated link is disconnected, virt_wifi_start_xmit() returns
NET_XMIT_DROP without freeing the skb. dev_hard_start_xmit() treats this
return value as consumed, so every packet sent while disconnected leaks its
skb.
Free the skb before returning the drop status.
Fixes: c7cdba31ed8b ("mac80211-next: rtnetlink wifi simulation device")
Signed-off-by: Mariano Baragiola <mbaragiola@linux.com>
Link: https://patch.msgid.link/20260809124947.3590270-1-mbaragiola@linux.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/virtual/virt_wifi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/virtual/virt_wifi.c b/drivers/net/wireless/virtual/virt_wifi.c
index 976edacb689de..056d375e3f41f 100644
--- a/drivers/net/wireless/virtual/virt_wifi.c
+++ b/drivers/net/wireless/virtual/virt_wifi.c
@@ -432,6 +432,7 @@ static netdev_tx_t virt_wifi_start_xmit(struct sk_buff *skb,
priv->tx_packets++;
if (!priv->is_connected) {
priv->tx_failed++;
+ dev_kfree_skb_any(skb);
return NET_XMIT_DROP;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 042/877] wifi: mwifiex: fix IRQ leak using wrong index in MSI-X error path
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (40 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 041/877] wifi: virt_wifi: free skb when disconnected Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 043/877] wifi: libipw: reject too-short beacon and probe responses Greg Kroah-Hartman
` (842 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Peng Hao, Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Hao <flyingpenghao@gmail.com>
[ Upstream commit a3d722190cdef18da4878b5efc27c3c386dda248 ]
mwifiex_pcie_request_irq() registers each MSI-X vector with a per-index
dev_id (&card->msix_ctx[i]). On a request_irq() failure the cleanup loop
"for (j = 0; j < i; j++)" frees msix_entries[j].vector but passes the
failed index's &card->msix_ctx[i] as the dev_id. free_irq() matches on
(irq, dev_id), so it fails to find the action registered with
&card->msix_ctx[j]: the already-requested IRQ j is not freed (leaked) and
free_irq() warns about freeing a non-existent IRQ. Use &card->msix_ctx[j].
Fixes: 99074fc1e67b ("mwifiex: enable pcie MSIx interrupt mode support")
Signed-off-by: Peng Hao <flyingpeng@tencent.com>
Link: https://patch.msgid.link/20260828111531.56723-1-flyingpeng@tencent.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/marvell/mwifiex/pcie.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index 5f997becdbaa2..d36d431f53679 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -3068,7 +3068,7 @@ static int mwifiex_pcie_request_irq(struct mwifiex_adapter *adapter)
ret);
for (j = 0; j < i; j++)
free_irq(card->msix_entries[j].vector,
- &card->msix_ctx[i]);
+ &card->msix_ctx[j]);
pci_disable_msix(pdev);
} else {
mwifiex_dbg(adapter, MSG, "MSIx enabled!");
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 043/877] wifi: libipw: reject too-short beacon and probe responses
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (41 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 042/877] wifi: mwifiex: fix IRQ leak using wrong index in MSI-X error path Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 044/877] wifi: libipw: reject too-short association responses Greg Kroah-Hartman
` (841 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shmulik Cohen, Johannes Berg,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shmulik Cohen <anuk909@gmail.com>
[ Upstream commit 5ce5721e8cbe3e80db8f43851cc2a2a92485ef4b ]
libipw_process_probe_response() and the libipw_network_init() call it
makes assume the frame contains the full 36-byte beacon and probe
response prefix, but the ipw2100 and ipw2200 receive paths only
establish that a management frame carries the generic 24-byte
three-address header.
libipw_network_init() then computes the information element length as
stats->len - sizeof(*beacon)
stats->len is a u16 and sizeof() has type size_t, so the subtraction is
evaluated as size_t and wraps instead of going negative. Truncating
that to the u16 length parameter of libipw_parse_info_param() yields
65524 for a 24-byte beacon, and the parser then walks the receive
buffer as if it held almost 64 KiB of information elements, reading
past the allocation.
Reject the frame before any fixed field is touched.
Found by an AI-assisted review of length arithmetic in management frame
parsers. Verified with a KUnit case under Generic KASAN on arm64 under
QEMU; I do not have the hardware, so it is not tested on a real device.
Fixes: b453872c35cf ("[NET] ieee80211 subsystem")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Shmulik Cohen <anuk909@gmail.com>
Link: https://patch.msgid.link/20260812190412.18333-2-anuk909@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/intel/ipw2x00/libipw_rx.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_rx.c b/drivers/net/wireless/intel/ipw2x00/libipw_rx.c
index 2220a9814c8a6..33f5dbe274c74 100644
--- a/drivers/net/wireless/intel/ipw2x00/libipw_rx.c
+++ b/drivers/net/wireless/intel/ipw2x00/libipw_rx.c
@@ -1514,6 +1514,9 @@ static void libipw_process_probe_response(struct libipw_device
#endif
unsigned long flags;
+ if (stats->len < sizeof(*beacon))
+ return;
+
LIBIPW_DEBUG_SCAN("'%*pE' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
info_element->len, info_element->data,
beacon->header.addr3,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 044/877] wifi: libipw: reject too-short association responses
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (42 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 043/877] wifi: libipw: reject too-short beacon and probe responses Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 045/877] IB/IPoIB: Avoid restoring OPER_UP after multicast flush Greg Kroah-Hartman
` (840 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shmulik Cohen, Johannes Berg,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shmulik Cohen <anuk909@gmail.com>
[ Upstream commit adb7118b7d2cfd7e8213c17d7d2829f353017754 ]
libipw_handle_assoc_resp() reads the capability, status and aid fields
of the 30-byte association response prefix and then computes the
information element length as
stats->len - sizeof(*frame)
stats->len is a u16 and sizeof() has type size_t, so the subtraction is
evaluated as size_t and wraps instead of going negative. Truncating
that to the u16 length parameter of libipw_parse_info_param() turns a
frame shorter than the fixed fields into a length near 64 KiB, and the
parser then reads past the receive buffer.
Both the ipw2100 and ipw2200 management receive paths reach this
function having established only that the frame carries the generic
24-byte three-address header.
Reject the frame before any fixed field is touched.
Found by an AI-assisted review of length arithmetic in management frame
parsers. Verified with a KUnit case under Generic KASAN on arm64 under
QEMU; I do not have the hardware, so it is not tested on a real device.
Fixes: 9e8571affd1c ("[PATCH] ieee80211: Add QoS (WME) support to the ieee80211 subsystem")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Shmulik Cohen <anuk909@gmail.com>
Link: https://patch.msgid.link/20260812190412.18333-3-anuk909@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/intel/ipw2x00/libipw_rx.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_rx.c b/drivers/net/wireless/intel/ipw2x00/libipw_rx.c
index 33f5dbe274c74..762ed2704bf65 100644
--- a/drivers/net/wireless/intel/ipw2x00/libipw_rx.c
+++ b/drivers/net/wireless/intel/ipw2x00/libipw_rx.c
@@ -1302,6 +1302,9 @@ static int libipw_handle_assoc_resp(struct libipw_device *ieee, struct libipw_as
struct libipw_network *network = &network_resp;
struct net_device *dev = ieee->dev;
+ if (stats->len < sizeof(*frame))
+ return 1;
+
network->flags = 0;
network->qos_data.active = 0;
network->qos_data.supported = 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 045/877] IB/IPoIB: Avoid restoring OPER_UP after multicast flush
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (43 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 044/877] wifi: libipw: reject too-short association responses Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 046/877] wifi: cfg80211: dont get the radio mask for netdev-less wdevs Greg Kroah-Hartman
` (839 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ben Davies, Carolina Jubran,
Cosmin Ratiu, Edward Srouji, Leon Romanovsky, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Carolina Jubran <cjubran@nvidia.com>
[ Upstream commit 9a141d3dc869d18b2eab35e999f4790a9b84e40f ]
ipoib_ib_dev_flush_light() temporarily clears IPOIB_FLAG_OPER_UP to
prevent multicast joins while ipoib_mcast_dev_flush() is running, and
restores the flag afterwards if it was previously set.
This restore races with ipoib_ib_dev_down(). If the interface is brought
down while the flush is in progress, ipoib_ib_dev_down() clears
IPOIB_FLAG_OPER_UP, but the flush path may set it again after the device
has already gone down.
Since commit 894021a75291 ("IB/ipoib: Make the carrier_on_task race
aware"), ipoib_mcast_carrier_on_task() relies on IPOIB_FLAG_OPER_UP
being cleared to terminate its rtnl_trylock() retry loop. If the flag is
left set after shutdown, the workqueue retries forever, causing teardown
to deadlock when ipoib_ndo_uninit() waits in destroy_workqueue() while
holding RTNL.
Instead of overloading IPOIB_FLAG_OPER_UP to block multicast joins
during a light flush, introduce a dedicated IPOIB_FLAG_MCAST_FLUSH flag.
Use it together with IPOIB_FLAG_OPER_UP to determine whether multicast
joins are allowed, avoiding the race with device shutdown.
Fixes: 344bacca8cd8 ("IB/ipoib: Don't allow MC joins during light MC flush")
Reported-by: Ben Davies <ben.davies@gresearch.co.uk>
Signed-off-by: Carolina Jubran <cjubran@nvidia.com>
Reviewed-by: Cosmin Ratiu <cratiu@nvidia.com>
Signed-off-by: Edward Srouji <edwards@nvidia.com>
Link: https://patch.msgid.link/20260902-avoid-rest-oper-up-v1-1-04fcd4916cae@nvidia.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/ulp/ipoib/ipoib.h | 7 +++++++
drivers/infiniband/ulp/ipoib/ipoib_ib.c | 12 +++++++-----
drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 16 ++++++++--------
3 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index abe0522b7df46..ee23b8d37b977 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -87,6 +87,7 @@ enum {
IPOIB_FLAG_INITIALIZED = 1,
IPOIB_FLAG_ADMIN_UP = 2,
IPOIB_PKEY_ASSIGNED = 3,
+ IPOIB_FLAG_MCAST_FLUSH = 4,
IPOIB_FLAG_SUBINTERFACE = 5,
IPOIB_STOP_REAPER = 7,
IPOIB_FLAG_ADMIN_CM = 9,
@@ -419,6 +420,12 @@ struct ipoib_dev_priv {
const struct net_device_ops *rn_ops;
};
+static inline bool ipoib_mcast_allowed(struct ipoib_dev_priv *priv)
+{
+ return test_bit(IPOIB_FLAG_OPER_UP, &priv->flags) &&
+ !test_bit(IPOIB_FLAG_MCAST_FLUSH, &priv->flags);
+}
+
struct ipoib_ah {
struct net_device *dev;
struct ib_ah *ah;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 5cde275daa941..76850a7d300bb 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -1235,17 +1235,19 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv,
}
if (level == IPOIB_FLUSH_LIGHT) {
- int oper_up;
ipoib_mark_paths_invalid(dev);
- /* Set IPoIB operation as down to prevent races between:
+ /* Set MCAST_FLUSH to prevent races between:
* the flush flow which leaves MCG and on the fly joins
* which can happen during that time. mcast restart task
* should deal with join requests we missed.
+ *
+ * Do not clear OPER_UP for this; restoring it races with
+ * ipoib_ib_dev_down() and can leave OPER_UP set after the
+ * device is down.
*/
- oper_up = test_and_clear_bit(IPOIB_FLAG_OPER_UP, &priv->flags);
+ set_bit(IPOIB_FLAG_MCAST_FLUSH, &priv->flags);
ipoib_mcast_dev_flush(dev);
- if (oper_up)
- set_bit(IPOIB_FLAG_OPER_UP, &priv->flags);
+ clear_bit(IPOIB_FLAG_MCAST_FLUSH, &priv->flags);
ipoib_reap_dead_ahs(priv);
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 8a4ab9ff0a681..4f7639bbc7dc5 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -74,7 +74,7 @@ static void __ipoib_mcast_schedule_join_thread(struct ipoib_dev_priv *priv,
struct ipoib_mcast *mcast,
bool delay)
{
- if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags))
+ if (!ipoib_mcast_allowed(priv))
return;
/*
@@ -469,7 +469,7 @@ static int ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast)
int ret = 0;
if (!priv->broadcast ||
- !test_bit(IPOIB_FLAG_OPER_UP, &priv->flags))
+ !ipoib_mcast_allowed(priv))
return -EINVAL;
init_completion(&mcast->done);
@@ -555,7 +555,7 @@ void ipoib_mcast_join_task(struct work_struct *work)
unsigned long delay_until = 0;
struct ipoib_mcast *mcast = NULL;
- if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags))
+ if (!ipoib_mcast_allowed(priv))
return;
if (ib_query_port(priv->ca, priv->port, &port_attr)) {
@@ -577,7 +577,7 @@ void ipoib_mcast_join_task(struct work_struct *work)
netif_addr_unlock_bh(dev);
spin_lock_irq(&priv->lock);
- if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags))
+ if (!ipoib_mcast_allowed(priv))
goto out;
if (!priv->broadcast) {
@@ -749,7 +749,7 @@ void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb)
spin_lock_irqsave(&priv->lock, flags);
- if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags) ||
+ if (!ipoib_mcast_allowed(priv) ||
!priv->broadcast ||
!test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) {
++dev->stats.tx_dropped;
@@ -871,7 +871,7 @@ void ipoib_mcast_restart_task(struct work_struct *work)
LIST_HEAD(remove_list);
struct ib_sa_mcmember_rec rec;
- if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags))
+ if (!ipoib_mcast_allowed(priv))
/*
* shortcut...on shutdown flush is called next, just
* let it do all the work
@@ -965,9 +965,9 @@ void ipoib_mcast_restart_task(struct work_struct *work)
ipoib_mcast_remove_list(&remove_list);
/*
- * Double check that we are still up
+ * Double check that we are still up and not flushing
*/
- if (test_bit(IPOIB_FLAG_OPER_UP, &priv->flags)) {
+ if (ipoib_mcast_allowed(priv)) {
spin_lock_irq(&priv->lock);
__ipoib_mcast_schedule_join_thread(priv, NULL, 0);
spin_unlock_irq(&priv->lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 046/877] wifi: cfg80211: dont get the radio mask for netdev-less wdevs
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (44 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 045/877] IB/IPoIB: Avoid restoring OPER_UP after multicast flush Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 047/877] wifi: cfg80211: check IP header size in cfg80211_classify8021d() Greg Kroah-Hartman
` (838 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+abff43d2d045e37c0bb2,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit a7783e585360ee05dfe21d3173dbbe985c94f29e ]
cfg80211_calculate_bi_data() calls rdev_get_radio_mask() with
wdev->netdev, which can be NULL and then crashes in mac80211.
To avoid that, invert the order of checks since wdev->netdev
is always valid for beaconing interfaces.
Assisted-by: LLM
Fixes: abb4cfe3661a ("wifi: cfg80211: extend interface combination check for multi-radio")
Reported-by: syzbot+abff43d2d045e37c0bb2@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=abff43d2d045e37c0bb2
Link: https://patch.msgid.link/20260904165614.2056a8b7dc91.I7412c5062d8166ad6c81ee7252cec49dea19a60f@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/wireless/util.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 8478f3a0e9402..f565fb5ddd44a 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -2355,16 +2355,15 @@ static void cfg80211_calculate_bi_data(struct wiphy *wiphy, u32 new_beacon_int,
if (wdev->valid_links)
continue;
+ wdev_bi = cfg80211_wdev_bi(wdev);
+ if (!wdev_bi)
+ continue;
+
/* skip wdevs not active on the given wiphy radio */
if (radio_idx >= 0 &&
!(rdev_get_radio_mask(rdev, wdev->netdev) & BIT(radio_idx)))
continue;
- wdev_bi = cfg80211_wdev_bi(wdev);
-
- if (!wdev_bi)
- continue;
-
if (!*beacon_int_gcd) {
*beacon_int_gcd = wdev_bi;
continue;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 047/877] wifi: cfg80211: check IP header size in cfg80211_classify8021d()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (45 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 046/877] wifi: cfg80211: dont get the radio mask for netdev-less wdevs Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 048/877] soundwire: cadence_master: wait and cancel cdns->work before clock stop Greg Kroah-Hartman
` (837 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+878ddc3962f792e9af59,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit 48b2c5c628b09cf36cbeca53e0432fc2a7518be7 ]
A frame that looks like IP can be transmitted, but be too short, so
the DS field is read incorrectly:
BUG: KMSAN: uninit-value in cfg80211_classify8021d+0x99d/0x12b0 net/wireless/util.c:1027
cfg80211_classify8021d+0x99d/0x12b0 net/wireless/util.c:1027
ieee80211_select_queue+0x37a/0x9e0 net/mac80211/wme.c:180
__ieee80211_subif_start_xmit+0x60f/0x1d90 net/mac80211/tx.c:4304
ieee80211_subif_start_xmit+0xa8/0x6d0 net/mac80211/tx.c:4538
...
packet_sendmsg+0x9173/0xa2a0 net/packet/af_packet.c:3108
Use skb_header_pointer() like the MPLS case.
Assisted-by: LLM
Fixes: e31a16d6f64e ("wireless: move some utility functions from mac80211 to cfg80211")
Reported-by: syzbot+878ddc3962f792e9af59@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=878ddc3962f792e9af59
Link: https://patch.msgid.link/20260904165614.5e61a4c80b92.I37d68d3f406cb3b90b32e6943418d66070b65197@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/wireless/util.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/net/wireless/util.c b/net/wireless/util.c
index f565fb5ddd44a..f9e0ec311982e 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -989,12 +989,30 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb,
}
switch (skb->protocol) {
- case htons(ETH_P_IP):
- dscp = ipv4_get_dsfield(ip_hdr(skb)) & 0xfc;
+ case htons(ETH_P_IP): {
+ const struct iphdr *iph;
+ struct iphdr _iph;
+
+ iph = skb_header_pointer(skb, sizeof(struct ethhdr),
+ sizeof(*iph), &_iph);
+ if (!iph)
+ return 0;
+
+ dscp = ipv4_get_dsfield(iph) & 0xfc;
break;
- case htons(ETH_P_IPV6):
- dscp = ipv6_get_dsfield(ipv6_hdr(skb)) & 0xfc;
+ }
+ case htons(ETH_P_IPV6): {
+ const struct ipv6hdr *ip6h;
+ struct ipv6hdr _ip6h;
+
+ ip6h = skb_header_pointer(skb, sizeof(struct ethhdr),
+ sizeof(*ip6h), &_ip6h);
+ if (!ip6h)
+ return 0;
+
+ dscp = ipv6_get_dsfield(ip6h) & 0xfc;
break;
+ }
case htons(ETH_P_MPLS_UC):
case htons(ETH_P_MPLS_MC): {
struct mpls_label mpls_tmp, *mpls;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 048/877] soundwire: cadence_master: wait and cancel cdns->work before clock stop
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (46 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 047/877] wifi: cfg80211: check IP header size in cfg80211_classify8021d() Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 049/877] MIPS: Octeon: apply USB FDT fixups also when USB is modular Greg Kroah-Hartman
` (836 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bard Liao, David Lin, Shuming Fan,
Pierre-Louis Bossart, Vinod Koul, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bard Liao <yung-chuan.liao@linux.intel.com>
[ Upstream commit aba7b41faeecb7692458095ce6fafc341fe0b80e ]
A peripheral event could happen during the clock stop process. We need
to wait for the event be handled before stopping the bus clock.
Otherwise, we will get the IO transfer timed out issue.
Fixes: af4cc917826f ("soundwire: cadence: mask Slave interrupt before stopping clock")
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: David Lin <david.lin@intel.com>
Reviewed-by: Shuming Fan <shumingf@realtek.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
Link: https://patch.msgid.link/20260901031019.233254-1-yung-chuan.liao@linux.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/soundwire/cadence_master.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index a503ef606a62c..1557d6b044491 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -1670,6 +1670,13 @@ int sdw_cdns_clock_stop(struct sdw_cdns *cdns, bool block_wake)
return 0;
}
+ /*
+ * wait for any in-flight peripheral event handling to complete before stopping the clock.
+ * No need to disable peripheral interrupts before canceling the work, as the peripheral
+ * interrupts are already masked before the work is scheduled.
+ */
+ cancel_work_sync(&cdns->work);
+
/*
* Before entering clock stop we mask the Slave
* interrupts. This helps avoid having to deal with e.g. a
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 049/877] MIPS: Octeon: apply USB FDT fixups also when USB is modular
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (47 preceding siblings ...)
2026-09-30 15:15 ` [PATCH 6.12 048/877] soundwire: cadence_master: wait and cancel cdns->work before clock stop Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 050/877] dma-coherent: Warn if OF reserved memory is beyond current coherent DMA mask Greg Kroah-Hartman
` (835 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Orgad Shaneh, Thomas Bogendoerfer,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Orgad Shaneh <orgads@gmail.com>
[ Upstream commit 126f16e0a1b353c2ba5c7e2c8626cfa865934f9f ]
The uctl/usbn device-tree fixups in octeon_prune_device_tree() - which
set the board's USB reference-clock frequency and type from
__cvmx_helper_board_usb_get_clock_type() - are guarded by
"#ifdef CONFIG_USB", which is false when USB is built as a module. The
fixups then silently disappear and octeon-hcd sees whatever default the
DTS carries (12MHz crystal in octeon_3xxx.dts), leaving the PHY dead or
the bus erroring on boards with a different reference clock.
Use IS_ENABLED() so USB=m gets the same fixups as USB=y.
Fixes: 7fd57ab9d9cf ("MIPS: Octeon: Fix compile error when USB is not enabled.")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Orgad Shaneh <orgads@gmail.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/mips/cavium-octeon/octeon-platform.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
index 5e1dd4e6e82fb..4b5c99e6f5bcc 100644
--- a/arch/mips/cavium-octeon/octeon-platform.c
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -17,7 +17,7 @@
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-helper-board.h>
-#ifdef CONFIG_USB
+#if IS_ENABLED(CONFIG_USB)
#include <linux/usb/ehci_def.h>
#include <linux/usb/ehci_pdriver.h>
#include <linux/usb/ohci_pdriver.h>
@@ -1080,7 +1080,7 @@ int __init octeon_prune_device_tree(void)
;
}
-#ifdef CONFIG_USB
+#if IS_ENABLED(CONFIG_USB)
/* OHCI/UHCI USB */
alias_prop = fdt_getprop(initial_boot_params, aliases,
"uctl", NULL);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 050/877] dma-coherent: Warn if OF reserved memory is beyond current coherent DMA mask
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (48 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 049/877] MIPS: Octeon: apply USB FDT fixups also when USB is modular Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 051/877] dma-coherent: report a failed reserved memory assignment Greg Kroah-Hartman
` (834 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chen-Yu Tsai, Marek Szyprowski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen-Yu Tsai <wenst@chromium.org>
[ Upstream commit 89461db349cc00816c01d55507d511466b3b7151 ]
When a reserved memory region described in the device tree is attached
to a device, it is expected that the device's limitations are correctly
included in that description.
However, if the device driver failed to implement DMA address masking
or addressing beyond the default 32 bits (on arm64), then bad things
could happen because the DMA address was truncated, such as playing
back audio with no actual audio coming out, or DMA overwriting random
blocks of kernel memory.
Check against the coherent DMA mask when the memory regions are attached
to the device. Give a warning when the memory region can not be covered
by the mask.
A warning instead of a hard error was chosen, because it is possible
that existing drivers could be working fine even if they forgot to
extend the coherent DMA mask.
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Link: https://lore.kernel.org/r/20250421083930.374173-1-wenst@chromium.org
Stable-dep-of: 504981db4f69 ("dma-coherent: report a failed reserved memory assignment")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/dma/coherent.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/kernel/dma/coherent.c b/kernel/dma/coherent.c
index 3b2bdca9f1d4b..77c8d9487a9ab 100644
--- a/kernel/dma/coherent.c
+++ b/kernel/dma/coherent.c
@@ -336,16 +336,22 @@ static phys_addr_t dma_reserved_default_memory_size __initdata;
static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev)
{
- if (!rmem->priv) {
- struct dma_coherent_mem *mem;
+ struct dma_coherent_mem *mem = rmem->priv;
+ if (!mem) {
mem = dma_init_coherent_memory(rmem->base, rmem->base,
rmem->size, true);
if (IS_ERR(mem))
return PTR_ERR(mem);
rmem->priv = mem;
}
- dma_assign_coherent_memory(dev, rmem->priv);
+
+ /* Warn if the device potentially can't use the reserved memory */
+ if (mem->device_base + rmem->size - 1 >
+ min_not_zero(dev->coherent_dma_mask, dev->bus_dma_limit))
+ dev_warn(dev, "reserved memory is beyond device's set DMA address range\n");
+
+ dma_assign_coherent_memory(dev, mem);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 051/877] dma-coherent: report a failed reserved memory assignment
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (49 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 050/877] dma-coherent: Warn if OF reserved memory is beyond current coherent DMA mask Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 052/877] dmaengine: Fix device kref underflow in dma_chan_put() Greg Kroah-Hartman
` (833 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Donggeun Yoo, Marek Szyprowski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
[ Upstream commit 504981db4f69bdd28054fb98c96a3a67f7248dde ]
rmem_dma_device_init() drops the return value of
dma_assign_coherent_memory() and always reports success. That call fails
with -EBUSY when the device already has a coherent pool, and the file
allows only "*one* such region of memory" per device.
of_reserved_mem_device_init_by_idx() reads the zero as success. It logs
"assigned reserved memory node" for a region that was not assigned and
records the pairing, so of_reserved_mem_device_release() later runs
rmem_dma_device_release() for it. That clears dev->dma_mem without
looking at which region it was called for, dropping the pool the device
did get and leaving it on ordinary memory.
dma_declare_coherent_memory() checks the same call and releases the
memory on failure, and rmem_swiotlb_device_init() propagates its own
errors. Return the error here as well, so a device tree that assigns two
pools to one device fails the probe instead of half working.
Fixes: 7bfa5ab6fa1b ("drivers: dma-coherent: add initialization from device tree")
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Link: https://lore.kernel.org/r/20260905074727.108029-1-donggeunyoo.kernel@gmail.com
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/dma/coherent.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/kernel/dma/coherent.c b/kernel/dma/coherent.c
index 77c8d9487a9ab..87f2f02e921a6 100644
--- a/kernel/dma/coherent.c
+++ b/kernel/dma/coherent.c
@@ -351,8 +351,7 @@ static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev)
min_not_zero(dev->coherent_dma_mask, dev->bus_dma_limit))
dev_warn(dev, "reserved memory is beyond device's set DMA address range\n");
- dma_assign_coherent_memory(dev, mem);
- return 0;
+ return dma_assign_coherent_memory(dev, mem);
}
static void rmem_dma_device_release(struct reserved_mem *rmem,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 052/877] dmaengine: Fix device kref underflow in dma_chan_put()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (50 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 051/877] dma-coherent: report a failed reserved memory assignment Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 053/877] dmaengine: fix use-after-free in dma_chan_put() and dma_release_channel() Greg Kroah-Hartman
` (832 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Frank Li, Logan Gunthorpe,
Shivank Garg, Vinod Koul, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shivank Garg <shivankg@amd.com>
[ Upstream commit 44dab659064eb5c10adb0306510eebe848ed592d ]
dma_chan_get() takes chan->device->ref only on the slow path:
/* no kref on fast path */
if (chan->client_count) {
__module_get(owner);
chan->client_count++;
return 0;
}
if (!try_module_get(owner))
return -ENODEV;
if (!dma_device_get(chan->device)) { // calls kref_get_unless_zero()
dma_chan_put() drops the ref unconditionally, so every fast-path
get/put pair drops one extra device reference.
The bug fires when two conditions hold together: a non-private
provider has a persistent client holding chan->client_count > 0
and another client cycles dmaengine_get()/dmaengine_put().
When the kref hits zero, the subsequent dma_find_channel() returns
NULL even though the provider module is still loaded.
Fix this by dropping device->ref only on the last put, matching the
single slow-path get.
Fixes: 8ad342a86359 ("dmaengine: Add reference counting to dma_device struct")
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Shivank Garg <shivankg@amd.com>
Link: https://patch.msgid.link/20260822-dmaengine-kref-fix-v5-2-d4a4ee47d927@amd.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/dma/dmaengine.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index e241b7b01233e..ea3ed830061dc 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -513,7 +513,9 @@ static void dma_chan_put(struct dma_chan *chan)
chan->route_data = NULL;
}
- dma_device_put(chan->device);
+ /* This channel is not in use anymore, drop the device ref */
+ if (!chan->client_count)
+ dma_device_put(chan->device);
module_put(dma_chan_to_owner(chan));
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 053/877] dmaengine: fix use-after-free in dma_chan_put() and dma_release_channel()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (51 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 052/877] dmaengine: Fix device kref underflow in dma_chan_put() Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 054/877] dmaengine: wait for RCU readers before releasing dma_device Greg Kroah-Hartman
` (831 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Frank Li, Logan Gunthorpe,
Shivank Garg, Vinod Koul, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shivank Garg <shivankg@amd.com>
[ Upstream commit e873c74132f0c5f1452816cd9bb26208f0bba1e1 ]
When dma_device_put() drops the last reference on chan->device->ref,
dma_device_release() runs and may free the dma_device along with its
channels.
dma_chan_put() then still reads chan->device->owner via
dma_chan_to_owner() for the trailing module_put(). KASAN catches it:
slab-use-after-free in dma_chan_put+0x3e6/0x4c0
Read of size 8 by task insmod/6319
Freed by task 6319:
kfree+0x225/0x470
dma_chan_put+0x395/0x4c0
dmaengine_put+0xf8/0x160
Cache the module owner in dma_chan_put() before the put so the trailing
module_put() does not need chan->device.
Fixes: 8ad342a86359 ("dmaengine: Add reference counting to dma_device struct")
Suggested-by: Sashiko <sashiko-bot@kernel.org>
Link: https://sashiko.dev/#/patchset/20260518-dmaengine-kref-fix-v1-1-4d6125048fb7@amd.com
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Shivank Garg <shivankg@amd.com>
Link: https://patch.msgid.link/20260822-dmaengine-kref-fix-v5-3-d4a4ee47d927@amd.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/dma/dmaengine.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index ea3ed830061dc..d6a4e914018da 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -493,10 +493,13 @@ static int dma_chan_get(struct dma_chan *chan)
*/
static void dma_chan_put(struct dma_chan *chan)
{
+ struct module *owner;
+
/* This channel is not in use, bail out */
if (!chan->client_count)
return;
+ owner = dma_chan_to_owner(chan);
chan->client_count--;
/* This channel is not in use anymore, free it */
@@ -516,7 +519,7 @@ static void dma_chan_put(struct dma_chan *chan)
/* This channel is not in use anymore, drop the device ref */
if (!chan->client_count)
dma_device_put(chan->device);
- module_put(dma_chan_to_owner(chan));
+ module_put(owner);
}
enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 054/877] dmaengine: wait for RCU readers before releasing dma_device
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (52 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 053/877] dmaengine: fix use-after-free in dma_chan_put() and dma_release_channel() Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 055/877] wifi: cfg80211: only group hidden BSSes with beacon entries Greg Kroah-Hartman
` (830 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Frank Li, Logan Gunthorpe,
Shivank Garg, Vinod Koul, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shivank Garg <shivankg@amd.com>
[ Upstream commit dc750422170a563c7a81f6e49d36bb02c62ae37f ]
dma_issue_pending_all() walks the dma_device_list with
list_for_each_entry_rcu() under rcu_read_lock(). dma_device_release()
unlinks the device with list_del_rcu() and then calls
device->device_release() (which in many drivers, such as plx_dma.c,
directly calls kfree()).
Because there is no grace period between unlinking the device and
freeing it, concurrent RCU readers in dma_issue_pending_all() can
access the device after it has been freed.
The lockless walk originally relied on clients holding a dmaengine
reference to pin the provider module, and therefore the device, for as
long as they might traverse the list. Commit 8ad342a86359 ("dmaengine:
Add reference counting to dma_device struct") decoupled the dma_device
lifetime from the module reference, so the device can now be released
while a reader is still walking the list.
Add synchronize_rcu() before the device is freed, so RCU readers are
guaranteed to have finished. Keep it unconditional: providers that do
not implement device_release() free the device themselves once
dma_async_device_unregister() returns. This call will delay for a grace
period with dma_list_mutex held, which is safe and only teardown path is
delayed.
Fixes: 2ba05622b8b1 ("dmaengine: provide a common 'issue_pending_all' implementation")
Suggested-by: Sashiko <sashiko-bot@kernel.org>
Link: https://sashiko.dev/#/patchset/20260526-dmaengine-kref-fix-v2-0-3df60afac01d@amd.com
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Shivank Garg <shivankg@amd.com>
Link: https://patch.msgid.link/20260822-dmaengine-kref-fix-v5-4-d4a4ee47d927@amd.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/dma/dmaengine.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index d6a4e914018da..9a591bc15a36b 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -426,6 +426,7 @@ static void dma_device_release(struct kref *ref)
list_del_rcu(&device->global_node);
dma_channel_rebalance();
+ synchronize_rcu();
if (device->device_release)
device->device_release(device);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 055/877] wifi: cfg80211: only group hidden BSSes with beacon entries
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (53 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 054/877] dmaengine: wait for RCU readers before releasing dma_device Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 056/877] wifi: cfg80211: dont filter by BSS type when removing stale entries Greg Kroah-Hartman
` (829 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+1a797e1c81be78a2ace7,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit 068843ed0902c552a13860c5ec6b2ca65b57a065 ]
When a probe response for an unknown BSS comes in, __cfg80211_bss_update()
looks for an existing entry with the same BSSID and a hidden (zero-length
or NUL-filled) SSID, and if it finds one it groups them, using the beacon
IEs from the existing entry.
But that could find another entry without a beacon, if it was also from a
probe response (with SSID), so there's a group without beacon elements.
If a beacon with a hidden SSID for that BSSID arrives later,
cfg80211_combine_bsses() goes looking for the probe response entries that
belong to it - i.e. entries with the same BSSID and channel that have no
beacon IEs - and finds those two. They are already grouped with each
other, so it hits its
WARN_ON_ONCE(bss->pub.hidden_beacon_bss)
WARN_ON_ONCE(!list_empty(&bss->hidden_list))
which are there because an entry without beacon elements is not supposed
to be part of a group yet.
Only combine entries when a beacon was already received, ones that are
kept separate will be combined when a beacon arrives.
Assisted-by: LLM
Fixes: 4593c4cbe1c9 ("cfg80211: fix BSS list hidden SSID lookup")
Reported-by: syzbot+1a797e1c81be78a2ace7@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=1a797e1c81be78a2ace7
Link: https://patch.msgid.link/20260904165614.bcfa64715745.Iad740347c86de56d4ff4f96a95f3c3afc47c42de@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/wireless/scan.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 3c439841578c4..f3b9e7a519ff9 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -1960,6 +1960,13 @@ __cfg80211_bss_update(struct cfg80211_registered_device *rdev,
if (!hidden)
hidden = rb_find_bss(rdev, tmp,
BSS_CMP_HIDE_NUL);
+ /*
+ * Only group with an entry with beacon data, otherwise
+ * beacon data can never be filled/updated.
+ */
+ if (hidden &&
+ !rcu_access_pointer(hidden->pub.beacon_ies))
+ hidden = NULL;
if (hidden) {
new->pub.hidden_beacon_bss = &hidden->pub;
list_add(&new->hidden_list,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 056/877] wifi: cfg80211: dont filter by BSS type when removing stale entries
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (54 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 055/877] wifi: cfg80211: only group hidden BSSes with beacon entries Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 057/877] wifi: mac80211: dont start a ROC while scanning Greg Kroah-Hartman
` (828 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+dc6f4dce0d707900cdea,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit b377e1000d963e7182a987082b4b06580bd7ac84 ]
When an assoc AP switches to a channel that already has a BSS entry,
cfg80211_update_assoc_bss_entry() removes that entry before rehashing
the real one, since the two would otherwise collide in the BSS rbtree.
The lookup for that entry also required it to match the connection's BSS
type, so an entry advertising e.g. the IBSS capability bit was left in
place, and the following cfg80211_rehash_bss() then ran into it:
WARN_ON(!cmp)
Changing the type shouldn't really happen, but can be triggered by a
rogue AP/device, so drop the check and remove any entries matching
the comparison.
Assisted-by: LLM
Fixes: 0afd425b1b64 ("cfg80211: fix duplicated scan entries after channel switch")
Reported-by: syzbot+dc6f4dce0d707900cdea@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=dc6f4dce0d707900cdea
Link: https://patch.msgid.link/20260904165614.1f05dae1c546.Ib52d57b57caa912efee020f9d4a033a5160617ce@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/wireless/scan.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index f3b9e7a519ff9..9d21667641a50 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -3398,11 +3398,6 @@ void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev,
cbss->pub.channel = chan;
list_for_each_entry(bss, &rdev->bss_list, list) {
- if (!cfg80211_bss_type_match(bss->pub.capability,
- bss->pub.channel->band,
- wdev->conn_bss_type))
- continue;
-
if (bss == cbss)
continue;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 057/877] wifi: mac80211: dont start a ROC while scanning
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (55 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 056/877] wifi: cfg80211: dont filter by BSS type when removing stale entries Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 058/877] wifi: cfg80211: add option for vif allowed radios Greg Kroah-Hartman
` (827 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+c3a167b5615df4ccd7fb,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit 733f0fde95392ed5f61a4e36aee661ea8d0e8581 ]
The ROC work can be pending when a scan starts (which requires
ROC list to be empty, but that's possible), and then a new ROC
can be added to the list and the work will pick it up.
Avoid starting that ROC if a scan made it between things, as
otherwise we'll hit a warning later:
WARNING: net/mac80211/offchannel.c:404 at ieee80211_start_next_roc+0x256/0x2d0
Workqueue: events_unbound cfg80211_wiphy_work
Call Trace:
__ieee80211_scan_completed+0x4fd/0xe40 net/mac80211/scan.c:537
ieee80211_scan_work+0x472/0x1ff0 net/mac80211/scan.c:1193
cfg80211_wiphy_work+0x410/0x570 net/wireless/core.c:513
Assisted-by: LLM
Fixes: aaa016ccd5df ("mac80211: rewrite remain-on-channel logic")
Reported-by: syzbot+c3a167b5615df4ccd7fb@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=c3a167b5615df4ccd7fb
Link: https://patch.msgid.link/20260904165722.f9d5b150edd8.I61bc9de8c8d089096ad695213b9c85c7df38c3bd@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/offchannel.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 29fab7ae47b4c..0d9807526ecbd 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -462,6 +462,13 @@ static void __ieee80211_roc_work(struct ieee80211_local *local)
return;
if (!roc->started) {
+ /*
+ * The work can be started by a previous ROC work, but a scan
+ * can get between things; scan finish will retrigger us.
+ */
+ if (local->scanning)
+ return;
+
WARN_ON(!local->emulate_chanctx);
_ieee80211_start_next_roc(local);
} else {
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 058/877] wifi: cfg80211: add option for vif allowed radios
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (56 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 057/877] wifi: mac80211: dont start a ROC while scanning Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 059/877] wifi: mac80211: use vif radio mask to limit ibss scan frequencies Greg Kroah-Hartman
` (826 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Felix Fietkau, Johannes Berg,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit 3607798ad9bdef35ad08489a8239390fccaac6b5 ]
This allows users to prevent a vif from affecting radios other than the
configured ones. This can be useful in cases where e.g. an AP is running
on one radio, and triggering a scan on another radio should not disturb it.
Changing the allowed radios list for a vif is supported, but only while
it is down.
While it is possible to achieve the same by always explicitly specifying
a frequency list for scan requests and ensuring that the wrong channel/band
is never accidentally set on an unrelated interface, this change makes
multi-radio wiphy setups a lot easier to deal with for CLI users.
By itself, this patch only enforces the radio mask for scanning requests
and remain-on-channel. Follow-up changes build on this to limit configured
frequencies.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/eefcb218780f71a1549875d149f1196486762756.1728462320.git-series.nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Stable-dep-of: a7491b7efbd9 ("wifi: mac80211: don't warn when an IBSS has no channel to scan")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/cfg80211.h | 14 +++++++++
include/uapi/linux/nl80211.h | 5 +++
net/wireless/core.c | 2 ++
net/wireless/nl80211.c | 60 +++++++++++++++++++++++++++++++-----
net/wireless/scan.c | 10 ++++--
net/wireless/util.c | 29 +++++++++++++++++
6 files changed, 109 insertions(+), 11 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index fcc5934a20c0f..f3915118c15d7 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -6353,6 +6353,7 @@ enum ieee80211_ap_reg_power {
* entered.
* @links.cac_time_ms: CAC time in ms
* @valid_links: bitmap describing what elements of @links are valid
+ * @radio_mask: Bitmask of radios that this interface is allowed to operate on.
*/
struct wireless_dev {
struct wiphy *wiphy;
@@ -6465,6 +6466,8 @@ struct wireless_dev {
unsigned int cac_time_ms;
} links[IEEE80211_MLD_MAX_NUM_LINKS];
u16 valid_links;
+
+ u32 radio_mask;
};
static inline const u8 *wdev_address(struct wireless_dev *wdev)
@@ -6650,6 +6653,17 @@ static inline bool cfg80211_channel_is_psc(struct ieee80211_channel *chan)
bool cfg80211_radio_chandef_valid(const struct wiphy_radio *radio,
const struct cfg80211_chan_def *chandef);
+/**
+ * cfg80211_wdev_channel_allowed - Check if the wdev may use the channel
+ *
+ * @wdev: the wireless device
+ * @chan: channel to check
+ *
+ * Return: whether or not the wdev may use the channel
+ */
+bool cfg80211_wdev_channel_allowed(struct wireless_dev *wdev,
+ struct ieee80211_channel *chan);
+
/**
* ieee80211_get_response_rate - get basic rate for a given rate
*
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index c2d7faf8d87fa..8ce0c143e9fde 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2868,6 +2868,9 @@ enum nl80211_commands {
* nested item, it contains attributes defined in
* &enum nl80211_if_combination_attrs.
*
+ * @NL80211_ATTR_VIF_RADIO_MASK: Bitmask of allowed radios (u32).
+ * A value of 0 means all radios.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3416,6 +3419,8 @@ enum nl80211_attrs {
NL80211_ATTR_WIPHY_RADIOS,
NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS,
+ NL80211_ATTR_VIF_RADIO_MASK,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 8f7f84c5f440b..7c278b8694393 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -1456,6 +1456,8 @@ void cfg80211_init_wdev(struct wireless_dev *wdev)
/* allow mac80211 to determine the timeout */
wdev->ps_timeout = -1;
+ wdev->radio_mask = BIT(wdev->wiphy->n_radio) - 1;
+
if ((wdev->iftype == NL80211_IFTYPE_STATION ||
wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index b302caafd4d31..6261befa1e949 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -834,6 +834,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_MLO_TTLM_DLINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
[NL80211_ATTR_MLO_TTLM_ULINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
[NL80211_ATTR_ASSOC_SPP_AMSDU] = { .type = NLA_FLAG },
+ [NL80211_ATTR_VIF_RADIO_MASK] = { .type = NLA_U32 },
};
/* policy for the key attributes */
@@ -3975,7 +3976,8 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
nla_put_u32(msg, NL80211_ATTR_GENERATION,
rdev->devlist_generation ^
(cfg80211_rdev_list_generation << 2)) ||
- nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr))
+ nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr) ||
+ nla_put_u32(msg, NL80211_ATTR_VIF_RADIO_MASK, wdev->radio_mask))
goto nla_put_failure;
if (rdev->ops->get_channel && !wdev->valid_links) {
@@ -4296,6 +4298,29 @@ static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
return -EOPNOTSUPP;
}
+static int nl80211_parse_vif_radio_mask(struct genl_info *info,
+ u32 *radio_mask)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct nlattr *attr = info->attrs[NL80211_ATTR_VIF_RADIO_MASK];
+ u32 mask, allowed;
+
+ if (!attr) {
+ *radio_mask = 0;
+ return 0;
+ }
+
+ allowed = BIT(rdev->wiphy.n_radio) - 1;
+ mask = nla_get_u32(attr);
+ if (mask & ~allowed)
+ return -EINVAL;
+ if (!mask)
+ mask = allowed;
+ *radio_mask = mask;
+
+ return 1;
+}
+
static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -4303,6 +4328,8 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
int err;
enum nl80211_iftype otype, ntype;
struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ u32 radio_mask = 0;
bool change = false;
memset(¶ms, 0, sizeof(params));
@@ -4316,8 +4343,6 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
}
if (info->attrs[NL80211_ATTR_MESH_ID]) {
- struct wireless_dev *wdev = dev->ieee80211_ptr;
-
if (ntype != NL80211_IFTYPE_MESH_POINT)
return -EINVAL;
if (otype != NL80211_IFTYPE_MESH_POINT)
@@ -4348,6 +4373,12 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
if (err > 0)
change = true;
+ err = nl80211_parse_vif_radio_mask(info, &radio_mask);
+ if (err < 0)
+ return err;
+ if (err && netif_running(dev))
+ return -EBUSY;
+
if (change)
err = cfg80211_change_iface(rdev, dev, ntype, ¶ms);
else
@@ -4356,11 +4387,11 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
if (!err && params.use_4addr != -1)
dev->ieee80211_ptr->use_4addr = params.use_4addr;
- if (change && !err) {
- struct wireless_dev *wdev = dev->ieee80211_ptr;
+ if (radio_mask)
+ wdev->radio_mask = radio_mask;
+ if (change && !err)
nl80211_notify_iface(rdev, wdev, NL80211_CMD_SET_INTERFACE);
- }
return err;
}
@@ -4371,6 +4402,7 @@ static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
struct vif_params params;
struct wireless_dev *wdev;
struct sk_buff *msg;
+ u32 radio_mask;
int err;
enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
@@ -4408,6 +4440,10 @@ static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
if (err < 0)
return err;
+ err = nl80211_parse_vif_radio_mask(info, &radio_mask);
+ if (err < 0)
+ return err;
+
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
return -ENOMEM;
@@ -4449,6 +4485,9 @@ static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
break;
}
+ if (radio_mask)
+ wdev->radio_mask = radio_mask;
+
if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
nlmsg_free(msg);
@@ -9178,6 +9217,9 @@ static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev,
lockdep_assert_wiphy(wdev->wiphy);
+ if (!cfg80211_wdev_channel_allowed(wdev, chan))
+ return false;
+
if (!cfg80211_beaconing_iface_active(wdev))
return true;
@@ -9390,7 +9432,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
}
/* ignore disabled channels */
- if (chan->flags & IEEE80211_CHAN_DISABLED)
+ if (chan->flags & IEEE80211_CHAN_DISABLED ||
+ !cfg80211_wdev_channel_allowed(wdev, chan))
continue;
request->channels[i] = chan;
@@ -9410,7 +9453,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
chan = &wiphy->bands[band]->channels[j];
- if (chan->flags & IEEE80211_CHAN_DISABLED)
+ if (chan->flags & IEEE80211_CHAN_DISABLED ||
+ !cfg80211_wdev_channel_allowed(wdev, chan))
continue;
request->channels[i] = chan;
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 9d21667641a50..a7d704d0a282a 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -953,7 +953,8 @@ static int cfg80211_scan_6ghz(struct cfg80211_registered_device *rdev)
struct ieee80211_channel *chan =
ieee80211_get_channel(&rdev->wiphy, ap->center_freq);
- if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
+ if (!chan || chan->flags & IEEE80211_CHAN_DISABLED ||
+ !cfg80211_wdev_channel_allowed(rdev_req->wdev, chan))
continue;
for (i = 0; i < rdev_req->n_channels; i++) {
@@ -3519,9 +3520,12 @@ int cfg80211_wext_siwscan(struct net_device *dev,
continue;
for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
+ struct ieee80211_channel *chan;
+
/* ignore disabled channels */
- if (wiphy->bands[band]->channels[j].flags &
- IEEE80211_CHAN_DISABLED)
+ chan = &wiphy->bands[band]->channels[j];
+ if (chan->flags & IEEE80211_CHAN_DISABLED ||
+ !cfg80211_wdev_channel_allowed(creq->wdev, chan))
continue;
/* If we have a wireless request structure and the
diff --git a/net/wireless/util.c b/net/wireless/util.c
index f9e0ec311982e..8cc205b9f105c 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -2965,3 +2965,32 @@ bool cfg80211_radio_chandef_valid(const struct wiphy_radio *radio,
return true;
}
EXPORT_SYMBOL(cfg80211_radio_chandef_valid);
+
+bool cfg80211_wdev_channel_allowed(struct wireless_dev *wdev,
+ struct ieee80211_channel *chan)
+{
+ struct wiphy *wiphy = wdev->wiphy;
+ const struct wiphy_radio *radio;
+ struct cfg80211_chan_def chandef;
+ u32 radio_mask;
+ int i;
+
+ radio_mask = wdev->radio_mask;
+ if (!wiphy->n_radio || radio_mask == BIT(wiphy->n_radio) - 1)
+ return true;
+
+ cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20);
+ for (i = 0; i < wiphy->n_radio; i++) {
+ if (!(radio_mask & BIT(i)))
+ continue;
+
+ radio = &wiphy->radio[i];
+ if (!cfg80211_radio_chandef_valid(radio, &chandef))
+ continue;
+
+ return true;
+ }
+
+ return false;
+}
+EXPORT_SYMBOL(cfg80211_wdev_channel_allowed);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 059/877] wifi: mac80211: use vif radio mask to limit ibss scan frequencies
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (57 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 058/877] wifi: cfg80211: add option for vif allowed radios Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 060/877] wifi: mac80211: dont warn when an IBSS has no channel to scan Greg Kroah-Hartman
` (825 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Felix Fietkau, Johannes Berg,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit 32ee616a7f8c36fa3ab00985ebd038c3487e721f ]
Reject frequencies not supported by any radio that the vif is allowed to
use.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/9d5c0b6b00a7ecef6a0ac6de765c0af00c8bb0e1.1728462320.git-series.nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Stable-dep-of: a7491b7efbd9 ("wifi: mac80211: don't warn when an IBSS has no channel to scan")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/scan.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 8675d2e99c564..07ce9cd35dab2 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -1180,14 +1180,14 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
unsigned int n_channels)
{
struct ieee80211_local *local = sdata->local;
- int ret = -EBUSY, i, n_ch = 0;
+ int i, n_ch = 0;
enum nl80211_band band;
lockdep_assert_wiphy(local->hw.wiphy);
/* busy scanning */
if (local->scan_req)
- goto unlock;
+ return -EBUSY;
/* fill internal scan request */
if (!channels) {
@@ -1204,7 +1204,9 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
&local->hw.wiphy->bands[band]->channels[i];
if (tmp_ch->flags & (IEEE80211_CHAN_NO_IR |
- IEEE80211_CHAN_DISABLED))
+ IEEE80211_CHAN_DISABLED) ||
+ !cfg80211_wdev_channel_allowed(&sdata->wdev,
+ tmp_ch))
continue;
local->int_scan_req->channels[n_ch] = tmp_ch;
@@ -1213,21 +1215,23 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
}
if (WARN_ON_ONCE(n_ch == 0))
- goto unlock;
+ return -EINVAL;
local->int_scan_req->n_channels = n_ch;
} else {
for (i = 0; i < n_channels; i++) {
if (channels[i]->flags & (IEEE80211_CHAN_NO_IR |
- IEEE80211_CHAN_DISABLED))
+ IEEE80211_CHAN_DISABLED) ||
+ !cfg80211_wdev_channel_allowed(&sdata->wdev,
+ channels[i]))
continue;
local->int_scan_req->channels[n_ch] = channels[i];
n_ch++;
}
- if (WARN_ON_ONCE(n_ch == 0))
- goto unlock;
+ if (n_ch == 0)
+ return -EINVAL;
local->int_scan_req->n_channels = n_ch;
}
@@ -1237,9 +1241,7 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN);
local->int_scan_req->ssids[0].ssid_len = ssid_len;
- ret = __ieee80211_start_scan(sdata, sdata->local->int_scan_req);
- unlock:
- return ret;
+ return __ieee80211_start_scan(sdata, sdata->local->int_scan_req);
}
void ieee80211_scan_cancel(struct ieee80211_local *local)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 060/877] wifi: mac80211: dont warn when an IBSS has no channel to scan
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (58 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 059/877] wifi: mac80211: use vif radio mask to limit ibss scan frequencies Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 061/877] wifi: mac80211: dont offload TC setup on AP_VLAN interfaces Greg Kroah-Hartman
` (824 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+1634c5399e29d8b66789,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit a7491b7efbd9136b120a12ed72af9c12121dd134 ]
ieee80211_request_ibss_scan() warns when regulatory leaves no
allowed channel, but that can happen as the regdomain can change
while IBSS is operating, and it can continue to operate briefly
during the 60s grace period until it's shut down.
Just remove the warning in this case.
Assisted-by: LLM
Fixes: 34bcf7150241 ("mac80211: fix ibss scanning")
Reported-by: syzbot+1634c5399e29d8b66789@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=1634c5399e29d8b66789
Link: https://patch.msgid.link/20260904165722.fe380c27fef4.I0e8bee2e12a40d240851a4bc724d47753af46159@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/scan.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 07ce9cd35dab2..19e374fa00795 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -1214,7 +1214,7 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
}
}
- if (WARN_ON_ONCE(n_ch == 0))
+ if (n_ch == 0)
return -EINVAL;
local->int_scan_req->n_channels = n_ch;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 061/877] wifi: mac80211: dont offload TC setup on AP_VLAN interfaces
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (59 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 060/877] wifi: mac80211: dont warn when an IBSS has no channel to scan Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 062/877] wifi: mac80211: suppress chanctx warning for debugfs reset Greg Kroah-Hartman
` (823 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+f1ba58d6b55abd13239e,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit 362bd5bce29ed0f6fd3d39a7065567777d70606e ]
AP_VLAN interfaces are purely virtual, so don't try to offload
TC setup to drivers. We can't really use the AP interface either
since we may not know it all the time, and it could technically
even change.
Just reject the TC offload so things get done in software.
Assisted-by: LLM
Fixes: 61587f1556fe ("wifi: mac80211: add support for letting drivers register tc offload support")
Reported-by: syzbot+f1ba58d6b55abd13239e@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=f1ba58d6b55abd13239e
Link: https://patch.msgid.link/20260904165722.726cc076cecb.Iccfd88b13635425e850ce031376eb60a4ce5f4f8@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/iface.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 7a79b40d23b36..98bc924d74fa6 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -873,6 +873,9 @@ static int ieee80211_netdev_setup_tc(struct net_device *dev,
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local;
+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+ return -EOPNOTSUPP;
+
return drv_net_setup_tc(local, sdata, dev, type, type_data);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 062/877] wifi: mac80211: suppress chanctx warning for debugfs reset
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (60 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 061/877] wifi: mac80211: dont offload TC setup on AP_VLAN interfaces Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 063/877] wifi: mac80211: abort chanswitch when leaving a mesh Greg Kroah-Hartman
` (822 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+56a1a45a9a2c04d425ff,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit bf29d085e0eba92388518719d044f4702a8c6644 ]
Before suspend all the channel contexts should removed, so the
warning makes sense and should be there, but during reset the
same code is called without first removing. Limit the check to
the real suspend case.
Assisted-by: LLM
Fixes: 12e7f517029d ("mac80211: cleanup generic suspend/resume procedures")
Reported-by: syzbot+56a1a45a9a2c04d425ff@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=56a1a45a9a2c04d425ff
Link: https://patch.msgid.link/20260904165722.fe46395e310b.Ic4aaa95bd9d0ceb6a3cd7d84c425afee7d7d3dd7@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/cfg.c | 2 +-
net/mac80211/debugfs.c | 2 +-
net/mac80211/ieee80211_i.h | 2 +-
net/mac80211/pm.c | 8 +++++---
4 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index f6c5de994898c..73d7183c1ce59 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2844,7 +2844,7 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
static int ieee80211_suspend(struct wiphy *wiphy,
struct cfg80211_wowlan *wowlan)
{
- return __ieee80211_suspend(wiphy_priv(wiphy), wowlan);
+ return __ieee80211_suspend(wiphy_priv(wiphy), wowlan, false);
}
static int ieee80211_resume(struct wiphy *wiphy)
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index e9b3b2c7b6faa..28b1355cc062f 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -418,7 +418,7 @@ static ssize_t reset_write(struct file *file, const char __user *user_buf,
rtnl_lock();
wiphy_lock(local->hw.wiphy);
- __ieee80211_suspend(&local->hw, NULL);
+ __ieee80211_suspend(&local->hw, NULL, true);
ret = __ieee80211_resume(&local->hw);
wiphy_unlock(local->hw.wiphy);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 3b00b3f9f17dd..24edf2d4eb4f5 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -2287,7 +2287,7 @@ int ieee80211_reconfig(struct ieee80211_local *local);
void ieee80211_stop_device(struct ieee80211_local *local, bool suspend);
int __ieee80211_suspend(struct ieee80211_hw *hw,
- struct cfg80211_wowlan *wowlan);
+ struct cfg80211_wowlan *wowlan, bool reset);
static inline int __ieee80211_resume(struct ieee80211_hw *hw)
{
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 7be52345f218c..56c222bdd4905 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -18,7 +18,8 @@ static void ieee80211_sched_scan_cancel(struct ieee80211_local *local)
cfg80211_sched_scan_stopped_locked(local->hw.wiphy, 0);
}
-int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
+int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan,
+ bool reset)
{
struct ieee80211_local *local = hw_to_local(hw);
struct ieee80211_sub_if_data *sdata;
@@ -166,9 +167,10 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
/*
* We disconnected on all interfaces before suspend, all channel
- * contexts should be released.
+ * contexts should be released, but on 'reset' debugfs that's
+ * not true so don't check there.
*/
- WARN_ON(!list_empty(&local->chanctx_list));
+ WARN_ON(!reset && !list_empty(&local->chanctx_list));
/* stop hardware - this must stop RX */
ieee80211_stop_device(local, true);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 063/877] wifi: mac80211: abort chanswitch when leaving a mesh
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (61 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 062/877] wifi: mac80211: suppress chanctx warning for debugfs reset Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 064/877] wifi: mac80211: reset state when starting AP fails Greg Kroah-Hartman
` (821 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+81cd9dc1596563141d19,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit ac7472a24bd433b81c06582835dd1d5547c10da9 ]
The code in ieee80211_stop_mesh() leaves CSA active, but leaving
the mesh released the channel context, so the CSA finalize work
crashes:
Oops: general protection fault, probably for non-canonical address
0xdffffc0000000003
KASAN: null-ptr-deref in range [0x0000000000000018-0x000000000000001f]
RIP: 0010:ieee80211_put_srates_elem+0x42/0x640 net/mac80211/util.c:3272
Call Trace:
ieee80211_mesh_build_beacon+0xa83/0x1b50 net/mac80211/mesh.c:1093
ieee80211_mesh_rebuild_beacon+0xc7/0x170 net/mac80211/mesh.c:1147
ieee80211_mesh_finish_csa+0x131/0x210 net/mac80211/mesh.c:1542
ieee80211_set_after_csa_beacon net/mac80211/cfg.c:4085 [inline]
__ieee80211_csa_finalize net/mac80211/cfg.c:4133 [inline]
ieee80211_csa_finalize+0x633/0x1150 net/mac80211/cfg.c:4155
cfg80211_wiphy_work+0x2ab/0x450 net/wireless/core.c:438
Abort the channel switch properly.
Assisted-by: LLM
Fixes: b8456a14e9d2 ("{nl,cfg,mac}80211: implement mesh channel switch userspace API")
Reported-by: syzbot+81cd9dc1596563141d19@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=81cd9dc1596563141d19
Link: https://patch.msgid.link/20260904165722.d0b87eee08aa.I80550d6127e0bb26efb49a5fbe95be1aef1cd0cb@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/mesh.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 253f4b0642842..57cf3f90f7fbe 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1225,6 +1225,10 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
netif_carrier_off(sdata->dev);
+ /* abort any running channel switch */
+ sdata->vif.bss_conf.csa_active = false;
+ ieee80211_vif_unblock_queues_csa(sdata);
+
/* flush STAs and mpaths on this iface */
sta_info_flush(sdata, -1);
ieee80211_free_keys(sdata, true);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 064/877] wifi: mac80211: reset state when starting AP fails
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (62 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 063/877] wifi: mac80211: abort chanswitch when leaving a mesh Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 065/877] wifi: mac80211: unlist vifs when their netdev is unregistered Greg Kroah-Hartman
` (820 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+ca7a2759caaa6cd4e3db,
syzbot+c4686c3eb8b64032618f, Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit 3f28551d0241254a75626d868041c6340285088b ]
ieee80211_start_ap() can set enable_beacon (and beacon_int) and fail
later, leaving it set forever. Scanning can then attempt to restore
beaconing on such an interface, leading to:
Oops: divide error: 0000 [#1] SMP KASAN NOPTI
RIP: 0010:mac80211_hwsim_link_info_changed+0xca7/0xf00
Call Trace:
drv_link_info_changed+0x413/0x860 net/mac80211/driver-ops.c:495
ieee80211_link_info_change_notify+0x24b/0x3c0 net/mac80211/main.c:427
ieee80211_offchannel_return+0x381/0x580 net/mac80211/offchannel.c:160
__ieee80211_scan_completed+0x993/0xe30 net/mac80211/scan.c:519
ieee80211_scan_work+0x472/0x2010 net/mac80211/scan.c:1193
cfg80211_wiphy_work+0x2b7/0x550 net/wireless/core.c:538
in hwsim. Also, cfg80211 then allows changing the interface type,
and the off-channel path getgs confused about beaconing as well,
leading to another warning:
WARNING: net/mac80211/driver-ops.c:468 at drv_link_info_changed+0x583/0x880
ieee80211_link_info_change_notify+0x24b/0x3c0 net/mac80211/main.c:427
ieee80211_offchannel_stop_vifs+0x328/0x5c0 net/mac80211/offchannel.c:122
ieee80211_start_sw_scan net/mac80211/scan.c:583 [inline]
__ieee80211_start_scan+0xfb6/0x1af0 net/mac80211/scan.c:882
Reset the state on failures to always have it correct.
Assisted-by: LLM
Fixes: d6a83228823f ("mac80211: track enable_beacon explicitly")
Reported-by: syzbot+ca7a2759caaa6cd4e3db@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=ca7a2759caaa6cd4e3db
Reported-by: syzbot+c4686c3eb8b64032618f@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=c4686c3eb8b64032618f
Link: https://patch.msgid.link/20260904165722.9629429a5221.I7f599412bfe12a09d41ea4901be9ad165d07d133@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/cfg.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 73d7183c1ce59..71310d708dbc4 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1514,6 +1514,9 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
return 0;
error:
+ link_conf->enable_beacon = false;
+ link_conf->beacon_int = prev_beacon_int;
+ sdata->vif.cfg.ssid_len = 0;
ieee80211_link_release_channel(link);
return err;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 065/877] wifi: mac80211: unlist vifs when their netdev is unregistered
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (63 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 064/877] wifi: mac80211: reset state when starting AP fails Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 066/877] wifi: mac80211_hwsim: dont hand frames to mac80211 while stopping Greg Kroah-Hartman
` (819 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit eee2efd82867b623982ac51925b5a1812a74c50d ]
mac80211 only removes vifs from the local->interfaces list when
an interface is removed via ieee80211_if_remove(), before it
unregisters the netdev. However, it's possible for a netdev to
be unregistered without going through that: When the netns that
holds the wiphy is destroyed, the wiphy is supposed to move to
the init_ns, but that can run into allocation failures.
Then, mac80211 has an interface listed that doesn't exist, and
will eventually hit
BUG: failure at net/wireless/core.h:141/wiphy_to_rdev()!
...
_cfg80211_unregister_wdev+0x24/0x36a [cfg80211]
cfg80211_unregister_wdev+0x15/0x1d [cfg80211]
ieee80211_remove_interfaces+0x1ff/0x257 [mac80211]
ieee80211_unregister_hw+0x73/0x1d1 [mac80211]
mac80211_hwsim_del_radio+0x114/0x166 [mac80211_hwsim]
Remove the interface from the list in ->ndo_uninit if it's still
around to avoid this.
Assisted-by: LLM
Fixes: 463d018323851 ("cfg80211: make aware of net namespaces")
Link: https://patch.msgid.link/20260904170220.038ad73e6c04.I990abca78483e058746b6f42b4796717c3028164@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/iface.c | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 98bc924d74fa6..ac0a7374d721a 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -862,9 +862,33 @@ static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata)
ieee80211_link_stop(&sdata->deflink);
}
+/*
+ * The netdev can be unregistered without mac80211 doing it, e.g. by the netdev
+ * core when cfg80211 couldn't move it out of a network namespace that's being
+ * destroyed. Drop it from the interface list either way.
+ */
+static void ieee80211_unlist_sdata(struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_sub_if_data *iter;
+
+ ASSERT_RTNL();
+
+ list_for_each_entry(iter, &local->interfaces, list) {
+ if (iter != sdata)
+ continue;
+ guard(mutex)(&local->iflist_mtx);
+ list_del_rcu(&sdata->list);
+ return;
+ }
+}
+
static void ieee80211_uninit(struct net_device *dev)
{
- ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev));
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+ ieee80211_unlist_sdata(sdata);
+ ieee80211_teardown_sdata(sdata);
}
static int ieee80211_netdev_setup_tc(struct net_device *dev,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 066/877] wifi: mac80211_hwsim: dont hand frames to mac80211 while stopping
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (64 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 065/877] wifi: mac80211: unlist vifs when their netdev is unregistered Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 067/877] wifi: cfg80211: skip regulatory for punctured subchannels Greg Kroah-Hartman
` (818 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+b4aa2b672b18f1d4dc5f,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit 87840d4a3a21b1c19b867a80e16ba69dff284de2 ]
The code checks ->started for frames coming from wmediumd, but the
radio can be stopped after the check and before frame delivery,
causing mac80211 to hit the WARN_ON(!local->started).
Expand the mutex for this case and synchronise against it when the
radio is stopped to avoid being able to hit the warning with hwsim.
Drop the error print that would've complicated the error path, it
only triggers for allocation failures (already noisy) and malformed
frames anyway.
Assisted-by: LLM
Fixes: 7882513bacb1 ("mac80211_hwsim driver support userspace frame tx/rx")
Reported-by: syzbot+b4aa2b672b18f1d4dc5f@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=b4aa2b672b18f1d4dc5f
Link: https://patch.msgid.link/20260904170140.5f69a10d606b.I4a7921d00643f69e439c7a3b221d104f66a3dcdc@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/virtual/mac80211_hwsim.c | 39 ++++++++++++-------
1 file changed, 24 insertions(+), 15 deletions(-)
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c
index 9410059e97f01..f1b96cd1198c5 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
@@ -2120,7 +2120,12 @@ static void mac80211_hwsim_stop(struct ieee80211_hw *hw, bool suspend)
struct sk_buff *skb;
int i;
- data->started = false;
+ /*
+ * Serialise against wmediumd userspace, so no more frames
+ * can be handed to mac80211 after this returns.
+ */
+ scoped_guard(mutex, &data->mutex)
+ data->started = false;
for (i = 0; i < ARRAY_SIZE(data->link_data); i++)
hrtimer_cancel(&data->link_data[i].beacon_timer);
@@ -5851,12 +5856,12 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
if (frame_data_len < sizeof(struct ieee80211_hdr_3addr) ||
frame_data_len > IEEE80211_MAX_DATA_LEN)
- goto err;
+ goto out;
/* Allocate new skb here */
skb = alloc_skb(frame_data_len, GFP_KERNEL);
if (skb == NULL)
- goto err;
+ goto out;
/* Copy the data */
skb_put_data(skb, frame_data, frame_data_len);
@@ -5881,10 +5886,17 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
goto out;
}
+ /*
+ * Serialise against mac80211_hwsim_stop() - mac80211 doesn't allow
+ * frames reported while the HW is down, hence the ->started check
+ * must be under mutex.
+ */
+ mutex_lock(&data2->mutex);
+
/* check if radio is configured properly */
if ((data2->idle && !data2->tmp_chan) || !data2->started)
- goto out;
+ goto out_unlock;
/* A frame is received from user space */
memset(&rx_status, 0, sizeof(rx_status));
@@ -5900,22 +5912,18 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
iter_data.channel = ieee80211_get_channel(data2->hw->wiphy,
rx_status.freq);
if (!iter_data.channel)
- goto out;
+ goto out_unlock;
rx_status.band = iter_data.channel->band;
- mutex_lock(&data2->mutex);
if (!hwsim_chans_compat(iter_data.channel, channel)) {
ieee80211_iterate_active_interfaces_atomic(
data2->hw, IEEE80211_IFACE_ITER_NORMAL,
mac80211_hwsim_tx_iter, &iter_data);
- if (!iter_data.receive) {
- mutex_unlock(&data2->mutex);
- goto out;
- }
+ if (!iter_data.receive)
+ goto out_unlock;
}
- mutex_unlock(&data2->mutex);
} else if (!channel) {
- goto out;
+ goto out_unlock;
} else {
rx_status.freq = channel->center_freq;
rx_status.band = channel->band;
@@ -5923,7 +5931,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]);
if (rx_status.rate_idx >= data2->hw->wiphy->bands[rx_status.band]->n_bitrates)
- goto out;
+ goto out_unlock;
rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
hdr = (void *)skb->data;
@@ -5933,10 +5941,11 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
rx_status.boottime_ns = ktime_get_boottime_ns();
mac80211_hwsim_rx(data2, &rx_status, skb);
+ mutex_unlock(&data2->mutex);
return 0;
-err:
- pr_debug("mac80211_hwsim: error occurred in %s\n", __func__);
+out_unlock:
+ mutex_unlock(&data2->mutex);
out:
dev_kfree_skb(skb);
return -EINVAL;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 067/877] wifi: cfg80211: skip regulatory for punctured subchannels
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (65 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 066/877] wifi: mac80211_hwsim: dont hand frames to mac80211 while stopping Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 068/877] wifi: cfg80211: expose cfg80211_chandef_get_width() Greg Kroah-Hartman
` (817 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Manaswini Paluri, Kavita Kavita,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kavita Kavita <quic_kkavita@quicinc.com>
[ Upstream commit 9add053591ed9d126b6f071236e33e762c439fa8 ]
The kernel performs several regulatory checks for AP mode in
nl80211/cfg80211. These checks include radar detection,
verification of whether the sub-channel is disabled, and
an examination to determine if the channel is a DFS channel
(both DFS usable and DFS available). These checks are
performed across a frequency range, examining each sub-channel.
However, these checks are also performed on subchannels that
have been punctured which should not be examined as they are
not in use.
This leads to the issue where the AP stops because one of
the 20 MHz sub-channels is disabled or radar detected on
the channel, even when the sub-channel is punctured.
To address this issue, add a condition check wherever
regulatory checks exist for AP mode in nl80211/cfg80211.
This check identifies punctured channels and, upon finding
them, skips the regulatory checks for those channels.
Co-developed-by: Manaswini Paluri <quic_mpaluri@quicinc.com>
Signed-off-by: Manaswini Paluri <quic_mpaluri@quicinc.com>
Signed-off-by: Kavita Kavita <quic_kkavita@quicinc.com>
Link: https://patch.msgid.link/20250109050409.25351-1-quic_kkavita@quicinc.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Stable-dep-of: e14bf37bb2b3 ("wifi: mac80211: don't allow injecting frames wider than the chanctx")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/wireless/chan.c | 370 +++++++++++++++-----------------------------
1 file changed, 123 insertions(+), 247 deletions(-)
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 515d40c09e788..b1a8d17baa62a 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -55,6 +55,56 @@ void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
}
EXPORT_SYMBOL(cfg80211_chandef_create);
+static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
+{
+ return nl80211_chan_width_to_mhz(c->width);
+}
+
+static u32 cfg80211_get_start_freq(const struct cfg80211_chan_def *chandef,
+ u32 cf)
+{
+ u32 start_freq, center_freq, bandwidth;
+
+ center_freq = MHZ_TO_KHZ((cf == 1) ?
+ chandef->center_freq1 : chandef->center_freq2);
+ bandwidth = MHZ_TO_KHZ(cfg80211_chandef_get_width(chandef));
+
+ if (bandwidth <= MHZ_TO_KHZ(20))
+ start_freq = center_freq;
+ else
+ start_freq = center_freq - bandwidth / 2 + MHZ_TO_KHZ(10);
+
+ return start_freq;
+}
+
+static u32 cfg80211_get_end_freq(const struct cfg80211_chan_def *chandef,
+ u32 cf)
+{
+ u32 end_freq, center_freq, bandwidth;
+
+ center_freq = MHZ_TO_KHZ((cf == 1) ?
+ chandef->center_freq1 : chandef->center_freq2);
+ bandwidth = MHZ_TO_KHZ(cfg80211_chandef_get_width(chandef));
+
+ if (bandwidth <= MHZ_TO_KHZ(20))
+ end_freq = center_freq;
+ else
+ end_freq = center_freq + bandwidth / 2 - MHZ_TO_KHZ(10);
+
+ return end_freq;
+}
+
+#define for_each_subchan(chandef, freq, cf) \
+ for (u32 punctured = chandef->punctured, \
+ cf = 1, freq = cfg80211_get_start_freq(chandef, cf); \
+ freq <= cfg80211_get_end_freq(chandef, cf); \
+ freq += MHZ_TO_KHZ(20), \
+ ((cf == 1 && chandef->center_freq2 != 0 && \
+ freq > cfg80211_get_end_freq(chandef, cf)) ? \
+ (cf++, freq = cfg80211_get_start_freq(chandef, cf), \
+ punctured = 0) : (punctured >>= 1))) \
+ if (!(punctured & 1))
+
struct cfg80211_per_bw_puncturing_values {
u8 len;
const u16 *valid_values;
@@ -258,11 +308,6 @@ int nl80211_chan_width_to_mhz(enum nl80211_chan_width chan_width)
}
EXPORT_SYMBOL(nl80211_chan_width_to_mhz);
-static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
-{
- return nl80211_chan_width_to_mhz(c->width);
-}
-
static bool cfg80211_valid_center_freq(u32 center,
enum nl80211_chan_width width)
{
@@ -582,29 +627,11 @@ cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
}
EXPORT_SYMBOL(cfg80211_chandef_compatible);
-static void cfg80211_set_chans_dfs_state(struct wiphy *wiphy, u32 center_freq,
- u32 bandwidth,
- enum nl80211_dfs_state dfs_state)
-{
- struct ieee80211_channel *c;
- u32 freq;
-
- for (freq = center_freq - bandwidth/2 + 10;
- freq <= center_freq + bandwidth/2 - 10;
- freq += 20) {
- c = ieee80211_get_channel(wiphy, freq);
- if (!c || !(c->flags & IEEE80211_CHAN_RADAR))
- continue;
-
- c->dfs_state = dfs_state;
- c->dfs_state_entered = jiffies;
- }
-}
-
void cfg80211_set_dfs_state(struct wiphy *wiphy,
const struct cfg80211_chan_def *chandef,
enum nl80211_dfs_state dfs_state)
{
+ struct ieee80211_channel *c;
int width;
if (WARN_ON(!cfg80211_chandef_valid(chandef)))
@@ -614,41 +641,14 @@ void cfg80211_set_dfs_state(struct wiphy *wiphy,
if (width < 0)
return;
- cfg80211_set_chans_dfs_state(wiphy, chandef->center_freq1,
- width, dfs_state);
-
- if (!chandef->center_freq2)
- return;
- cfg80211_set_chans_dfs_state(wiphy, chandef->center_freq2,
- width, dfs_state);
-}
-
-static u32 cfg80211_get_start_freq(u32 center_freq,
- u32 bandwidth)
-{
- u32 start_freq;
-
- bandwidth = MHZ_TO_KHZ(bandwidth);
- if (bandwidth <= MHZ_TO_KHZ(20))
- start_freq = center_freq;
- else
- start_freq = center_freq - bandwidth / 2 + MHZ_TO_KHZ(10);
-
- return start_freq;
-}
-
-static u32 cfg80211_get_end_freq(u32 center_freq,
- u32 bandwidth)
-{
- u32 end_freq;
-
- bandwidth = MHZ_TO_KHZ(bandwidth);
- if (bandwidth <= MHZ_TO_KHZ(20))
- end_freq = center_freq;
- else
- end_freq = center_freq + bandwidth / 2 - MHZ_TO_KHZ(10);
+ for_each_subchan(chandef, freq, cf) {
+ c = ieee80211_get_channel_khz(wiphy, freq);
+ if (!c || !(c->flags & IEEE80211_CHAN_RADAR))
+ continue;
- return end_freq;
+ c->dfs_state = dfs_state;
+ c->dfs_state_entered = jiffies;
+ }
}
static bool
@@ -725,17 +725,12 @@ static bool cfg80211_dfs_permissive_chan(struct wiphy *wiphy,
}
static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy,
- u32 center_freq,
- u32 bandwidth,
- enum nl80211_iftype iftype)
+ const struct cfg80211_chan_def *chandef,
+ enum nl80211_iftype iftype)
{
struct ieee80211_channel *c;
- u32 freq, start_freq, end_freq;
-
- start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
- end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
- for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
+ for_each_subchan(chandef, freq, cf) {
c = ieee80211_get_channel_khz(wiphy, freq);
if (!c)
return -EINVAL;
@@ -768,25 +763,9 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
if (width < 0)
return -EINVAL;
- ret = cfg80211_get_chans_dfs_required(wiphy,
- ieee80211_chandef_to_khz(chandef),
- width, iftype);
- if (ret < 0)
- return ret;
- else if (ret > 0)
- return BIT(chandef->width);
-
- if (!chandef->center_freq2)
- return 0;
-
- ret = cfg80211_get_chans_dfs_required(wiphy,
- MHZ_TO_KHZ(chandef->center_freq2),
- width, iftype);
- if (ret < 0)
- return ret;
- else if (ret > 0)
- return BIT(chandef->width);
+ ret = cfg80211_get_chans_dfs_required(wiphy, chandef, iftype);
+ return (ret > 0) ? BIT(chandef->width) : ret;
break;
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_OCB:
@@ -806,16 +785,18 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
}
EXPORT_SYMBOL(cfg80211_chandef_dfs_required);
-static int cfg80211_get_chans_dfs_usable(struct wiphy *wiphy,
- u32 center_freq,
- u32 bandwidth)
+bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
+ const struct cfg80211_chan_def *chandef)
{
struct ieee80211_channel *c;
- u32 freq, start_freq, end_freq;
- int count = 0;
+ int width, count = 0;
- start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
- end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
+ if (WARN_ON(!cfg80211_chandef_valid(chandef)))
+ return false;
+
+ width = cfg80211_chandef_get_width(chandef);
+ if (width < 0)
+ return false;
/*
* Check entire range of channels for the bandwidth.
@@ -823,61 +804,24 @@ static int cfg80211_get_chans_dfs_usable(struct wiphy *wiphy,
* DFS_AVAILABLE). Return number of usable channels
* (require CAC). Allow DFS and non-DFS channel mix.
*/
- for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
+ for_each_subchan(chandef, freq, cf) {
c = ieee80211_get_channel_khz(wiphy, freq);
if (!c)
- return -EINVAL;
+ return false;
if (c->flags & IEEE80211_CHAN_DISABLED)
- return -EINVAL;
+ return false;
if (c->flags & IEEE80211_CHAN_RADAR) {
if (c->dfs_state == NL80211_DFS_UNAVAILABLE)
- return -EINVAL;
+ return false;
if (c->dfs_state == NL80211_DFS_USABLE)
count++;
}
}
- return count;
-}
-
-bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
- const struct cfg80211_chan_def *chandef)
-{
- int width;
- int r1, r2 = 0;
-
- if (WARN_ON(!cfg80211_chandef_valid(chandef)))
- return false;
-
- width = cfg80211_chandef_get_width(chandef);
- if (width < 0)
- return false;
-
- r1 = cfg80211_get_chans_dfs_usable(wiphy,
- MHZ_TO_KHZ(chandef->center_freq1),
- width);
-
- if (r1 < 0)
- return false;
-
- switch (chandef->width) {
- case NL80211_CHAN_WIDTH_80P80:
- WARN_ON(!chandef->center_freq2);
- r2 = cfg80211_get_chans_dfs_usable(wiphy,
- MHZ_TO_KHZ(chandef->center_freq2),
- width);
- if (r2 < 0)
- return false;
- break;
- default:
- WARN_ON(chandef->center_freq2);
- break;
- }
-
- return (r1 + r2 > 0);
+ return count > 0;
}
EXPORT_SYMBOL(cfg80211_chandef_dfs_usable);
@@ -1051,26 +995,29 @@ bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
return false;
}
-static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
- u32 center_freq,
- u32 bandwidth)
+static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
+ const struct cfg80211_chan_def *chandef)
{
struct ieee80211_channel *c;
- u32 freq, start_freq, end_freq;
+ int width;
bool dfs_offload;
+ if (WARN_ON(!cfg80211_chandef_valid(chandef)))
+ return false;
+
+ width = cfg80211_chandef_get_width(chandef);
+ if (width < 0)
+ return false;
+
dfs_offload = wiphy_ext_feature_isset(wiphy,
NL80211_EXT_FEATURE_DFS_OFFLOAD);
- start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
- end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
-
/*
* Check entire range of channels for the bandwidth.
* If any channel in between is disabled or has not
* had gone through CAC return false
*/
- for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
+ for_each_subchan(chandef, freq, cf) {
c = ieee80211_get_channel_khz(wiphy, freq);
if (!c)
return false;
@@ -1087,124 +1034,54 @@ static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
return true;
}
-static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
- const struct cfg80211_chan_def *chandef)
+unsigned int
+cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
+ const struct cfg80211_chan_def *chandef)
{
+ struct ieee80211_channel *c;
int width;
- int r;
+ unsigned int t1 = 0, t2 = 0;
if (WARN_ON(!cfg80211_chandef_valid(chandef)))
- return false;
+ return 0;
width = cfg80211_chandef_get_width(chandef);
if (width < 0)
- return false;
-
- r = cfg80211_get_chans_dfs_available(wiphy,
- MHZ_TO_KHZ(chandef->center_freq1),
- width);
-
- /* If any of channels unavailable for cf1 just return */
- if (!r)
- return r;
-
- switch (chandef->width) {
- case NL80211_CHAN_WIDTH_80P80:
- WARN_ON(!chandef->center_freq2);
- r = cfg80211_get_chans_dfs_available(wiphy,
- MHZ_TO_KHZ(chandef->center_freq2),
- width);
- break;
- default:
- WARN_ON(chandef->center_freq2);
- break;
- }
-
- return r;
-}
-
-static unsigned int cfg80211_get_chans_dfs_cac_time(struct wiphy *wiphy,
- u32 center_freq,
- u32 bandwidth)
-{
- struct ieee80211_channel *c;
- u32 start_freq, end_freq, freq;
- unsigned int dfs_cac_ms = 0;
-
- start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
- end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
+ return 0;
- for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
+ for_each_subchan(chandef, freq, cf) {
c = ieee80211_get_channel_khz(wiphy, freq);
- if (!c)
- return 0;
-
- if (c->flags & IEEE80211_CHAN_DISABLED)
- return 0;
+ if (!c || (c->flags & IEEE80211_CHAN_DISABLED)) {
+ if (cf == 1)
+ t1 = INT_MAX;
+ else
+ t2 = INT_MAX;
+ continue;
+ }
if (!(c->flags & IEEE80211_CHAN_RADAR))
continue;
- if (c->dfs_cac_ms > dfs_cac_ms)
- dfs_cac_ms = c->dfs_cac_ms;
- }
-
- return dfs_cac_ms;
-}
-
-unsigned int
-cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
- const struct cfg80211_chan_def *chandef)
-{
- int width;
- unsigned int t1 = 0, t2 = 0;
+ if (cf == 1 && c->dfs_cac_ms > t1)
+ t1 = c->dfs_cac_ms;
- if (WARN_ON(!cfg80211_chandef_valid(chandef)))
- return 0;
+ if (cf == 2 && c->dfs_cac_ms > t2)
+ t2 = c->dfs_cac_ms;
+ }
- width = cfg80211_chandef_get_width(chandef);
- if (width < 0)
+ if (t1 == INT_MAX && t2 == INT_MAX)
return 0;
- t1 = cfg80211_get_chans_dfs_cac_time(wiphy,
- MHZ_TO_KHZ(chandef->center_freq1),
- width);
+ if (t1 == INT_MAX)
+ return t2;
- if (!chandef->center_freq2)
+ if (t2 == INT_MAX)
return t1;
- t2 = cfg80211_get_chans_dfs_cac_time(wiphy,
- MHZ_TO_KHZ(chandef->center_freq2),
- width);
-
return max(t1, t2);
}
EXPORT_SYMBOL(cfg80211_chandef_dfs_cac_time);
-static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
- u32 center_freq, u32 bandwidth,
- u32 prohibited_flags,
- u32 permitting_flags)
-{
- struct ieee80211_channel *c;
- u32 freq, start_freq, end_freq;
-
- start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
- end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
-
- for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
- c = ieee80211_get_channel_khz(wiphy, freq);
- if (!c)
- return false;
- if (c->flags & permitting_flags)
- continue;
- if (c->flags & prohibited_flags)
- return false;
- }
-
- return true;
-}
-
/* check if the operating channels are valid and supported */
static bool cfg80211_edmg_usable(struct wiphy *wiphy, u8 edmg_channels,
enum ieee80211_edmg_bw_config edmg_bw_config,
@@ -1270,6 +1147,7 @@ bool _cfg80211_chandef_usable(struct wiphy *wiphy,
bool ext_nss_cap, support_80_80 = false, support_320 = false;
const struct ieee80211_sband_iftype_data *iftd;
struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *c;
int i;
if (WARN_ON(!cfg80211_chandef_valid(chandef)))
@@ -1420,19 +1298,17 @@ bool _cfg80211_chandef_usable(struct wiphy *wiphy,
if (width < 20)
prohibited_flags |= IEEE80211_CHAN_NO_OFDM;
+ for_each_subchan(chandef, freq, cf) {
+ c = ieee80211_get_channel_khz(wiphy, freq);
+ if (!c)
+ return false;
+ if (c->flags & permitting_flags)
+ continue;
+ if (c->flags & prohibited_flags)
+ return false;
+ }
- if (!cfg80211_secondary_chans_ok(wiphy,
- ieee80211_chandef_to_khz(chandef),
- width, prohibited_flags,
- permitting_flags))
- return false;
-
- if (!chandef->center_freq2)
- return true;
- return cfg80211_secondary_chans_ok(wiphy,
- MHZ_TO_KHZ(chandef->center_freq2),
- width, prohibited_flags,
- permitting_flags);
+ return true;
}
bool cfg80211_chandef_usable(struct wiphy *wiphy,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 068/877] wifi: cfg80211: expose cfg80211_chandef_get_width()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (66 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 067/877] wifi: cfg80211: skip regulatory for punctured subchannels Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 069/877] wifi: mac80211: dont allow injecting frames wider than the chanctx Greg Kroah-Hartman
` (816 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Miriam Rachel Korenblit,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit b5c1622762f0937a66b69b7f15466c28fe85dcf1 ]
This can be just a trivial inline, to simplify some code.
Expose it, and also use it in util.c where it wasn't
previously available.
Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20250311122534.c5c3b4af9a74.Ib25cf60f634dc359961182113214e5cdc3504e9c@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Stable-dep-of: e14bf37bb2b3 ("wifi: mac80211: don't allow injecting frames wider than the chanctx")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/cfg80211.h | 11 +++++++++++
net/wireless/chan.c | 5 -----
net/wireless/util.c | 4 ++--
3 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f3915118c15d7..ede91e4709ee5 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1008,6 +1008,17 @@ cfg80211_chandef_compatible(const struct cfg80211_chan_def *chandef1,
*/
int nl80211_chan_width_to_mhz(enum nl80211_chan_width chan_width);
+/**
+ * cfg80211_chandef_get_width - return chandef width in MHz
+ * @c: chandef to return bandwidth for
+ * Return: channel width in MHz for the given chandef; note that it returns
+ * 80 for 80+80 configurations
+ */
+static inline int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
+{
+ return nl80211_chan_width_to_mhz(c->width);
+}
+
/**
* cfg80211_chandef_valid - check if a channel definition is valid
* @chandef: the channel definition to check
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index b1a8d17baa62a..6f4b4770bf50b 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -55,11 +55,6 @@ void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
}
EXPORT_SYMBOL(cfg80211_chandef_create);
-static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
-{
- return nl80211_chan_width_to_mhz(c->width);
-}
-
static u32 cfg80211_get_start_freq(const struct cfg80211_chan_def *chandef,
u32 cf)
{
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 8cc205b9f105c..66f95044adb2a 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -5,7 +5,7 @@
* Copyright 2007-2009 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright 2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2023 Intel Corporation
+ * Copyright (C) 2018-2023, 2025 Intel Corporation
*/
#include <linux/export.h>
#include <linux/bitops.h>
@@ -2954,7 +2954,7 @@ bool cfg80211_radio_chandef_valid(const struct wiphy_radio *radio,
u32 freq, width;
freq = ieee80211_chandef_to_khz(chandef);
- width = nl80211_chan_width_to_mhz(chandef->width);
+ width = cfg80211_chandef_get_width(chandef);
if (!ieee80211_radio_freq_range_valid(radio, freq, width))
return false;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 069/877] wifi: mac80211: dont allow injecting frames wider than the chanctx
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (67 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 068/877] wifi: cfg80211: expose cfg80211_chandef_get_width() Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 070/877] wifi: mac80211: reset the AP_VLAN tailroom counter on ifdown Greg Kroah-Hartman
` (815 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+435fdb053cf98bfa5778,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit e14bf37bb2b3853012ff160131d1c6233f7a9cc9 ]
Frames injected on a monitor interface can carry a radiotap
field requesting a bandwidth, which mac80211 passes down to
the driver regardless of the the actual operational bandwidth.
If the bandwidth requested is too wide, that triggers a warning
in hwsim:
WARN_ON(hwsim_get_chanwidth(bw) > hwsim_get_chanwidth(confbw))
Drop such frames entirely instead since they cannot be sent.
Assisted-by: LLM
Fixes: 646e76bb5daf ("mac80211: parse VHT info in injected frames")
Reported-by: syzbot+435fdb053cf98bfa5778@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=435fdb053cf98bfa5778
Link: https://patch.msgid.link/20260908122838.201719-13-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/mac80211.h | 5 ++++-
net/mac80211/iface.c | 2 +-
net/mac80211/tx.c | 28 ++++++++++++++++++++++++++--
3 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 7d71a4149cdf9..41ae682015fc0 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -7228,11 +7228,14 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
*
* @skb: packet injected by userspace
* @dev: the &struct device of this 802.11 device
+ * @chandef: the channel definition the frame will be transmitted on, or
+ * %NULL to skip the bandwidth checks
*
* Return: %true if the radiotap header was parsed, %false otherwise
*/
bool ieee80211_parse_tx_radiotap(struct sk_buff *skb,
- struct net_device *dev);
+ struct net_device *dev,
+ const struct cfg80211_chan_def *chandef);
/**
* struct ieee80211_noa_data - holds temporary data for tracking P2P NoA state
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index ac0a7374d721a..3726dded1959a 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -929,7 +929,7 @@ static u16 ieee80211_monitor_select_queue(struct net_device *dev,
/* reset flags and info before parsing radiotap header */
memset(info, 0, sizeof(*info));
- if (!ieee80211_parse_tx_radiotap(skb, dev))
+ if (!ieee80211_parse_tx_radiotap(skb, dev, NULL))
return 0; /* doesn't matter, frame will be dropped */
len_rthdr = ieee80211_get_radiotap_len(skb->data);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 9bc1a80e80570..e78e71cb92f7f 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2084,8 +2084,29 @@ static bool ieee80211_validate_radiotap_len(struct sk_buff *skb)
return true;
}
+static bool ieee80211_rate_bw_usable(u16 rate_flags,
+ const struct cfg80211_chan_def *chandef)
+{
+ int width;
+
+ if (!chandef)
+ return true;
+
+ if (rate_flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
+ width = 160;
+ else if (rate_flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
+ width = 80;
+ else if (rate_flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ width = 40;
+ else
+ return true;
+
+ return width <= cfg80211_chandef_get_width(chandef);
+}
+
bool ieee80211_parse_tx_radiotap(struct sk_buff *skb,
- struct net_device *dev)
+ struct net_device *dev,
+ const struct cfg80211_chan_def *chandef)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_radiotap_iterator iterator;
@@ -2259,6 +2280,9 @@ bool ieee80211_parse_tx_radiotap(struct sk_buff *skb,
struct ieee80211_supported_band *sband =
local->hw.wiphy->bands[info->band];
+ if (!ieee80211_rate_bw_usable(rate_flags, chandef))
+ return false;
+
info->control.flags |= IEEE80211_TX_CTRL_RATE_INJECT;
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
@@ -2448,7 +2472,7 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
* selected chandef above to accurately set injection rates and
* retransmissions.
*/
- if (!ieee80211_parse_tx_radiotap(skb, dev))
+ if (!ieee80211_parse_tx_radiotap(skb, dev, chandef))
goto fail_rcu;
/* remove the injection radiotap header */
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 070/877] wifi: mac80211: reset the AP_VLAN tailroom counter on ifdown
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (68 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 069/877] wifi: mac80211: dont allow injecting frames wider than the chanctx Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 071/877] wifi: mac80211: require a peer station for TDLS setup confirm Greg Kroah-Hartman
` (814 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+de3ee5362db09487ea37,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit 4504f3960dc4501c73be9f99eabda2e26e9db41e ]
On ifup, AP_VLAN interfaces get crypto_tx_tailroom_needed_cnt from
the AP interface, but it's never decremented again unless the AP is
also brought down. Thus, bringing the same AP_VLAN up again will
increment the counter again and eventually hit the sanity check:
WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt !=
master->crypto_tx_tailroom_needed_cnt);
Reset it on ifdown to avoid that.
Assisted-by: LLM
Fixes: f9dca80b98ca ("mac80211: fix AP_VLAN crypto tailroom calculation")
Reported-by: syzbot+de3ee5362db09487ea37@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=de3ee5362db09487ea37
Link: https://patch.msgid.link/20260908122838.201719-14-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/iface.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 3726dded1959a..14a80583956c1 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -618,6 +618,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
RCU_INIT_POINTER(sdata->vif.bss_conf.chanctx_conf, NULL);
/* see comment in the default case below */
ieee80211_free_keys(sdata, true);
+ /* increased by AP value on ifup, so reset on ifdown */
+ sdata->crypto_tx_tailroom_needed_cnt = 0;
/* no need to tell driver */
break;
case NL80211_IFTYPE_MONITOR:
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 071/877] wifi: mac80211: require a peer station for TDLS setup confirm
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (69 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 070/877] wifi: mac80211: reset the AP_VLAN tailroom counter on ifdown Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 072/877] wifi: mac80211: dont allow link changes when iface is down Greg Kroah-Hartman
` (813 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+e55106f8389651870be0,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit 038e1d126304fd25d507fd4e671232df57bd1799 ]
It's nonsense for the setup confirm to go to station that
doesn't even exist, and it hits a warning when building
the frame:
WARN_ON_ONCE(!sta || !ap_sta)
Only accept WLAN_TDLS_SETUP_CONFIRM when the station is
already there as a TDLS station. Need to copy the call
to ieee80211_tdls_prep_mgmt_packet() since the existing
WLAN_TDLS_DISCOVERY_REQUEST already falls through to it.
Assisted-by: LLM
Fixes: 6f7eaa47e1de ("mac80211: add TDLS QoS param IE on setup-confirm")
Reported-by: syzbot+e55106f8389651870be0@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=e55106f8389651870be0
Link: https://patch.msgid.link/20260908122838.201719-15-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/tdls.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c
index 92ab7be3d4824..b4bedf0b2b552 100644
--- a/net/mac80211/tdls.c
+++ b/net/mac80211/tdls.c
@@ -1285,6 +1285,24 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
peer_capability, initiator,
extra_ies, extra_ies_len);
break;
+ case WLAN_TDLS_SETUP_CONFIRM: {
+ struct sta_info *sta;
+
+ sta = sta_info_get(sdata, peer);
+ if (!sta || !sta->sta.tdls) {
+ ret = -ENOLINK;
+ break;
+ }
+
+ ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer,
+ link_id, action_code,
+ dialog_token,
+ status_code,
+ peer_capability,
+ initiator, extra_ies,
+ extra_ies_len, 0, NULL);
+ break;
+ }
case WLAN_TDLS_DISCOVERY_REQUEST:
/*
* Protect the discovery so we can hear the TDLS discovery
@@ -1293,7 +1311,6 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
*/
drv_mgd_protect_tdls_discover(sdata->local, sdata, link_id);
fallthrough;
- case WLAN_TDLS_SETUP_CONFIRM:
case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
/* no special handling */
ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 072/877] wifi: mac80211: dont allow link changes when iface is down
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (70 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 071/877] wifi: mac80211: require a peer station for TDLS setup confirm Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 073/877] wifi: mac80211: dont RCU-dereference the mesh CSA settings we just set Greg Kroah-Hartman
` (812 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+582469b3a9ef5f13606b,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit 370872d30349d81dec519e15ea2949fd63511cf7 ]
ieee80211_set_active_links() only checks that the interface is running in
the inner __ieee80211_set_active_links(), after drv_can_activate_links()
was already called, so using active_links on an interface that's down
triggers the check-sdata-in-driver warning.
Add the missing check in the debugfs file.
Assisted-by: LLM
Fixes: 3d9011029227 ("wifi: mac80211: implement link switching")
Reported-by: syzbot+582469b3a9ef5f13606b@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=582469b3a9ef5f13606b
Link: https://patch.msgid.link/20260908122838.201719-16-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/debugfs_netdev.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index d0b145888e139..bb5812925d82e 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -731,6 +731,9 @@ static ssize_t ieee80211_if_parse_active_links(struct ieee80211_sub_if_data *sda
if (kstrtou16(buf, 0, &active_links) || !active_links)
return -EINVAL;
+ if (!ieee80211_sdata_running(sdata))
+ return -ENETDOWN;
+
return ieee80211_set_active_links(&sdata->vif, active_links) ?: buflen;
}
IEEE80211_IF_FILE_RW(active_links);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 073/877] wifi: mac80211: dont RCU-dereference the mesh CSA settings we just set
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (71 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 072/877] wifi: mac80211: dont allow link changes when iface is down Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 074/877] wifi: mac80211: dont access the TSF of a down interface Greg Kroah-Hartman
` (811 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+b59873f5699e941717ca,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit b481e64e4498e2c053d5954f546ee02338f6ab63 ]
In the error path of ieee80211_mesh_csa_beacon() the settings that were
just assigned are read back with rcu_dereference(), which lockdep then
complains about.
There's no need to read the pointer at all, tmp_csa_settings still is
the right value anyway.
Assisted-by: LLM
Fixes: b8456a14e9d2 ("{nl,cfg,mac}80211: implement mesh channel switch userspace API")
Reported-by: syzbot+b59873f5699e941717ca@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=b59873f5699e941717ca
Link: https://patch.msgid.link/20260908122838.201719-17-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/mesh.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 57cf3f90f7fbe..4c601b9cb3bb2 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1577,7 +1577,6 @@ int ieee80211_mesh_csa_beacon(struct ieee80211_sub_if_data *sdata,
ret = ieee80211_mesh_rebuild_beacon(sdata);
if (ret) {
- tmp_csa_settings = rcu_dereference(ifmsh->csa);
RCU_INIT_POINTER(ifmsh->csa, NULL);
kfree_rcu(tmp_csa_settings, rcu_head);
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 074/877] wifi: mac80211: dont access the TSF of a down interface
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (72 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 073/877] wifi: mac80211: dont RCU-dereference the mesh CSA settings we just set Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 075/877] wifi: mac80211: add HE 6 GHz capability in the scan elems len Greg Kroah-Hartman
` (810 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+1c8c45017f784e646b47,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit 0b1de9feeb8651f7a3bb53ed7c9006e3b5298c01 ]
The tsf debugfs files call the driver even if the interface
isn't up, tgriggering check-sdata-in-driver warnings.
Reject the access in that case.
Assisted-by: LLM
Fixes: 37a41b4affa3 ("mac80211: add ieee80211_vif param to tsf functions")
Reported-by: syzbot+1c8c45017f784e646b47@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=1c8c45017f784e646b47
Link: https://patch.msgid.link/20260908122838.201719-18-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/debugfs_netdev.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index bb5812925d82e..d3519bbc4285f 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -659,6 +659,9 @@ static ssize_t ieee80211_if_fmt_tsf(
struct ieee80211_local *local = sdata->local;
u64 tsf;
+ if (!ieee80211_sdata_running((struct ieee80211_sub_if_data *)sdata))
+ return -ENETDOWN;
+
tsf = drv_get_tsf(local, (struct ieee80211_sub_if_data *)sdata);
return scnprintf(buf, buflen, "0x%016llx\n", (unsigned long long) tsf);
@@ -672,6 +675,9 @@ static ssize_t ieee80211_if_parse_tsf(
int ret;
int tsf_is_delta = 0;
+ if (!ieee80211_sdata_running(sdata))
+ return -ENETDOWN;
+
if (strncmp(buf, "reset", 5) == 0) {
if (local->ops->reset_tsf) {
drv_reset_tsf(local, sdata);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 075/877] wifi: mac80211: add HE 6 GHz capability in the scan elems len
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (73 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 074/877] wifi: mac80211: dont access the TSF of a down interface Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 076/877] wifi: mac80211: mesh: reset the CSA state when leaving Greg Kroah-Hartman
` (809 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+f961b9f94edbc266f1f8,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit cd54bf333f5631d3630bab0a832e9ae648f73515 ]
The HE 6 GHz Band Capability element is in the probe request for
every band if 6 GHz is supported, so add the size to scan_ies_len.
Otherwise, building probe request elements can fail, triggering the
WARN_ON in __ieee80211_start_scan().
Assisted-by: LLM
Fixes: 2ad2274c58ee ("mac80211: Add HE 6GHz capabilities element to probe request")
Reported-by: syzbot+f961b9f94edbc266f1f8@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=f961b9f94edbc266f1f8
Link: https://patch.msgid.link/20260908122838.201719-19-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/main.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 84cc2a21a9a59..a65d49e4402ad 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1424,6 +1424,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
sizeof(struct ieee80211_he_mcs_nss_supp) +
IEEE80211_HE_PPE_THRES_MAX_LEN;
+ if (local->hw.wiphy->bands[NL80211_BAND_6GHZ])
+ local->scan_ies_len +=
+ 3 + sizeof(struct ieee80211_he_6ghz_capa);
+
if (supp_eht)
local->scan_ies_len +=
3 + sizeof(struct ieee80211_eht_cap_elem) +
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 076/877] wifi: mac80211: mesh: reset the CSA state when leaving
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (74 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 075/877] wifi: mac80211: add HE 6 GHz capability in the scan elems len Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 077/877] wifi: mac80211: mesh: release the channel if start fails Greg Kroah-Hartman
` (808 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+f5752cd6b94fe38be666,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit 860134b3af77970e006feab7e5decb8c84771c7f ]
ifmsh->csa is allocated in ieee80211_mesh_csa_beacon() and only freed
in ieee80211_mesh_finish_csa(), i.e. when the channel switch completes.
Leaving the mesh while a switch is still pending therefore leaks it.
Additionally, ifmsh->csa_role and ifmsh->chsw_ttl have their state leak
in this case, so things can get mixed up in addition to the memory
leak.
Refactor the reset and call it in ieee80211_stop_mesh() to fix it all.
Assisted-by: LLM
Reported-by: syzbot+f5752cd6b94fe38be666@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=f5752cd6b94fe38be666
Fixes: b8456a14e9d2 ("{nl,cfg,mac}80211: implement mesh channel switch userspace API")
Link: https://patch.msgid.link/20260908122838.201719-20-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/mesh.c | 29 ++++++++++++++++++-----------
1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 4c601b9cb3bb2..258c865921784 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1217,6 +1217,21 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
return 0;
}
+static void ieee80211_mesh_reset_csa(struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+ struct mesh_csa_settings *csa;
+
+ /* Reset the TTL value and Initiator flag */
+ ifmsh->csa_role = IEEE80211_MESH_CSA_ROLE_NONE;
+ ifmsh->chsw_ttl = 0;
+
+ /* Remove the CSA and MCSP elements from the beacon */
+ csa = sdata_dereference(ifmsh->csa, sdata);
+ RCU_INIT_POINTER(ifmsh->csa, NULL);
+ kfree_rcu(csa, rcu_head);
+}
+
void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
@@ -1227,6 +1242,7 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
/* abort any running channel switch */
sdata->vif.bss_conf.csa_active = false;
+ ieee80211_mesh_reset_csa(sdata);
ieee80211_vif_unblock_queues_csa(sdata);
/* flush STAs and mpaths on this iface */
@@ -1531,19 +1547,10 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata, u64 *changed)
{
- struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
- struct mesh_csa_settings *tmp_csa_settings;
- int ret = 0;
+ int ret;
- /* Reset the TTL value and Initiator flag */
- ifmsh->csa_role = IEEE80211_MESH_CSA_ROLE_NONE;
- ifmsh->chsw_ttl = 0;
+ ieee80211_mesh_reset_csa(sdata);
- /* Remove the CSA and MCSP elements from the beacon */
- tmp_csa_settings = sdata_dereference(ifmsh->csa, sdata);
- RCU_INIT_POINTER(ifmsh->csa, NULL);
- if (tmp_csa_settings)
- kfree_rcu(tmp_csa_settings, rcu_head);
ret = ieee80211_mesh_rebuild_beacon(sdata);
if (ret)
return -EINVAL;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 077/877] wifi: mac80211: mesh: release the channel if start fails
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (75 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 076/877] wifi: mac80211: mesh: reset the CSA state when leaving Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 078/877] wifi: mac80211: set up the TX info early to fix failure paths Greg Kroah-Hartman
` (807 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+63a84ea9c0f57d6133fa,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit ae97fff6495a8764bc0ef281cfe5444f701e527f ]
ieee80211_join_mesh() acquires a channel context and then calls
ieee80211_start_mesh(), which can fail. In that case, the chanctx
isn't released then interface removal will attempt to unassign it
after it's removed from the driver, hitting:
wlan0: Failed check-sdata-in-driver check, flags: 0x0
WARNING: net/mac80211/driver-ops.c:366 at drv_unassign_vif_chanctx
ieee80211_assign_link_chanctx
__ieee80211_link_release_channel
ieee80211_link_release_channel
ieee80211_teardown_sdata
unregister_netdevice_many_notify
_cfg80211_unregister_wdev
ieee80211_remove_interfaces
ieee80211_unregister_hw
mac80211_hwsim_del_radio
hwsim_exit_net
Correctly release the channel on start failures.
Assisted-by: LLM
Reported-by: syzbot+63a84ea9c0f57d6133fa@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=63a84ea9c0f57d6133fa
Fixes: 2b5e19677592 ("mac80211: cache mesh beacon")
Link: https://patch.msgid.link/20260908122838.201719-21-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/cfg.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 71310d708dbc4..73f56e4143f66 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2691,7 +2691,11 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
if (err)
return err;
- return ieee80211_start_mesh(sdata);
+ err = ieee80211_start_mesh(sdata);
+ if (err)
+ ieee80211_link_release_channel(&sdata->deflink);
+
+ return err;
}
static int ieee80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 078/877] wifi: mac80211: set up the TX info early to fix failure paths
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (76 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 077/877] wifi: mac80211: mesh: release the channel if start fails Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 079/877] mm: memblock: show all region flags in debugfs Greg Kroah-Hartman
` (806 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
[ Upstream commit 50d3d79dc0743b616afb00d01a626c76758721f7 ]
The previous commit 2c51457d930f ("wifi: mac80211: free ack status
frame on TX header build failure") cleaned up the leak, but still
left the code a bit messy and the failed SKB didn't get reported
to userspace.
Fix this up by initialising skb->cb[] earlier, which allows using
ieee80211_free_txskb() and therefore reports it for the failure
in ieee80211_build_hdr(), and unifies the ieee80211_skb_resize()
failure path with it.
Assisted-by: LLM
Fixes: c3e7724b6bc2 ("mac80211: use ieee80211_free_txskb to fix possible skb leaks")
Link: https://patch.msgid.link/20260908122838.201719-22-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/tx.c | 38 ++++++++++++++++++++------------------
1 file changed, 20 insertions(+), 18 deletions(-)
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e78e71cb92f7f..228c717ea314b 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2927,10 +2927,23 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
*/
skb = skb_share_check(skb, GFP_ATOMIC);
if (unlikely(!skb)) {
- ret = -ENOMEM;
- goto free;
+ /* skb_share_check() already freed the skb */
+ if (info_id)
+ ieee80211_remove_ack_skb(local, info_id);
+ return ERR_PTR(-ENOMEM);
}
+ /* set this up so failure paths can clean up ack skb */
+ info = IEEE80211_SKB_CB(skb);
+ memset(info, 0, sizeof(*info));
+
+ info->flags = info_flags;
+ if (info_id) {
+ info->status_data = info_id;
+ info->status_data_idr = 1;
+ }
+ info->band = band;
+
hdr.frame_control = fc;
hdr.duration_id = 0;
hdr.seq_ctrl = 0;
@@ -2969,10 +2982,8 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
head_need += local->tx_headroom;
head_need = max_t(int, 0, head_need);
if (ieee80211_skb_resize(sdata, skb, head_need, ENCRYPT_DATA)) {
- ieee80211_free_txskb(&local->hw, skb);
- skb = NULL;
ret = -ENOMEM;
- goto free;
+ goto free_txskb;
}
}
@@ -2999,16 +3010,6 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
skb_reset_mac_header(skb);
- info = IEEE80211_SKB_CB(skb);
- memset(info, 0, sizeof(*info));
-
- info->flags = info_flags;
- if (info_id) {
- info->status_data = info_id;
- info->status_data_idr = 1;
- }
- info->band = band;
-
if (likely(!cookie)) {
ctrl_flags |= u32_encode_bits(link_id,
IEEE80211_TX_CTRL_MLO_LINK);
@@ -3032,16 +3033,17 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
pre_conf_link_id, link_id);
#endif
ret = -EINVAL;
- goto free;
+ goto free_txskb;
}
}
info->control.flags = ctrl_flags;
return skb;
+ free_txskb:
+ ieee80211_free_txskb(&local->hw, skb);
+ return ERR_PTR(ret);
free:
- if (info_id)
- ieee80211_remove_ack_skb(local, info_id);
kfree_skb(skb);
return ERR_PTR(ret);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 079/877] mm: memblock: show all region flags in debugfs
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (77 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 078/877] wifi: mac80211: set up the TX info early to fix failure paths Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 080/877] scsi: qla2xxx: Fix the ql2xfc2target parameter description Greg Kroah-Hartman
` (805 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Meijing Zhao,
Mike Rapoport (Microsoft), Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Meijing Zhao <zhaomeijing@lixiang.com>
[ Upstream commit e2d5b01f878d76bd1142e512a0b979a1d3cd0abf ]
Commit 493f349e38d0 ("memblock: Add flags and nid info in memblock
debugfs") made memblock_debug_show() stop after finding the first set
flag. A memblock region can carry multiple flags, so the remaining flags
are hidden from debugfs.
Walk all bits in the region flags and print every set flag separated by
"|". Keep walking beyond flagname[] so that a set flag without a known
name is reported as UNKNOWN rather than silently ignored.
Fixes: 493f349e38d0 ("memblock: Add flags and nid info in memblock debugfs")
Signed-off-by: Meijing Zhao <zhaomeijing@lixiang.com>
Link: https://patch.msgid.link/20260902075944.3742866-1-zhaomeijing100@gmail.com
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/memblock.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/mm/memblock.c b/mm/memblock.c
index 3d7b0114442c4..00ef6bea6fe8c 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -2416,14 +2416,18 @@ static int memblock_debug_show(struct seq_file *m, void *private)
else
seq_printf(m, "%4c ", 'x');
if (reg->flags) {
- for (j = 0; j < count; j++) {
- if (reg->flags & (1U << j)) {
- seq_printf(m, "%s\n", flagname[j]);
- break;
- }
+ unsigned int flags = reg->flags;
+ bool first = true;
+
+ for (j = 0; flags; j++, flags >>= 1) {
+ if (!(flags & 1))
+ continue;
+ if (!first)
+ seq_putc(m, '|');
+ seq_puts(m, j < count ? flagname[j] : "UNKNOWN");
+ first = false;
}
- if (j == count)
- seq_printf(m, "%s\n", "UNKNOWN");
+ seq_putc(m, '\n');
} else {
seq_printf(m, "%s\n", "NONE");
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 080/877] scsi: qla2xxx: Fix the ql2xfc2target parameter description
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (78 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 079/877] mm: memblock: show all region flags in debugfs Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 081/877] dmaengine: xilinx_dma: Fix hardware buffer descriptor reuse order Greg Kroah-Hartman
` (804 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter,
Martin K. Petersen (Oracle), Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
[ Upstream commit 779f202a92ef10a426efc07d0f4267918cb07ca3 ]
The module parameter is ql2xfc2target, but its MODULE_PARM_DESC() names
qla2xfc2target, so modinfo describes a parameter that does not exist and
shows no description for the real one.
Use the parameter name in the description.
Fixes: 877b03795fcf ("scsi: qla2xxx: Add option to disable FC2 Target support")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Link: https://patch.msgid.link/20260906171009.2560-1-kmehltretter@gmail.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/qla2xxx/qla_os.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 7a78cff128cfa..e2c0c99a5b052 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -363,7 +363,7 @@ MODULE_PARM_DESC(ql2xnvme_queues,
int ql2xfc2target = 1;
module_param(ql2xfc2target, int, 0444);
-MODULE_PARM_DESC(qla2xfc2target,
+MODULE_PARM_DESC(ql2xfc2target,
"Enables FC2 Target support. "
"0 - FC2 Target support is disabled. "
"1 - FC2 Target support is enabled (default).");
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 081/877] dmaengine: xilinx_dma: Fix hardware buffer descriptor reuse order
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (79 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 080/877] scsi: qla2xxx: Fix the ql2xfc2target parameter description Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 082/877] dmaengine: xilinx_dma: Fix hardware buffer descriptor chain after cyclic DMA Greg Kroah-Hartman
` (803 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alex Bereza, Frank Li, Suraj Gupta,
Vinod Koul, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Bereza <alex@bereza.email>
[ Upstream commit cee9c863ee68cb27d66745eb03f60e357f4f8ad2 ]
xilinx_dma_alloc_chan_resources() builds a static ring of hardware
buffer descriptors once and the driver uses this ring throughout the
lifetime of a channel. This requires the allocation order of hardware
buffer descriptors from chan->free_seg_list to stay in sync with the
hardware buffer descriptor ring built at channel allocation time by
returning oldest descriptors to chan->free_seg_list first.
When chan->pending_list is not empty e.g. during
xilinx_dma_terminate_all() the chan->free_seg_list and the order of the
static hardware buffer descriptor ring get out of sync. Descriptors age
in this order: pending -> active -> done. So freeing pending_list first
returns the newest buffer descriptors to the chan->free_seg_list first
and thus breaks the order required by the static hardware buffer
descriptor ring. Then when the channel is reused, after a wrap around of
the free_seg_list the DMA will find a hardware buffer descriptor with a
length field that is still zeroed and stop with something like this:
xilinx-vdma 86000000.dma: Channel 000000003a21d7b8 has errors 10, cdr 6de4c000 tdr 6de4c000
After this no more descriptors are completed and a consumer potentially
blocks and waits forever. The only way to get out of this error state is
to rebuild the static hardware buffer descriptor ring and the
free_seg_list by releasing and re-acquiring the channel.
Fix the order in which hardware buffer descriptors are returned to
free_seg_list to ensure the mentioned requirement holds.
Fixes: 23059408b6a3 ("dmaengine: xilinx_dma: Fix race condition in the driver for multiple descriptor scenario")
Signed-off-by: Alex Bereza <alex@bereza.email>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Suraj Gupta <suraj.gupta2@amd.com>
Link: https://patch.msgid.link/20260817-fix-hw-buf-desc-reuse-v1-1-d79827a844c7@bereza.email
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/dma/xilinx/xilinx_dma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index bea55dc99673b..29ff6c8082fb1 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -917,9 +917,9 @@ static void xilinx_dma_free_descriptors(struct xilinx_dma_chan *chan)
spin_lock_irqsave(&chan->lock, flags);
- xilinx_dma_free_desc_list(chan, &chan->pending_list);
xilinx_dma_free_desc_list(chan, &chan->done_list);
xilinx_dma_free_desc_list(chan, &chan->active_list);
+ xilinx_dma_free_desc_list(chan, &chan->pending_list);
spin_unlock_irqrestore(&chan->lock, flags);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 082/877] dmaengine: xilinx_dma: Fix hardware buffer descriptor chain after cyclic DMA
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (80 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 081/877] dmaengine: xilinx_dma: Fix hardware buffer descriptor reuse order Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 083/877] RDMA/efa: Keep admin queues alive while IRQ is registered Greg Kroah-Hartman
` (802 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alex Bereza, Frank Li, Suraj Gupta,
Vinod Koul, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Bereza <alex@bereza.email>
[ Upstream commit 7ed1e3070c9b4bbd67d5519e14711038dd53ab13 ]
Using the DMA in cyclic mode modifies the hardware buffer descriptor
chain in xilinx_dma_prep_dma_cyclic so that the last descriptor used by
the cyclic transfer points back to the first descriptor, but it never
restores the original descriptor ring. This breaks using non-cyclic mode
after cyclic mode with an error like:
xilinx-vdma 86000000.dma: Channel 00000000354d5c8d has errors 100, cdr 6de40000 tdr 6de40400
The only way to get out of this error state is to rebuild the hardware
buffer descriptor ring by releasing and re-acquiring the channel.
Fix using non-cyclic mode after cyclic mode by always restoring the
original buffer descriptor ring in the same manner as it is set up by
xilinx_dma_alloc_chan_resources().
Fixes: 23059408b6a3 ("dmaengine: xilinx_dma: Fix race condition in the driver for multiple descriptor scenario")
Signed-off-by: Alex Bereza <alex@bereza.email>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Suraj Gupta <suraj.gupta2@amd.com>
Link: https://patch.msgid.link/20260817-fix-hw-buf-desc-after-cyclic-mode-v1-1-1fe47e701d6c@bereza.email
Link: https://patch.msgid.link/20260818-fix-hw-buf-desc-after-cyclic-mode-v2-1-530ff44c6a81@bereza.email
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/dma/xilinx/xilinx_dma.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 29ff6c8082fb1..4a89ad8c90a34 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -753,15 +753,25 @@ xilinx_aximcdma_alloc_tx_segment(struct xilinx_dma_chan *chan)
return segment;
}
-static void xilinx_dma_clean_hw_desc(struct xilinx_axidma_desc_hw *hw)
+static void xilinx_dma_clean_hw_desc(struct xilinx_dma_chan *chan,
+ struct xilinx_axidma_tx_segment *segment)
{
- u32 next_desc = hw->next_desc;
- u32 next_desc_msb = hw->next_desc_msb;
+ dma_addr_t next;
+ u32 i;
- memset(hw, 0, sizeof(struct xilinx_axidma_desc_hw));
+ /*
+ * Restore the buffer descriptor's next descriptor pointer to the value
+ * set up in xilinx_dma_alloc_chan_resources(). Otherwise using the DMA
+ * in cyclic mode leaves the next descriptor pointer altered and
+ * prevents subsequent non-cyclic transfers.
+ */
+ i = segment - chan->seg_v;
+ next = chan->seg_p +
+ sizeof(*chan->seg_v) * ((i + 1) % XILINX_DMA_NUM_DESCS);
- hw->next_desc = next_desc;
- hw->next_desc_msb = next_desc_msb;
+ memset(&segment->hw, 0, sizeof(segment->hw));
+ segment->hw.next_desc = lower_32_bits(next);
+ segment->hw.next_desc_msb = upper_32_bits(next);
}
static void xilinx_mcdma_clean_hw_desc(struct xilinx_aximcdma_desc_hw *hw)
@@ -783,7 +793,7 @@ static void xilinx_mcdma_clean_hw_desc(struct xilinx_aximcdma_desc_hw *hw)
static void xilinx_dma_free_tx_segment(struct xilinx_dma_chan *chan,
struct xilinx_axidma_tx_segment *segment)
{
- xilinx_dma_clean_hw_desc(&segment->hw);
+ xilinx_dma_clean_hw_desc(chan, segment);
list_add_tail(&segment->node, &chan->free_seg_list);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 083/877] RDMA/efa: Keep admin queues alive while IRQ is registered
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (81 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 082/877] dmaengine: xilinx_dma: Fix hardware buffer descriptor chain after cyclic DMA Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 084/877] RDMA/efa: Keep EQ resources " Greg Kroah-Hartman
` (801 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael Margolin, Leon Romanovsky,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leon Romanovsky <leonro@nvidia.com>
[ Upstream commit e08aca85c02ff290f785f07acae758f0daf5f49e ]
The management IRQ handler accesses both the admin completion queue and the
async event queue. The driver registered the IRQ before constructing these
queues and destroyed them before freeing the IRQ, so the handler's lifetime
was not contained by the resources it accesses.
Initialize the queues with interrupts masked, request the IRQ, and then
switch to interrupt mode. On removal, reset the device and free the IRQ
before destroying the queues. Also reset the device before destroying the
queues if IRQ registration fails, because the device already has their DMA
addresses.
Fixes: b7f5e880f377 ("RDMA/efa: Add the efa module")
Link: https://patch.msgid.link/20260907-use-after-free-of-admin-queue-struct-v1-1-dd9d9267fbf4@nvidia.com
Reviewed-by: Michael Margolin <mrgolin@amazon.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/hw/efa/efa_com.c | 4 +---
drivers/infiniband/hw/efa/efa_main.c | 15 +++++++++------
2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/infiniband/hw/efa/efa_com.c b/drivers/infiniband/hw/efa/efa_com.c
index bafd210dd43e8..d6fb2edc96891 100644
--- a/drivers/infiniband/hw/efa/efa_com.c
+++ b/drivers/infiniband/hw/efa/efa_com.c
@@ -743,7 +743,7 @@ int efa_com_admin_init(struct efa_com_dev *edev,
aq->dmadev = edev->dmadev;
aq->efa_dev = edev->efa_dev;
- set_bit(EFA_AQ_STATE_POLLING_BIT, &aq->state);
+ efa_com_set_admin_polling_mode(edev, true);
sema_init(&aq->avail_cmds, aq->depth);
@@ -761,8 +761,6 @@ int efa_com_admin_init(struct efa_com_dev *edev,
if (err)
goto err_destroy_sq;
- efa_com_set_admin_polling_mode(edev, false);
-
err = efa_com_admin_init_aenq(edev, aenq_handlers);
if (err)
goto err_destroy_cq;
diff --git a/drivers/infiniband/hw/efa/efa_main.c b/drivers/infiniband/hw/efa/efa_main.c
index 45a4564c670c0..83323a7ad7120 100644
--- a/drivers/infiniband/hw/efa/efa_main.c
+++ b/drivers/infiniband/hw/efa/efa_main.c
@@ -615,18 +615,21 @@ static struct efa_dev *efa_probe_device(struct pci_dev *pdev)
edev->aq.msix_vector_idx = dev->admin_msix_vector_idx;
edev->aenq.msix_vector_idx = dev->admin_msix_vector_idx;
- err = efa_set_mgmnt_irq(dev);
+ err = efa_com_admin_init(edev, &aenq_handlers);
if (err)
goto err_disable_msix;
- err = efa_com_admin_init(edev, &aenq_handlers);
+ err = efa_set_mgmnt_irq(dev);
if (err)
- goto err_free_mgmnt_irq;
+ goto err_destroy_admin;
+
+ efa_com_set_admin_polling_mode(edev, false);
return dev;
-err_free_mgmnt_irq:
- efa_free_irq(dev, &dev->admin_irq);
+err_destroy_admin:
+ efa_com_dev_reset(edev, EFA_REGS_RESET_INIT_ERR);
+ efa_com_admin_destroy(edev);
err_disable_msix:
efa_disable_msix(dev);
err_reg_read_destroy:
@@ -650,8 +653,8 @@ static void efa_remove_device(struct pci_dev *pdev,
edev = &dev->edev;
efa_com_dev_reset(edev, reset_reason);
- efa_com_admin_destroy(edev);
efa_free_irq(dev, &dev->admin_irq);
+ efa_com_admin_destroy(edev);
efa_disable_msix(dev);
efa_com_mmio_reg_read_destroy(edev);
devm_iounmap(&pdev->dev, edev->reg_bar);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 084/877] RDMA/efa: Keep EQ resources alive while IRQ is registered
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (82 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 083/877] RDMA/efa: Keep admin queues alive while IRQ is registered Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 085/877] RDMA/siw: Bound fragmented header copies by the remaining length Greg Kroah-Hartman
` (800 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael Margolin, Leon Romanovsky,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leon Romanovsky <leonro@nvidia.com>
[ Upstream commit e22a3627b7151754f07f90ea3d1ab6e85f5d93f4 ]
The completion IRQ handler accesses the EQ state and DMA buffer. Its IRQ was
registered before that state was initialized, while teardown released the
buffer before free_irq() synchronized the handler.
Initialize the EQ without arming it, register the IRQ, and then arm it.
Reverse the resource order during teardown by freeing the IRQ before
destroying the EQ.
Fixes: 2a152512a155 ("RDMA/efa: CQ notifications")
Link: https://patch.msgid.link/20260907-use-after-free-of-admin-queue-struct-v1-2-dd9d9267fbf4@nvidia.com
Reviewed-by: Michael Margolin <mrgolin@amazon.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/hw/efa/efa_com.c | 3 +--
drivers/infiniband/hw/efa/efa_com.h | 1 +
drivers/infiniband/hw/efa/efa_main.c | 18 ++++++++++--------
3 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/drivers/infiniband/hw/efa/efa_com.c b/drivers/infiniband/hw/efa/efa_com.c
index d6fb2edc96891..00e339abc2c13 100644
--- a/drivers/infiniband/hw/efa/efa_com.c
+++ b/drivers/infiniband/hw/efa/efa_com.c
@@ -1149,7 +1149,7 @@ static void efa_com_destroy_eq(struct efa_com_dev *edev,
err);
}
-static void efa_com_arm_eq(struct efa_com_dev *edev, struct efa_com_eq *eeq)
+void efa_com_arm_eq(struct efa_com_dev *edev, struct efa_com_eq *eeq)
{
u32 val = 0;
@@ -1238,7 +1238,6 @@ int efa_com_eq_init(struct efa_com_dev *edev, struct efa_com_eq *eeq,
eeq->phase = 1;
eeq->depth = params.depth;
eeq->cb = cb;
- efa_com_arm_eq(edev, eeq);
return 0;
diff --git a/drivers/infiniband/hw/efa/efa_com.h b/drivers/infiniband/hw/efa/efa_com.h
index 77282234ce686..29a9d087db5d9 100644
--- a/drivers/infiniband/hw/efa/efa_com.h
+++ b/drivers/infiniband/hw/efa/efa_com.h
@@ -157,6 +157,7 @@ int efa_com_admin_init(struct efa_com_dev *edev,
void efa_com_admin_destroy(struct efa_com_dev *edev);
int efa_com_eq_init(struct efa_com_dev *edev, struct efa_com_eq *eeq,
efa_eqe_handler cb, u16 depth, u8 msix_vec);
+void efa_com_arm_eq(struct efa_com_dev *edev, struct efa_com_eq *eeq);
void efa_com_eq_destroy(struct efa_com_dev *edev, struct efa_com_eq *eeq);
int efa_com_dev_reset(struct efa_com_dev *edev,
enum efa_regs_reset_reason_types reset_reason);
diff --git a/drivers/infiniband/hw/efa/efa_main.c b/drivers/infiniband/hw/efa/efa_main.c
index 83323a7ad7120..30cefd0bb4f56 100644
--- a/drivers/infiniband/hw/efa/efa_main.c
+++ b/drivers/infiniband/hw/efa/efa_main.c
@@ -301,28 +301,30 @@ static void efa_set_host_info(struct efa_dev *dev)
static void efa_destroy_eq(struct efa_dev *dev, struct efa_eq *eq)
{
- efa_com_eq_destroy(&dev->edev, &eq->eeq);
efa_free_irq(dev, &eq->irq);
+ efa_com_eq_destroy(&dev->edev, &eq->eeq);
}
static int efa_create_eq(struct efa_dev *dev, struct efa_eq *eq, u8 msix_vec)
{
int err;
- efa_setup_comp_irq(dev, eq, msix_vec);
- err = efa_request_irq(dev, &eq->irq);
+ err = efa_com_eq_init(&dev->edev, &eq->eeq, efa_process_eqe,
+ dev->dev_attr.max_eq_depth, msix_vec);
if (err)
return err;
- err = efa_com_eq_init(&dev->edev, &eq->eeq, efa_process_eqe,
- dev->dev_attr.max_eq_depth, msix_vec);
+ efa_setup_comp_irq(dev, eq, msix_vec);
+ err = efa_request_irq(dev, &eq->irq);
if (err)
- goto err_free_comp_irq;
+ goto err_destroy_eq;
+
+ efa_com_arm_eq(&dev->edev, &eq->eeq);
return 0;
-err_free_comp_irq:
- efa_free_irq(dev, &eq->irq);
+err_destroy_eq:
+ efa_com_eq_destroy(&dev->edev, &eq->eeq);
return err;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 085/877] RDMA/siw: Bound fragmented header copies by the remaining length
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (83 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 084/877] RDMA/efa: Keep EQ resources " Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 086/877] netfilter: nft_nat: fully initialise new_addr in netmap setup Greg Kroah-Hartman
` (799 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jérémy Jean,
Bernard Metzler, Leon Romanovsky, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
[ Upstream commit 9ff797e516dbc1ecb73701ec4c24055712d44411 ]
siw_get_hdr() can receive an extended DDP/RDMAP header across more than
one TCP callback. The first callback may receive most of the header,
while the next one still limits the copy to hdrlen - MIN_DDP_HDR instead
of the number of missing bytes. This makes the destination move past the
end of the header and overwrite the receive state, including
fpdu_part_rcvd. A later callback can then use a negative fpdu_part_rcvd
value as a copy offset, which creates an OOB write.
Use the number of header bytes already received when calculating the
next copy length.
Fixes: 754209850df8 ("RDMA/siw: Always consume all skbuf data in sk_data_ready() upcall.")
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Link: https://patch.msgid.link/20260908085520.1746329-1-Jeremy.Jean@oss.cyber.gouv.fr
Assisted-by: Codex:gpt-6
Acked-by: Bernard Metzler <bernard.metzler@linux.dev>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/infiniband/sw/siw/siw_qp_rx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/infiniband/sw/siw/siw_qp_rx.c b/drivers/infiniband/sw/siw/siw_qp_rx.c
index ad281da44cb49..4db245748af0b 100644
--- a/drivers/infiniband/sw/siw/siw_qp_rx.c
+++ b/drivers/infiniband/sw/siw/siw_qp_rx.c
@@ -1079,7 +1079,7 @@ static int siw_get_hdr(struct siw_rx_stream *srx)
if (iwarp_pktinfo[opcode].hdr_len > sizeof(struct iwarp_ctrl_tagged)) {
int hdrlen = iwarp_pktinfo[opcode].hdr_len;
- bytes = min_t(int, hdrlen - MIN_DDP_HDR, srx->skb_new);
+ bytes = min_t(int, hdrlen - srx->fpdu_part_rcvd, srx->skb_new);
skb_copy_bits(skb, srx->skb_offset,
(char *)c_hdr + srx->fpdu_part_rcvd, bytes);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 086/877] netfilter: nft_nat: fully initialise new_addr in netmap setup
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (84 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 085/877] RDMA/siw: Bound fragmented header copies by the remaining length Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 087/877] netfilter: flowtable: hold reference on ct until flow is released Greg Kroah-Hartman
` (798 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Theodor Arsenij Larionov Trichkine,
Pablo Neira Ayuso, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodor Arsenij Larionov Trichkine <theodorlarionov@gmail.com>
[ Upstream commit d313499df66159b4b7971d760d16729598ab7e5a ]
nft_nat_setup_netmap() builds the mapped address in an on-stack
union nf_inet_addr. For an IPv4 mapping it writes only the 4-byte .ip
member and the loop runs a single 32-bit iteration, but it then copies
the whole 16-byte union into range->min_addr and range->max_addr, so the
upper 12 bytes reach nf_nat_setup_info() uninitialised.
KMSAN reports an uninit-value in nf_nat_setup_info() reached from
nft_nat_eval(). The IPv6 path fills all 16 bytes and is not affected.
Zero-initialise new_addr.
Fixes: 3ff7ddb1353d ("netfilter: nft_nat: add netmap support")
Signed-off-by: Theodor Arsenij Larionov Trichkine <theodorlarionov@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/nft_nat.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c
index e32cd9fbc7c2e..cdbd800cac969 100644
--- a/net/netfilter/nft_nat.c
+++ b/net/netfilter/nft_nat.c
@@ -64,8 +64,8 @@ static void nft_nat_setup_netmap(struct nf_nat_range2 *range,
const struct nft_pktinfo *pkt,
const struct nft_nat *priv)
{
+ union nf_inet_addr new_addr = {};
struct sk_buff *skb = pkt->skb;
- union nf_inet_addr new_addr;
__be32 netmask;
int i, len = 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 087/877] netfilter: flowtable: hold reference on ct until flow is released
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (85 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 086/877] netfilter: nft_nat: fully initialise new_addr in netmap setup Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 088/877] perf/arm-cmn: Fix wp_dev_sel2 setting for multi-DTM configurations Greg Kroah-Hartman
` (797 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Pablo Neira Ayuso, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <pablo@netfilter.org>
[ Upstream commit e75a9fa1d44bcbd66ea02e8781bcca6ea4076e0d ]
nf_ct_put() releases the ct->ext area inmediately, the rcu typesafe
semantics also allow to refer to the wrong conntrack from the flowtable
datapath. Hold reference on ct until flow is released after rcu grace
period.
Add rcu_barrier() on module exit path, to ensure pending flow entries
are release before module goes away.
Fixes: 0ff90b6c2034 ("netfilter: nf_flow_offload: fix use-after-free and a resource leak")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/nf_flow_table_core.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c
index b9e3ac950894f..b00f1c68a8e76 100644
--- a/net/netfilter/nf_flow_table_core.c
+++ b/net/netfilter/nf_flow_table_core.c
@@ -205,6 +205,14 @@ static void flow_offload_route_release(struct flow_offload *flow)
nft_flow_dst_release(flow, FLOW_OFFLOAD_DIR_REPLY);
}
+static void flow_offload_free_rcu(struct rcu_head *rcu_head)
+{
+ struct flow_offload *flow = container_of(rcu_head, struct flow_offload, rcu_head);
+
+ nf_ct_put(flow->ct);
+ kfree(flow);
+}
+
void flow_offload_free(struct flow_offload *flow)
{
switch (flow->type) {
@@ -214,8 +222,7 @@ void flow_offload_free(struct flow_offload *flow)
default:
break;
}
- nf_ct_put(flow->ct);
- kfree_rcu(flow, rcu_head);
+ call_rcu(&flow->rcu_head, flow_offload_free_rcu);
}
EXPORT_SYMBOL_GPL(flow_offload_free);
@@ -686,6 +693,7 @@ static int __init nf_flow_table_module_init(void)
static void __exit nf_flow_table_module_exit(void)
{
+ rcu_barrier();
nf_flow_table_offload_exit();
unregister_pernet_subsys(&nf_flow_table_net_ops);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 088/877] perf/arm-cmn: Fix wp_dev_sel2 setting for multi-DTM configurations
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (86 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 087/877] netfilter: flowtable: hold reference on ct until flow is released Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 089/877] arm64: hibernate: clone only the linear map that exists at runtime Greg Kroah-Hartman
` (796 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shouping Wang, Robin Murphy,
Will Deacon, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shouping Wang <allen.wang@hj-micro.com>
[ Upstream commit 49daa3d668b69a5454b5aba0078848a479f79f1c ]
When MXP_MULTIPLE_DTM_EN is TRUE, each DTM will monitor at most
two device ports. In this case, {wp_dev_sel2, wp_dev_sel} will
only use values 2'b00 and 2'b01 per DTM.
Previously the setting allowed values beyond the supported range
per DTM, which could cause each DTM to select invalid ports when
MXP_MULTIPLE_DTM_EN is TRUE.
Fix this by only setting CMN_DTM_WPn_CONFIG_WP_DEV_SEL2 when
!multi_dtm.
Fixes: 60d1504070c2 ("perf/arm-cmn: Support new IP features")
Signed-off-by: Shouping Wang <allen.wang@hj-micro.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/perf/arm-cmn.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
index 892bc6b5875a7..3a4541c51863b 100644
--- a/drivers/perf/arm-cmn.c
+++ b/drivers/perf/arm-cmn.c
@@ -1395,13 +1395,14 @@ static void arm_cmn_claim_wp_idx(struct arm_cmn_dtm *dtm,
static u32 arm_cmn_wp_config(struct perf_event *event, int wp_idx)
{
+ struct arm_cmn *cmn = to_cmn(event->pmu);
u32 config;
u32 dev = CMN_EVENT_WP_DEV_SEL(event);
u32 chn = CMN_EVENT_WP_CHN_SEL(event);
u32 grp = CMN_EVENT_WP_GRP(event);
u32 exc = CMN_EVENT_WP_EXCLUSIVE(event);
u32 combine = CMN_EVENT_WP_COMBINE(event);
- bool is_cmn600 = to_cmn(event->pmu)->part == PART_CMN600;
+ bool is_cmn600 = cmn->part == PART_CMN600;
/* CMN-600 supports only primary and secondary matching groups */
if (is_cmn600)
@@ -1409,8 +1410,11 @@ static u32 arm_cmn_wp_config(struct perf_event *event, int wp_idx)
config = FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_DEV_SEL, dev) |
FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_CHN_SEL, chn) |
- FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_GRP, grp) |
- FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_DEV_SEL2, dev >> 1);
+ FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_GRP, grp);
+
+ if (!cmn->multi_dtm)
+ config |= FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_DEV_SEL2, dev >> 1);
+
if (exc)
config |= is_cmn600 ? CMN600_WPn_CONFIG_WP_EXCLUSIVE :
CMN_DTM_WPn_CONFIG_WP_EXCLUSIVE;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 089/877] arm64: hibernate: clone only the linear map that exists at runtime
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (87 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 088/877] perf/arm-cmn: Fix wp_dev_sel2 setting for multi-DTM configurations Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 090/877] drm: Fix drm_pending_vblank_event leak in error path for out_fence_ptr Greg Kroah-Hartman
` (795 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Breno Leitao, Ard Biesheuvel,
Will Deacon, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <leitao@debian.org>
[ Upstream commit e4a6f57d22e079e23fafac51057fad534160b269 ]
This is similar to commit 1537e55728ec2 ("arm64: trans_pgd: clone only
the linear map that exists at runtime"), but in a different place.
swsusp_arch_resume() clones the kernel linear map with
trans_pgd_create_copy(..., PAGE_OFFSET, PAGE_END). PAGE_OFFSET comes
from the compile-time VA_BITS, so a CONFIG_ARM64_VA_BITS_52 kernel
booting on hardware without LPA2 -- vabits_actual is 48 and the fifth
level is folded -- hands the walk a 3.9PB window while its linear map
only spans the top 128TB.
On a VA_BITS_52 4k kernel with CONFIG_KASAN_GENERIC in a 4GB VM, I see:
swapper/0: page allocation failure: order:0, mode:0x920(GFP_ATOMIC|__GFP_ZERO)
hibernate_page_alloc+0x10/0x1c
swsusp_arch_resume+0x70/0x320
hibernation_restore+0xa4/0x138
software_resume+0x15c/0x270
PM: hibernation: Failed to load image, recovering.
PM: hibernation: resume failed (-12)
Fix it by copying the linear map that is the actual one, not the
compiled one.
Fixes: a6bbf5d4d9d1 ("arm64: mm: Add definitions to support 5 levels of paging")
Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kernel/hibernate.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
index 44d31b019efd5..b883f6d833b6b 100644
--- a/arch/arm64/kernel/hibernate.c
+++ b/arch/arm64/kernel/hibernate.c
@@ -417,8 +417,8 @@ int __nocfi swsusp_arch_resume(void)
* Create a second copy of just the linear map, and use this when
* restoring.
*/
- rc = trans_pgd_create_copy(&trans_info, &tmp_pg_dir, PAGE_OFFSET,
- PAGE_END);
+ rc = trans_pgd_create_copy(&trans_info, &tmp_pg_dir,
+ _PAGE_OFFSET(vabits_actual), PAGE_END);
if (rc)
return rc;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 090/877] drm: Fix drm_pending_vblank_event leak in error path for out_fence_ptr
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (88 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 089/877] arm64: hibernate: clone only the linear map that exists at runtime Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 091/877] keys: fix lost wakeup when reaping a dead key type Greg Kroah-Hartman
` (794 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, sashiko-bot,
Thadeu Lima de Souza Cascardo, Melissa Wen, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
[ Upstream commit 9eb1a393c89a79c4210230d23e7d88d239c61d7b ]
When an out_fence_ptr is provided but DRM_MODE_PAGE_FLIP_EVENT is not
set, a drm_pending_vblank_event will be allocated. If later, there is an
allocation failure or another failure at setup_out_fence(), that event
will not have base.fence set and it will not be released at
complete_signaling().
Release the event and set crtc_state->event to NULL just like in the
DRM_MODE_PAGE_FLIP_EVENT case when there is a failure at
drm_event_reserve_init(). That is, prepare_signaling() releases the
event and there is nothing to be done at complete_signaling(). Use
drm_event_cancel_free() as that will also undo drm_event_reserve_init()
in case it has been called.
Reported-by: sashiko-bot@kernel.org
Closes: https://sashiko.dev/#/patchset/20260727-drm_crtc_atomic_commit_leak-v1-1-23d9948a9d7c@igalia.com?part=1
Fixes: 92c715fca907 ("drm/atomic: Fix double free in drm_atomic_state_default_clear")
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
Reviewed-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
Link: https://patch.msgid.link/20260826-drm_pending_vblank_event_leak-v4-1-f8de8b996b9d@igalia.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/drm_atomic_uapi.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index fc20b039bed40..02255296cc576 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -1225,10 +1225,12 @@ static int prepare_signaling(struct drm_device *dev,
struct dma_fence *fence;
struct drm_out_fence_state *f;
+ ret = -ENOMEM;
+
f = krealloc(*fence_state, sizeof(**fence_state) *
(*num_fences + 1), GFP_KERNEL);
if (!f)
- return -ENOMEM;
+ goto err_free_event;
memset(&f[*num_fences], 0, sizeof(*f));
@@ -1237,12 +1239,12 @@ static int prepare_signaling(struct drm_device *dev,
fence = drm_crtc_create_fence(crtc);
if (!fence)
- return -ENOMEM;
+ goto err_free_event;
ret = setup_out_fence(&f[(*num_fences)++], fence);
if (ret) {
dma_fence_put(fence);
- return ret;
+ goto err_free_event;
}
crtc_state->event->base.fence = fence;
@@ -1298,6 +1300,11 @@ static int prepare_signaling(struct drm_device *dev,
}
return 0;
+
+err_free_event:
+ drm_event_cancel_free(dev, &crtc_state->event->base);
+ crtc_state->event = NULL;
+ return ret;
}
static void complete_signaling(struct drm_device *dev,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 091/877] keys: fix lost wakeup when reaping a dead key type
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (89 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 090/877] drm: Fix drm_pending_vblank_event leak in error path for out_fence_ptr Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 092/877] neighbour: Use rtnl_register_many() Greg Kroah-Hartman
` (793 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Jarkko Sakkinen,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
[ Upstream commit 2725ab3f5ad1c5f375c7c9fee4af02a9b138f701 ]
clear_bit() is atomic with respect to the word it modifies, but it is
an unordered operation: it implies no memory barrier on either side
(Documentation/atomic_bitops.txt).
key_garbage_collector() clears KEY_GC_REAPING_KEYTYPE with clear_bit()
and calls wake_up_bit() after reaping a dead key type. wake_up_bit()
uses a lockless waitqueue check and requires a full barrier after the
clear.
The existing smp_mb() is before clear_bit(), so nothing orders the clear
against that check. The GC can see an empty waitqueue while
unregister_key_type() still sees the bit set. The final wakeup is then
lost, leaving module unload stuck in wait_on_bit().
Use clear_and_wake_up_bit(). Its clear_bit_unlock() has RELEASE
semantics, so the completed GC work stays ordered before the clear, and
its smp_mb__after_atomic() orders the clear before the waitqueue check.
Fixes: 0c061b5707ab ("KEYS: Correctly destroy key payloads when their keytype is removed")
Assisted-by: Claude:claude-fable-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Link: https://lore.kernel.org/r/20260821025327.61488-1-kmehltretter@gmail.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
security/keys/gc.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/security/keys/gc.c b/security/keys/gc.c
index f27223ea4578f..cf71b26c0c008 100644
--- a/security/keys/gc.c
+++ b/security/keys/gc.c
@@ -318,9 +318,7 @@ static void key_garbage_collector(struct work_struct *work)
if (unlikely(gc_state & KEY_GC_REAPING_DEAD_3)) {
kdebug("dead wake");
- smp_mb();
- clear_bit(KEY_GC_REAPING_KEYTYPE, &key_gc_flags);
- wake_up_bit(&key_gc_flags, KEY_GC_REAPING_KEYTYPE);
+ clear_and_wake_up_bit(KEY_GC_REAPING_KEYTYPE, &key_gc_flags);
}
if (gc_state & KEY_GC_REAP_AGAIN)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 092/877] neighbour: Use rtnl_register_many().
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (90 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 091/877] keys: fix lost wakeup when reaping a dead key type Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-10-01 19:19 ` Harshit Mogalapalli
2026-09-30 15:16 ` [PATCH 6.12 093/877] neighbour: Make neigh_valid_get_req() return ndmsg Greg Kroah-Hartman
` (792 subsequent siblings)
884 siblings, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Eric Dumazet,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@amazon.com>
[ Upstream commit d0d14aef50a6184426c5a05b9815fb2697d6d42c ]
We will remove rtnl_register() in favour of rtnl_register_many().
When it succeeds, rtnl_register_many() guarantees all rtnetlink types
in the passed array are supported, and there is no chance that a part
of message types is not supported.
Let's use rtnl_register_many() instead.
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20241014201828.91221-4-kuniyu@amazon.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/neighbour.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index bf07438d6dfa5..1dd9f85b74997 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -3898,17 +3898,18 @@ EXPORT_SYMBOL(neigh_sysctl_unregister);
#endif /* CONFIG_SYSCTL */
+static const struct rtnl_msg_handler neigh_rtnl_msg_handlers[] __initconst = {
+ {.msgtype = RTM_NEWNEIGH, .doit = neigh_add},
+ {.msgtype = RTM_DELNEIGH, .doit = neigh_delete},
+ {.msgtype = RTM_GETNEIGH, .doit = neigh_get, .dumpit = neigh_dump_info,
+ .flags = RTNL_FLAG_DUMP_UNLOCKED},
+ {.msgtype = RTM_GETNEIGHTBL, .dumpit = neightbl_dump_info},
+ {.msgtype = RTM_SETNEIGHTBL, .doit = neightbl_set},
+};
+
static int __init neigh_init(void)
{
- rtnl_register(PF_UNSPEC, RTM_NEWNEIGH, neigh_add, NULL, 0);
- rtnl_register(PF_UNSPEC, RTM_DELNEIGH, neigh_delete, NULL, 0);
- rtnl_register(PF_UNSPEC, RTM_GETNEIGH, neigh_get, neigh_dump_info,
- RTNL_FLAG_DUMP_UNLOCKED);
-
- rtnl_register(PF_UNSPEC, RTM_GETNEIGHTBL, NULL, neightbl_dump_info,
- 0);
- rtnl_register(PF_UNSPEC, RTM_SETNEIGHTBL, neightbl_set, NULL, 0);
-
+ rtnl_register_many(neigh_rtnl_msg_handlers);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 092/877] neighbour: Use rtnl_register_many().
2026-09-30 15:16 ` [PATCH 6.12 092/877] neighbour: Use rtnl_register_many() Greg Kroah-Hartman
@ 2026-10-01 19:19 ` Harshit Mogalapalli
2026-10-02 8:48 ` Greg Kroah-Hartman
2026-10-02 21:10 ` Sasha Levin
0 siblings, 2 replies; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-01 19:19 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, Kuniyuki Iwashima, Eric Dumazet, Jakub Kicinski,
Sasha Levin
On 30/09/26 8:46 pm, Greg Kroah-Hartman wrote:
> 6.12-stable review patch. If anyone has any objections, please let me know.
>
> ------------------
>
> From: Kuniyuki Iwashima <kuniyu@amazon.com>
>
> [ Upstream commit d0d14aef50a6184426c5a05b9815fb2697d6d42c ]
>
> We will remove rtnl_register() in favour of rtnl_register_many().
>
> When it succeeds, rtnl_register_many() guarantees all rtnetlink types
> in the passed array are supported, and there is no chance that a part
> of message types is not supported.
>
> Let's use rtnl_register_many() instead.
>
> Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
> Reviewed-by: Eric Dumazet <edumazet@google.com>
> Link: https://patch.msgid.link/20241014201828.91221-4-kuniyu@amazon.com
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---
> net/core/neighbour.c | 19 ++++++++++---------
> 1 file changed, 10 insertions(+), 9 deletions(-)
>
> diff --git a/net/core/neighbour.c b/net/core/neighbour.c
> index bf07438d6dfa5..1dd9f85b74997 100644
> --- a/net/core/neighbour.c
> +++ b/net/core/neighbour.c
> @@ -3898,17 +3898,18 @@ EXPORT_SYMBOL(neigh_sysctl_unregister);
>
> #endif /* CONFIG_SYSCTL */
>
> +static const struct rtnl_msg_handler neigh_rtnl_msg_handlers[] __initconst = {
> + {.msgtype = RTM_NEWNEIGH, .doit = neigh_add},
> + {.msgtype = RTM_DELNEIGH, .doit = neigh_delete},
> + {.msgtype = RTM_GETNEIGH, .doit = neigh_get, .dumpit = neigh_dump_info,
> + .flags = RTNL_FLAG_DUMP_UNLOCKED},
> + {.msgtype = RTM_GETNEIGHTBL, .dumpit = neightbl_dump_info},
> + {.msgtype = RTM_SETNEIGHTBL, .doit = neightbl_set},
> +};
> +
I ran an AI-assisted backport review and it flagged this; I
independently checked the upstream code and 6.12.y at f4ffa8dc360b.
Upstream __rtnl_register_many() at
d0d14aef50a6184426c5a05b9815fb2697d6d42c, net/core/rtnetlink.c:
if (err) {
if (!handler->owner)
panic("Unable to register rtnetlink message "
"handlers, %pS\n", handlers);
__rtnl_unregister_many(handlers, i);
break;
}
6.12.y's net/core/rtnetlink.c:
if (err) {
__rtnl_unregister_many(handlers, i);
break;
}
neigh_init() ignores the helper's return value. On allocation failure,
the helper rolls back the batch, so boot can continue with none of the
five neighbour handlers. Previously, failures were logged and the
other registrations continued. This boot-time failure path remains at
the review tip; upstream makes failed built-in registration fatal.
I think 6.12 should take 09aec57d8379f14ffde566621b920d97cc0c46e1
("rtnetlink: Panic when __rtnl_register_many() fails for builtin
callers.") before this conversion so the ignored failure cannot silently
continue, thoughts?
Lets drop this until we also take a prereq ?
thanks,
Harshit
> static int __init neigh_init(void)
> {
> - rtnl_register(PF_UNSPEC, RTM_NEWNEIGH, neigh_add, NULL, 0);
> - rtnl_register(PF_UNSPEC, RTM_DELNEIGH, neigh_delete, NULL, 0);
> - rtnl_register(PF_UNSPEC, RTM_GETNEIGH, neigh_get, neigh_dump_info,
> - RTNL_FLAG_DUMP_UNLOCKED);
> -
> - rtnl_register(PF_UNSPEC, RTM_GETNEIGHTBL, NULL, neightbl_dump_info,
> - 0);
> - rtnl_register(PF_UNSPEC, RTM_SETNEIGHTBL, neightbl_set, NULL, 0);
> -
> + rtnl_register_many(neigh_rtnl_msg_handlers);
> return 0;
> }
>
^ permalink raw reply [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 092/877] neighbour: Use rtnl_register_many().
2026-10-01 19:19 ` Harshit Mogalapalli
@ 2026-10-02 8:48 ` Greg Kroah-Hartman
2026-10-02 21:10 ` Sasha Levin
1 sibling, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-02 8:48 UTC (permalink / raw)
To: Harshit Mogalapalli
Cc: stable, patches, Kuniyuki Iwashima, Eric Dumazet, Jakub Kicinski,
Sasha Levin
On Fri, Oct 02, 2026 at 12:49:41AM +0530, Harshit Mogalapalli wrote:
>
>
> On 30/09/26 8:46 pm, Greg Kroah-Hartman wrote:
> > 6.12-stable review patch. If anyone has any objections, please let me know.
> >
> > ------------------
> >
> > From: Kuniyuki Iwashima <kuniyu@amazon.com>
> >
> > [ Upstream commit d0d14aef50a6184426c5a05b9815fb2697d6d42c ]
> >
> > We will remove rtnl_register() in favour of rtnl_register_many().
> >
> > When it succeeds, rtnl_register_many() guarantees all rtnetlink types
> > in the passed array are supported, and there is no chance that a part
> > of message types is not supported.
> >
> > Let's use rtnl_register_many() instead.
> >
> > Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
> > Reviewed-by: Eric Dumazet <edumazet@google.com>
> > Link: https://patch.msgid.link/20241014201828.91221-4-kuniyu@amazon.com
> > Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> > Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
> > Signed-off-by: Sasha Levin <sashal@kernel.org>
> > ---
> > net/core/neighbour.c | 19 ++++++++++---------
> > 1 file changed, 10 insertions(+), 9 deletions(-)
> >
> > diff --git a/net/core/neighbour.c b/net/core/neighbour.c
> > index bf07438d6dfa5..1dd9f85b74997 100644
> > --- a/net/core/neighbour.c
> > +++ b/net/core/neighbour.c
> > @@ -3898,17 +3898,18 @@ EXPORT_SYMBOL(neigh_sysctl_unregister);
> > #endif /* CONFIG_SYSCTL */
> > +static const struct rtnl_msg_handler neigh_rtnl_msg_handlers[] __initconst = {
> > + {.msgtype = RTM_NEWNEIGH, .doit = neigh_add},
> > + {.msgtype = RTM_DELNEIGH, .doit = neigh_delete},
> > + {.msgtype = RTM_GETNEIGH, .doit = neigh_get, .dumpit = neigh_dump_info,
> > + .flags = RTNL_FLAG_DUMP_UNLOCKED},
> > + {.msgtype = RTM_GETNEIGHTBL, .dumpit = neightbl_dump_info},
> > + {.msgtype = RTM_SETNEIGHTBL, .doit = neightbl_set},
> > +};
> > +
>
> I ran an AI-assisted backport review and it flagged this; I independently
> checked the upstream code and 6.12.y at f4ffa8dc360b.
>
> Upstream __rtnl_register_many() at
> d0d14aef50a6184426c5a05b9815fb2697d6d42c, net/core/rtnetlink.c:
>
> if (err) {
> if (!handler->owner)
> panic("Unable to register rtnetlink message "
> "handlers, %pS\n", handlers);
>
> __rtnl_unregister_many(handlers, i);
> break;
> }
>
> 6.12.y's net/core/rtnetlink.c:
>
> if (err) {
> __rtnl_unregister_many(handlers, i);
> break;
> }
>
> neigh_init() ignores the helper's return value. On allocation failure,
> the helper rolls back the batch, so boot can continue with none of the
> five neighbour handlers. Previously, failures were logged and the
> other registrations continued. This boot-time failure path remains at
> the review tip; upstream makes failed built-in registration fatal.
>
> I think 6.12 should take 09aec57d8379f14ffde566621b920d97cc0c46e1
> ("rtnetlink: Panic when __rtnl_register_many() fails for builtin
> callers.") before this conversion so the ignored failure cannot silently
> continue, thoughts?
>
> Lets drop this until we also take a prereq ?
I've dropped the whole series now, thanks.
greg k-h
^ permalink raw reply [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 092/877] neighbour: Use rtnl_register_many().
2026-10-01 19:19 ` Harshit Mogalapalli
2026-10-02 8:48 ` Greg Kroah-Hartman
@ 2026-10-02 21:10 ` Sasha Levin
2026-10-02 21:23 ` Harshit Mogalapalli
1 sibling, 1 reply; 922+ messages in thread
From: Sasha Levin @ 2026-10-02 21:10 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: Sasha Levin, patches, Kuniyuki Iwashima, Eric Dumazet,
Jakub Kicinski, Harshit Mogalapalli
> > Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
[...]
> Lets drop this until we also take a prereq ?
Greg dropped the series. I've queued the neightbl_dump_info() fix by
itself for 6.12, thanks.
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 092/877] neighbour: Use rtnl_register_many().
2026-10-02 21:10 ` Sasha Levin
@ 2026-10-02 21:23 ` Harshit Mogalapalli
0 siblings, 0 replies; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-02 21:23 UTC (permalink / raw)
To: Sasha Levin, Greg Kroah-Hartman, stable
Cc: patches, Kuniyuki Iwashima, Eric Dumazet, Jakub Kicinski
On 03/10/26 2:40 am, Sasha Levin wrote:
>>> Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
>
> [...]
>
>> Lets drop this until we also take a prereq ?
>
> Greg dropped the series. I've queued the neightbl_dump_info() fix by
> itself for 6.12, thanks.
thanks Sasha.
Regards,
Harshit>
^ permalink raw reply [flat|nested] 922+ messages in thread
* [PATCH 6.12 093/877] neighbour: Make neigh_valid_get_req() return ndmsg.
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (91 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 092/877] neighbour: Use rtnl_register_many() Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 094/877] neighbour: Move two validations from neigh_get() to neigh_valid_get_req() Greg Kroah-Hartman
` (791 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Jakub Kicinski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit caf0a753a8eb7ca2b035e199b71a3dabb853a18a ]
neigh_get() passes 4 local variable pointers to neigh_valid_get_req().
If it returns a pointer of struct ndmsg, we do not need to pass two
of them.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20250716221221.442239-2-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/neighbour.c | 43 +++++++++++++++++++------------------------
1 file changed, 19 insertions(+), 24 deletions(-)
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 1dd9f85b74997..fe921f8cc81c1 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2911,10 +2911,9 @@ static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
return err;
}
-static int neigh_valid_get_req(const struct nlmsghdr *nlh,
- struct neigh_table **tbl,
- void **dst, int *dev_idx, u8 *ndm_flags,
- struct netlink_ext_ack *extack)
+static struct ndmsg *neigh_valid_get_req(const struct nlmsghdr *nlh,
+ struct neigh_table **tbl, void **dst,
+ struct netlink_ext_ack *extack)
{
struct nlattr *tb[NDA_MAX + 1];
struct ndmsg *ndm;
@@ -2922,32 +2921,30 @@ static int neigh_valid_get_req(const struct nlmsghdr *nlh,
if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ndm))) {
NL_SET_ERR_MSG(extack, "Invalid header for neighbor get request");
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
}
ndm = nlmsg_data(nlh);
if (ndm->ndm_pad1 || ndm->ndm_pad2 || ndm->ndm_state ||
ndm->ndm_type) {
NL_SET_ERR_MSG(extack, "Invalid values in header for neighbor get request");
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
}
if (ndm->ndm_flags & ~NTF_PROXY) {
NL_SET_ERR_MSG(extack, "Invalid flags in header for neighbor get request");
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
}
err = nlmsg_parse_deprecated_strict(nlh, sizeof(struct ndmsg), tb,
NDA_MAX, nda_policy, extack);
if (err < 0)
- return err;
+ return ERR_PTR(err);
- *ndm_flags = ndm->ndm_flags;
- *dev_idx = ndm->ndm_ifindex;
*tbl = neigh_find_table(ndm->ndm_family);
- if (*tbl == NULL) {
+ if (!*tbl) {
NL_SET_ERR_MSG(extack, "Unsupported family in header for neighbor get request");
- return -EAFNOSUPPORT;
+ return ERR_PTR(-EAFNOSUPPORT);
}
for (i = 0; i <= NDA_MAX; ++i) {
@@ -2958,17 +2955,17 @@ static int neigh_valid_get_req(const struct nlmsghdr *nlh,
case NDA_DST:
if (nla_len(tb[i]) != (int)(*tbl)->key_len) {
NL_SET_ERR_MSG(extack, "Invalid network address in neighbor get request");
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
}
*dst = nla_data(tb[i]);
break;
default:
NL_SET_ERR_MSG(extack, "Unsupported attribute in neighbor get request");
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
}
}
- return 0;
+ return ndm;
}
static inline size_t neigh_nlmsg_size(void)
@@ -3039,18 +3036,16 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
struct net_device *dev = NULL;
struct neigh_table *tbl = NULL;
struct neighbour *neigh;
+ struct ndmsg *ndm;
void *dst = NULL;
- u8 ndm_flags = 0;
- int dev_idx = 0;
int err;
- err = neigh_valid_get_req(nlh, &tbl, &dst, &dev_idx, &ndm_flags,
- extack);
- if (err < 0)
- return err;
+ ndm = neigh_valid_get_req(nlh, &tbl, &dst, extack);
+ if (IS_ERR(ndm))
+ return PTR_ERR(ndm);
- if (dev_idx) {
- dev = __dev_get_by_index(net, dev_idx);
+ if (ndm->ndm_ifindex) {
+ dev = __dev_get_by_index(net, ndm->ndm_ifindex);
if (!dev) {
NL_SET_ERR_MSG(extack, "Unknown device ifindex");
return -ENODEV;
@@ -3062,7 +3057,7 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
return -EINVAL;
}
- if (ndm_flags & NTF_PROXY) {
+ if (ndm->ndm_flags & NTF_PROXY) {
struct pneigh_entry *pn;
pn = pneigh_lookup(tbl, net, dst, dev, 0);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 094/877] neighbour: Move two validations from neigh_get() to neigh_valid_get_req().
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (92 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 093/877] neighbour: Make neigh_valid_get_req() return ndmsg Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 095/877] neighbour: Allocate skb in neigh_get() Greg Kroah-Hartman
` (790 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Jakub Kicinski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit f5046fbc1b6d8c5168d47a617f368f9d4a025e34 ]
We will remove RTNL for neigh_get() and run it under RCU instead.
neigh_get() returns -EINVAL in the following cases:
* NDA_DST is not specified
* Both ndm->ndm_ifindex and NTF_PROXY are not specified
These validations do not require RCU.
Let's move them to neigh_valid_get_req().
While at it, the extack string for the first case is replaced with
NL_SET_ERR_ATTR_MISS().
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20250716221221.442239-3-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/neighbour.c | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index fe921f8cc81c1..ecfa1cc2f85f2 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2936,6 +2936,11 @@ static struct ndmsg *neigh_valid_get_req(const struct nlmsghdr *nlh,
return ERR_PTR(-EINVAL);
}
+ if (!(ndm->ndm_flags & NTF_PROXY) && !ndm->ndm_ifindex) {
+ NL_SET_ERR_MSG(extack, "No device specified");
+ return ERR_PTR(-EINVAL);
+ }
+
err = nlmsg_parse_deprecated_strict(nlh, sizeof(struct ndmsg), tb,
NDA_MAX, nda_policy, extack);
if (err < 0)
@@ -2948,11 +2953,13 @@ static struct ndmsg *neigh_valid_get_req(const struct nlmsghdr *nlh,
}
for (i = 0; i <= NDA_MAX; ++i) {
- if (!tb[i])
- continue;
-
switch (i) {
case NDA_DST:
+ if (!tb[i]) {
+ NL_SET_ERR_ATTR_MISS(extack, NULL, NDA_DST);
+ return ERR_PTR(-EINVAL);
+ }
+
if (nla_len(tb[i]) != (int)(*tbl)->key_len) {
NL_SET_ERR_MSG(extack, "Invalid network address in neighbor get request");
return ERR_PTR(-EINVAL);
@@ -2960,6 +2967,9 @@ static struct ndmsg *neigh_valid_get_req(const struct nlmsghdr *nlh,
*dst = nla_data(tb[i]);
break;
default:
+ if (!tb[i])
+ continue;
+
NL_SET_ERR_MSG(extack, "Unsupported attribute in neighbor get request");
return ERR_PTR(-EINVAL);
}
@@ -3052,11 +3062,6 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
}
}
- if (!dst) {
- NL_SET_ERR_MSG(extack, "Network address not specified");
- return -EINVAL;
- }
-
if (ndm->ndm_flags & NTF_PROXY) {
struct pneigh_entry *pn;
@@ -3069,11 +3074,6 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
nlh->nlmsg_seq, tbl);
}
- if (!dev) {
- NL_SET_ERR_MSG(extack, "No device specified");
- return -EINVAL;
- }
-
neigh = neigh_lookup(tbl, dst, dev);
if (!neigh) {
NL_SET_ERR_MSG(extack, "Neighbour entry not found");
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 095/877] neighbour: Allocate skb in neigh_get().
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (93 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 094/877] neighbour: Move two validations from neigh_get() to neigh_valid_get_req() Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 096/877] neighbour: Move neigh_find_table() to neigh_get() Greg Kroah-Hartman
` (789 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Jakub Kicinski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit 3dfe0b57dcda070d9f1ed2bfb3a9bf0ec8632e08 ]
We will remove RTNL for neigh_get() and run it under RCU instead.
neigh_get_reply() and pneigh_get_reply() allocate skb with GFP_KERNEL.
Let's move the allocation before __dev_get_by_index() in neigh_get().
Now, neigh_get_reply() and pneigh_get_reply() are inlined and
rtnl_unicast() is factorised.
We will convert pneigh_lookup() to __pneigh_lookup() later.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20250716221221.442239-4-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/neighbour.c | 88 ++++++++++++++++----------------------------
1 file changed, 32 insertions(+), 56 deletions(-)
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index ecfa1cc2f85f2..b57d5810fa0d8 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2989,27 +2989,6 @@ static inline size_t neigh_nlmsg_size(void)
+ nla_total_size(1); /* NDA_PROTOCOL */
}
-static int neigh_get_reply(struct net *net, struct neighbour *neigh,
- u32 pid, u32 seq)
-{
- struct sk_buff *skb;
- int err = 0;
-
- skb = nlmsg_new(neigh_nlmsg_size(), GFP_KERNEL);
- if (!skb)
- return -ENOBUFS;
-
- err = neigh_fill_info(skb, neigh, pid, seq, RTM_NEWNEIGH, 0);
- if (err) {
- kfree_skb(skb);
- goto errout;
- }
-
- err = rtnl_unicast(skb, net, pid);
-errout:
- return err;
-}
-
static inline size_t pneigh_nlmsg_size(void)
{
return NLMSG_ALIGN(sizeof(struct ndmsg))
@@ -3018,34 +2997,16 @@ static inline size_t pneigh_nlmsg_size(void)
+ nla_total_size(1); /* NDA_PROTOCOL */
}
-static int pneigh_get_reply(struct net *net, struct pneigh_entry *neigh,
- u32 pid, u32 seq, struct neigh_table *tbl)
-{
- struct sk_buff *skb;
- int err = 0;
-
- skb = nlmsg_new(pneigh_nlmsg_size(), GFP_KERNEL);
- if (!skb)
- return -ENOBUFS;
-
- err = pneigh_fill_info(skb, neigh, pid, seq, RTM_NEWNEIGH, 0, tbl);
- if (err) {
- kfree_skb(skb);
- goto errout;
- }
-
- err = rtnl_unicast(skb, net, pid);
-errout:
- return err;
-}
-
static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
struct netlink_ext_ack *extack)
{
struct net *net = sock_net(in_skb->sk);
+ u32 pid = NETLINK_CB(in_skb).portid;
struct net_device *dev = NULL;
struct neigh_table *tbl = NULL;
+ u32 seq = nlh->nlmsg_seq;
struct neighbour *neigh;
+ struct sk_buff *skb;
struct ndmsg *ndm;
void *dst = NULL;
int err;
@@ -3054,11 +3015,19 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
if (IS_ERR(ndm))
return PTR_ERR(ndm);
+ if (ndm->ndm_flags & NTF_PROXY)
+ skb = nlmsg_new(neigh_nlmsg_size(), GFP_KERNEL);
+ else
+ skb = nlmsg_new(pneigh_nlmsg_size(), GFP_KERNEL);
+ if (!skb)
+ return -ENOBUFS;
+
if (ndm->ndm_ifindex) {
dev = __dev_get_by_index(net, ndm->ndm_ifindex);
if (!dev) {
NL_SET_ERR_MSG(extack, "Unknown device ifindex");
- return -ENODEV;
+ err = -ENODEV;
+ goto err_free_skb;
}
}
@@ -3068,23 +3037,30 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
pn = pneigh_lookup(tbl, net, dst, dev, 0);
if (!pn) {
NL_SET_ERR_MSG(extack, "Proxy neighbour entry not found");
- return -ENOENT;
+ err = -ENOENT;
+ goto err_free_skb;
}
- return pneigh_get_reply(net, pn, NETLINK_CB(in_skb).portid,
- nlh->nlmsg_seq, tbl);
- }
-
- neigh = neigh_lookup(tbl, dst, dev);
- if (!neigh) {
- NL_SET_ERR_MSG(extack, "Neighbour entry not found");
- return -ENOENT;
- }
- err = neigh_get_reply(net, neigh, NETLINK_CB(in_skb).portid,
- nlh->nlmsg_seq);
+ err = pneigh_fill_info(skb, pn, pid, seq, RTM_NEWNEIGH, 0, tbl);
+ if (err)
+ goto err_free_skb;
+ } else {
+ neigh = neigh_lookup(tbl, dst, dev);
+ if (!neigh) {
+ NL_SET_ERR_MSG(extack, "Neighbour entry not found");
+ err = -ENOENT;
+ goto err_free_skb;
+ }
- neigh_release(neigh);
+ err = neigh_fill_info(skb, neigh, pid, seq, RTM_NEWNEIGH, 0);
+ neigh_release(neigh);
+ if (err)
+ goto err_free_skb;
+ }
+ return rtnl_unicast(skb, net, pid);
+err_free_skb:
+ kfree_skb(skb);
return err;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 096/877] neighbour: Move neigh_find_table() to neigh_get().
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (94 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 095/877] neighbour: Allocate skb in neigh_get() Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 097/877] neighbour: Convert RTM_GETNEIGH to RCU Greg Kroah-Hartman
` (788 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Jakub Kicinski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit 0e5ac19c78654abbf43dc4ffdae290c8cb81c59c ]
neigh_valid_get_req() calls neigh_find_table() to fetch neigh_tables[].
neigh_find_table() uses rcu_dereference_rtnl(), but RTNL actually does
not protect it at all; neigh_table_clear() can be called without RTNL
and only waits for RCU readers by synchronize_rcu().
Fortunately, there is no bug because IPv4 is built-in, IPv6 cannot be
unloaded, and DECNET was removed.
To fetch neigh_tables[] by rcu_dereference() later, let's move
neigh_find_table() from neigh_valid_get_req() to neigh_get().
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20250716221221.442239-5-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/neighbour.c | 37 ++++++++++++++++++++-----------------
1 file changed, 20 insertions(+), 17 deletions(-)
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index b57d5810fa0d8..0dc0ba5cf7443 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2912,10 +2912,9 @@ static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
}
static struct ndmsg *neigh_valid_get_req(const struct nlmsghdr *nlh,
- struct neigh_table **tbl, void **dst,
+ struct nlattr **tb,
struct netlink_ext_ack *extack)
{
- struct nlattr *tb[NDA_MAX + 1];
struct ndmsg *ndm;
int err, i;
@@ -2946,12 +2945,6 @@ static struct ndmsg *neigh_valid_get_req(const struct nlmsghdr *nlh,
if (err < 0)
return ERR_PTR(err);
- *tbl = neigh_find_table(ndm->ndm_family);
- if (!*tbl) {
- NL_SET_ERR_MSG(extack, "Unsupported family in header for neighbor get request");
- return ERR_PTR(-EAFNOSUPPORT);
- }
-
for (i = 0; i <= NDA_MAX; ++i) {
switch (i) {
case NDA_DST:
@@ -2959,12 +2952,6 @@ static struct ndmsg *neigh_valid_get_req(const struct nlmsghdr *nlh,
NL_SET_ERR_ATTR_MISS(extack, NULL, NDA_DST);
return ERR_PTR(-EINVAL);
}
-
- if (nla_len(tb[i]) != (int)(*tbl)->key_len) {
- NL_SET_ERR_MSG(extack, "Invalid network address in neighbor get request");
- return ERR_PTR(-EINVAL);
- }
- *dst = nla_data(tb[i]);
break;
default:
if (!tb[i])
@@ -3002,16 +2989,17 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
{
struct net *net = sock_net(in_skb->sk);
u32 pid = NETLINK_CB(in_skb).portid;
+ struct nlattr *tb[NDA_MAX + 1];
struct net_device *dev = NULL;
- struct neigh_table *tbl = NULL;
u32 seq = nlh->nlmsg_seq;
+ struct neigh_table *tbl;
struct neighbour *neigh;
struct sk_buff *skb;
struct ndmsg *ndm;
- void *dst = NULL;
+ void *dst;
int err;
- ndm = neigh_valid_get_req(nlh, &tbl, &dst, extack);
+ ndm = neigh_valid_get_req(nlh, tb, extack);
if (IS_ERR(ndm))
return PTR_ERR(ndm);
@@ -3022,6 +3010,21 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
if (!skb)
return -ENOBUFS;
+ tbl = neigh_find_table(ndm->ndm_family);
+ if (!tbl) {
+ NL_SET_ERR_MSG(extack, "Unsupported family in header for neighbor get request");
+ err = -EAFNOSUPPORT;
+ goto err_free_skb;
+ }
+
+ if (nla_len(tb[NDA_DST]) != (int)tbl->key_len) {
+ NL_SET_ERR_MSG(extack, "Invalid network address in neighbor get request");
+ err = -EINVAL;
+ goto err_free_skb;
+ }
+
+ dst = nla_data(tb[NDA_DST]);
+
if (ndm->ndm_ifindex) {
dev = __dev_get_by_index(net, ndm->ndm_ifindex);
if (!dev) {
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 097/877] neighbour: Convert RTM_GETNEIGH to RCU.
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (95 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 096/877] neighbour: Move neigh_find_table() to neigh_get() Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 098/877] neighbour: Convert RTM_GETNEIGHTBL " Greg Kroah-Hartman
` (787 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Jakub Kicinski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit ed6e380d2d419a3e8ca73de7b4c7ccb522835f1e ]
Only __dev_get_by_index() is the RTNL dependant in neigh_get().
Let's replace it with dev_get_by_index_rcu() and convert RTM_GETNEIGH
to RCU.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20250716221221.442239-10-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/neighbour.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 0dc0ba5cf7443..50a18ae55409e 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -3010,27 +3010,29 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
if (!skb)
return -ENOBUFS;
+ rcu_read_lock();
+
tbl = neigh_find_table(ndm->ndm_family);
if (!tbl) {
NL_SET_ERR_MSG(extack, "Unsupported family in header for neighbor get request");
err = -EAFNOSUPPORT;
- goto err_free_skb;
+ goto err_unlock;
}
if (nla_len(tb[NDA_DST]) != (int)tbl->key_len) {
NL_SET_ERR_MSG(extack, "Invalid network address in neighbor get request");
err = -EINVAL;
- goto err_free_skb;
+ goto err_unlock;
}
dst = nla_data(tb[NDA_DST]);
if (ndm->ndm_ifindex) {
- dev = __dev_get_by_index(net, ndm->ndm_ifindex);
+ dev = dev_get_by_index_rcu(net, ndm->ndm_ifindex);
if (!dev) {
NL_SET_ERR_MSG(extack, "Unknown device ifindex");
err = -ENODEV;
- goto err_free_skb;
+ goto err_unlock;
}
}
@@ -3041,28 +3043,31 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
if (!pn) {
NL_SET_ERR_MSG(extack, "Proxy neighbour entry not found");
err = -ENOENT;
- goto err_free_skb;
+ goto err_unlock;
}
err = pneigh_fill_info(skb, pn, pid, seq, RTM_NEWNEIGH, 0, tbl);
if (err)
- goto err_free_skb;
+ goto err_unlock;
} else {
neigh = neigh_lookup(tbl, dst, dev);
if (!neigh) {
NL_SET_ERR_MSG(extack, "Neighbour entry not found");
err = -ENOENT;
- goto err_free_skb;
+ goto err_unlock;
}
err = neigh_fill_info(skb, neigh, pid, seq, RTM_NEWNEIGH, 0);
neigh_release(neigh);
if (err)
- goto err_free_skb;
+ goto err_unlock;
}
+ rcu_read_unlock();
+
return rtnl_unicast(skb, net, pid);
-err_free_skb:
+err_unlock:
+ rcu_read_unlock();
kfree_skb(skb);
return err;
}
@@ -3876,7 +3881,7 @@ static const struct rtnl_msg_handler neigh_rtnl_msg_handlers[] __initconst = {
{.msgtype = RTM_NEWNEIGH, .doit = neigh_add},
{.msgtype = RTM_DELNEIGH, .doit = neigh_delete},
{.msgtype = RTM_GETNEIGH, .doit = neigh_get, .dumpit = neigh_dump_info,
- .flags = RTNL_FLAG_DUMP_UNLOCKED},
+ .flags = RTNL_FLAG_DOIT_UNLOCKED | RTNL_FLAG_DUMP_UNLOCKED},
{.msgtype = RTM_GETNEIGHTBL, .dumpit = neightbl_dump_info},
{.msgtype = RTM_SETNEIGHTBL, .doit = neightbl_set},
};
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 098/877] neighbour: Convert RTM_GETNEIGHTBL to RCU.
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (96 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 097/877] neighbour: Convert RTM_GETNEIGH to RCU Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-10-01 19:34 ` Harshit Mogalapalli
2026-09-30 15:16 ` [PATCH 6.12 099/877] neighbour: Add missing RCU annotation for neightbl_dump_info() Greg Kroah-Hartman
` (786 subsequent siblings)
884 siblings, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Eric Dumazet,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit 4ae34be500649ec452ac1fc2748958683ad9b55d ]
neightbl_dump_info() calls these functions for each neigh_tables[]
entry:
1. neightbl_fill_info() for tbl->parms
2. neightbl_fill_param_info() for tbl->parms_list (except tbl->parms)
Both functions rely on the table lock (read_lock_bh(&tbl->lock))
and RTNL is not needed.
Let's fetch the table under RCU and convert RTM_GETNEIGHTBL to RCU.
Note that the first entry of tbl->parms_list is tbl->parms.list and
embedded in neigh_table, so list_next_entry() is safe.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20251022054004.2514876-4-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/neighbour.c | 23 +++++++++--------------
1 file changed, 9 insertions(+), 14 deletions(-)
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 50a18ae55409e..d38c309e7fa61 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2131,7 +2131,7 @@ static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms)
return -ENOBUFS;
if ((parms->dev &&
- nla_put_u32(skb, NDTPA_IFINDEX, parms->dev->ifindex)) ||
+ nla_put_u32(skb, NDTPA_IFINDEX, READ_ONCE(parms->dev->ifindex))) ||
nla_put_u32(skb, NDTPA_REFCNT, refcount_read(&parms->refcnt)) ||
nla_put_u32(skb, NDTPA_QUEUE_LENBYTES,
NEIGH_VAR(parms, QUEUE_LEN_BYTES)) ||
@@ -2183,8 +2183,6 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
return -EMSGSIZE;
ndtmsg = nlmsg_data(nlh);
-
- read_lock_bh(&tbl->lock);
ndtmsg->ndtm_family = tbl->family;
ndtmsg->ndtm_pad1 = 0;
ndtmsg->ndtm_pad2 = 0;
@@ -2210,11 +2208,9 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
.ndtc_proxy_qlen = READ_ONCE(tbl->proxy_queue.qlen),
};
- rcu_read_lock();
nht = rcu_dereference(tbl->nht);
ndc.ndtc_hash_rnd = nht->hash_rnd[0];
ndc.ndtc_hash_mask = ((1 << nht->hash_shift) - 1);
- rcu_read_unlock();
if (nla_put(skb, NDTA_CONFIG, sizeof(ndc), &ndc))
goto nla_put_failure;
@@ -2252,12 +2248,10 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
if (neightbl_fill_parms(skb, &tbl->parms) < 0)
goto nla_put_failure;
- read_unlock_bh(&tbl->lock);
nlmsg_end(skb, nlh);
return 0;
nla_put_failure:
- read_unlock_bh(&tbl->lock);
nlmsg_cancel(skb, nlh);
return -EMSGSIZE;
}
@@ -2276,8 +2270,6 @@ static int neightbl_fill_param_info(struct sk_buff *skb,
return -EMSGSIZE;
ndtmsg = nlmsg_data(nlh);
-
- read_lock_bh(&tbl->lock);
ndtmsg->ndtm_family = tbl->family;
ndtmsg->ndtm_pad1 = 0;
ndtmsg->ndtm_pad2 = 0;
@@ -2286,11 +2278,9 @@ static int neightbl_fill_param_info(struct sk_buff *skb,
neightbl_fill_parms(skb, parms) < 0)
goto errout;
- read_unlock_bh(&tbl->lock);
nlmsg_end(skb, nlh);
return 0;
errout:
- read_unlock_bh(&tbl->lock);
nlmsg_cancel(skb, nlh);
return -EMSGSIZE;
}
@@ -2531,10 +2521,12 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family;
+ rcu_read_lock();
+
for (tidx = 0; tidx < NEIGH_NR_TABLES; tidx++) {
struct neigh_parms *p;
- tbl = rcu_dereference_rtnl(neigh_tables[tidx]);
+ tbl = rcu_dereference(neigh_tables[tidx]);
if (!tbl)
continue;
@@ -2548,7 +2540,7 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
nidx = 0;
p = list_next_entry(&tbl->parms, list);
- list_for_each_entry_from(p, &tbl->parms_list, list) {
+ list_for_each_entry_from_rcu(p, &tbl->parms_list, list) {
if (!net_eq(neigh_parms_net(p), net))
continue;
@@ -2568,6 +2560,8 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
neigh_skip = 0;
}
out:
+ rcu_read_unlock();
+
cb->args[0] = tidx;
cb->args[1] = nidx;
@@ -3882,7 +3876,8 @@ static const struct rtnl_msg_handler neigh_rtnl_msg_handlers[] __initconst = {
{.msgtype = RTM_DELNEIGH, .doit = neigh_delete},
{.msgtype = RTM_GETNEIGH, .doit = neigh_get, .dumpit = neigh_dump_info,
.flags = RTNL_FLAG_DOIT_UNLOCKED | RTNL_FLAG_DUMP_UNLOCKED},
- {.msgtype = RTM_GETNEIGHTBL, .dumpit = neightbl_dump_info},
+ {.msgtype = RTM_GETNEIGHTBL, .dumpit = neightbl_dump_info,
+ .flags = RTNL_FLAG_DUMP_UNLOCKED},
{.msgtype = RTM_SETNEIGHTBL, .doit = neightbl_set},
};
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 098/877] neighbour: Convert RTM_GETNEIGHTBL to RCU.
2026-09-30 15:16 ` [PATCH 6.12 098/877] neighbour: Convert RTM_GETNEIGHTBL " Greg Kroah-Hartman
@ 2026-10-01 19:34 ` Harshit Mogalapalli
2026-10-02 12:06 ` Greg Kroah-Hartman
2026-10-02 21:10 ` Sasha Levin
0 siblings, 2 replies; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-01 19:34 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, Kuniyuki Iwashima, Eric Dumazet, Jakub Kicinski,
Sasha Levin
On 30/09/26 8:46 pm, Greg Kroah-Hartman wrote:
> 6.12-stable review patch. If anyone has any objections, please let me know.
>
> ------------------
>
> From: Kuniyuki Iwashima <kuniyu@google.com>
>
> [ Upstream commit 4ae34be500649ec452ac1fc2748958683ad9b55d ]
>
> neightbl_dump_info() calls these functions for each neigh_tables[]
> entry:
>
> 1. neightbl_fill_info() for tbl->parms
> 2. neightbl_fill_param_info() for tbl->parms_list (except tbl->parms)
>
> Both functions rely on the table lock (read_lock_bh(&tbl->lock))
> and RTNL is not needed.
>
> Let's fetch the table under RCU and convert RTM_GETNEIGHTBL to RCU.
>
> Note that the first entry of tbl->parms_list is tbl->parms.list and
> embedded in neigh_table, so list_next_entry() is safe.
>
> Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
> Reviewed-by: Eric Dumazet <edumazet@google.com>
> Link: https://patch.msgid.link/20251022054004.2514876-4-kuniyu@google.com
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
> Signed-off-by: Sasha Levin <sashal@kernel.org>
Hi Greg/Sasha,
An AI-assisted review flagged a reader/writer mismatch. I independently
checked upstream and 6.12.y at f4ffa8dc360b.
Upstream neigh_parms_release() in net/core/neighbour.c has:
write_lock_bh(&tbl->lock);
list_del_rcu(&parms->list);
parms->dead = 1;
write_unlock_bh(&tbl->lock);
netdev_put(parms->dev, &parms->dev_tracker);
call_rcu(&parms->rcu_head, neigh_rcu_free_parms);
6.12.y has
net/core/neighbour.c:
write_lock_bh(&tbl->lock);
list_del(&parms->list);
parms->dead = 1;
write_unlock_bh(&tbl->lock);
netdev_put(parms->dev, &parms->dev_tracker);
call_rcu(&parms->rcu_head, neigh_rcu_free_parms);
neightbl_dump_info() now uses RCU, but list_del() poisons the removed
node's forward link. A reader can follow that poisoned pointer despite
delayed free.
I think 6.12 should take 06d6322280d95757cef1e3ee0fc62c644629523e
("neighbour: Use RCU list helpers for neigh_parms.list writers.") and
35d7c70870338aa6a367b9e4ed528914320b0be0 ("neighbour: Annotate access to
neigh_parms fields.") before this conversion, retaining the later dump
fixes, thoughts?
thanks,
Harshit> ---
> net/core/neighbour.c | 23 +++++++++--------------
> 1 file changed, 9 insertions(+), 14 deletions(-)
>
> diff --git a/net/core/neighbour.c b/net/core/neighbour.c
> index 50a18ae55409e..d38c309e7fa61 100644
> --- a/net/core/neighbour.c
> +++ b/net/core/neighbour.c
> @@ -2131,7 +2131,7 @@ static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms)
> return -ENOBUFS;
>
> if ((parms->dev &&
> - nla_put_u32(skb, NDTPA_IFINDEX, parms->dev->ifindex)) ||
> + nla_put_u32(skb, NDTPA_IFINDEX, READ_ONCE(parms->dev->ifindex))) ||
> nla_put_u32(skb, NDTPA_REFCNT, refcount_read(&parms->refcnt)) ||
> nla_put_u32(skb, NDTPA_QUEUE_LENBYTES,
> NEIGH_VAR(parms, QUEUE_LEN_BYTES)) ||
> @@ -2183,8 +2183,6 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
> return -EMSGSIZE;
>
> ndtmsg = nlmsg_data(nlh);
> -
> - read_lock_bh(&tbl->lock);
> ndtmsg->ndtm_family = tbl->family;
> ndtmsg->ndtm_pad1 = 0;
> ndtmsg->ndtm_pad2 = 0;
> @@ -2210,11 +2208,9 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
> .ndtc_proxy_qlen = READ_ONCE(tbl->proxy_queue.qlen),
> };
>
> - rcu_read_lock();
> nht = rcu_dereference(tbl->nht);
> ndc.ndtc_hash_rnd = nht->hash_rnd[0];
> ndc.ndtc_hash_mask = ((1 << nht->hash_shift) - 1);
> - rcu_read_unlock();
>
> if (nla_put(skb, NDTA_CONFIG, sizeof(ndc), &ndc))
> goto nla_put_failure;
> @@ -2252,12 +2248,10 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
> if (neightbl_fill_parms(skb, &tbl->parms) < 0)
> goto nla_put_failure;
>
> - read_unlock_bh(&tbl->lock);
> nlmsg_end(skb, nlh);
> return 0;
>
> nla_put_failure:
> - read_unlock_bh(&tbl->lock);
> nlmsg_cancel(skb, nlh);
> return -EMSGSIZE;
> }
> @@ -2276,8 +2270,6 @@ static int neightbl_fill_param_info(struct sk_buff *skb,
> return -EMSGSIZE;
>
> ndtmsg = nlmsg_data(nlh);
> -
> - read_lock_bh(&tbl->lock);
> ndtmsg->ndtm_family = tbl->family;
> ndtmsg->ndtm_pad1 = 0;
> ndtmsg->ndtm_pad2 = 0;
> @@ -2286,11 +2278,9 @@ static int neightbl_fill_param_info(struct sk_buff *skb,
> neightbl_fill_parms(skb, parms) < 0)
> goto errout;
>
> - read_unlock_bh(&tbl->lock);
> nlmsg_end(skb, nlh);
> return 0;
> errout:
> - read_unlock_bh(&tbl->lock);
> nlmsg_cancel(skb, nlh);
> return -EMSGSIZE;
> }
> @@ -2531,10 +2521,12 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
>
> family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family;
>
> + rcu_read_lock();
> +
> for (tidx = 0; tidx < NEIGH_NR_TABLES; tidx++) {
> struct neigh_parms *p;
>
> - tbl = rcu_dereference_rtnl(neigh_tables[tidx]);
> + tbl = rcu_dereference(neigh_tables[tidx]);
> if (!tbl)
> continue;
>
> @@ -2548,7 +2540,7 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
>
> nidx = 0;
> p = list_next_entry(&tbl->parms, list);
> - list_for_each_entry_from(p, &tbl->parms_list, list) {
> + list_for_each_entry_from_rcu(p, &tbl->parms_list, list) {
> if (!net_eq(neigh_parms_net(p), net))
> continue;
>
> @@ -2568,6 +2560,8 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
> neigh_skip = 0;
> }
> out:
> + rcu_read_unlock();
> +
> cb->args[0] = tidx;
> cb->args[1] = nidx;
>
> @@ -3882,7 +3876,8 @@ static const struct rtnl_msg_handler neigh_rtnl_msg_handlers[] __initconst = {
> {.msgtype = RTM_DELNEIGH, .doit = neigh_delete},
> {.msgtype = RTM_GETNEIGH, .doit = neigh_get, .dumpit = neigh_dump_info,
> .flags = RTNL_FLAG_DOIT_UNLOCKED | RTNL_FLAG_DUMP_UNLOCKED},
> - {.msgtype = RTM_GETNEIGHTBL, .dumpit = neightbl_dump_info},
> + {.msgtype = RTM_GETNEIGHTBL, .dumpit = neightbl_dump_info,
> + .flags = RTNL_FLAG_DUMP_UNLOCKED},
> {.msgtype = RTM_SETNEIGHTBL, .doit = neightbl_set},
> };
>
^ permalink raw reply [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 098/877] neighbour: Convert RTM_GETNEIGHTBL to RCU.
2026-10-01 19:34 ` Harshit Mogalapalli
@ 2026-10-02 12:06 ` Greg Kroah-Hartman
2026-10-02 21:10 ` Sasha Levin
1 sibling, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-02 12:06 UTC (permalink / raw)
To: Harshit Mogalapalli
Cc: stable, patches, Kuniyuki Iwashima, Eric Dumazet, Jakub Kicinski,
Sasha Levin
On Fri, Oct 02, 2026 at 01:04:58AM +0530, Harshit Mogalapalli wrote:
>
>
> On 30/09/26 8:46 pm, Greg Kroah-Hartman wrote:
> > 6.12-stable review patch. If anyone has any objections, please let me know.
> >
> > ------------------
> >
> > From: Kuniyuki Iwashima <kuniyu@google.com>
> >
> > [ Upstream commit 4ae34be500649ec452ac1fc2748958683ad9b55d ]
> >
> > neightbl_dump_info() calls these functions for each neigh_tables[]
> > entry:
> >
> > 1. neightbl_fill_info() for tbl->parms
> > 2. neightbl_fill_param_info() for tbl->parms_list (except tbl->parms)
> >
> > Both functions rely on the table lock (read_lock_bh(&tbl->lock))
> > and RTNL is not needed.
> >
> > Let's fetch the table under RCU and convert RTM_GETNEIGHTBL to RCU.
> >
> > Note that the first entry of tbl->parms_list is tbl->parms.list and
> > embedded in neigh_table, so list_next_entry() is safe.
> >
> > Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
> > Reviewed-by: Eric Dumazet <edumazet@google.com>
> > Link: https://patch.msgid.link/20251022054004.2514876-4-kuniyu@google.com
> > Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> > Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
> > Signed-off-by: Sasha Levin <sashal@kernel.org>
>
> Hi Greg/Sasha,
>
> An AI-assisted review flagged a reader/writer mismatch. I independently
> checked upstream and 6.12.y at f4ffa8dc360b.
>
> Upstream neigh_parms_release() in net/core/neighbour.c has:
>
> write_lock_bh(&tbl->lock);
> list_del_rcu(&parms->list);
> parms->dead = 1;
> write_unlock_bh(&tbl->lock);
> netdev_put(parms->dev, &parms->dev_tracker);
> call_rcu(&parms->rcu_head, neigh_rcu_free_parms);
>
> 6.12.y has
> net/core/neighbour.c:
>
> write_lock_bh(&tbl->lock);
> list_del(&parms->list);
> parms->dead = 1;
> write_unlock_bh(&tbl->lock);
> netdev_put(parms->dev, &parms->dev_tracker);
> call_rcu(&parms->rcu_head, neigh_rcu_free_parms);
>
> neightbl_dump_info() now uses RCU, but list_del() poisons the removed
> node's forward link. A reader can follow that poisoned pointer despite
> delayed free.
>
> I think 6.12 should take 06d6322280d95757cef1e3ee0fc62c644629523e
> ("neighbour: Use RCU list helpers for neigh_parms.list writers.") and
> 35d7c70870338aa6a367b9e4ed528914320b0be0 ("neighbour: Annotate access to
> neigh_parms fields.") before this conversion, retaining the later dump
> fixes, thoughts?
Already dropped, thanks.
greg k-h
^ permalink raw reply [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 098/877] neighbour: Convert RTM_GETNEIGHTBL to RCU.
2026-10-01 19:34 ` Harshit Mogalapalli
2026-10-02 12:06 ` Greg Kroah-Hartman
@ 2026-10-02 21:10 ` Sasha Levin
1 sibling, 0 replies; 922+ messages in thread
From: Sasha Levin @ 2026-10-02 21:10 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: Sasha Levin, patches, Kuniyuki Iwashima, Eric Dumazet,
Jakub Kicinski, Harshit Mogalapalli
> I think 6.12 should take 06d6322280d95757cef1e3ee0fc62c644629523e
> ("neighbour: Use RCU list helpers for neigh_parms.list writers.") and
> 35d7c70870338aa6a367b9e4ed528914320b0be0 ("neighbour: Annotate access to
> neigh_parms fields.") before this conversion, retaining the later dump
> fixes, thoughts?
Greg dropped this from 6.12, but 6.18 already shipped the conversion in
6.18.54 without the writer side, so I've queued both of these for 6.18,
thanks.
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 922+ messages in thread
* [PATCH 6.12 099/877] neighbour: Add missing RCU annotation for neightbl_dump_info().
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (97 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 098/877] neighbour: Convert RTM_GETNEIGHTBL " Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 100/877] neighbour: Skip default parms when resumed in neightbl_dump_info() Greg Kroah-Hartman
` (785 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Ido Schimmel,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit 764dcebb033764633700a036c7351a7c6350eec6 ]
neightbl_dump_info() fetches the first non-default neigh_parms
with list_next_entry(&tbl->parms, ...) and iterates through the
list with list_for_each_entry_from_rcu().
However, list_next_entry() does not use RCU helper.
Let's use list_for_each_entry_rcu() and skip the default parms.
Fixes: 4ae34be50064 ("neighbour: Convert RTM_GETNEIGHTBL to RCU.")
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260909233143.2401847-2-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/neighbour.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index d38c309e7fa61..c9d848085dad3 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2539,11 +2539,14 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
break;
nidx = 0;
- p = list_next_entry(&tbl->parms, list);
- list_for_each_entry_from_rcu(p, &tbl->parms_list, list) {
+
+ list_for_each_entry_rcu(p, &tbl->parms_list, list) {
if (!net_eq(neigh_parms_net(p), net))
continue;
+ if (!p->dev)
+ continue;
+
if (nidx < neigh_skip)
goto next;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 100/877] neighbour: Skip default parms when resumed in neightbl_dump_info().
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (98 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 099/877] neighbour: Add missing RCU annotation for neightbl_dump_info() Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 101/877] ALSA: bcd2000: Fix race between rawmidi and disconnect Greg Kroah-Hartman
` (784 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Ido Schimmel,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit 979aabdad8dd03394467ee484a1a70f3d40b19ba ]
neightbl_dump_info() calls neightbl_fill_info() in each loop
to render the default parms.
If there are many devices and neightbl_fill_param_info() failed,
neightbl_fill_info() is called again when the dump resumes:
# ynl --family rt-neigh --dump getneightbl --output-json |
jq '.[] | {name: .name, ifindex: .parms.ifindex}'
...
{
"name": "ndisc_cache",
"ifindex": null
}
...
{
"name": "ndisc_cache",
"ifindex": 6
}
{
"name": "ndisc_cache",
"ifindex": null
}
{
"name": "ndisc_cache",
"ifindex": 5
}
Let's skip neightbl_fill_info() if it is already called in
neightbl_dump_info().
Note that we cannot use !neigh_skip instead of !default_skip
because default_skip == 1 && neigh_skip == 0 could be true
if the first neightbl_fill_param_info() fails.
Also, nidx must be cleared at the end of each table loop;
otherwise, if neightbl_fill_info() for a subsequent table
fails, the leftover nidx from the previous table would be
saved in cb->args[1], resulting in erroneously skipping parms
of the subsequent table in the next dump.
Fixes: c7fb64db001f ("[NETLINK]: Neighbour table configuration and statistics via rtnetlink")
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260909233143.2401847-5-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/neighbour.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index c9d848085dad3..99822878262c7 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2507,9 +2507,10 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
{
const struct nlmsghdr *nlh = cb->nlh;
struct net *net = sock_net(skb->sk);
+ int default_skip = cb->args[2];
+ int neigh_skip = cb->args[1];
int family, tidx, nidx = 0;
int tbl_skip = cb->args[0];
- int neigh_skip = cb->args[1];
struct neigh_table *tbl;
if (cb->strict_check) {
@@ -2533,12 +2534,13 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
if (tidx < tbl_skip || (family && tbl->family != family))
continue;
- if (neightbl_fill_info(skb, tbl, NETLINK_CB(cb->skb).portid,
+ if (!default_skip &&
+ neightbl_fill_info(skb, tbl, NETLINK_CB(cb->skb).portid,
nlh->nlmsg_seq, RTM_NEWNEIGHTBL,
NLM_F_MULTI) < 0)
break;
- nidx = 0;
+ default_skip = 1;
list_for_each_entry_rcu(p, &tbl->parms_list, list) {
if (!net_eq(neigh_parms_net(p), net))
@@ -2561,12 +2563,15 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
}
neigh_skip = 0;
+ nidx = 0;
+ default_skip = 0;
}
out:
rcu_read_unlock();
cb->args[0] = tidx;
cb->args[1] = nidx;
+ cb->args[2] = default_skip;
return skb->len;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 101/877] ALSA: bcd2000: Fix race between rawmidi and disconnect
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (99 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 100/877] neighbour: Skip default parms when resumed in neightbl_dump_info() Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 102/877] phy: mediatek: phy-mtk-hdmi-mt8195: Fix PLL calc divisor overflow Greg Kroah-Hartman
` (783 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Takashi Iwai, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <tiwai@suse.de>
[ Upstream commit 221253723dc58bb901c3f27a7659823e63fc598c ]
Although we tried to fix the potential UAF issues at USB disconnect on
bcd2000 driver, there is still an overlooked case -- namely, when a
rawmidi trigger callback has been already running at USB disconnect
handling, the in-flight function (e.g. bcd2000_midi_send()) could
still access the URB, because the previous URB NULL-check & clearance
was considered only for the URB complete callbacks, but not about the
parallel rawmidi operations.
For addressing the race, this patch introduced a new spinlock that
covers each rawmidi operation as well as the rawmidi handling in the
complete callback. The URB is cleared with the lock, so it guarantees
that the pending rawmidi task already finished or a NULL check is
effective.
Fixes: 459d3a64766f ("ALSA: bcd2000: clear the URB pointers on disconnect")
Link: https://patch.msgid.link/20260910155227.996210-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/bcd2000/bcd2000.c | 33 ++++++++++++++++++++++++++-------
1 file changed, 26 insertions(+), 7 deletions(-)
diff --git a/sound/usb/bcd2000/bcd2000.c b/sound/usb/bcd2000/bcd2000.c
index c7e7149c6dabd..dce6d1f611f94 100644
--- a/sound/usb/bcd2000/bcd2000.c
+++ b/sound/usb/bcd2000/bcd2000.c
@@ -43,6 +43,7 @@ struct bcd2000 {
struct usb_interface *intf;
int card_index;
+ spinlock_t midi_lock;
int midi_out_active;
struct snd_rawmidi *rmidi;
struct snd_rawmidi_substream *midi_receive_substream;
@@ -90,6 +91,8 @@ static void bcd2000_midi_input_trigger(struct snd_rawmidi_substream *substream,
int up)
{
struct bcd2000 *bcd2k = substream->rmidi->private_data;
+
+ guard(spinlock_irqsave)(&bcd2k->midi_lock);
bcd2k->midi_receive_substream = up ? substream : NULL;
}
@@ -195,6 +198,8 @@ static void bcd2000_midi_output_trigger(struct snd_rawmidi_substream *substream,
{
struct bcd2000 *bcd2k = substream->rmidi->private_data;
+ guard(spinlock_irqsave)(&bcd2k->midi_lock);
+
if (up) {
bcd2k->midi_out_substream = substream;
/* check if there is data userspace wants to send */
@@ -219,6 +224,7 @@ static void bcd2000_output_complete(struct urb *urb)
return;
/* check if there is more data userspace wants to send */
+ guard(spinlock_irqsave)(&bcd2k->midi_lock);
bcd2000_midi_send(bcd2k);
}
@@ -234,6 +240,8 @@ static void bcd2000_input_complete(struct urb *urb)
if (!bcd2k || urb->status == -ESHUTDOWN)
return;
+ guard(spinlock_irqsave)(&bcd2k->midi_lock);
+
if (urb->actual_length > 0)
bcd2000_midi_handle_input(bcd2k, urb->transfer_buffer,
urb->actual_length);
@@ -348,16 +356,26 @@ static int bcd2000_init_midi(struct bcd2000 *bcd2k)
return 0;
}
+static void bcd2000_midi_free(struct bcd2000 *bcd2k,
+ struct urb **urb_p)
+{
+ struct urb *urb = *urb_p;
+
+ if (!urb)
+ return;
+
+ usb_poison_urb(urb);
+ scoped_guard(spinlock_irq, &bcd2k->midi_lock)
+ *urb_p = NULL;
+
+ usb_free_urb(urb);
+}
+
static void bcd2000_free_usb_related_resources(struct bcd2000 *bcd2k,
struct usb_interface *interface)
{
- usb_poison_urb(bcd2k->midi_out_urb);
- usb_poison_urb(bcd2k->midi_in_urb);
-
- usb_free_urb(bcd2k->midi_out_urb);
- usb_free_urb(bcd2k->midi_in_urb);
- bcd2k->midi_out_urb = NULL;
- bcd2k->midi_in_urb = NULL;
+ bcd2000_midi_free(bcd2k, &bcd2k->midi_out_urb);
+ bcd2000_midi_free(bcd2k, &bcd2k->midi_in_urb);
if (bcd2k->intf) {
usb_set_intfdata(bcd2k->intf, NULL);
@@ -397,6 +415,7 @@ static int bcd2000_probe(struct usb_interface *interface,
bcd2k->card = card;
bcd2k->card_index = card_index;
bcd2k->intf = interface;
+ spin_lock_init(&bcd2k->midi_lock);
snd_card_set_dev(card, &interface->dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 102/877] phy: mediatek: phy-mtk-hdmi-mt8195: Fix PLL calc divisor overflow
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (100 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 101/877] ALSA: bcd2000: Fix race between rawmidi and disconnect Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 103/877] phy: mediatek: phy-mtk-hdmi-mt8195: Fix TMDS clk bit ratio setting Greg Kroah-Hartman
` (782 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Manivannan Sadhasivam,
AngeloGioacchino Del Regno, Vinod Koul, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
[ Upstream commit de7f29a1fe1dc2864d8a47f8c39d508442cae167 ]
When trying to calculate a PLL rate for target display resolutions
above 2560x1440, 24bpp, 30Hz, the pixel clock value will be more
than 32-bits long but the division to finally calculate the digital
clock divider is being done with div_u64(), which expects a 32bit
unsigned divisor.
Fix the overflow by using div64_u64() instead.
Fixes: 9d9ff3d2a4a5 ("phy: mediatek: hdmi: mt8195: fix wrong pll calculus")
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://patch.msgid.link/20260911074015.9994-2-angelogioacchino.delregno@collabora.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
index bbfe11d6a69d7..80600b2b6b38d 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
@@ -288,7 +288,7 @@ static int mtk_hdmi_pll_calc(struct mtk_hdmi_phy *hdmi_phy, struct clk_hw *hw,
posdiv2 = 1;
/* Digital clk divider, max /32 */
- digital_div = div_u64(ns_hdmipll_ck, posdiv1 * posdiv2 * pixel_clk);
+ digital_div = div64_u64(ns_hdmipll_ck, posdiv1 * posdiv2 * pixel_clk);
if (!(digital_div <= 32 && digital_div >= 1))
return -EINVAL;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 103/877] phy: mediatek: phy-mtk-hdmi-mt8195: Fix TMDS clk bit ratio setting
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (101 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 102/877] phy: mediatek: phy-mtk-hdmi-mt8195: Fix PLL calc divisor overflow Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 104/877] ALSA: pcm: set timer->private_data before registering the PCM timer Greg Kroah-Hartman
` (781 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Manivannan Sadhasivam,
AngeloGioacchino Del Regno, Vinod Koul, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
[ Upstream commit 486a70ef848264dcf9a57f0bb0452848db9537de ]
The comment in the mtk_phy_tmds_clk_ratio() function clearly and
correctly explains that the TMDS ratio has to be 1/10 for data
rates under 3.4Gbps, and 1/40 over that.
Unfortunately though, the TXC_DIV register setting was wrong, as
in value 3 means to divide by 8 and, in order to achieve the in
spec 1/40 (tmds) data rate, this has to divide by 4 instead!
Add definitions for the TXC_DIV register values clearly explaining
the meanings (DIV2, DIV4, DIV8), and program the correct, DIV 4,
value to the register in mtk_phy_tmds_clk_ratio().
This fixes out of spec clocking and, with this change, SoCs using
the MT8195 class HDMI PHYs can now successfully be configured to
output 3840x2160@60Hz over HDMI.
Fixes: 45810d486bb4 ("phy: mediatek: add support for phy-mtk-hdmi-mt8195")
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://patch.msgid.link/20260911074015.9994-3-angelogioacchino.delregno@collabora.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c | 2 +-
drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
index 80600b2b6b38d..9f2c4db843479 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
@@ -34,7 +34,7 @@ mtk_phy_tmds_clk_ratio(struct mtk_hdmi_phy *hdmi_phy, bool enable)
* clock bit ratio 1:40, under 3.4Gbps, clock bit ratio 1:10
*/
if (enable)
- mtk_phy_update_field(regs + HDMI20_CLK_CFG, REG_TXC_DIV, 3);
+ mtk_phy_update_field(regs + HDMI20_CLK_CFG, REG_TXC_DIV, VAL_TXC_DIV4);
else
mtk_phy_clear_bits(regs + HDMI20_CLK_CFG, REG_TXC_DIV);
}
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h
index 22a68dc9550ca..8e118a10ffbf2 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h
@@ -17,6 +17,9 @@
#define HDMI20_CLK_CFG 0x70
#define REG_TXC_DIV GENMASK(31, 30)
+#define VAL_TXC_DIV2 1
+#define VAL_TXC_DIV4 2
+#define VAL_TXC_DIV8 3
#define HDMI_1_CFG_0 0x00
#define RG_HDMITX21_DRV_IBIAS_CLK GENMASK(10, 5)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 104/877] ALSA: pcm: set timer->private_data before registering the PCM timer
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (102 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 103/877] phy: mediatek: phy-mtk-hdmi-mt8195: Fix TMDS clk bit ratio setting Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 105/877] ASoC: Rename snd_soc_dai_link_ch_map.ch_mask to cpu_ch_mask Greg Kroah-Hartman
` (780 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+19da64013c46df87f971,
Nguyen Ngoc Thang, Takashi Iwai, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
[ Upstream commit 1e713f9bb2ac583521f06b0eb4e22440b1e3d078 ]
snd_pcm_timer_init() calls snd_device_register() to link the new
struct snd_timer into the global timer list while it still carries
hw.c_resolution = snd_pcm_timer_resolution (and hw.start/hw.stop),
and only afterwards sets timer->private_data = substream.
Once the timer is on the list under register_mutex, a concurrent
reader can already reach it through the same mutex and invoke these
callbacks. /proc/asound/timers does this via c_resolution(), and
snd_timer_open()+snd_timer_start() reach start()/stop() the same way.
All three dereference timer->private_data, which for this brief
window is NULL, giving a NULL-pointer dereference:
substream = timer->private_data;
return substream->runtime ? ... // substream is NULL
Move the private_data/private_free assignment before
snd_device_register() so the timer is never visible on the list
without its private_data set. On the snd_device_register() failure
path, private_free() (snd_pcm_timer_free()) can now run, but it only
does substream->timer = NULL, which is already NULL at that point
since substream->timer is set to the new timer just once, after a
successful registration -- so the failure path stays safe.
Reported-by: syzbot+19da64013c46df87f971@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=19da64013c46df87f971
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
Link: https://patch.msgid.link/20260913134446.114724-1-ngocthang2710.1999@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/core/pcm_timer.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/sound/core/pcm_timer.c b/sound/core/pcm_timer.c
index ab0e5bd70f8fa..18bedd66435dc 100644
--- a/sound/core/pcm_timer.c
+++ b/sound/core/pcm_timer.c
@@ -111,12 +111,15 @@ void snd_pcm_timer_init(struct snd_pcm_substream *substream)
snd_pcm_direction_name(substream->stream),
tid.card, tid.device, tid.subdevice);
timer->hw = snd_pcm_timer;
+ /* Set before registering: a concurrent reader can invoke our hw
+ * callbacks as soon as the timer is on the global list.
+ */
+ timer->private_data = substream;
+ timer->private_free = snd_pcm_timer_free;
if (snd_device_register(timer->card, timer) < 0) {
snd_device_free(timer->card, timer);
return;
}
- timer->private_data = substream;
- timer->private_free = snd_pcm_timer_free;
substream->timer = timer;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 105/877] ASoC: Rename snd_soc_dai_link_ch_map.ch_mask to cpu_ch_mask
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (103 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 104/877] ALSA: pcm: set timer->private_data before registering the PCM timer Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 106/877] ASoC: Add codec_ch_mask to snd_soc_dai_link_ch_map Greg Kroah-Hartman
` (779 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Richard Fitzgerald, Mark Brown,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Fitzgerald <rf@opensource.cirrus.com>
[ Upstream commit 4d855d747521505b54457c96bc73577bf74b2374 ]
Rename the ch_mask member of snd_soc_dai_link_ch_map to cpu_ch_mask,
as that is what it is used for.
The CPU and codec channel masks are not necessarily the same, and are
quite likely different. SoundWire and I2S/TDM both support assigning
different sample slots to each codec, so for example channel 0 on each
codec could map to different channels at the CPU. So it's quite normal
that the channel mask at the CPU end is different for each codec, but
the codec channel masks are the same for each codec.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://patch.msgid.link/20260910114500.1586637-2-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 6b382bdfe26a ("ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/sound/soc.h | 2 +-
sound/soc/sdw_utils/soc_sdw_utils.c | 2 +-
sound/soc/soc-pcm.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h
index cd467f8babdb6..87e50c8cdda31 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -717,7 +717,7 @@ struct snd_soc_dai_link_component {
struct snd_soc_dai_link_ch_map {
unsigned int cpu;
unsigned int codec;
- unsigned int ch_mask;
+ unsigned int cpu_ch_mask;
};
struct snd_soc_dai_link {
diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c
index e6ac5c0fd3bec..70a7abede618f 100644
--- a/sound/soc/sdw_utils/soc_sdw_utils.c
+++ b/sound/soc/sdw_utils/soc_sdw_utils.c
@@ -795,7 +795,7 @@ int asoc_sdw_hw_params(struct snd_pcm_substream *substream,
* ASoC will set the corresponding channel numbers for each cpu dai.
*/
for_each_link_ch_maps(rtd->dai_link, i, ch_maps)
- ch_maps->ch_mask = ch_mask << (i * step);
+ ch_maps->cpu_ch_mask = ch_mask << (i * step);
return 0;
}
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 628322790c878..440acec700a56 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1180,7 +1180,7 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd,
*/
for_each_rtd_ch_maps(rtd, j, ch_maps)
if (ch_maps->cpu == i)
- ch_mask |= ch_maps->ch_mask;
+ ch_mask |= ch_maps->cpu_ch_mask;
/* fixup cpu channel number */
if (ch_mask)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 106/877] ASoC: Add codec_ch_mask to snd_soc_dai_link_ch_map
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (104 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 105/877] ASoC: Rename snd_soc_dai_link_ch_map.ch_mask to cpu_ch_mask Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 107/877] ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params Greg Kroah-Hartman
` (778 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Richard Fitzgerald, Mark Brown,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Fitzgerald <rf@opensource.cirrus.com>
[ Upstream commit 88b14c0d0bab5c0f3e7c641f274e3c70210c0e36 ]
Add a codec_ch_mask member to snd_soc_dai_link_ch_map.
The CPU and codec channel masks are not necessarily the same, and are
quite likely different. SoundWire and I2S/TDM both support assigning
different sample slots to each codec, so for example channel 0 on each
codec could map to different channels at the CPU.
It is also possible for one TX channel to map to multiple RX channels.
So it isn't _always_ safe to assume that the total number of set bits
in the CPU ch_mask is the same as the total number of enabled channels
on the codec.
For example consider this mapping on a capture stream:
CPU0 CODEC0 cpu_ch_mask = 0x03
CPU1 CODEC0 cpu_ch_mask = 0x03
This could be either four TX channels on the codec split across two
receiving CPUs, or two TX channels on the codec duplicated to two CPUs.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://patch.msgid.link/20260910114500.1586637-3-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 6b382bdfe26a ("ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/sound/soc.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 87e50c8cdda31..a5f8e83e6ced4 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -718,6 +718,7 @@ struct snd_soc_dai_link_ch_map {
unsigned int cpu;
unsigned int codec;
unsigned int cpu_ch_mask;
+ unsigned int codec_ch_mask;
};
struct snd_soc_dai_link {
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 107/877] ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (105 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 106/877] ASoC: Add codec_ch_mask to snd_soc_dai_link_ch_map Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-10-01 20:39 ` Harshit Mogalapalli
2026-09-30 15:16 ` [PATCH 6.12 108/877] Input: trackpoint - fix the inertia attribute name in the ABI document Greg Kroah-Hartman
` (777 subsequent siblings)
884 siblings, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Richard Fitzgerald, Mark Brown,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Fitzgerald <rf@opensource.cirrus.com>
[ Upstream commit 6b382bdfe26a2232091bf743e454e6794295783e ]
In __soc_pcm_hw_params() if there is a snd_soc_dai_link_ch_map with
non-zero codec_ch_mask, use that channel mask to restrict which channels
are enabled on the codec. But only if there isn't a TDM mask.
It is possible that a snd_soc_dai_link_ch_map could include the same codec
multiple times on different CPUs so the for_each_rtd_ch_maps() loop
accumulates the channel masks for all entries of that codec.
If a TDM mask was also set, it takes priority and is used instead of any
possible snd_soc_dai_link_ch_map entries. (They cannot be ANDed together
because the bit positions are indicating different things: TDM is a bit
for each TDM slot, codec_ch_mask is a bit for each codec channel.)
This fixes a problem of incorrect TX channels enabled on the codec when
multiple codecs are aggregated on a single capture link. For example:
- Two CPUs with six 4-channel codecs.
- The machine driver chooses to assign one channel from each codec to
one channel on the CPU
- But the codec hw_params() would be passed a channel count of 6, which
(a) is more channels than the codec has and (b) allows enabling channels
that should not be driving the audio bus.
Fixes: ac950278b087 ("ASoC: add N cpus to M codecs dai link support")
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://patch.msgid.link/20260910114500.1586637-4-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/soc-pcm.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 440acec700a56..d52771a4a723b 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1122,7 +1122,9 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd,
goto out;
for_each_rtd_codec_dais(rtd, i, codec_dai) {
- unsigned int tdm_mask = snd_soc_dai_tdm_mask_get(codec_dai, substream->stream);
+ unsigned int ch_mask = snd_soc_dai_tdm_mask_get(codec_dai, substream->stream);
+ struct snd_soc_dai_link_ch_map *ch_maps;
+ int j;
/*
* Skip CODECs which don't support the current stream type,
@@ -1144,9 +1146,15 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd,
/* copy params for each codec */
tmp_params = *params;
- /* fixup params based on TDM slot masks */
- if (tdm_mask)
- soc_pcm_codec_params_fixup(&tmp_params, tdm_mask);
+ /* fixup params based on TDM or ch_map masks */
+ if (!ch_mask) {
+ for_each_rtd_ch_maps(rtd, j, ch_maps)
+ if (ch_maps->codec == i)
+ ch_mask |= ch_maps->codec_ch_mask;
+ }
+
+ if (ch_mask)
+ soc_pcm_codec_params_fixup(&tmp_params, ch_mask);
ret = snd_soc_dai_hw_params(codec_dai, substream,
&tmp_params);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 107/877] ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params
2026-09-30 15:16 ` [PATCH 6.12 107/877] ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params Greg Kroah-Hartman
@ 2026-10-01 20:39 ` Harshit Mogalapalli
2026-10-02 12:07 ` Greg Kroah-Hartman
2026-10-02 21:10 ` Sasha Levin
0 siblings, 2 replies; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-01 20:39 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, Richard Fitzgerald, Mark Brown, Sasha Levin
On 30/09/26 8:46 pm, Greg Kroah-Hartman wrote:
> 6.12-stable review patch. If anyone has any objections, please let me know.
>
> ------------------
>
> From: Richard Fitzgerald <rf@opensource.cirrus.com>
>
> [ Upstream commit 6b382bdfe26a2232091bf743e454e6794295783e ]
>
> In __soc_pcm_hw_params() if there is a snd_soc_dai_link_ch_map with
> non-zero codec_ch_mask, use that channel mask to restrict which channels
> are enabled on the codec. But only if there isn't a TDM mask.
>
> It is possible that a snd_soc_dai_link_ch_map could include the same codec
> multiple times on different CPUs so the for_each_rtd_ch_maps() loop
> accumulates the channel masks for all entries of that codec.
>
> If a TDM mask was also set, it takes priority and is used instead of any
> possible snd_soc_dai_link_ch_map entries. (They cannot be ANDed together
> because the bit positions are indicating different things: TDM is a bit
> for each TDM slot, codec_ch_mask is a bit for each codec channel.)
>
> This fixes a problem of incorrect TX channels enabled on the codec when
> multiple codecs are aggregated on a single capture link. For example:
>
> - Two CPUs with six 4-channel codecs.
> - The machine driver chooses to assign one channel from each codec to
> one channel on the CPU
> - But the codec hw_params() would be passed a channel count of 6, which
> (a) is more channels than the codec has and (b) allows enabling channels
> that should not be driving the audio bus.
>
> Fixes: ac950278b087 ("ASoC: add N cpus to M codecs dai link support")
> Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
> Link: https://patch.msgid.link/20260910114500.1586637-4-rf@opensource.cirrus.com
> Signed-off-by: Mark Brown <broonie@kernel.org>
> Signed-off-by: Sasha Levin <sashal@kernel.org>
Hi Greg/Sasha,
An AI-assisted review flagged a possible omission. I independently
checked the core and SoundWire producer at 6.12.y f4ffa8dc360b.
The core backport correctly preserves TDM precedence and combines
codec_ch_mask entries for each codec. The question is its missing
SoundWire producer.
Upstream's companion has: 290845e151cd4e307cc1f25319583aaceb4eeb30,
sound/soc/sdw_utils/soc_sdw_utils.c:
for_each_link_ch_maps(rtd->dai_link, i, ch_maps) {
ch_maps->cpu_ch_mask = cpu_ch_mask << (i * step);
ch_maps->codec_ch_mask = codec_ch_mask;
}
6.12.y asoc_sdw_hw_params() at f4ffa8dc360bce834e6ea7b0148eab0118f4a42e,
sound/soc/sdw_utils/soc_sdw_utils.c:
for_each_link_ch_maps(rtd->dai_link, i, ch_maps)
ch_maps->cpu_ch_mask = ch_mask << (i * step);
Only the declaration and core consumer use codec_ch_mask in include/ and
sound/. SoundWire leaves it zero, so without a TDM mask the codec keeps
the aggregate channel count and capture restriction stays inactive.
Hardware impact was not tested.
Could the ASoC maintainer confirm whether
290845e151cd4e307cc1f25319583aaceb4eeb30 ("ASoC: sdw_utils: Set
snd_soc_dai_link_ch_map.codec_ch_mask for capture") should accompany
this 6.12 series to complete the SoundWire capture fix?
this is all in a series:
https://lore.kernel.org/all/20260910114500.1586637-1-rf@opensource.cirrus.com/
thanks
Harshit> ---
> sound/soc/soc-pcm.c | 16 ++++++++++++----
> 1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
> index 440acec700a56..d52771a4a723b 100644
> --- a/sound/soc/soc-pcm.c
> +++ b/sound/soc/soc-pcm.c
> @@ -1122,7 +1122,9 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd,
> goto out;
>
> for_each_rtd_codec_dais(rtd, i, codec_dai) {
> - unsigned int tdm_mask = snd_soc_dai_tdm_mask_get(codec_dai, substream->stream);
> + unsigned int ch_mask = snd_soc_dai_tdm_mask_get(codec_dai, substream->stream);
> + struct snd_soc_dai_link_ch_map *ch_maps;
> + int j;
>
> /*
> * Skip CODECs which don't support the current stream type,
> @@ -1144,9 +1146,15 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd,
> /* copy params for each codec */
> tmp_params = *params;
>
> - /* fixup params based on TDM slot masks */
> - if (tdm_mask)
> - soc_pcm_codec_params_fixup(&tmp_params, tdm_mask);
> + /* fixup params based on TDM or ch_map masks */
> + if (!ch_mask) {
> + for_each_rtd_ch_maps(rtd, j, ch_maps)
> + if (ch_maps->codec == i)
> + ch_mask |= ch_maps->codec_ch_mask;
> + }
> +
> + if (ch_mask)
> + soc_pcm_codec_params_fixup(&tmp_params, ch_mask);
>
> ret = snd_soc_dai_hw_params(codec_dai, substream,
> &tmp_params);
^ permalink raw reply [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 107/877] ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params
2026-10-01 20:39 ` Harshit Mogalapalli
@ 2026-10-02 12:07 ` Greg Kroah-Hartman
2026-10-02 13:09 ` Richard Fitzgerald
2026-10-02 21:10 ` Sasha Levin
1 sibling, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-02 12:07 UTC (permalink / raw)
To: Harshit Mogalapalli
Cc: stable, patches, Richard Fitzgerald, Mark Brown, Sasha Levin
On Fri, Oct 02, 2026 at 02:09:11AM +0530, Harshit Mogalapalli wrote:
>
>
> On 30/09/26 8:46 pm, Greg Kroah-Hartman wrote:
> > 6.12-stable review patch. If anyone has any objections, please let me know.
> >
> > ------------------
> >
> > From: Richard Fitzgerald <rf@opensource.cirrus.com>
> >
> > [ Upstream commit 6b382bdfe26a2232091bf743e454e6794295783e ]
> >
> > In __soc_pcm_hw_params() if there is a snd_soc_dai_link_ch_map with
> > non-zero codec_ch_mask, use that channel mask to restrict which channels
> > are enabled on the codec. But only if there isn't a TDM mask.
> >
> > It is possible that a snd_soc_dai_link_ch_map could include the same codec
> > multiple times on different CPUs so the for_each_rtd_ch_maps() loop
> > accumulates the channel masks for all entries of that codec.
> >
> > If a TDM mask was also set, it takes priority and is used instead of any
> > possible snd_soc_dai_link_ch_map entries. (They cannot be ANDed together
> > because the bit positions are indicating different things: TDM is a bit
> > for each TDM slot, codec_ch_mask is a bit for each codec channel.)
> >
> > This fixes a problem of incorrect TX channels enabled on the codec when
> > multiple codecs are aggregated on a single capture link. For example:
> >
> > - Two CPUs with six 4-channel codecs.
> > - The machine driver chooses to assign one channel from each codec to
> > one channel on the CPU
> > - But the codec hw_params() would be passed a channel count of 6, which
> > (a) is more channels than the codec has and (b) allows enabling channels
> > that should not be driving the audio bus.
> >
> > Fixes: ac950278b087 ("ASoC: add N cpus to M codecs dai link support")
> > Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
> > Link: https://patch.msgid.link/20260910114500.1586637-4-rf@opensource.cirrus.com
> > Signed-off-by: Mark Brown <broonie@kernel.org>
> > Signed-off-by: Sasha Levin <sashal@kernel.org>
>
> Hi Greg/Sasha,
>
> An AI-assisted review flagged a possible omission. I independently
> checked the core and SoundWire producer at 6.12.y f4ffa8dc360b.
>
> The core backport correctly preserves TDM precedence and combines
> codec_ch_mask entries for each codec. The question is its missing
> SoundWire producer.
>
> Upstream's companion has: 290845e151cd4e307cc1f25319583aaceb4eeb30,
> sound/soc/sdw_utils/soc_sdw_utils.c:
>
> for_each_link_ch_maps(rtd->dai_link, i, ch_maps) {
> ch_maps->cpu_ch_mask = cpu_ch_mask << (i * step);
> ch_maps->codec_ch_mask = codec_ch_mask;
> }
>
> 6.12.y asoc_sdw_hw_params() at f4ffa8dc360bce834e6ea7b0148eab0118f4a42e,
> sound/soc/sdw_utils/soc_sdw_utils.c:
>
> for_each_link_ch_maps(rtd->dai_link, i, ch_maps)
> ch_maps->cpu_ch_mask = ch_mask << (i * step);
>
> Only the declaration and core consumer use codec_ch_mask in include/ and
> sound/. SoundWire leaves it zero, so without a TDM mask the codec keeps
> the aggregate channel count and capture restriction stays inactive.
> Hardware impact was not tested.
>
> Could the ASoC maintainer confirm whether
> 290845e151cd4e307cc1f25319583aaceb4eeb30 ("ASoC: sdw_utils: Set
> snd_soc_dai_link_ch_map.codec_ch_mask for capture") should accompany
> this 6.12 series to complete the SoundWire capture fix?
If that is true, then that needs to be backported to all stable kernel
trees.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 107/877] ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params
2026-10-02 12:07 ` Greg Kroah-Hartman
@ 2026-10-02 13:09 ` Richard Fitzgerald
0 siblings, 0 replies; 922+ messages in thread
From: Richard Fitzgerald @ 2026-10-02 13:09 UTC (permalink / raw)
To: Greg Kroah-Hartman, Harshit Mogalapalli
Cc: stable, patches, Mark Brown, Sasha Levin
On 02/10/2026 1:07 pm, Greg Kroah-Hartman wrote:
> On Fri, Oct 02, 2026 at 02:09:11AM +0530, Harshit Mogalapalli wrote:
>>
>>
>> On 30/09/26 8:46 pm, Greg Kroah-Hartman wrote:
>>> 6.12-stable review patch. If anyone has any objections, please let me know.
>>>
>>> ------------------
>>>
>>> From: Richard Fitzgerald <rf@opensource.cirrus.com>
>>>
>>> [ Upstream commit 6b382bdfe26a2232091bf743e454e6794295783e ]
>>>
>>> In __soc_pcm_hw_params() if there is a snd_soc_dai_link_ch_map with
>>> non-zero codec_ch_mask, use that channel mask to restrict which channels
>>> are enabled on the codec. But only if there isn't a TDM mask.
>>>
>>> It is possible that a snd_soc_dai_link_ch_map could include the same codec
>>> multiple times on different CPUs so the for_each_rtd_ch_maps() loop
>>> accumulates the channel masks for all entries of that codec.
>>>
>>> If a TDM mask was also set, it takes priority and is used instead of any
>>> possible snd_soc_dai_link_ch_map entries. (They cannot be ANDed together
>>> because the bit positions are indicating different things: TDM is a bit
>>> for each TDM slot, codec_ch_mask is a bit for each codec channel.)
>>>
>>> This fixes a problem of incorrect TX channels enabled on the codec when
>>> multiple codecs are aggregated on a single capture link. For example:
>>>
>>> - Two CPUs with six 4-channel codecs.
>>> - The machine driver chooses to assign one channel from each codec to
>>> one channel on the CPU
>>> - But the codec hw_params() would be passed a channel count of 6, which
>>> (a) is more channels than the codec has and (b) allows enabling channels
>>> that should not be driving the audio bus.
>>>
>>> Fixes: ac950278b087 ("ASoC: add N cpus to M codecs dai link support")
>>> Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
>>> Link: https://patch.msgid.link/20260910114500.1586637-4-rf@opensource.cirrus.com
>>> Signed-off-by: Mark Brown <broonie@kernel.org>
>>> Signed-off-by: Sasha Levin <sashal@kernel.org>
>>
>> Hi Greg/Sasha,
>>
>> An AI-assisted review flagged a possible omission. I independently
>> checked the core and SoundWire producer at 6.12.y f4ffa8dc360b.
>>
>> The core backport correctly preserves TDM precedence and combines
>> codec_ch_mask entries for each codec. The question is its missing
>> SoundWire producer.
>>
>> Upstream's companion has: 290845e151cd4e307cc1f25319583aaceb4eeb30,
>> sound/soc/sdw_utils/soc_sdw_utils.c:
>>
>> for_each_link_ch_maps(rtd->dai_link, i, ch_maps) {
>> ch_maps->cpu_ch_mask = cpu_ch_mask << (i * step);
>> ch_maps->codec_ch_mask = codec_ch_mask;
>> }
>>
>> 6.12.y asoc_sdw_hw_params() at f4ffa8dc360bce834e6ea7b0148eab0118f4a42e,
>> sound/soc/sdw_utils/soc_sdw_utils.c:
>>
>> for_each_link_ch_maps(rtd->dai_link, i, ch_maps)
>> ch_maps->cpu_ch_mask = ch_mask << (i * step);
>>
>> Only the declaration and core consumer use codec_ch_mask in include/ and
>> sound/. SoundWire leaves it zero, so without a TDM mask the codec keeps
>> the aggregate channel count and capture restriction stays inactive.
>> Hardware impact was not tested.
>>
>> Could the ASoC maintainer confirm whether
>> 290845e151cd4e307cc1f25319583aaceb4eeb30 ("ASoC: sdw_utils: Set
>> snd_soc_dai_link_ch_map.codec_ch_mask for capture") should accompany
>> this 6.12 series to complete the SoundWire capture fix?
>
> If that is true, then that needs to be backported to all stable kernel
> trees.
>
> thanks,
>
> greg k-h
It's likely not a critical omission if nobody has noticed the bug before
now.
So I'd guess all currently shipping products just happen to work (either
it's a single codec so no aggregation, or 2 stereo amp so the incorrect
channel count of 2 is supported by the codec driver anyway).
However, I can only speak for Cirrus Logic amps, which aren't
_currently_ using this (but will in future). I can't say whether there
is other silicon that uses this and is in fact broken without anyone
having noticed.
^ permalink raw reply [flat|nested] 922+ messages in thread
* Re: [PATCH 6.12 107/877] ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params
2026-10-01 20:39 ` Harshit Mogalapalli
2026-10-02 12:07 ` Greg Kroah-Hartman
@ 2026-10-02 21:10 ` Sasha Levin
1 sibling, 0 replies; 922+ messages in thread
From: Sasha Levin @ 2026-10-02 21:10 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: Sasha Levin, patches, Richard Fitzgerald, Mark Brown,
Harshit Mogalapalli
> Could the ASoC maintainer confirm whether
> 290845e151cd4e307cc1f25319583aaceb4eeb30 ("ASoC: sdw_utils: Set
> snd_soc_dai_link_ch_map.codec_ch_mask for capture") should accompany
> this 6.12 series to complete the SoundWire capture fix?
Queued for 7.2, 6.18 and 6.12, thanks.
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 922+ messages in thread
* [PATCH 6.12 108/877] Input: trackpoint - fix the inertia attribute name in the ABI document
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (106 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 107/877] ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 109/877] gpio: virtuser: skip free_irq when no IRQ is installed Greg Kroah-Hartman
` (776 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Dmitry Torokhov,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
[ Upstream commit 45b0037899704caf9078be2be4de69361ca7d933 ]
The attribute is created as "inertia" (TRACKPOINT_INT_ATTR(inertia, ...)
in drivers/input/mouse/trackpoint.c); the ABI file spells the path
"intertia". The description below it already says inertia.
Fix the spelling.
Fixes: aebb47d4e7a9 ("Input: trackpoint: document sysfs interface")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Link: https://patch.msgid.link/20260905102038.42882-1-kmehltretter@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/ABI/testing/sysfs-devices-platform-trackpoint | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/ABI/testing/sysfs-devices-platform-trackpoint b/Documentation/ABI/testing/sysfs-devices-platform-trackpoint
index df11901a6b3df..7954434b0434a 100644
--- a/Documentation/ABI/testing/sysfs-devices-platform-trackpoint
+++ b/Documentation/ABI/testing/sysfs-devices-platform-trackpoint
@@ -5,7 +5,7 @@ Contact: linux-input@vger.kernel.org
Description:
(RW) Trackpoint sensitivity.
-What: /sys/devices/platform/i8042/.../intertia
+What: /sys/devices/platform/i8042/.../inertia
Date: Aug, 2005
KernelVersion: 2.6.14
Contact: linux-input@vger.kernel.org
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 109/877] gpio: virtuser: skip free_irq when no IRQ is installed
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (107 preceding siblings ...)
2026-09-30 15:16 ` [PATCH 6.12 108/877] Input: trackpoint - fix the inertia attribute name in the ABI document Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 110/877] ALSA: 6fire: Clean ups with guard() Greg Kroah-Hartman
` (775 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Runyu Xiao, Linus Walleij,
Bartosz Golaszewski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Runyu Xiao <runyu.xiao@seu.edu.cn>
[ Upstream commit 50fd0ada8d37587223001600933270b59cb30e19 ]
Disabling interrupt monitoring uses atomic_xchg() to clear the stored IRQ.
When monitoring is already disabled, atomic_xchg() returns 0. It must not
be passed to free_irq().
The bug is reproducible on an x86_64 QEMU guest with
CONFIG_GPIO_VIRTUSER=y and CONFIG_GPIO_SIM=y. Configure a live
gpio-virtuser device through configfs. Its input lookup must refer to a
live gpio-sim bank, such as key gpio-sim-test with offset 0. The
consumer's dev_name attribute is shown as <dev> below; then run:
echo 0 > /sys/kernel/debug/gpio-virtuser/<dev>/gpiod:input:0/interrupts
On an unpatched kernel, this reaches gpio_virtuser_interrupts_set() with
ld->irq still at its initial value 0, and free_irq() reports:
Trying to free already-free IRQ 0
The same reproducer completes without the warning on the patched kernel.
Fixes: 91581c4b3f29 ("gpio: virtuser: new virtual testing driver for the GPIO API")
Assisted-by: LLM
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260914051537.15320-1-runyu.xiao@seu.edu.cn
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpio/gpio-virtuser.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpio/gpio-virtuser.c b/drivers/gpio/gpio-virtuser.c
index ff1977b269914..5de9cee51fd08 100644
--- a/drivers/gpio/gpio-virtuser.c
+++ b/drivers/gpio/gpio-virtuser.c
@@ -698,7 +698,8 @@ static int gpio_virtuser_interrupts_set(void *data, u64 val)
atomic_set(&ld->irq, irq);
} else {
irq = atomic_xchg(&ld->irq, 0);
- free_irq(irq, ld);
+ if (irq)
+ free_irq(irq, ld);
}
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 110/877] ALSA: 6fire: Clean ups with guard()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (108 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 109/877] gpio: virtuser: skip free_irq when no IRQ is installed Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 111/877] ALSA: usb: 6fire: Avoid embedded URBs Greg Kroah-Hartman
` (774 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Takashi Iwai, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <tiwai@suse.de>
[ Upstream commit 6ff0d95774f0c728f96b8f78367318e95e09ee64 ]
Simple code cleanups with the guard() for spinlock and mutex.
No functional changes.
Link: https://patch.msgid.link/20250811082231.31498-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Stable-dep-of: 1589afe2d099 ("ALSA: 6fire: fix OOB write from device-reported iso length")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/6fire/chip.c | 40 ++++++++++----------
sound/usb/6fire/midi.c | 21 +++--------
sound/usb/6fire/pcm.c | 83 ++++++++++++++++++------------------------
3 files changed, 59 insertions(+), 85 deletions(-)
diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c
index e5916c6b75aea..30b240e06a8c8 100644
--- a/sound/usb/6fire/chip.c
+++ b/sound/usb/6fire/chip.c
@@ -83,24 +83,22 @@ static int usb6fire_chip_probe(struct usb_interface *intf,
struct snd_card *card = NULL;
/* look if we already serve this card and return if so */
- mutex_lock(®ister_mutex);
- for (i = 0; i < SNDRV_CARDS; i++) {
- if (devices[i] == device) {
- if (chips[i])
- chips[i]->intf_count++;
- usb_set_intfdata(intf, chips[i]);
- mutex_unlock(®ister_mutex);
- return 0;
- } else if (!devices[i] && regidx < 0)
- regidx = i;
- }
- if (regidx < 0) {
- mutex_unlock(®ister_mutex);
- dev_err(&intf->dev, "too many cards registered.\n");
- return -ENODEV;
+ scoped_guard(mutex, ®ister_mutex) {
+ for (i = 0; i < SNDRV_CARDS; i++) {
+ if (devices[i] == device) {
+ if (chips[i])
+ chips[i]->intf_count++;
+ usb_set_intfdata(intf, chips[i]);
+ return 0;
+ } else if (!devices[i] && regidx < 0)
+ regidx = i;
+ }
+ if (regidx < 0) {
+ dev_err(&intf->dev, "too many cards registered.\n");
+ return -ENODEV;
+ }
+ devices[regidx] = device;
}
- devices[regidx] = device;
- mutex_unlock(®ister_mutex);
/* check, if firmware is present on device, upload it if not */
ret = usb6fire_fw_init(intf);
@@ -175,10 +173,10 @@ static void usb6fire_chip_disconnect(struct usb_interface *intf)
if (chip) { /* if !chip, fw upload has been performed */
chip->intf_count--;
if (!chip->intf_count) {
- mutex_lock(®ister_mutex);
- devices[chip->regidx] = NULL;
- chips[chip->regidx] = NULL;
- mutex_unlock(®ister_mutex);
+ scoped_guard(mutex, ®ister_mutex) {
+ devices[chip->regidx] = NULL;
+ chips[chip->regidx] = NULL;
+ }
/*
* Save card pointer before teardown.
diff --git a/sound/usb/6fire/midi.c b/sound/usb/6fire/midi.c
index de2691d58de6e..6c6bccc0c410d 100644
--- a/sound/usb/6fire/midi.c
+++ b/sound/usb/6fire/midi.c
@@ -23,9 +23,8 @@ static void usb6fire_midi_out_handler(struct urb *urb)
{
struct midi_runtime *rt = urb->context;
int ret;
- unsigned long flags;
- spin_lock_irqsave(&rt->out_lock, flags);
+ guard(spinlock_irqsave)(&rt->out_lock);
if (rt->out) {
ret = snd_rawmidi_transmit(rt->out, rt->out_buffer + 4,
@@ -43,18 +42,14 @@ static void usb6fire_midi_out_handler(struct urb *urb)
} else /* no more data to transmit */
rt->out = NULL;
}
- spin_unlock_irqrestore(&rt->out_lock, flags);
}
static void usb6fire_midi_in_received(
struct midi_runtime *rt, u8 *data, int length)
{
- unsigned long flags;
-
- spin_lock_irqsave(&rt->in_lock, flags);
+ guard(spinlock_irqsave)(&rt->in_lock);
if (rt->in)
snd_rawmidi_receive(rt->in, data, length);
- spin_unlock_irqrestore(&rt->in_lock, flags);
}
static int usb6fire_midi_out_open(struct snd_rawmidi_substream *alsa_sub)
@@ -73,14 +68,11 @@ static void usb6fire_midi_out_trigger(
struct midi_runtime *rt = alsa_sub->rmidi->private_data;
struct urb *urb = &rt->out_urb;
__s8 ret;
- unsigned long flags;
- spin_lock_irqsave(&rt->out_lock, flags);
+ guard(spinlock_irqsave)(&rt->out_lock);
if (up) { /* start transfer */
- if (rt->out) { /* we are already transmitting so just return */
- spin_unlock_irqrestore(&rt->out_lock, flags);
+ if (rt->out) /* we are already transmitting so just return */
return;
- }
ret = snd_rawmidi_transmit(alsa_sub, rt->out_buffer + 4,
MIDI_BUFSIZE - 4);
@@ -99,7 +91,6 @@ static void usb6fire_midi_out_trigger(
}
} else if (rt->out == alsa_sub)
rt->out = NULL;
- spin_unlock_irqrestore(&rt->out_lock, flags);
}
static void usb6fire_midi_out_drain(struct snd_rawmidi_substream *alsa_sub)
@@ -125,14 +116,12 @@ static void usb6fire_midi_in_trigger(
struct snd_rawmidi_substream *alsa_sub, int up)
{
struct midi_runtime *rt = alsa_sub->rmidi->private_data;
- unsigned long flags;
- spin_lock_irqsave(&rt->in_lock, flags);
+ guard(spinlock_irqsave)(&rt->in_lock);
if (up)
rt->in = alsa_sub;
else
rt->in = NULL;
- spin_unlock_irqrestore(&rt->in_lock, flags);
}
static const struct snd_rawmidi_ops out_ops = {
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c
index 32c39d8bd2e55..14d23e3103989 100644
--- a/sound/usb/6fire/pcm.c
+++ b/sound/usb/6fire/pcm.c
@@ -289,7 +289,7 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
struct pcm_urb *out_urb = in_urb->peer;
struct pcm_runtime *rt = in_urb->chip->pcm;
struct pcm_substream *sub;
- unsigned long flags;
+ bool period_elapsed;
int total_length = 0;
int frame_count;
int frame;
@@ -313,17 +313,18 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
/* receive our capture data */
sub = &rt->capture;
- spin_lock_irqsave(&sub->lock, flags);
- if (sub->active) {
- usb6fire_pcm_capture(sub, in_urb);
- if (sub->period_off >= sub->instance->runtime->period_size) {
- sub->period_off %= sub->instance->runtime->period_size;
- spin_unlock_irqrestore(&sub->lock, flags);
- snd_pcm_period_elapsed(sub->instance);
- } else
- spin_unlock_irqrestore(&sub->lock, flags);
- } else
- spin_unlock_irqrestore(&sub->lock, flags);
+ period_elapsed = false;
+ scoped_guard(spinlock_irqsave, &sub->lock) {
+ if (sub->active) {
+ usb6fire_pcm_capture(sub, in_urb);
+ if (sub->period_off >= sub->instance->runtime->period_size) {
+ sub->period_off %= sub->instance->runtime->period_size;
+ period_elapsed = true;
+ }
+ }
+ }
+ if (period_elapsed)
+ snd_pcm_period_elapsed(sub->instance);
/* setup out urb structure */
for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
@@ -338,17 +339,18 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
/* now send our playback data (if a free out urb was found) */
sub = &rt->playback;
- spin_lock_irqsave(&sub->lock, flags);
- if (sub->active) {
- usb6fire_pcm_playback(sub, out_urb);
- if (sub->period_off >= sub->instance->runtime->period_size) {
- sub->period_off %= sub->instance->runtime->period_size;
- spin_unlock_irqrestore(&sub->lock, flags);
- snd_pcm_period_elapsed(sub->instance);
- } else
- spin_unlock_irqrestore(&sub->lock, flags);
- } else
- spin_unlock_irqrestore(&sub->lock, flags);
+ period_elapsed = false;
+ scoped_guard(spinlock_irqsave, &sub->lock) {
+ if (sub->active) {
+ usb6fire_pcm_playback(sub, out_urb);
+ if (sub->period_off >= sub->instance->runtime->period_size) {
+ sub->period_off %= sub->instance->runtime->period_size;
+ period_elapsed = true;
+ }
+ }
+ }
+ if (period_elapsed)
+ snd_pcm_period_elapsed(sub->instance);
/* setup the 4th byte of each sample (0x40 for analog channels) */
dest = out_urb->buffer;
@@ -392,7 +394,7 @@ static int usb6fire_pcm_open(struct snd_pcm_substream *alsa_sub)
if (rt->panic)
return -EPIPE;
- mutex_lock(&rt->stream_mutex);
+ guard(mutex)(&rt->stream_mutex);
alsa_rt->hw = pcm_hw;
if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -408,14 +410,12 @@ static int usb6fire_pcm_open(struct snd_pcm_substream *alsa_sub)
}
if (!sub) {
- mutex_unlock(&rt->stream_mutex);
dev_err(&rt->chip->dev->dev, "invalid stream type.\n");
return -EINVAL;
}
sub->instance = alsa_sub;
sub->active = false;
- mutex_unlock(&rt->stream_mutex);
return 0;
}
@@ -423,18 +423,17 @@ static int usb6fire_pcm_close(struct snd_pcm_substream *alsa_sub)
{
struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
- unsigned long flags;
if (rt->panic)
return 0;
- mutex_lock(&rt->stream_mutex);
+ guard(mutex)(&rt->stream_mutex);
if (sub) {
/* deactivate substream */
- spin_lock_irqsave(&sub->lock, flags);
- sub->instance = NULL;
- sub->active = false;
- spin_unlock_irqrestore(&sub->lock, flags);
+ scoped_guard(spinlock_irqsave, &sub->lock) {
+ sub->instance = NULL;
+ sub->active = false;
+ }
/* all substreams closed? if so, stop streaming */
if (!rt->playback.instance && !rt->capture.instance) {
@@ -442,7 +441,6 @@ static int usb6fire_pcm_close(struct snd_pcm_substream *alsa_sub)
rt->rate = ARRAY_SIZE(rates);
}
}
- mutex_unlock(&rt->stream_mutex);
return 0;
}
@@ -458,7 +456,7 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
if (!sub)
return -ENODEV;
- mutex_lock(&rt->stream_mutex);
+ guard(mutex)(&rt->stream_mutex);
sub->dma_off = 0;
sub->period_off = 0;
@@ -467,7 +465,6 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
if (alsa_rt->rate == rates[rt->rate])
break;
if (rt->rate == ARRAY_SIZE(rates)) {
- mutex_unlock(&rt->stream_mutex);
dev_err(&rt->chip->dev->dev,
"invalid rate %d in prepare.\n",
alsa_rt->rate);
@@ -475,19 +472,15 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
}
ret = usb6fire_pcm_set_rate(rt);
- if (ret) {
- mutex_unlock(&rt->stream_mutex);
+ if (ret)
return ret;
- }
ret = usb6fire_pcm_stream_start(rt);
if (ret) {
- mutex_unlock(&rt->stream_mutex);
dev_err(&rt->chip->dev->dev,
"could not start pcm stream.\n");
return ret;
}
}
- mutex_unlock(&rt->stream_mutex);
return 0;
}
@@ -495,26 +488,22 @@ static int usb6fire_pcm_trigger(struct snd_pcm_substream *alsa_sub, int cmd)
{
struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
- unsigned long flags;
if (rt->panic)
return -EPIPE;
if (!sub)
return -ENODEV;
+ guard(spinlock_irqsave)(&sub->lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- spin_lock_irqsave(&sub->lock, flags);
sub->active = true;
- spin_unlock_irqrestore(&sub->lock, flags);
return 0;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- spin_lock_irqsave(&sub->lock, flags);
sub->active = false;
- spin_unlock_irqrestore(&sub->lock, flags);
return 0;
default:
@@ -527,15 +516,13 @@ static snd_pcm_uframes_t usb6fire_pcm_pointer(
{
struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
- unsigned long flags;
snd_pcm_uframes_t ret;
if (rt->panic || !sub)
return SNDRV_PCM_POS_XRUN;
- spin_lock_irqsave(&sub->lock, flags);
+ guard(spinlock_irqsave)(&sub->lock);
ret = sub->dma_off;
- spin_unlock_irqrestore(&sub->lock, flags);
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 111/877] ALSA: usb: 6fire: Avoid embedded URBs
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (109 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 110/877] ALSA: 6fire: Clean ups with guard() Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 112/877] ALSA: 6fire: fix OOB write from device-reported iso length Greg Kroah-Hartman
` (773 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Takashi Iwai, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <tiwai@suse.de>
[ Upstream commit 9fe49dbc023e82dfaee7b245997d820d01742a9a ]
The USB 6fire driver uses URBs embedded in different structs for PCM,
MIDI and communication, and this is basically a buggy implementation
nowadays; since a URB is managed with a refcount, this may lead to a
UAF when the URB is released asynchronously.
For addressing the problem, this patch converts those embedded URBs to
ones that are properly allocated via usb_alloc_urb(). The
pcm_urb.packets[] is gone, as it's allocated by usb_alloc_urb(), hence
it's found in urb.iso_frame_desc[] instead.
The conversions are rather straightforward; each embedded struct urb
is changed to a pointer, and its callers are updated accordingly.
The resource for those structs are released in the common destructor
functions (usb6fire_comm_free(), etc), which are called at both the
init error path and the disconnect.
No functional changes, only compile-tested.
Link: https://lore.kernel.org/20260903130757.0668310a.michal.pecio@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260903160458.1938392-4-tiwai@suse.de
Stable-dep-of: 1589afe2d099 ("ALSA: 6fire: fix OOB write from device-reported iso length")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/6fire/comm.c | 42 +++++++++-----
sound/usb/6fire/comm.h | 2 +-
sound/usb/6fire/midi.c | 43 +++++++++-----
sound/usb/6fire/midi.h | 2 +-
sound/usb/6fire/pcm.c | 128 ++++++++++++++++++++++++-----------------
sound/usb/6fire/pcm.h | 5 +-
6 files changed, 136 insertions(+), 86 deletions(-)
diff --git a/sound/usb/6fire/comm.c b/sound/usb/6fire/comm.c
index bcfb34db37d95..cfaaad9d24028 100644
--- a/sound/usb/6fire/comm.c
+++ b/sound/usb/6fire/comm.c
@@ -21,7 +21,6 @@ enum {
static void usb6fire_comm_init_urb(struct comm_runtime *rt, struct urb *urb,
u8 *buffer, void *context, void(*handler)(struct urb *urb))
{
- usb_init_urb(urb);
urb->transfer_buffer = buffer;
urb->pipe = usb_sndintpipe(rt->chip->dev, COMM_EP);
urb->complete = handler;
@@ -142,6 +141,19 @@ static int usb6fire_comm_write16(struct comm_runtime *rt, u8 request,
return ret;
}
+static void usb6fire_comm_free(struct comm_runtime *rt)
+{
+ if (!rt)
+ return;
+
+ if (rt->chip)
+ rt->chip->comm = NULL;
+
+ usb_free_urb(rt->receiver);
+ kfree(rt->receiver_buffer);
+ kfree(rt);
+}
+
int usb6fire_comm_init(struct sfire_chip *chip)
{
struct comm_runtime *rt = kzalloc(sizeof(struct comm_runtime),
@@ -154,14 +166,18 @@ int usb6fire_comm_init(struct sfire_chip *chip)
rt->receiver_buffer = kzalloc(COMM_RECEIVER_BUFSIZE, GFP_KERNEL);
if (!rt->receiver_buffer) {
- kfree(rt);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto error;
}
- urb = &rt->receiver;
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ ret = -ENOMEM;
+ goto error;
+ }
+ rt->receiver = urb;
rt->serial = 1;
rt->chip = chip;
- usb_init_urb(urb);
rt->init_urb = usb6fire_comm_init_urb;
rt->write8 = usb6fire_comm_write8;
rt->write16 = usb6fire_comm_write16;
@@ -176,13 +192,15 @@ int usb6fire_comm_init(struct sfire_chip *chip)
urb->interval = 1;
ret = usb_submit_urb(urb, GFP_KERNEL);
if (ret < 0) {
- kfree(rt->receiver_buffer);
- kfree(rt);
dev_err(&chip->dev->dev, "cannot create comm data receiver.");
- return ret;
+ goto error;
}
chip->comm = rt;
return 0;
+
+ error:
+ usb6fire_comm_free(rt);
+ return ret;
}
void usb6fire_comm_abort(struct sfire_chip *chip)
@@ -190,14 +208,10 @@ void usb6fire_comm_abort(struct sfire_chip *chip)
struct comm_runtime *rt = chip->comm;
if (rt)
- usb_poison_urb(&rt->receiver);
+ usb_poison_urb(rt->receiver);
}
void usb6fire_comm_destroy(struct sfire_chip *chip)
{
- struct comm_runtime *rt = chip->comm;
-
- kfree(rt->receiver_buffer);
- kfree(rt);
- chip->comm = NULL;
+ usb6fire_comm_free(chip->comm);
}
diff --git a/sound/usb/6fire/comm.h b/sound/usb/6fire/comm.h
index 2447d7ecf1798..89976f510f6c2 100644
--- a/sound/usb/6fire/comm.h
+++ b/sound/usb/6fire/comm.h
@@ -19,7 +19,7 @@ enum /* settings for comm */
struct comm_runtime {
struct sfire_chip *chip;
- struct urb receiver;
+ struct urb *receiver;
u8 *receiver_buffer;
u8 serial; /* urb serial */
diff --git a/sound/usb/6fire/midi.c b/sound/usb/6fire/midi.c
index 6c6bccc0c410d..9a1dd5b6557c7 100644
--- a/sound/usb/6fire/midi.c
+++ b/sound/usb/6fire/midi.c
@@ -66,7 +66,7 @@ static void usb6fire_midi_out_trigger(
struct snd_rawmidi_substream *alsa_sub, int up)
{
struct midi_runtime *rt = alsa_sub->rmidi->private_data;
- struct urb *urb = &rt->out_urb;
+ struct urb *urb = rt->out_urb;
__s8 ret;
guard(spinlock_irqsave)(&rt->out_lock);
@@ -137,6 +137,19 @@ static const struct snd_rawmidi_ops in_ops = {
.trigger = usb6fire_midi_in_trigger
};
+static void usb6fire_midi_free(struct midi_runtime *rt)
+{
+ if (!rt)
+ return;
+
+ if (rt->chip)
+ rt->chip->midi = NULL;
+
+ usb_free_urb(rt->out_urb);
+ kfree(rt->out_buffer);
+ kfree(rt);
+}
+
int usb6fire_midi_init(struct sfire_chip *chip)
{
int ret;
@@ -149,8 +162,14 @@ int usb6fire_midi_init(struct sfire_chip *chip)
rt->out_buffer = kzalloc(MIDI_BUFSIZE, GFP_KERNEL);
if (!rt->out_buffer) {
- kfree(rt);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ rt->out_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!rt->out_urb) {
+ ret = -ENOMEM;
+ goto error;
}
rt->chip = chip;
@@ -161,15 +180,13 @@ int usb6fire_midi_init(struct sfire_chip *chip)
spin_lock_init(&rt->in_lock);
spin_lock_init(&rt->out_lock);
- comm_rt->init_urb(comm_rt, &rt->out_urb, rt->out_buffer, rt,
+ comm_rt->init_urb(comm_rt, rt->out_urb, rt->out_buffer, rt,
usb6fire_midi_out_handler);
ret = snd_rawmidi_new(chip->card, "6FireUSB", 0, 1, 1, &rt->instance);
if (ret < 0) {
- kfree(rt->out_buffer);
- kfree(rt);
dev_err(&chip->dev->dev, "unable to create midi.\n");
- return ret;
+ goto error;
}
rt->instance->private_data = rt;
strcpy(rt->instance->name, "DMX6FireUSB MIDI");
@@ -183,6 +200,10 @@ int usb6fire_midi_init(struct sfire_chip *chip)
chip->midi = rt;
return 0;
+
+ error:
+ usb6fire_midi_free(rt);
+ return ret;
}
void usb6fire_midi_abort(struct sfire_chip *chip)
@@ -190,14 +211,10 @@ void usb6fire_midi_abort(struct sfire_chip *chip)
struct midi_runtime *rt = chip->midi;
if (rt)
- usb_poison_urb(&rt->out_urb);
+ usb_poison_urb(rt->out_urb);
}
void usb6fire_midi_destroy(struct sfire_chip *chip)
{
- struct midi_runtime *rt = chip->midi;
-
- kfree(rt->out_buffer);
- kfree(rt);
- chip->midi = NULL;
+ usb6fire_midi_free(chip->midi);
}
diff --git a/sound/usb/6fire/midi.h b/sound/usb/6fire/midi.h
index 47640c845903b..8716ab8a863ae 100644
--- a/sound/usb/6fire/midi.h
+++ b/sound/usb/6fire/midi.h
@@ -22,7 +22,7 @@ struct midi_runtime {
spinlock_t in_lock;
spinlock_t out_lock;
struct snd_rawmidi_substream *out;
- struct urb out_urb;
+ struct urb *out_urb;
u8 out_serial; /* serial number of out packet */
u8 *out_buffer;
int buffer_offset;
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c
index 14d23e3103989..9e8f4371e89ff 100644
--- a/sound/usb/6fire/pcm.c
+++ b/sound/usb/6fire/pcm.c
@@ -138,8 +138,8 @@ static void usb6fire_pcm_stream_stop(struct pcm_runtime *rt)
rt->stream_state = STREAM_STOPPING;
for (i = 0; i < PCM_N_URBS; i++) {
- usb_kill_urb(&rt->in_urbs[i].instance);
- usb_kill_urb(&rt->out_urbs[i].instance);
+ usb_kill_urb(rt->in_urbs[i].instance);
+ usb_kill_urb(rt->out_urbs[i].instance);
}
ctrl_rt->usb_streaming = false;
ctrl_rt->update_streaming(ctrl_rt);
@@ -161,13 +161,13 @@ static int usb6fire_pcm_stream_start(struct pcm_runtime *rt)
rt->stream_state = STREAM_STARTING;
for (i = 0; i < PCM_N_URBS; i++) {
for (k = 0; k < PCM_N_PACKETS_PER_URB; k++) {
- packet = &rt->in_urbs[i].packets[k];
+ packet = &rt->in_urbs[i].instance->iso_frame_desc[k];
packet->offset = k * rt->in_packet_size;
packet->length = rt->in_packet_size;
packet->actual_length = 0;
packet->status = 0;
}
- ret = usb_submit_urb(&rt->in_urbs[i].instance,
+ ret = usb_submit_urb(rt->in_urbs[i].instance,
GFP_ATOMIC);
if (ret) {
usb6fire_pcm_stream_stop(rt);
@@ -197,6 +197,7 @@ static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb)
unsigned int total_length = 0;
struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance);
struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
+ struct usb_iso_packet_descriptor *isoc;
u32 *src = NULL;
u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off
* (alsa_rt->frame_bits >> 3));
@@ -207,8 +208,9 @@ static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb)
for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
/* at least 4 header bytes for valid packet.
* after that: 32 bits per sample for analog channels */
- if (urb->packets[i].actual_length > 4)
- frame_count = (urb->packets[i].actual_length - 4)
+ isoc = &urb->instance->iso_frame_desc[i];
+ if (isoc->actual_length > 4)
+ frame_count = (isoc->actual_length - 4)
/ (rt->in_n_analog << 2);
else
frame_count = 0;
@@ -220,7 +222,7 @@ static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb)
else
return;
src++; /* skip leading 4 bytes of every packet */
- total_length += urb->packets[i].length;
+ total_length += isoc->length;
for (frame = 0; frame < frame_count; frame++) {
memcpy(dest, src, bytes_per_frame);
dest += alsa_rt->channels;
@@ -244,6 +246,7 @@ static void usb6fire_pcm_playback(struct pcm_substream *sub,
int frame_count;
struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance);
struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
+ struct usb_iso_packet_descriptor *isoc;
u32 *src = (u32 *) (alsa_rt->dma_area + sub->dma_off
* (alsa_rt->frame_bits >> 3));
u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size
@@ -263,8 +266,9 @@ static void usb6fire_pcm_playback(struct pcm_substream *sub,
for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
/* at least 4 header bytes for valid packet.
* after that: 32 bits per sample for analog channels */
- if (urb->packets[i].length > 4)
- frame_count = (urb->packets[i].length - 4)
+ isoc = &urb->instance->iso_frame_desc[i];
+ if (isoc->length > 4)
+ frame_count = (isoc->length - 4)
/ (rt->out_n_analog << 2);
else
frame_count = 0;
@@ -289,6 +293,7 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
struct pcm_urb *out_urb = in_urb->peer;
struct pcm_runtime *rt = in_urb->chip->pcm;
struct pcm_substream *sub;
+ struct usb_iso_packet_descriptor *isoc_out, *isoc_in;
bool period_elapsed;
int total_length = 0;
int frame_count;
@@ -299,11 +304,13 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
if (usb_urb->status || rt->panic || rt->stream_state == STREAM_STOPPING)
return;
- for (i = 0; i < PCM_N_PACKETS_PER_URB; i++)
- if (in_urb->packets[i].status) {
+ for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
+ isoc_in = &in_urb->instance->iso_frame_desc[i];
+ if (isoc_in->status) {
rt->panic = true;
return;
}
+ }
if (rt->stream_state == STREAM_DISABLED) {
dev_err(&rt->chip->dev->dev,
@@ -328,12 +335,13 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
/* setup out urb structure */
for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
- out_urb->packets[i].offset = total_length;
- out_urb->packets[i].length = (in_urb->packets[i].actual_length
- - 4) / (rt->in_n_analog << 2)
+ isoc_out = &out_urb->instance->iso_frame_desc[i];
+ isoc_in = &in_urb->instance->iso_frame_desc[i];
+ isoc_out->offset = total_length;
+ isoc_out->length = (isoc_in->actual_length - 4) / (rt->in_n_analog << 2)
* (rt->out_n_analog << 2) + 4;
- out_urb->packets[i].status = 0;
- total_length += out_urb->packets[i].length;
+ isoc_out->status = 0;
+ total_length += isoc_out->length;
}
memset(out_urb->buffer, 0, total_length);
@@ -354,9 +362,10 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
/* setup the 4th byte of each sample (0x40 for analog channels) */
dest = out_urb->buffer;
- for (i = 0; i < PCM_N_PACKETS_PER_URB; i++)
- if (out_urb->packets[i].length >= 4) {
- frame_count = (out_urb->packets[i].length - 4)
+ for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
+ isoc_out = &out_urb->instance->iso_frame_desc[i];
+ if (isoc_out->length >= 4) {
+ frame_count = (isoc_out->length - 4)
/ (rt->out_n_analog << 2);
*(dest++) = 0xaa;
*(dest++) = 0xaa;
@@ -370,8 +379,10 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
*(dest++) = 0x40;
}
}
- usb_submit_urb(&out_urb->instance, GFP_ATOMIC);
- usb_submit_urb(&in_urb->instance, GFP_ATOMIC);
+ }
+
+ usb_submit_urb(out_urb->instance, GFP_ATOMIC);
+ usb_submit_urb(in_urb->instance, GFP_ATOMIC);
}
static void usb6fire_pcm_out_urb_handler(struct urb *usb_urb)
@@ -534,22 +545,25 @@ static const struct snd_pcm_ops pcm_ops = {
.pointer = usb6fire_pcm_pointer,
};
-static void usb6fire_pcm_init_urb(struct pcm_urb *urb,
- struct sfire_chip *chip, bool in, int ep,
- void (*handler)(struct urb *))
+static int usb6fire_pcm_init_urb(struct pcm_urb *urb,
+ struct sfire_chip *chip, bool in, int ep,
+ void (*handler)(struct urb *))
{
urb->chip = chip;
- usb_init_urb(&urb->instance);
- urb->instance.transfer_buffer = urb->buffer;
- urb->instance.transfer_buffer_length =
+ urb->instance = usb_alloc_urb(PCM_N_PACKETS_PER_URB, GFP_KERNEL);
+ if (!urb->instance)
+ return -ENOMEM;
+ urb->instance->transfer_buffer = urb->buffer;
+ urb->instance->transfer_buffer_length =
PCM_N_PACKETS_PER_URB * PCM_MAX_PACKET_SIZE;
- urb->instance.dev = chip->dev;
- urb->instance.pipe = in ? usb_rcvisocpipe(chip->dev, ep)
+ urb->instance->dev = chip->dev;
+ urb->instance->pipe = in ? usb_rcvisocpipe(chip->dev, ep)
: usb_sndisocpipe(chip->dev, ep);
- urb->instance.interval = 1;
- urb->instance.complete = handler;
- urb->instance.context = urb;
- urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB;
+ urb->instance->interval = 1;
+ urb->instance->complete = handler;
+ urb->instance->context = urb;
+ urb->instance->number_of_packets = PCM_N_PACKETS_PER_URB;
+ return 0;
}
static int usb6fire_pcm_buffers_init(struct pcm_runtime *rt)
@@ -571,14 +585,23 @@ static int usb6fire_pcm_buffers_init(struct pcm_runtime *rt)
return 0;
}
-static void usb6fire_pcm_buffers_destroy(struct pcm_runtime *rt)
+static void usb6fire_pcm_free(struct pcm_runtime *rt)
{
int i;
+ if (!rt)
+ return;
+
+ if (rt->chip)
+ rt->chip->pcm = NULL;
+
for (i = 0; i < PCM_N_URBS; i++) {
+ usb_free_urb(rt->out_urbs[i].instance);
kfree(rt->out_urbs[i].buffer);
+ usb_free_urb(rt->in_urbs[i].instance);
kfree(rt->in_urbs[i].buffer);
}
+ kfree(rt);
}
int usb6fire_pcm_init(struct sfire_chip *chip)
@@ -593,11 +616,8 @@ int usb6fire_pcm_init(struct sfire_chip *chip)
return -ENOMEM;
ret = usb6fire_pcm_buffers_init(rt);
- if (ret) {
- usb6fire_pcm_buffers_destroy(rt);
- kfree(rt);
- return ret;
- }
+ if (ret)
+ goto error;
rt->chip = chip;
rt->stream_state = STREAM_DISABLED;
@@ -609,10 +629,14 @@ int usb6fire_pcm_init(struct sfire_chip *chip)
spin_lock_init(&rt->capture.lock);
for (i = 0; i < PCM_N_URBS; i++) {
- usb6fire_pcm_init_urb(&rt->in_urbs[i], chip, true, IN_EP,
- usb6fire_pcm_in_urb_handler);
- usb6fire_pcm_init_urb(&rt->out_urbs[i], chip, false, OUT_EP,
- usb6fire_pcm_out_urb_handler);
+ ret = usb6fire_pcm_init_urb(&rt->in_urbs[i], chip, true, IN_EP,
+ usb6fire_pcm_in_urb_handler);
+ if (ret < 0)
+ goto error;
+ ret = usb6fire_pcm_init_urb(&rt->out_urbs[i], chip, false, OUT_EP,
+ usb6fire_pcm_out_urb_handler);
+ if (ret < 0)
+ goto error;
rt->in_urbs[i].peer = &rt->out_urbs[i];
rt->out_urbs[i].peer = &rt->in_urbs[i];
@@ -620,10 +644,8 @@ int usb6fire_pcm_init(struct sfire_chip *chip)
ret = snd_pcm_new(chip->card, "DMX6FireUSB", 0, 1, 1, &pcm);
if (ret < 0) {
- usb6fire_pcm_buffers_destroy(rt);
- kfree(rt);
dev_err(&chip->dev->dev, "cannot create pcm instance.\n");
- return ret;
+ goto error;
}
pcm->private_data = rt;
@@ -636,6 +658,10 @@ int usb6fire_pcm_init(struct sfire_chip *chip)
chip->pcm = rt;
return 0;
+
+ error:
+ usb6fire_pcm_free(rt);
+ return ret;
}
void usb6fire_pcm_abort(struct sfire_chip *chip)
@@ -653,8 +679,8 @@ void usb6fire_pcm_abort(struct sfire_chip *chip)
snd_pcm_stop_xrun(rt->capture.instance);
for (i = 0; i < PCM_N_URBS; i++) {
- usb_poison_urb(&rt->in_urbs[i].instance);
- usb_poison_urb(&rt->out_urbs[i].instance);
+ usb_poison_urb(rt->in_urbs[i].instance);
+ usb_poison_urb(rt->out_urbs[i].instance);
}
}
@@ -662,9 +688,5 @@ void usb6fire_pcm_abort(struct sfire_chip *chip)
void usb6fire_pcm_destroy(struct sfire_chip *chip)
{
- struct pcm_runtime *rt = chip->pcm;
-
- usb6fire_pcm_buffers_destroy(rt);
- kfree(rt);
- chip->pcm = NULL;
+ usb6fire_pcm_free(chip->pcm);
}
diff --git a/sound/usb/6fire/pcm.h b/sound/usb/6fire/pcm.h
index 5a092dfd69f5a..b586fe220fd11 100644
--- a/sound/usb/6fire/pcm.h
+++ b/sound/usb/6fire/pcm.h
@@ -24,10 +24,7 @@ enum /* settings for pcm */
struct pcm_urb {
struct sfire_chip *chip;
- /* BEGIN DO NOT SEPARATE */
- struct urb instance;
- struct usb_iso_packet_descriptor packets[PCM_N_PACKETS_PER_URB];
- /* END DO NOT SEPARATE */
+ struct urb *instance;
u8 *buffer;
struct pcm_urb *peer;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 112/877] ALSA: 6fire: fix OOB write from device-reported iso length
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (110 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 111/877] ALSA: usb: 6fire: Avoid embedded URBs Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 113/877] wifi: virt_wifi: dont transfer operstate before register Greg Kroah-Hartman
` (772 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, co+855929c2df672879, Xiang Mei,
Takashi Iwai, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiang Mei <xmei5@asu.edu>
[ Upstream commit 1589afe2d099d3e817873bc474676968d7080410 ]
usb6fire_pcm_in_urb_handler() sizes each outgoing isochronous packet as
(actual_length - 4) / (in_n_analog << 2) * (out_n_analog << 2) + 4, where
actual_length is the unsigned length the device reported for the matching
IN packet. A packet completed with status 0 and actual_length < 4 wraps
the subtraction to 0x7fffffec; a zero-length isochronous packet is legal
on the bus, and the preceding loop rejects only non-zero status. The sum
reaches memset() on out_urb->buffer, a 4832-byte object from
kcalloc(PCM_MAX_PACKET_SIZE, PCM_N_PACKETS_PER_URB).
Even without the wrap the result is out of bounds: at 88.2/96 kHz the
4-in/6-out scaling turns a full 420-byte IN packet into 628, so eight
packets span 5024 bytes of that buffer. usb_submit_urb() rejects an
over-long descriptor only after the memset() and the
usb6fire_pcm_playback() copy of user PCM data have run.
Guard the subtraction as the sibling usb6fire_pcm_capture() already does,
and limit the frame count to what fits in rt->out_packet_size, the OUT
endpoint's wMaxPacketSize. This bounds total_length by the buffer size
while keeping each packet length aligned to a whole output frame.
BUG: KASAN: out-of-bounds in usb6fire_pcm_in_urb_handler (sound/usb/6fire/pcm.c:338)
Write of size 18446744073709551456 at addr ffff88802a3d0000 by task vhci_rx/5018
Call Trace:
dump_stack_lvl (lib/dump_stack.c:94 lib/dump_stack.c:120)
print_report (mm/kasan/report.c:378 mm/kasan/report.c:482)
kasan_report (mm/kasan/report.c:595)
kasan_check_range (mm/kasan/generic.c:186 mm/kasan/generic.c:200)
__asan_memset (mm/kasan/shadow.c:84)
usb6fire_pcm_in_urb_handler (sound/usb/6fire/pcm.c:338)
__usb_hcd_giveback_urb (drivers/usb/core/hcd.c:1657)
usb_hcd_giveback_urb (drivers/usb/core/hcd.c:1741)
vhci_rx_loop (drivers/usb/usbip/vhci_rx.c:107 drivers/usb/usbip/vhci_rx.c:242)
kthread (kernel/kthread.c:436)
ret_from_fork (arch/x86/kernel/process.c:158)
ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
Allocated by task 10:
__kmalloc_cache_noprof (mm/slub.c:5563)
usb6fire_pcm_init (sound/usb/6fire/pcm.c:560 sound/usb/6fire/pcm.c:595)
usb6fire_chip_probe (sound/usb/6fire/chip.c:133)
usb_probe_interface (drivers/usb/core/driver.c:399)
The buggy address belongs to the object at ffff88802a3d0000
which belongs to the cache kmalloc-8k of size 8192
The buggy address is located 0 bytes inside of
4832-byte region [ffff88802a3d0000, ffff88802a3d12e0)
Kernel panic - not syncing: Fatal exception in interrupt
Fixes: c6d43ba816d1 ("ALSA: usb/6fire - Driver for TerraTec DMX 6Fire USB")
Reported-by: co+855929c2df672879@bugs.sh
Closes: https://lore.kernel.org/all/gisnub8aWGLbyZLcDCSc7zWsHonMWGcyRgt5%40bugs.sh/
Assisted-by: LLM
Signed-off-by: Xiang Mei <xmei5@asu.edu>
Link: https://patch.msgid.link/20260914074324.3590843-1-xmei5@asu.edu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/6fire/pcm.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c
index 9e8f4371e89ff..5f6a63f79990b 100644
--- a/sound/usb/6fire/pcm.c
+++ b/sound/usb/6fire/pcm.c
@@ -335,11 +335,19 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
/* setup out urb structure */
for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
+ unsigned int frames = 0;
+
isoc_out = &out_urb->instance->iso_frame_desc[i];
isoc_in = &in_urb->instance->iso_frame_desc[i];
+ if (isoc_in->actual_length > 4)
+ frames = (isoc_in->actual_length - 4)
+ / (rt->in_n_analog << 2);
+ frames = min_t(unsigned int, frames,
+ (rt->out_packet_size - 4)
+ / (rt->out_n_analog << 2));
+
isoc_out->offset = total_length;
- isoc_out->length = (isoc_in->actual_length - 4) / (rt->in_n_analog << 2)
- * (rt->out_n_analog << 2) + 4;
+ isoc_out->length = frames * (rt->out_n_analog << 2) + 4;
isoc_out->status = 0;
total_length += isoc_out->length;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 113/877] wifi: virt_wifi: dont transfer operstate before register
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (111 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 112/877] ALSA: 6fire: fix OOB write from device-reported iso length Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 114/877] drm/vc4: Use managed KMS polling to fix UAF on unbind Greg Kroah-Hartman
` (771 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Luxing Yin, Zihan Xi,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zihan Xi <zihanx@nebusec.ai>
[ Upstream commit e5c8d7acd31b27057ea42cd405d0b3ece097bc89 ]
virt_wifi_newlink() calls netif_stacked_transfer_operstate() before
register_netdevice(). If the lower device is dormant, that queues the
new netdev on lweventlist while it is still uninitialized. If
registration fails after that, for example because of an invalid name
such as "bad/name", free_netdev() immediately frees the object. A
later linkwatch_fire_event() then use-after-frees the list entry.
Move the transfer to after netdev_upper_dev_link(), as macvlan and
ipvlan already do.
Fixes: c7cdba31ed8b ("mac80211-next: rtnetlink wifi simulation device")
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Co-developed-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Link: https://patch.msgid.link/f5a832fb0ab228ce6e2b5a91fba4ca8b79198a2f.1788948455.git.zihanx@nebusec.ai
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/virtual/virt_wifi.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/virtual/virt_wifi.c b/drivers/net/wireless/virtual/virt_wifi.c
index 056d375e3f41f..4d36c15c1118e 100644
--- a/drivers/net/wireless/virtual/virt_wifi.c
+++ b/drivers/net/wireless/virtual/virt_wifi.c
@@ -554,7 +554,6 @@ static int virt_wifi_newlink(struct net *src_net, struct net_device *dev,
}
eth_hw_addr_inherit(dev, priv->lowerdev);
- netif_stacked_transfer_operstate(priv->lowerdev, dev);
dev->ieee80211_ptr = kzalloc(sizeof(*dev->ieee80211_ptr), GFP_KERNEL);
@@ -580,6 +579,8 @@ static int virt_wifi_newlink(struct net *src_net, struct net_device *dev,
goto unregister_netdev;
}
+ netif_stacked_transfer_operstate(priv->lowerdev, dev);
+
dev->priv_destructor = virt_wifi_net_device_destructor;
priv->being_deleted = false;
priv->is_connected = false;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 114/877] drm/vc4: Use managed KMS polling to fix UAF on unbind
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (112 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 113/877] wifi: virt_wifi: dont transfer operstate before register Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 115/877] ALSA: hda: trace PCM open only after assigning a stream Greg Kroah-Hartman
` (770 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Maíra Canal,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
[ Upstream commit 073a30d75f309812ed61af134f24ffef4107b13a ]
vc4_kms_load() calls drm_kms_helper_poll_init() but the driver provides
no matching drm_kms_helper_poll_fini(). The output poll work stays
scheduled after unbind and runs on the freed drm_device:
# modprobe vc4; rmmod vc4; sleep 10
BUG: KASAN: slab-use-after-free in delayed_work_timer_fn
BUG: KASAN: slab-use-after-free in drm_client_dev_hotplug [drm]
Workqueue: events output_poll_execute [drm_kms_helper]
Allocated by task 171: __devm_drm_dev_alloc
Freed by task 262 (rmmod): drm_dev_put / component_del
Use drmm_kms_helper_poll_init() so polling is finalized with the device,
as other drivers do.
Fixes: c8b75bca92cb ("drm/vc4: Add KMS support for Raspberry Pi.")
Assisted-by: Claude:claude-fable-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Link: https://patch.msgid.link/20260822143110.68594-1-kmehltretter@gmail.com
Reviewed-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/vc4/vc4_kms.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index bddfcad109501..c5e28ff3931a7 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -1084,7 +1084,7 @@ int vc4_kms_load(struct drm_device *dev)
drm_mode_config_reset(dev);
- drm_kms_helper_poll_init(dev);
+ drmm_kms_helper_poll_init(dev);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 115/877] ALSA: hda: trace PCM open only after assigning a stream
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (113 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 114/877] drm/vc4: Use managed KMS polling to fix UAF on unbind Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 116/877] wifi: ath11k: cleanup arsta in ath11k_mac_peer_cleanup_all() Greg Kroah-Hartman
` (769 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Slavin Liu, Takashi Iwai,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Slavin Liu <bolin.liu@seu.edu.cn>
[ Upstream commit c9e6e5f38bf75276605f1952b22285f5f3abcaff ]
Stream assignment can fail when hardware streams are exhausted.
Move the tracepoint after the NULL check because its payload accesses
the assigned stream tag.
Detected by static analysis and reviewed with AI-assisted source auditing.
Fixes: 184865085b88 ("ALSA: hda - rename hda_intel_trace.h to hda_controller_trace.h")
Assisted-by: LLM
Signed-off-by: Slavin Liu <bolin.liu@seu.edu.cn>
Link: https://patch.msgid.link/20260913125154.109944-1-bolin.liu@seu.edu.cn
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/pci/hda/hda_controller.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index bd13ea0c9352e..7c0574eb54c61 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -593,11 +593,11 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
snd_hda_codec_pcm_get(apcm->info);
mutex_lock(&chip->open_mutex);
azx_dev = azx_assign_device(chip, substream);
- trace_azx_pcm_open(chip, azx_dev);
if (azx_dev == NULL) {
err = -EBUSY;
goto unlock;
}
+ trace_azx_pcm_open(chip, azx_dev);
runtime->private_data = azx_dev;
runtime->hw = azx_pcm_hw;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 116/877] wifi: ath11k: cleanup arsta in ath11k_mac_peer_cleanup_all()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (114 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 115/877] ALSA: hda: trace PCM open only after assigning a stream Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 117/877] btrfs: tree-checker: print dev extent offset in error message Greg Kroah-Hartman
` (768 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolas Escande,
Rameshkumar Sundaram, Baochen Qiang, Jeff Johnson, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolas Escande <nico.escande@gmail.com>
[ Upstream commit 820b8cff81c796ba20573e04722ab62500713f97 ]
When mac80211 removes a sta, it calls .sta_state() which in turn calls
ath11k_mac_station_remove(). In that function we clean up both peers &
arsta related resources.
But when the firmware crashes, ath11k calls ieee80211_restart_hw(), which
assumes that all driver related resources are cleaned up beforehand. This
cleanup is supposedly done by ath11k_mac_peer_cleanup_all() but does not
in fact free arsta->rx_stats / tx_stats.
Extract the arsta cleanup from ath11k_mac_station_remove() into a
new ath11k_mac_station_cleanup() and call it from both there and
ath11k_mac_peer_cleanup_all().
This should handle kmemleaks reports like:
unreferenced object 0xffffff801ae66400 (size 1024):
comm "hostapd", pid 1306, jiffies 4295011565
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace (crc d61c08ec):
kmemleak_alloc+0x3c/0x50
__kmalloc_cache_noprof+0x2b0/0x3e0
ath11k_mac_op_sta_state+0x1dc/0xb10
drv_sta_state+0xac/0x6f8
sta_info_insert_rcu+0x314/0x5e0
sta_info_insert+0x14/0x38
ieee80211_add_station+0x10c/0x1a0
nl80211_new_station+0x3e8/0x680
genl_family_rcv_msg_doit+0xc0/0x120
genl_rcv_msg+0x1b4/0x258
netlink_rcv_skb+0x4c/0x108
genl_rcv+0x38/0x60
netlink_unicast+0x190/0x278
netlink_sendmsg+0x15c/0x370
____sys_sendmsg+0x120/0x290
___sys_sendmsg+0x70/0xa0
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.9.0.1-01977-QCAHKSWPL_SILICONZ-1
Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260731145830.769811-1-nico.escande@gmail.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/ath/ath11k/mac.c | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index c4856480fffe7..53bc1b90bab3c 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -873,6 +873,22 @@ static int ath11k_mac_set_kickout(struct ath11k_vif *arvif)
return 0;
}
+static void ath11k_mac_station_cleanup(struct ieee80211_sta *sta)
+{
+ struct ath11k_sta *arsta;
+
+ if (!sta)
+ return;
+
+ arsta = ath11k_sta_to_arsta(sta);
+
+ kfree(arsta->tx_stats);
+ arsta->tx_stats = NULL;
+
+ kfree(arsta->rx_stats);
+ arsta->rx_stats = NULL;
+}
+
void ath11k_mac_peer_cleanup_all(struct ath11k *ar)
{
struct ath11k_peer *peer, *tmp;
@@ -885,6 +901,7 @@ void ath11k_mac_peer_cleanup_all(struct ath11k *ar)
list_for_each_entry_safe(peer, tmp, &ab->peers, list) {
ath11k_peer_rx_tid_cleanup(ar, peer);
ath11k_peer_rhash_delete(ab, peer);
+ ath11k_mac_station_cleanup(peer->sta);
list_del(&peer->list);
kfree(peer);
}
@@ -9759,7 +9776,6 @@ static int ath11k_mac_station_remove(struct ath11k *ar,
{
struct ath11k_base *ab = ar->ab;
struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
- struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
int ret;
if (ab->hw_params.vdev_start_delay &&
@@ -9783,12 +9799,7 @@ static int ath11k_mac_station_remove(struct ath11k *ar,
sta->addr, arvif->vdev_id);
ath11k_mac_dec_num_stations(arvif, sta);
-
- kfree(arsta->tx_stats);
- arsta->tx_stats = NULL;
-
- kfree(arsta->rx_stats);
- arsta->rx_stats = NULL;
+ ath11k_mac_station_cleanup(sta);
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 117/877] btrfs: tree-checker: print dev extent offset in error message
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (115 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 116/877] wifi: ath11k: cleanup arsta in ath11k_mac_peer_cleanup_all() Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 118/877] drm/msm/dsi: round the byte clock rate after reparenting to the PHY PLL Greg Kroah-Hartman
` (767 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qu Wenruo, Filipe Manana,
David Sterba, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <fdmanana@suse.com>
[ Upstream commit a1167d9420474ab9ed9efca99d86aeb6217c0265 ]
If a dev extent's offset is not sector size aligned, the error message is
printing the dev extent's objectid instead of the offset. This is a copy
paste error, as before this check we check the objectid field.
Fixes: 008e2512dc56 ("btrfs: tree-checker: add dev extent item checks")
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/tree-checker.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c
index 92a2df6dd3a4e..6b68d87cbf446 100644
--- a/fs/btrfs/tree-checker.c
+++ b/fs/btrfs/tree-checker.c
@@ -1914,7 +1914,7 @@ static int check_dev_extent_item(const struct extent_buffer *leaf,
sectorsize))) {
generic_err(leaf, slot,
"invalid dev extent chunk offset, has %llu not aligned to %u",
- btrfs_dev_extent_chunk_objectid(leaf, de),
+ btrfs_dev_extent_chunk_offset(leaf, de),
sectorsize);
return -EUCLEAN;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 118/877] drm/msm/dsi: round the byte clock rate after reparenting to the PHY PLL
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (116 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 117/877] btrfs: tree-checker: print dev extent offset in error message Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 119/877] seg6: set IPSKB_L3SLAVE from IP6SKB_L3SLAVE on IPIP decapsulation Greg Kroah-Hartman
` (766 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Abel Vesa, Krzysztof Kozlowski,
Dmitry Baryshkov, Konrad Dybcio, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
[ Upstream commit 2028280686f4fa78e2f1f6dede4b6c1fd782b9e3 ]
DSI 6G v2.9 hosts (SM8650, SM8750, Kaanapali, etc.) reparent the byte and
pixel RCGs to the DSI PHY PLL at runtime from
dsi_link_clk_set_rate_6g_v2_9(), after the PHY has been enabled. However
dsi_calc_clk_rate_6g() runs earlier, in order to compute the bit clock
request for the PHY. At that point the byte RCG still has its reset
parent (XO), so clk_round_rate() returns a bogus rate, which then ends up
in the PHY bit clock request and the PLL gets programmed to a wrong
frequency, breaking the panel.
Move the rounding to dsi_link_clk_set_rate_6g(), which is called after
the RCGs have been reparented to the PLL. Storing the rounded rate at
this point still makes later link_clk_set_rate() calls no-ops in the
CCF. Derive the byte interface clock rate from the rounded byte clock
rate, otherwise it would keep requesting the idealized rate and
retrigger the PLL on every transfer.
Reported-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Reported-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Fixes: 6cd33b6f4155 ("drm/msm/dsi: round 6G byte clock rate to the PLL-achievable value")
Assisted-by: LLM
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Tested-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> # SM6115P J606F
Tested-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Patchwork: https://patchwork.freedesktop.org/patch/750496/
Link: https://lore.kernel.org/r/20260903-fix-eliza-dsi-v1-1-3474a6c9f2e0@oss.qualcomm.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/msm/dsi/dsi_host.c | 36 ++++++++++++++++--------------
1 file changed, 19 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 77173183509f1..cd605c75cef8e 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -120,7 +120,7 @@ struct msm_dsi_host {
struct clk *byte_intf_clk;
unsigned long byte_clk_rate;
- unsigned long byte_intf_clk_rate;
+ bool byte_intf_clk_div_2;
unsigned long pixel_clk_rate;
unsigned long esc_clk_rate;
@@ -350,8 +350,20 @@ int msm_dsi_runtime_resume(struct device *dev)
int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
{
+ unsigned long byte_intf_clk_rate;
+ long rounded_byte_clk_rate;
int ret;
+ rounded_byte_clk_rate = clk_round_rate(msm_host->byte_clk,
+ msm_host->byte_clk_rate);
+ if (rounded_byte_clk_rate < 0) {
+ pr_err("%s: failed to round byte clock rate, %ld\n",
+ __func__, rounded_byte_clk_rate);
+ return rounded_byte_clk_rate;
+ }
+
+ msm_host->byte_clk_rate = rounded_byte_clk_rate;
+
DBG("Set clk rates: pclk=%lu, byteclk=%lu",
msm_host->pixel_clk_rate, msm_host->byte_clk_rate);
@@ -369,7 +381,11 @@ int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
}
if (msm_host->byte_intf_clk) {
- ret = clk_set_rate(msm_host->byte_intf_clk, msm_host->byte_intf_clk_rate);
+ byte_intf_clk_rate = msm_host->byte_clk_rate;
+ if (msm_host->byte_intf_clk_div_2)
+ byte_intf_clk_rate /= 2;
+
+ ret = clk_set_rate(msm_host->byte_intf_clk, byte_intf_clk_rate);
if (ret) {
pr_err("%s: Failed to set rate byte intf clk, %d\n",
__func__, ret);
@@ -619,24 +635,12 @@ static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
{
- long rounded_byte_clk_rate;
-
if (!msm_host->mode) {
pr_err("%s: mode not set\n", __func__);
return -EINVAL;
}
dsi_calc_pclk(msm_host, is_bonded_dsi);
-
- rounded_byte_clk_rate = clk_round_rate(msm_host->byte_clk,
- msm_host->byte_clk_rate);
- if (rounded_byte_clk_rate < 0) {
- pr_err("%s: failed to round byte clock rate, %ld\n",
- __func__, rounded_byte_clk_rate);
- return rounded_byte_clk_rate;
- }
-
- msm_host->byte_clk_rate = rounded_byte_clk_rate;
msm_host->esc_clk_rate = clk_get_rate(msm_host->esc_clk);
return 0;
}
@@ -2419,9 +2423,7 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
goto unlock_ret;
}
- msm_host->byte_intf_clk_rate = msm_host->byte_clk_rate;
- if (phy_shared_timings->byte_intf_clk_div_2)
- msm_host->byte_intf_clk_rate /= 2;
+ msm_host->byte_intf_clk_div_2 = phy_shared_timings->byte_intf_clk_div_2;
msm_dsi_sfpb_config(msm_host, true);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 119/877] seg6: set IPSKB_L3SLAVE from IP6SKB_L3SLAVE on IPIP decapsulation
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (117 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 118/877] drm/msm/dsi: round the byte clock rate after reparenting to the PHY PLL Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 120/877] ipv4: icmp: reject RTN_UNREACHABLE input routes in icmp_route_lookup Greg Kroah-Hartman
` (765 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andrea Mayer, David Ahern,
Hangbin Liu, Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrea Mayer <andrea.mayer@uniroma2.it>
[ Upstream commit 7616242a2b37883f7322aaa1d2bd6cd0fed28315 ]
When an SRv6 packet arrives on an interface enslaved to a VRF,
vrf_ip6_rcv() sets IP6SKB_L3SLAVE in IP6CB, but decap_and_validate()
has never set IPSKB_L3SLAVE in IPCB. The bit stayed clear in the
common case, and with CONFIG_IPV6_MIP6 the leftover frag_max_size of
a reassembled outer packet could even set it, with no VRF involved.
Commit 44930446dde4 ("ipv6: seg6: clear IPv4 control block on IPIP
decapsulation") then made the unreliable bit reliably clear.
The effect of the missing flag is visible with End.DX4 when a
delivery to a local address of the node reaches the socket lookup.
For example, a UDP socket bound to the enslaved ingress interface
does not receive any of the decapsulated packets, while an unbound
socket outside the VRF does.
This contradicts Documentation/networking/vrf.rst: by default the
scope of an unbound UDP or TCP socket is limited to the default VRF.
Set IPSKB_L3SLAVE for IPv4 in decap_and_validate(), which already does
the same for IPv6. The socket lookup then matches the decapsulated
packet like any other packet received on that enslaved interface. Such
a packet matches an unbound UDP or TCP socket only when
udp_l3mdev_accept or tcp_l3mdev_accept is set.
Fixes: 891ef8dd2a8d ("ipv6: sr: implement additional seg6local actions")
Signed-off-by: Andrea Mayer <andrea.mayer@uniroma2.it>
Reviewed-by: David Ahern <dsahern@kernel.org>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Link: https://patch.msgid.link/20260913194421.31-1-andrea.mayer@uniroma2.it
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/seg6_local.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c
index 10f29bb8e608f..191b99b073b06 100644
--- a/net/ipv6/seg6_local.c
+++ b/net/ipv6/seg6_local.c
@@ -257,10 +257,13 @@ static bool decap_and_validate(struct sk_buff *skb, int proto)
return false;
if (proto == IPPROTO_IPIP) {
+ bool l3slave = ipv6_l3mdev_skb(IP6CB(skb)->flags);
int iif = IP6CB(skb)->iif;
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
IPCB(skb)->iif = iif;
+ if (l3slave)
+ IPCB(skb)->flags |= IPSKB_L3SLAVE;
} else if (proto == IPPROTO_IPV6) {
bool l3slave = ipv6_l3mdev_skb(IP6CB(skb)->flags);
int iif = IP6CB(skb)->iif;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 120/877] ipv4: icmp: reject RTN_UNREACHABLE input routes in icmp_route_lookup
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (118 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 119/877] seg6: set IPSKB_L3SLAVE from IP6SKB_L3SLAVE on IPIP decapsulation Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 121/877] net: fddi: skfp: fix NULL deref when setting the MAC address while down Greg Kroah-Hartman
` (764 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ido Schimmel, Jiayuan Chen,
Dong Chenchen, Paolo Abeni, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dong Chenchen <dongchenchen2@huawei.com>
[ Upstream commit 2998147b59c9df0a51477c7a6b3d1f0ba3127dd4 ]
When the forward output route cannot be used in icmp_route_lookup(),
it enters the "reverse path" and calls ip_route_input() on fl4_dec.daddr,
the original packet's source address.
ip_route_input() only returns an error for truly invalid packets. For
unreachable addresses it will succeed and return an input route whose
dst.output is set to ip_rt_bug(). The existing check only rejects
RTN_LOCAL routes, so the RTN_UNREACHABLE route types can still be returned
and later used for output, syzkaller triggering a WARN_ON_ONCE()
in ip_rt_bug() as bellow:
------------[ cut here ]------------
WARNING: net/ipv4/route.c:1273 at ip_rt_bug+0x14/0x20
RIP: 0010:ip_rt_bug+0x14/0x20
Call Trace:
ip_push_pending_frames+0xfa/0x100
__icmp_send+0x905/0xf10
ip_options_compile+0xc0/0xd0
ip_rcv_finish_core+0x321/0xae0
ip_rcv+0x1de/0x260
__netif_receive_skb_one_core+0x11a/0x130
netif_receive_skb+0x7b/0x260
tun_get_user+0x11bf/0x1c10
------------[ cut here ]------------
Reject input route that is RTN_UNREACHABLE to fix it. The net warning
is only printed for RTN_LOCAL, as RTN_UNREACHABLE is not the result of
a race condition.
Fixes: 8b7817f3a959 ("[IPSEC]: Add ICMP host relookup support")
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com>
Link: https://patch.msgid.link/20260910140042.1880242-1-dongchenchen2@huawei.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/icmp.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 7e391c2bc5bc0..3b0475f658105 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -573,16 +573,19 @@ static struct rtable *icmp_route_lookup(struct net *net, struct flowi4 *fl4,
skb_dstref_restore(skb_in, orefdst);
/*
- * At this point, fl4_dec.daddr should NOT be local (we
- * checked fl4_dec.saddr above). However, a race condition
- * may occur if the address is added to the interface
- * concurrently. In that case, ip_route_input() returns a
- * LOCAL route with dst.output=ip_rt_bug, which must not
- * be used for output.
+ * fl4_dec.daddr is not expected to be local here, but it can be
+ * added to an interface concurrently, in which case
+ * ip_route_input() returns a LOCAL route. It can also fail to
+ * build a forwarding route towards fl4_dec.daddr, for example,
+ * when forwarding is disabled, and return an UNREACHABLE route.
+ * Both cases will result in a route with dst.output=ip_rt_bug,
+ * which must not be used for output.
*/
- if (!err && rt2 && rt2->rt_type == RTN_LOCAL) {
+ if (!err && rt2 && rt2->rt_type == RTN_LOCAL)
net_warn_ratelimited("detected local route for %pI4 during ICMP sending, src %pI4\n",
&fl4_dec.daddr, &fl4_dec.saddr);
+ if (!err && rt2 &&
+ (rt2->rt_type == RTN_LOCAL || rt2->rt_type == RTN_UNREACHABLE)) {
dst_release(&rt2->dst);
err = -EINVAL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 121/877] net: fddi: skfp: fix NULL deref when setting the MAC address while down
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (119 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 120/877] ipv4: icmp: reject RTN_UNREACHABLE input routes in icmp_route_lookup Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 122/877] wifi: brcmfmac: fix lost 802.1x TX completion wakeup Greg Kroah-Hartman
` (763 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hohyun Sim, Paolo Abeni, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hohyun Sim <tlaghgus0425@korea.ac.kr>
[ Upstream commit 7c8810c2e69c3d9ca6df870b40ae9218e50b4fb1 ]
skfp_ctl_set_mac_address() calls ResetAdapter() unconditionally, without
checking netif_running(). ResetAdapter() first calls card_stop(), which
sets smc->hw.hw_state to STOPPED, and then mac_drv_clear_tx_queue(),
which walks the two transmit queues:
for (i = QUEUE_S; i <= QUEUE_A0; i++) {
queue = smc->hw.fp.tx[i] ;
...
t = queue->tx_curr_get ;
smc->hw.fp.tx[] is only populated by init_tx(), which is reached from
skfp_open() through init_smt() -> init_fddi_driver() -> init_fplus() ->
init_mac() -> init_tx(). The private area is allocated and zeroed by
alloc_fddidev(), so on an interface that has never been brought up both
queue pointers are still NULL. The hw_state test at the top of
mac_drv_clear_tx_queue() does not catch this, because card_stop() has
just set STOPPED; the function proceeds into the loop and dereferences
NULL. ResetAdapter() does call init_smt() itself, but only after the
queues have been cleared.
Setting the MAC address on a down interface therefore oopses:
ip link set dev fddi0 address 02:00:00:00:00:01
BUG: KASAN: null-ptr-deref in mac_drv_clear_tx_queue+0x68/0x2c0 [skfp]
Read of size 8 at addr 0000000000000010 by task ip/302
Call Trace:
<TASK>
mac_drv_clear_tx_queue+0x68/0x2c0 [skfp 6c01d4bab63c36978bd0a7d7e90837adb44cc37b]
ResetAdapter+0x29/0x100 [skfp 6c01d4bab63c36978bd0a7d7e90837adb44cc37b]
skfp_ctl_set_mac_address+0x57/0x80 [skfp 6c01d4bab63c36978bd0a7d7e90837adb44cc37b]
netif_set_mac_address+0x1e4/0x2c0
do_setlink+0x684/0x2680
</TASK>
Address 0x10 is the offset of tx_curr_get, the third pointer in
struct s_smt_tx_queue, on 64-bit. mac_drv_clear_rx_queue(), which
ResetAdapter() calls immediately afterwards, dereferences
smc->hw.fp.rx[QUEUE_R1] in the same way behind the same ineffective
hw_state test; the transmit queue merely crashes first. Both are
covered by the guard below.
Skip the adapter reset when the interface is down. dev_addr_set() is
left unconditional, so the new address is still recorded in
dev->dev_addr. Nothing is lost by not resetting the adapter here:
skfp_open() deliberately re-reads the factory address on every open,
read_address(smc, NULL);
eth_hw_addr_set(dev, smc->hw.fddi_canon_addr.a);
and the comment above it states this is done to discard exactly such an
address override across a close/open cycle. An address set while the
interface is down could not have survived the following open even
before this change, so the guard removes no working behaviour. Guarding
the hardware side of ndo_set_mac_address() with netif_running() is
established practice; skge_set_mac_address() has done so since commit
2eb3e621c4e0 ("skge: set mac address bonding fix").
Guarding the reset as a whole, rather than NULL-checking the queues, is
also what the rest of the driver expects. After a previous open/close
the queue pointers are stale but non-NULL, so there is no crash, yet
ResetAdapter() goes on to call smt_online() and STI_FBI() ("Enable
Board Interrupts") while skfp_close() has already called free_irq() -
the adapter would be brought back online with no handler installed. The
only other ResetAdapter() caller is skfp_interrupt(), which by
construction runs only while the device is open.
Found by automated driver testing against an emulated SysKonnect FDDI
adapter under a KASAN-enabled 7.0.0 kernel. Triggering it requires
CAP_NET_ADMIN.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Assisted-by: LLM KASAN
Signed-off-by: Hohyun Sim <tlaghgus0425@korea.ac.kr>
Link: https://patch.msgid.link/20260910063743.110747-1-tlaghgus0425@korea.ac.kr
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/fddi/skfp/skfddi.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/fddi/skfp/skfddi.c b/drivers/net/fddi/skfp/skfddi.c
index a273362c9e703..feea7baa48168 100644
--- a/drivers/net/fddi/skfp/skfddi.c
+++ b/drivers/net/fddi/skfp/skfddi.c
@@ -928,7 +928,8 @@ static int skfp_ctl_set_mac_address(struct net_device *dev, void *addr)
dev_addr_set(dev, p_sockaddr->sa_data);
spin_lock_irqsave(&bp->DriverLock, Flags);
- ResetAdapter(smc);
+ if (netif_running(dev))
+ ResetAdapter(smc);
spin_unlock_irqrestore(&bp->DriverLock, Flags);
return 0; /* always return zero */
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 122/877] wifi: brcmfmac: fix lost 802.1x TX completion wakeup
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (120 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 121/877] net: fddi: skfp: fix NULL deref when setting the MAC address while down Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 123/877] net: bridge: mst: move switchdev call outside rcu Greg Kroah-Hartman
` (762 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Arend van Spriel,
Johannes Berg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
[ Upstream commit 621d90169cef6c8da5b6134db5c0c4e23cdd09ce ]
brcmf_txfinalize() decrements pend_8021x_cnt before a lockless
waitqueue_active() check. atomic_dec() does not order the decrement
against the check.
The waiter can therefore observe a nonzero count while the waker observes
an empty queue, losing the final wakeup and delaying key installation
until the 950 ms timeout.
Add smp_mb__after_atomic() to order the decrement before the queue
check. wait_event_timeout() provides the matching barrier. LKMM confirms
that this forbids the lost-wakeup outcome.
Fixes: 21fff75d2fb6 ("brcmfmac: use wait_event_timeout for 8021x pending count")
Assisted-by: Claude:claude-fable-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Link: https://patch.msgid.link/20260811082702.44521-1-kmehltretter@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index 58eaf08a147b6..f99accc34a36e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -550,6 +550,8 @@ void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success)
if (type == ETH_P_PAE) {
atomic_dec(&ifp->pend_8021x_cnt);
+ /* Order the decrement before waitqueue_active() */
+ smp_mb__after_atomic();
if (waitqueue_active(&ifp->pend_8021x_wait))
wake_up(&ifp->pend_8021x_wait);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 123/877] net: bridge: mst: move switchdev call outside rcu
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (121 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 122/877] wifi: brcmfmac: fix lost 802.1x TX completion wakeup Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 124/877] tcp: Dont call skb_clone_and_charge_r() for close()d listener in tcp_v6_do_rcv() Greg Kroah-Hartman
` (761 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nikolay Aleksandrov, Ido Schimmel,
Paolo Abeni, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Aleksandrov <razor@blackwall.org>
[ Upstream commit 18a6fe05fb6e18de29fa90d388bb34044114b3d8 ]
This is a follow-up of one of sashiko's pre-existing bug reports.
br_mst_set_state() calls switchdev_port_attr_set() for nonzero MSTIs
while holding rcu_read_lock() which invokes the blocking switchdev
notifier chain and may sleep. Nonzero MSTI changes come from netlink
with rtnl held. Move the switchdev call before entering the rcu section and
assert that rtnl is held.
The call cannot be deferred because netlink needs its error and extack.
Also DSA reads the old bridge MST state during the callback and checks it.
A deferred callback will be late and will see the updated state.
Fixes: 3a7c1661ae13 ("net: bridge: mst: fix vlan use-after-free")
Signed-off-by: Nikolay Aleksandrov <razor@blackwall.org>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260911105021.1385934-1-razor@blackwall.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bridge/br_mst.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/net/bridge/br_mst.c b/net/bridge/br_mst.c
index 43a300ae6bfaf..1654efd3045b0 100644
--- a/net/bridge/br_mst.c
+++ b/net/bridge/br_mst.c
@@ -107,21 +107,24 @@ int br_mst_set_state(struct net_bridge_port *p, u16 msti, u8 state,
struct net_bridge_vlan *v;
int err = 0;
- rcu_read_lock();
- vg = nbp_vlan_group_rcu(p);
- if (!vg)
- goto out;
-
/* MSTI 0 (CST) state changes are notified via the regular
- * SWITCHDEV_ATTR_ID_PORT_STP_STATE.
+ * SWITCHDEV_ATTR_ID_PORT_STP_STATE. All other MSTIs are handled via
+ * netlink with RTNL held
*/
if (msti) {
+ ASSERT_RTNL();
+
err = switchdev_port_attr_set(p->dev, &attr, extack);
if (err && err != -EOPNOTSUPP)
goto out;
+ err = 0;
}
- err = 0;
+ rcu_read_lock();
+ vg = nbp_vlan_group_rcu(p);
+ if (!vg)
+ goto out_rcu_unlock;
+
list_for_each_entry_rcu(v, &vg->vlan_list, vlist) {
if (v->brvlan->msti != msti)
continue;
@@ -129,8 +132,9 @@ int br_mst_set_state(struct net_bridge_port *p, u16 msti, u8 state,
br_mst_vlan_set_state(vg, v, state);
}
-out:
+out_rcu_unlock:
rcu_read_unlock();
+out:
return err;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 124/877] tcp: Dont call skb_clone_and_charge_r() for close()d listener in tcp_v6_do_rcv().
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (122 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 123/877] net: bridge: mst: move switchdev call outside rcu Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 125/877] tcp: do not let tcp_rmem be set below 4096 Greg Kroah-Hartman
` (760 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Taras Madan, Kuniyuki Iwashima,
Xuanqiang Luo, Eric Dumazet, Paolo Abeni, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit 8e759cd1f6444a946bd1fd2b2b29eea582eea1d5 ]
tcp_v6_do_rcv() no longer calls skb_clone_and_charge_r() for
TCP_LISTEN since commit 073d89808c06 ("net: fix data-races around
sk->sk_forward_alloc").
However, there is still a small race window between tcp_v6_rcv()
and tcp_v6_do_rcv(), where concurrent close() changes TCP_LISTEN
to TCP_CLOSE, causing skb_clone_and_charge_r() to be called
locklessly and resulting in the splat below. [0]
Let's avoid calling skb_clone_and_charge_r() for TCP_CLOSE as well.
This is fine for non-listeners because tcp_rcv_state_process()
drops skb for TCP_CLOSE and opt_skb was freed immediately anyway.
[0]:
sk->sk_forward_alloc
WARNING: net/ipv4/af_inet.c:162 at inet_sock_destruct+0x64d/0x810 net/ipv4/af_inet.c:162, CPU#1: ksoftirqd/1/28
Modules linked in:
CPU: 1 UID: 0 PID: 28 Comm: ksoftirqd/1 Not tainted 7.2.0 #17 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
RIP: 0010:inet_sock_destruct+0x64d/0x810 net/ipv4/af_inet.c:162
Code: 3d 49 ff e9 06 fd ff ff e8 d0 5b 83 f8 90 0f 0b 90 e9 35 fe ff ff e8 c2 5b 83 f8 90 0f 0b 90 e9 c5 fe ff ff e8 b4 5b 83 f8 90 <0f> 0b 90 e9 04 ff ff ff e8 a6 5b 83 f8 90 0f 0b 90 e9 65 fe ff ff
RSP: 0018:ffffc90000677bb8 EFLAGS: 00010246
RAX: 0000000000000000 RBX: ffff8880117bde80 RCX: ffffffff8957eb41
RDX: ffff88801dad5d00 RSI: ffffffff8957ec3c RDI: 0000000000000005
RBP: 00000000fffff000 R08: ffffffff8957eb41 R09: 00000000fffff000
R10: 0000000000000005 R11: 0000000000000000 R12: dffffc0000000000
R13: ffff8880117bdf10 R14: ffffffff81c08eb7 R15: 0000000000000003
FS: 0000000000000000(0000) GS:ffff8880d7ae5000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f93a1021138 CR3: 00000000207a9000 CR4: 0000000000350ef0
Call Trace:
<TASK>
__sk_destruct+0x82/0xae0 net/core/sock.c:2356
rcu_do_batch kernel/rcu/tree.c:2645 [inline]
rcu_core+0x59c/0x1100 kernel/rcu/tree.c:2897
handle_softirqs+0x1e4/0x9b0 kernel/softirq.c:622
run_ksoftirqd kernel/softirq.c:1076 [inline]
run_ksoftirqd+0x38/0x60 kernel/softirq.c:1068
smpboot_thread_fn+0x458/0xc80 kernel/smpboot.c:160
kthread+0x396/0x4a0 kernel/kthread.c:436
ret_from_fork+0x8e0/0xe40 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
</TASK>
Fixes: e994b2f0fb92 ("tcp: do not lock listener to process SYN packets")
Reported-by: Taras Madan <tarasmadan@google.com>
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260914011420.115556-1-kuniyu@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/tcp_ipv6.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 533943a7127dc..e5f632b683c5d 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1605,7 +1605,8 @@ int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
by tcp. Feel free to propose better solution.
--ANK (980728)
*/
- if (np->rxopt.all && sk->sk_state != TCP_LISTEN)
+ if (np->rxopt.all &&
+ !((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)))
opt_skb = skb_clone_and_charge_r(skb, sk);
if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 125/877] tcp: do not let tcp_rmem be set below 4096
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (123 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 124/877] tcp: Dont call skb_clone_and_charge_r() for close()d listener in tcp_v6_do_rcv() Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 126/877] ksmbd: return buffer overflow for partial filesystem info Greg Kroah-Hartman
` (759 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Simon Horman,
Paolo Abeni, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 83a945a529d6e002dd7339c532288a931f463dba ]
We can hit a division by zero crash in tcp_rcvbuf_grow()
and tcp_rcv_space_adjust():
divide error: 0000 [#1] PREEMPT SMP
RIP: 0010:tcp_rcvbuf_grow+0x187/0x450 net/ipv4/tcp_input.c:939
...
grow = div_u64(((u64)rcvwin << 1) * (newval - oldval), oldval);
The division uses oldval = tp->rcvq_space.space as divisor.
When tp->rcvq_space.space is zero, this leads to a divide-by-zero
exception.
tp->rcvq_space.space is initialized in tcp_init_buffer_space():
tp->rcvq_space.space = min3(tp->rcv_ssthresh, tp->rcv_wnd,
(u32)TCP_INIT_CWND * tp->advmss);
If tcp_rmem[1] is configured to very small values (such as 1),
sk->sk_rcvbuf is initialized to 1. Then tcp_full_space(sk), which
computes (sk->sk_rcvbuf * scaling_ratio) >> 8, truncates to 0.
This sets tp->window_clamp = 0, tp->rcv_ssthresh = 0, and
tp->rcvq_space.space = 0. Later, when data arrives and DRS is invoked,
tcp_rcvbuf_grow() divides by oldval == 0.
Back in 2015, commit b1cb59cf2efe ("net: sysctl_net_core: check SNDBUF
and RCVBUF for min length") ensured that net.core.rmem_default and
net.core.rmem_max cannot be set below SOCK_MIN_RCVBUF. Similarly,
SO_RCVBUF setsockopt enforces max_t(int, val * 2, SOCK_MIN_RCVBUF).
However, net.ipv4.tcp_rmem still had .extra1 = SYSCTL_ONE, allowing
arbitrarily small values.
Because SOCK_MIN_RCVBUF depends on sizeof(struct sk_buff) and cacheline
alignment, its value varies across architectures and configuration options.
Using a fixed constant of 4096 ensures a predictable, architecture-
independent lower bound that is safely above SOCK_MIN_RCVBUF everywhere
and matches the documented 4K default.
Fix this by setting tcp_rmem.extra1 to 4096 and updating the documentation.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260912144848.3448026-1-edumazet@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/networking/ip-sysctl.rst | 2 ++
net/ipv4/sysctl_net_ipv4.c | 4 +++-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst
index dcbb6f6caf6de..eb2c136be63da 100644
--- a/Documentation/networking/ip-sysctl.rst
+++ b/Documentation/networking/ip-sysctl.rst
@@ -735,6 +735,8 @@ tcp_rmem - vector of 3 INTEGERs: min, default, max
case this value is ignored.
Default: between 131072 and 6MB, depending on RAM size.
+ Each of the three values cannot be set below 4096.
+
tcp_sack - BOOLEAN
Enable select acknowledgments (SACKS).
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 63625a5038af4..00d3be968a53d 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -46,6 +46,8 @@ static unsigned int udp_child_hash_entries_max = UDP_HTABLE_SIZE_MAX;
static int tcp_plb_max_rounds = 31;
static int tcp_plb_max_cong_thresh = 256;
+static int tcp_min_rcvbuf = 4096;
+
/* obsolete */
static int sysctl_tcp_low_latency __read_mostly;
@@ -1405,7 +1407,7 @@ static struct ctl_table ipv4_net_table[] = {
.maxlen = sizeof(init_net.ipv4.sysctl_tcp_rmem),
.mode = 0644,
.proc_handler = proc_dointvec_minmax,
- .extra1 = SYSCTL_ONE,
+ .extra1 = &tcp_min_rcvbuf,
},
{
.procname = "tcp_comp_sack_delay_ns",
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 126/877] ksmbd: return buffer overflow for partial filesystem info
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (124 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 125/877] tcp: do not let tcp_rmem be set below 4096 Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 127/877] ksmbd: fix partial file information responses Greg Kroah-Hartman
` (758 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit 0ecd35fac4b4f2828490689b46039744d201dcb0 ]
The query-info buffer check returns STATUS_INFO_LENGTH_MISMATCH for
every output buffer smaller than the complete response. Variable-length
filesystem information instead requires STATUS_BUFFER_OVERFLOW when the
fixed portion fits but the complete data does not.
Pass the fixed size for each filesystem information class to the buffer
checker. Keep INFO_LENGTH_MISMATCH for buffers below that size, and
return BUFFER_OVERFLOW with a response truncated to the requested length
for larger partial buffers.
This fixes smb2.getinfo.qfs_buffercheck.
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Stable-dep-of: 9fa26285ae70 ("ksmbd: keep compound responses on query info errors")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/smb2pdu.c | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 37d8db4bbbaec..b12dad36bb574 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -4648,21 +4648,30 @@ int smb2_query_dir(struct ksmbd_work *work)
/**
* buffer_check_err() - helper function to check buffer errors
* @reqOutputBufferLength: max buffer length expected in command response
+ * @fixed_len: minimum fixed response length
* @rsp: query info response buffer contains output buffer length
* @rsp_org: base response buffer pointer in case of chained response
*
* Return: 0 on success, otherwise error
*/
static int buffer_check_err(int reqOutputBufferLength,
+ unsigned int fixed_len,
struct smb2_query_info_rsp *rsp,
void *rsp_org)
{
- if (reqOutputBufferLength < le32_to_cpu(rsp->OutputBufferLength)) {
+ unsigned int output_len = le32_to_cpu(rsp->OutputBufferLength);
+
+ if (reqOutputBufferLength < fixed_len) {
pr_err("Invalid Buffer Size Requested\n");
rsp->hdr.Status = STATUS_INFO_LENGTH_MISMATCH;
*(__be32 *)rsp_org = cpu_to_be32(sizeof(struct smb2_hdr));
return -EINVAL;
}
+
+ if (reqOutputBufferLength < output_len) {
+ rsp->hdr.Status = STATUS_BUFFER_OVERFLOW;
+ rsp->OutputBufferLength = cpu_to_le32(reqOutputBufferLength);
+ }
return 0;
}
@@ -4725,11 +4734,13 @@ static int smb2_get_info_file_pipe(struct ksmbd_session *sess,
case FILE_STANDARD_INFORMATION:
get_standard_info_pipe(rsp, rsp_org);
rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
+ le32_to_cpu(rsp->OutputBufferLength),
rsp, rsp_org);
break;
case FILE_INTERNAL_INFORMATION:
get_internal_info_pipe(rsp, id, rsp_org);
rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
+ le32_to_cpu(rsp->OutputBufferLength),
rsp, rsp_org);
break;
default:
@@ -5523,6 +5534,7 @@ static int smb2_get_info_file(struct ksmbd_work *work,
}
if (!rc)
rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
+ le32_to_cpu(rsp->OutputBufferLength),
rsp, work->response_buf);
ksmbd_fd_put(work, fp);
@@ -5544,6 +5556,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
struct kstatfs stfs;
struct path path;
int rc = 0, len;
+ unsigned int fixed_len = 0;
if (!share->path)
return -EIO;
@@ -5578,6 +5591,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
info->DeviceCharacteristics |=
cpu_to_le32(FILE_READ_ONLY_DEVICE);
rsp->OutputBufferLength = cpu_to_le32(8);
+ fixed_len = 8;
break;
}
case FS_ATTRIBUTE_INFORMATION:
@@ -5606,6 +5620,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
info->FileSystemNameLen = cpu_to_le32(len);
sz = sizeof(struct filesystem_attribute_info) + len;
rsp->OutputBufferLength = cpu_to_le32(sz);
+ fixed_len = 16;
break;
}
case FS_VOLUME_INFORMATION:
@@ -5632,6 +5647,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
info->Reserved = 0;
sz = sizeof(struct filesystem_vol_info) + len;
rsp->OutputBufferLength = cpu_to_le32(sz);
+ fixed_len = 24;
break;
}
case FS_SIZE_INFORMATION:
@@ -5644,6 +5660,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
info->SectorsPerAllocationUnit = cpu_to_le32(1);
info->BytesPerSector = cpu_to_le32(stfs.f_bsize);
rsp->OutputBufferLength = cpu_to_le32(24);
+ fixed_len = 24;
break;
}
case FS_FULL_SIZE_INFORMATION:
@@ -5659,6 +5676,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
info->SectorsPerAllocationUnit = cpu_to_le32(1);
info->BytesPerSector = cpu_to_le32(stfs.f_bsize);
rsp->OutputBufferLength = cpu_to_le32(32);
+ fixed_len = 32;
break;
}
case FS_OBJECT_ID_INFORMATION:
@@ -5679,6 +5697,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
info->extended_info.rel_date = 0;
memcpy(info->extended_info.version_string, "1.1.0", strlen("1.1.0"));
rsp->OutputBufferLength = cpu_to_le32(64);
+ fixed_len = 64;
break;
}
case FS_SECTOR_SIZE_INFORMATION:
@@ -5700,6 +5719,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
info->ByteOffsetForSectorAlignment = 0;
info->ByteOffsetForPartitionAlignment = 0;
rsp->OutputBufferLength = cpu_to_le32(28);
+ fixed_len = 28;
break;
}
case FS_CONTROL_INFORMATION:
@@ -5720,6 +5740,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
info->DefaultQuotaLimit = cpu_to_le64(SMB2_NO_FID);
info->Padding = 0;
rsp->OutputBufferLength = cpu_to_le32(48);
+ fixed_len = 48;
break;
}
case FS_POSIX_INFORMATION:
@@ -5740,6 +5761,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
info->TotalFileNodes = cpu_to_le64(stfs.f_files);
info->FreeFileNodes = cpu_to_le64(stfs.f_ffree);
rsp->OutputBufferLength = cpu_to_le32(56);
+ fixed_len = 56;
}
break;
}
@@ -5748,6 +5770,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
return -EOPNOTSUPP;
}
rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
+ fixed_len,
rsp, work->response_buf);
path_put(&path);
@@ -5862,6 +5885,7 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
iov_pin:
rsp->OutputBufferLength = cpu_to_le32(secdesclen);
rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
+ le32_to_cpu(rsp->OutputBufferLength),
rsp, work->response_buf);
if (rc)
goto err_out;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 127/877] ksmbd: fix partial file information responses
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (125 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 126/877] ksmbd: return buffer overflow for partial filesystem info Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 128/877] ksmbd: keep compound responses on query info errors Greg Kroah-Hartman
` (757 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit 6b8b79226bc3e0ac3fdd4e91836241af712e8cd1 ]
Variable-length file information handlers use the client output length
while constructing the response. FILE_ALL_INFORMATION can consequently
return -EINVAL before the common buffer check, while stream information
can stop building the complete result too early.
Build the complete response within the available server response buffer
and apply the client output length only when selecting the final status
and transmitted length. Use the protocol-defined fixed sizes for all,
alternate-name, and stream information to distinguish
STATUS_INFO_LENGTH_MISMATCH from STATUS_BUFFER_OVERFLOW.
This fixes smb2.getinfo.qfile_buffercheck.
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Stable-dep-of: 9fa26285ae70 ("ksmbd: keep compound responses on query info errors")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/smb2pdu.c | 31 ++++++++++++++++++++-----------
1 file changed, 20 insertions(+), 11 deletions(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index b12dad36bb574..af3178031c1ee 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -5019,7 +5019,6 @@ static int get_file_all_info(struct ksmbd_work *work,
char *filename;
u64 time;
int ret, buf_free_len, filename_len;
- struct smb2_query_info_req *req = ksmbd_req_buf_next(work);
if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) {
ksmbd_debug(SMB, "no right to read the attributes : 0x%x\n",
@@ -5032,10 +5031,9 @@ static int get_file_all_info(struct ksmbd_work *work,
return PTR_ERR(filename);
filename_len = strlen(filename);
- buf_free_len = smb2_calc_max_out_buf_len(work,
+ buf_free_len = smb2_resp_buf_len(work,
offsetof(struct smb2_query_info_rsp, Buffer) +
- offsetof(struct smb2_file_all_info, FileName),
- le32_to_cpu(req->OutputBufferLength));
+ offsetof(struct smb2_file_all_info, FileName));
if (buf_free_len < (filename_len + 1) * 2) {
kfree(filename);
return -EINVAL;
@@ -5120,7 +5118,6 @@ static int get_file_stream_info(struct ksmbd_work *work,
ssize_t xattr_list_len;
int nbytes = 0, streamlen, stream_name_len, next, idx = 0;
int buf_free_len;
- struct smb2_query_info_req *req = ksmbd_req_buf_next(work);
int ret;
ret = vfs_getattr(&fp->filp->f_path, &stat, STATX_BASIC_STATS,
@@ -5130,10 +5127,8 @@ static int get_file_stream_info(struct ksmbd_work *work,
file_info = (struct smb2_file_stream_info *)rsp->Buffer;
- buf_free_len =
- smb2_calc_max_out_buf_len(work,
- offsetof(struct smb2_query_info_rsp, Buffer),
- le32_to_cpu(req->OutputBufferLength));
+ buf_free_len = smb2_resp_buf_len(work,
+ offsetof(struct smb2_query_info_rsp, Buffer));
if (buf_free_len < 0)
goto out;
@@ -5429,6 +5424,7 @@ static int smb2_get_info_file(struct ksmbd_work *work,
struct ksmbd_file *fp;
int fileinfoclass = 0;
int rc = 0;
+ unsigned int fixed_len;
unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID;
if (test_share_config_flag(work->tcon->share_conf,
@@ -5532,10 +5528,23 @@ static int smb2_get_info_file(struct ksmbd_work *work,
fileinfoclass);
rc = -EOPNOTSUPP;
}
- if (!rc)
+ if (!rc) {
+ fixed_len = le32_to_cpu(rsp->OutputBufferLength);
+ switch (fileinfoclass) {
+ case FILE_ALL_INFORMATION:
+ fixed_len = FILE_ALL_INFORMATION_SIZE;
+ break;
+ case FILE_ALTERNATE_NAME_INFORMATION:
+ fixed_len = FILE_ALTERNATE_NAME_INFORMATION_SIZE;
+ break;
+ case FILE_STREAM_INFORMATION:
+ fixed_len = FILE_STREAM_INFORMATION_SIZE;
+ break;
+ }
rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
- le32_to_cpu(rsp->OutputBufferLength),
+ fixed_len,
rsp, work->response_buf);
+ }
ksmbd_fd_put(work, fp);
iov_pin_out:
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 128/877] ksmbd: keep compound responses on query info errors
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (126 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 127/877] ksmbd: fix partial file information responses Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 129/877] dmaengine: mmp_pdma: fix wrong sg length in mmp_pdma_prep_slave_sg() Greg Kroah-Hartman
` (756 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mobin Aydinfar, ChenXiaoSong,
Namjae Jeon, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit 9fa26285ae70ac2d3d1b47459a6b4463ab053e1c ]
Do not reset the RFC1002 length of the complete response when a query
info buffer is too small. The current command will add its error response
through ksmbd_iov_pin_rsp(), while resetting the base length can truncate
earlier responses in a compound request.
This lets ksmbd return the earlier responses and the query-info error
response together. Remove the now-unused rsp_org parameter from the pipe
query-info helpers.
Fixes: e2b76ab8b5c9 ("ksmbd: add support for read compound")
Reported-by: Mobin Aydinfar <mobin@mobintestserver.ir>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/smb2pdu.c | 31 ++++++++++++-------------------
1 file changed, 12 insertions(+), 19 deletions(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index af3178031c1ee..283160908218e 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -4650,21 +4650,18 @@ int smb2_query_dir(struct ksmbd_work *work)
* @reqOutputBufferLength: max buffer length expected in command response
* @fixed_len: minimum fixed response length
* @rsp: query info response buffer contains output buffer length
- * @rsp_org: base response buffer pointer in case of chained response
*
* Return: 0 on success, otherwise error
*/
static int buffer_check_err(int reqOutputBufferLength,
unsigned int fixed_len,
- struct smb2_query_info_rsp *rsp,
- void *rsp_org)
+ struct smb2_query_info_rsp *rsp)
{
unsigned int output_len = le32_to_cpu(rsp->OutputBufferLength);
if (reqOutputBufferLength < fixed_len) {
pr_err("Invalid Buffer Size Requested\n");
rsp->hdr.Status = STATUS_INFO_LENGTH_MISMATCH;
- *(__be32 *)rsp_org = cpu_to_be32(sizeof(struct smb2_hdr));
return -EINVAL;
}
@@ -4675,8 +4672,7 @@ static int buffer_check_err(int reqOutputBufferLength,
return 0;
}
-static void get_standard_info_pipe(struct smb2_query_info_rsp *rsp,
- void *rsp_org)
+static void get_standard_info_pipe(struct smb2_query_info_rsp *rsp)
{
struct smb2_file_standard_info *sinfo;
@@ -4691,8 +4687,7 @@ static void get_standard_info_pipe(struct smb2_query_info_rsp *rsp,
cpu_to_le32(sizeof(struct smb2_file_standard_info));
}
-static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp, u64 num,
- void *rsp_org)
+static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp, u64 num)
{
struct smb2_file_internal_info *file_info;
@@ -4706,8 +4701,7 @@ static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp, u64 num,
static int smb2_get_info_file_pipe(struct ksmbd_session *sess,
struct smb2_query_info_req *req,
- struct smb2_query_info_rsp *rsp,
- void *rsp_org)
+ struct smb2_query_info_rsp *rsp)
{
u64 id;
int rc;
@@ -4732,16 +4726,16 @@ static int smb2_get_info_file_pipe(struct ksmbd_session *sess,
switch (req->FileInfoClass) {
case FILE_STANDARD_INFORMATION:
- get_standard_info_pipe(rsp, rsp_org);
+ get_standard_info_pipe(rsp);
rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
le32_to_cpu(rsp->OutputBufferLength),
- rsp, rsp_org);
+ rsp);
break;
case FILE_INTERNAL_INFORMATION:
- get_internal_info_pipe(rsp, id, rsp_org);
+ get_internal_info_pipe(rsp, id);
rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
le32_to_cpu(rsp->OutputBufferLength),
- rsp, rsp_org);
+ rsp);
break;
default:
ksmbd_debug(SMB, "smb2_info_file_pipe for %u not supported\n",
@@ -5430,8 +5424,7 @@ static int smb2_get_info_file(struct ksmbd_work *work,
if (test_share_config_flag(work->tcon->share_conf,
KSMBD_SHARE_FLAG_PIPE)) {
/* smb2 info file called for pipe */
- rc = smb2_get_info_file_pipe(work->sess, req, rsp,
- work->response_buf);
+ rc = smb2_get_info_file_pipe(work->sess, req, rsp);
goto iov_pin_out;
}
@@ -5543,7 +5536,7 @@ static int smb2_get_info_file(struct ksmbd_work *work,
}
rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
fixed_len,
- rsp, work->response_buf);
+ rsp);
}
ksmbd_fd_put(work, fp);
@@ -5780,7 +5773,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
}
rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
fixed_len,
- rsp, work->response_buf);
+ rsp);
path_put(&path);
if (!rc)
@@ -5895,7 +5888,7 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
rsp->OutputBufferLength = cpu_to_le32(secdesclen);
rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
le32_to_cpu(rsp->OutputBufferLength),
- rsp, work->response_buf);
+ rsp);
if (rc)
goto err_out;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 129/877] dmaengine: mmp_pdma: fix wrong sg length in mmp_pdma_prep_slave_sg()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (127 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 128/877] ksmbd: keep compound responses on query info errors Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 130/877] Bluetooth: hci_core: Print number of packets in conn->data_q Greg Kroah-Hartman
` (755 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Baineng Shou, Frank Li, Vinod Koul,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baineng Shou <shoubaineng@gmail.com>
[ Upstream commit 075bc7b1d3dde5ed43fbaabbc1a69f09b7fc3a47 ]
In mmp_pdma_prep_slave_sg(), for_each_sg() iterates the scatterlist
putting each entry into 'sg', but the entry length is read from 'sgl'
(the list head) instead of 'sg' (the current entry):
for_each_sg(sgl, sg, sg_len, i) {
addr = sg_dma_address(sg);
avail = sg_dma_len(sgl); /* should be 'sg' */
Consequently 'avail' is always the length of the first entry. For
multi-sg lists this causes out-of-bounds reads when a later entry is
shorter than the first, and silent data loss when it is longer.
Single-sg or uniformly-sized lists happen to mask the issue.
Fixes: c8acd6aa6bed3 ("dmaengine: mmp-pdma support")
Signed-off-by: Baineng Shou <shoubaineng@gmail.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260910021652.1296640-1-shoubaineng@gmail.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/dma/mmp_pdma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
index 852e6714d9f28..59227fbed9045 100644
--- a/drivers/dma/mmp_pdma.c
+++ b/drivers/dma/mmp_pdma.c
@@ -541,7 +541,7 @@ mmp_pdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl,
for_each_sg(sgl, sg, sg_len, i) {
addr = sg_dma_address(sg);
- avail = sg_dma_len(sgl);
+ avail = sg_dma_len(sg);
do {
len = min_t(size_t, avail, PDMA_MAX_DESC_BYTES);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 130/877] Bluetooth: hci_core: Print number of packets in conn->data_q
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (128 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 129/877] dmaengine: mmp_pdma: fix wrong sg length in mmp_pdma_prep_slave_sg() Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 131/877] Bluetooth: hci_core: Fix queuing tx_work after workqueue is drained Greg Kroah-Hartman
` (754 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Luiz Augusto von Dentz, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
[ Upstream commit 3c34d6428740e47b29ae3afd85d6f9eb656a3ea3 ]
This attempts to print the number of packets pending to be transmitted
in the conn->data_q.
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Stable-dep-of: 6610c6fe4b89 ("Bluetooth: hci_core: Fix queuing tx_work after workqueue is drained")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/hci_core.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index f68238406ad2e..24f2119c7abfa 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3273,6 +3273,8 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
spin_unlock_bh(&queue->lock);
}
+
+ bt_dev_dbg(hdev, "chan %p queued %d", chan, skb_queue_len(queue));
}
void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
@@ -3304,6 +3306,10 @@ void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
hci_skb_pkt_type(skb) = HCI_SCODATA_PKT;
skb_queue_tail(&conn->data_q, skb);
+
+ bt_dev_dbg(hdev, "hcon %p queued %d", conn,
+ skb_queue_len(&conn->data_q));
+
queue_work(hdev->workqueue, &hdev->tx_work);
}
@@ -3363,6 +3369,8 @@ static void hci_queue_iso(struct hci_conn *conn, struct sk_buff_head *queue,
__skb_queue_tail(queue, skb);
} while (list);
}
+
+ bt_dev_dbg(hdev, "hcon %p queued %d", conn, skb_queue_len(queue));
}
void hci_send_iso(struct hci_conn *conn, struct sk_buff *skb)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 131/877] Bluetooth: hci_core: Fix queuing tx_work after workqueue is drained
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (129 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 130/877] Bluetooth: hci_core: Print number of packets in conn->data_q Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 132/877] Bluetooth: coredump: Quiesce dump work on unregister Greg Kroah-Hartman
` (753 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+b6919040d9958e2fc1ae,
ThangNN99, Luiz Augusto von Dentz, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: ThangNN99 <ngocthang2710.1999@gmail.com>
[ Upstream commit 6610c6fe4b8936c232048e6049bf77c70a6f759c ]
hci_send_acl(), hci_send_sco() and hci_send_iso() queue hdev->tx_work
unconditionally. They can run from the L2CAP/SCO/ISO socket send path
while hci_dev_close_sync() is draining hdev->workqueue (HCIDEVDOWN
racing with a socket write). Since that queue_work() is not chained
work from the tx_work worker itself, __queue_work() sees the queue
marked __WQ_DRAINING, warns "cannot queue %ps on wq %s", and drops
the work:
WARNING: CPU: 1 PID: 5985 at kernel/workqueue.c:2352 __queue_work
Call Trace:
queue_work_on
l2cap_chan_send
l2cap_sock_sendmsg
...
hci_dev_close_sync() already sets HCI_CMD_DRAIN_WORKQUEUE before
draining, but only hci_cmd_work() and handle_cmd_cnt_and_timer()
check it before queuing. Route the tx_work producers through the
same guard via a shared hci_sched_tx() helper.
Fixes: 525daaea459f ("Bluetooth: hci_sync: Set HCI_CMD_DRAIN_WORKQUEUE during device close")
Reported-by: syzbot+b6919040d9958e2fc1ae@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=b6919040d9958e2fc1ae
Signed-off-by: ThangNN99 <ngocthang2710.1999@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/hci_core.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 24f2119c7abfa..85aecd4c5b9b2 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3277,6 +3277,17 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
bt_dev_dbg(hdev, "chan %p queued %d", chan, skb_queue_len(queue));
}
+/* Queue hdev->tx_work, unless hdev->workqueue is being drained by
+ * hci_dev_close_sync(), which would otherwise WARN and drop the work.
+ */
+static void hci_sched_tx(struct hci_dev *hdev)
+{
+ rcu_read_lock();
+ if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
+ queue_work(hdev->workqueue, &hdev->tx_work);
+ rcu_read_unlock();
+}
+
void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
{
struct hci_dev *hdev = chan->conn->hdev;
@@ -3285,7 +3296,7 @@ void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
hci_queue_acl(chan, &chan->data_q, skb, flags);
- queue_work(hdev->workqueue, &hdev->tx_work);
+ hci_sched_tx(hdev);
}
/* Send SCO data */
@@ -3310,7 +3321,7 @@ void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
bt_dev_dbg(hdev, "hcon %p queued %d", conn,
skb_queue_len(&conn->data_q));
- queue_work(hdev->workqueue, &hdev->tx_work);
+ hci_sched_tx(hdev);
}
/* Send ISO data */
@@ -3381,7 +3392,7 @@ void hci_send_iso(struct hci_conn *conn, struct sk_buff *skb)
hci_queue_iso(conn, &conn->data_q, skb);
- queue_work(hdev->workqueue, &hdev->tx_work);
+ hci_sched_tx(hdev);
}
/* ---- HCI TX task (outgoing data) ---- */
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 132/877] Bluetooth: coredump: Quiesce dump work on unregister
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (130 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 131/877] Bluetooth: hci_core: Fix queuing tx_work after workqueue is drained Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 133/877] Bluetooth: ISO: Fix parent socket leak in iso_conn_ready() Greg Kroah-Hartman
` (752 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+b170dbf55520ebf5969a,
Aby Sam Ross, Tristan Madani, Xiang Mei, Weiming Shi,
Luiz Augusto von Dentz, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <bestswngs@gmail.com>
[ Upstream commit d236517c264e41dc09833c708ef23bccb7a91219 ]
hci_devcd_handle_pkt_init() arms dump_timeout and coredump producers
queue dump_rx without holding an hdev reference. Unregister leaves both
works live, so disconnecting during an active dump lets them access hdev
after hci_release_dev() frees it.
Shut down coredump processing during unregister. Close the producer gate
under dump_q.lock before disabling both works, then free the active buffer
and queued packets under hci_dev_lock. Serializing the gate with enqueue
prevents controller-specific workers from adding packets after the final
purge.
Fixes: 9695ef876fd1 ("Bluetooth: Add support for hci devcoredump")
Reported-by: syzbot+b170dbf55520ebf5969a@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=b170dbf55520ebf5969a
Reported-by: Aby Sam Ross <abysamross@gmail.com>
Link: https://lore.kernel.org/r/20260322210849.68743-1-abysamross@gmail.com
Suggested-by: Aby Sam Ross <abysamross@gmail.com>
Reported-by: Tristan Madani <tristan@talencesecurity.com>
Link: https://lore.kernel.org/r/20260814231248.3096377-1-tristmd@gmail.com
Reported-by: Xiang Mei <xmei5@asu.edu>
Assisted-by: OpenAI Codex:gpt-5
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Reported-by: Xiang Mei <xmei5@asu.edu>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/bluetooth/coredump.h | 2 +
net/bluetooth/coredump.c | 65 +++++++++++++++++++++-----------
net/bluetooth/hci_core.c | 1 +
3 files changed, 47 insertions(+), 21 deletions(-)
diff --git a/include/net/bluetooth/coredump.h b/include/net/bluetooth/coredump.h
index 72f51b587a046..00c12c7ac042f 100644
--- a/include/net/bluetooth/coredump.h
+++ b/include/net/bluetooth/coredump.h
@@ -61,6 +61,7 @@ struct hci_devcoredump {
#ifdef CONFIG_DEV_COREDUMP
void hci_devcd_reset(struct hci_dev *hdev);
+void hci_devcd_shutdown(struct hci_dev *hdev);
void hci_devcd_rx(struct work_struct *work);
void hci_devcd_timeout(struct work_struct *work);
@@ -75,6 +76,7 @@ int hci_devcd_abort(struct hci_dev *hdev);
#else
static inline void hci_devcd_reset(struct hci_dev *hdev) {}
+static inline void hci_devcd_shutdown(struct hci_dev *hdev) {}
static inline void hci_devcd_rx(struct work_struct *work) {}
static inline void hci_devcd_timeout(struct work_struct *work) {}
diff --git a/net/bluetooth/coredump.c b/net/bluetooth/coredump.c
index c18df3a086075..517a61234ef43 100644
--- a/net/bluetooth/coredump.c
+++ b/net/bluetooth/coredump.c
@@ -105,6 +105,22 @@ static void hci_devcd_free(struct hci_dev *hdev)
hci_devcd_reset(hdev);
}
+void hci_devcd_shutdown(struct hci_dev *hdev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&hdev->dump.dump_q.lock, flags);
+ hdev->dump.supported = false;
+ spin_unlock_irqrestore(&hdev->dump.dump_q.lock, flags);
+
+ disable_work_sync(&hdev->dump.dump_rx);
+ disable_delayed_work_sync(&hdev->dump.dump_timeout);
+
+ hci_dev_lock(hdev);
+ hci_devcd_free(hdev);
+ hci_dev_unlock(hdev);
+}
+
/* Call with hci_dev_lock only. */
static int hci_devcd_alloc(struct hci_dev *hdev, u32 size)
{
@@ -426,7 +442,29 @@ EXPORT_SYMBOL(hci_devcd_register);
static inline bool hci_devcd_enabled(struct hci_dev *hdev)
{
- return hdev->dump.supported;
+ return READ_ONCE(hdev->dump.supported);
+}
+
+static int hci_devcd_queue(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ unsigned long flags;
+ int err = 0;
+
+ spin_lock_irqsave(&hdev->dump.dump_q.lock, flags);
+ if (!hdev->dump.supported)
+ err = -EOPNOTSUPP;
+ else
+ __skb_queue_tail(&hdev->dump.dump_q, skb);
+ spin_unlock_irqrestore(&hdev->dump.dump_q.lock, flags);
+
+ if (err) {
+ kfree_skb(skb);
+ return err;
+ }
+
+ queue_work(hdev->workqueue, &hdev->dump.dump_rx);
+
+ return 0;
}
int hci_devcd_init(struct hci_dev *hdev, u32 dump_size)
@@ -443,10 +481,7 @@ int hci_devcd_init(struct hci_dev *hdev, u32 dump_size)
hci_dmp_cb(skb)->pkt_type = HCI_DEVCOREDUMP_PKT_INIT;
put_unaligned_le32(dump_size, skb_put(skb, 4));
- skb_queue_tail(&hdev->dump.dump_q, skb);
- queue_work(hdev->workqueue, &hdev->dump.dump_rx);
-
- return 0;
+ return hci_devcd_queue(hdev, skb);
}
EXPORT_SYMBOL(hci_devcd_init);
@@ -462,10 +497,7 @@ int hci_devcd_append(struct hci_dev *hdev, struct sk_buff *skb)
hci_dmp_cb(skb)->pkt_type = HCI_DEVCOREDUMP_PKT_SKB;
- skb_queue_tail(&hdev->dump.dump_q, skb);
- queue_work(hdev->workqueue, &hdev->dump.dump_rx);
-
- return 0;
+ return hci_devcd_queue(hdev, skb);
}
EXPORT_SYMBOL(hci_devcd_append);
@@ -487,10 +519,7 @@ int hci_devcd_append_pattern(struct hci_dev *hdev, u8 pattern, u32 len)
hci_dmp_cb(skb)->pkt_type = HCI_DEVCOREDUMP_PKT_PATTERN;
skb_put_data(skb, &p, sizeof(p));
- skb_queue_tail(&hdev->dump.dump_q, skb);
- queue_work(hdev->workqueue, &hdev->dump.dump_rx);
-
- return 0;
+ return hci_devcd_queue(hdev, skb);
}
EXPORT_SYMBOL(hci_devcd_append_pattern);
@@ -507,10 +536,7 @@ int hci_devcd_complete(struct hci_dev *hdev)
hci_dmp_cb(skb)->pkt_type = HCI_DEVCOREDUMP_PKT_COMPLETE;
- skb_queue_tail(&hdev->dump.dump_q, skb);
- queue_work(hdev->workqueue, &hdev->dump.dump_rx);
-
- return 0;
+ return hci_devcd_queue(hdev, skb);
}
EXPORT_SYMBOL(hci_devcd_complete);
@@ -527,9 +553,6 @@ int hci_devcd_abort(struct hci_dev *hdev)
hci_dmp_cb(skb)->pkt_type = HCI_DEVCOREDUMP_PKT_ABORT;
- skb_queue_tail(&hdev->dump.dump_q, skb);
- queue_work(hdev->workqueue, &hdev->dump.dump_rx);
-
- return 0;
+ return hci_devcd_queue(hdev, skb);
}
EXPORT_SYMBOL(hci_devcd_abort);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 85aecd4c5b9b2..a85c77ed4a13e 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2731,6 +2731,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
disable_work_sync(&hdev->error_reset);
disable_delayed_work_sync(&hdev->cmd_timer);
disable_delayed_work_sync(&hdev->ncmd_timer);
+ hci_devcd_shutdown(hdev);
hci_cmd_sync_clear(hdev);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 133/877] Bluetooth: ISO: Fix parent socket leak in iso_conn_ready()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (131 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 132/877] Bluetooth: coredump: Quiesce dump work on unregister Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 134/877] Bluetooth: ISO: set BT_LISTEN before requesting a BIG sync Greg Kroah-Hartman
` (751 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Luiz Augusto von Dentz, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
[ Upstream commit ca18ee413a7cb6f09885778039225e58bae0d607 ]
iso_get_sock() returns the parent socket with a reference held, which is
dropped by sock_put() once the child socket has been set up. The error
path taken when iso_sock_alloc() fails only calls release_sock() and
returns, leaking the reference and thus the parent socket itself.
Drop the reference on that path as well.
Fixes: fa224d0c094a ("Bluetooth: ISO: Reassociate a socket with an active BIS")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/iso.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index 6e1fac4b1cf63..8cdfe3b6e1235 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -2013,6 +2013,7 @@ static void iso_conn_ready(struct iso_conn *conn)
BTPROTO_ISO, GFP_ATOMIC, 0);
if (!sk) {
release_sock(parent);
+ sock_put(parent);
return;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 134/877] Bluetooth: ISO: set BT_LISTEN before requesting a BIG sync
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (132 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 133/877] Bluetooth: ISO: Fix parent socket leak in iso_conn_ready() Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 135/877] Bluetooth: btmtk: fix wrong status for short WMT FUNC_CTRL events Greg Kroah-Hartman
` (750 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Luiz Augusto von Dentz, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
[ Upstream commit 296e7f3c5071cc02dc22e1566e759179fa1792ae ]
A BIS connection is matched to its parent socket by looking for a
socket in BT_LISTEN state with the same BIG handle:
iso_conn_ready()
if (test_bit(HCI_CONN_BIG_SYNC, &hcon->flags))
parent = iso_get_sock(hdev, &hcon->src, &hcon->dst,
BT_LISTEN, iso_match_big_hcon, hcon);
The socket was only moved to BT_LISTEN after iso_conn_big_sync()
returned, while the LE BIG Create Sync command has already been queued
by then. If the BIG sync is established before the state is updated,
which is easy to hit with an emulated controller as the command may
complete in a few hundred microseconds, no parent is found and the BIS
connections are never notified to the listening socket.
The user space is then left waiting for connections that never arrive,
e.g. bluetoothd never completes a MediaTransport1.Acquire of a
Broadcast Sink transport.
Move the socket to BT_LISTEN before requesting the BIG sync, so the
state is visible by the time the command is queued, and restore the
previous state if the request could not be started. Since the socket is
briefly visible as a listening socket, child sockets may have been
queued in the meantime, so drain the accept queue before restoring the
state: the cleanup paths of BT_CONNECT2/BT_CONNECTED don't do it and the
children would be left with a dangling parent pointer.
Fixes: fbdc4bc47268 ("Bluetooth: ISO: Use defer setup to separate PA sync and BIG sync")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/iso.c | 52 +++++++++++++++++++++++++++++++++++----------
1 file changed, 41 insertions(+), 11 deletions(-)
diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index 8cdfe3b6e1235..3cf4ef291bf54 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -738,19 +738,24 @@ static void iso_sock_destruct(struct sock *sk)
skb_queue_purge(&sk->sk_write_queue);
}
-static void iso_sock_cleanup_listen(struct sock *parent)
+/* Close not yet accepted channels */
+static void iso_sock_flush_accept_q(struct sock *parent)
{
struct sock *sk;
- BT_DBG("parent %p", parent);
-
- /* Close not yet accepted channels */
while ((sk = bt_accept_dequeue(parent, NULL))) {
iso_sock_close(sk);
iso_sock_kill(sk);
/* Drop the reference handed back by bt_accept_dequeue(). */
sock_put(sk);
}
+}
+
+static void iso_sock_cleanup_listen(struct sock *parent)
+{
+ BT_DBG("parent %p", parent);
+
+ iso_sock_flush_accept_q(parent);
/* If listening socket has a hcon, properly disconnect it */
if (iso_pi(parent)->conn && iso_pi(parent)->conn->hcon) {
@@ -1524,6 +1529,13 @@ static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg,
switch (sk->sk_state) {
case BT_CONNECT2:
if (test_bit(BT_SK_PA_SYNC, &pi->flags)) {
+ /* Move to BT_LISTEN before requesting the BIG
+ * sync: the BIS connections are matched to a
+ * parent socket in BT_LISTEN state, and they
+ * may be notified before the request returns.
+ */
+ sk->sk_state = BT_LISTEN;
+
release_sock(sk);
err = iso_conn_big_sync(sk);
lock_sock(sk);
@@ -1532,12 +1544,20 @@ static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg,
* connection may have been torn down
* meanwhile and iso_chan_del() may have
* already moved the socket to BT_CLOSED.
- * Only move on to BT_LISTEN if the BIG sync
- * was actually started and nothing else has
- * changed the state.
+ * Only move back if the BIG sync could not be
+ * started and nothing else has changed the
+ * state.
*/
- if (!err && sk->sk_state == BT_CONNECT2)
- sk->sk_state = BT_LISTEN;
+ if (err && sk->sk_state == BT_LISTEN) {
+ /* Discard any child socket that may
+ * have been queued while the socket
+ * was in BT_LISTEN, as the cleanup of
+ * BT_CONNECT2 doesn't drain the
+ * accept queue.
+ */
+ iso_sock_flush_accept_q(sk);
+ sk->sk_state = BT_CONNECT2;
+ }
} else {
iso_conn_defer_accept(pi->conn->hcon);
sk->sk_state = BT_CONFIG;
@@ -1547,12 +1567,22 @@ static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg,
break;
case BT_CONNECTED:
if (test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags)) {
+ /* As above, the BIS connections may be
+ * notified before the request returns.
+ */
+ sk->sk_state = BT_LISTEN;
+
release_sock(sk);
err = iso_conn_big_sync(sk);
lock_sock(sk);
- if (!err && sk->sk_state == BT_CONNECTED)
- sk->sk_state = BT_LISTEN;
+ if (err && sk->sk_state == BT_LISTEN) {
+ /* As above, don't leave any child
+ * socket behind in the accept queue.
+ */
+ iso_sock_flush_accept_q(sk);
+ sk->sk_state = BT_CONNECTED;
+ }
early_ret = true;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 135/877] Bluetooth: btmtk: fix wrong status for short WMT FUNC_CTRL events
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (133 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 134/877] Bluetooth: ISO: set BT_LISTEN before requesting a BIG sync Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 136/877] Bluetooth: btmtksdio: Fix PM runtime reference leak in shutdown Greg Kroah-Hartman
` (749 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Lu, Luiz Augusto von Dentz,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Lu <chris.lu@mediatek.com>
[ Upstream commit 78b6abd6c7a7591aacdae657f813214dae4fcd3b ]
A too-short BTMTK_WMT_FUNC_CTRL event (WMT header only, no trailing
2-byte status word) is always treated as BTMTK_WMT_ON_UNDONE. This
short form is how firmware acks a plain enable/disable request, and
the actual result is carried in the header's own flag byte (0 =
success), not a separate status word. Decode it from there instead of
assuming failure.
Verified setup on MT7920, MT7921, MT7922 and MT7925: no regression.
Fixes: e3ac0d9f1a20 ("Bluetooth: btmtk: accept too short WMT FUNC_CTRL events")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Chris Lu <chris.lu@mediatek.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btmtk.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
index eb42b694da7f2..33e0e3eb65159 100644
--- a/drivers/bluetooth/btmtk.c
+++ b/drivers/bluetooth/btmtk.c
@@ -709,7 +709,12 @@ static int btmtk_usb_hci_wmt_sync(struct hci_dev *hdev,
case BTMTK_WMT_FUNC_CTRL:
if (!skb_pull_data(data->evt_skb,
sizeof(wmt_evt_funcc->status))) {
- status = BTMTK_WMT_ON_UNDONE;
+ /* A plain enable/disable request is acked with just
+ * the WMT header and no trailing status word; the
+ * result is carried in the header's own flag byte.
+ */
+ status = wmt_evt->whdr.flag ? BTMTK_WMT_ON_UNDONE :
+ BTMTK_WMT_ON_DONE;
break;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 136/877] Bluetooth: btmtksdio: Fix PM runtime reference leak in shutdown
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (134 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 135/877] Bluetooth: btmtk: fix wrong status for short WMT FUNC_CTRL events Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 137/877] Bluetooth: btintel_pcie: fix off-by-one bounds check in RX submit Greg Kroah-Hartman
` (748 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tzung-Bi Shih,
Luiz Augusto von Dentz, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tzung-Bi Shih <tzungbi@kernel.org>
[ Upstream commit 7b60ee5f46f2ee329de661f7c68b6818d8136220 ]
In btmtksdio_shutdown(), pm_runtime_get_sync() is called at the
beginning of the function. However, if sending the WMT function
control command fails later, the driver returns early.
It bypasses the corresponding pm_runtime_put_noidle() and
pm_runtime_disable() calls, leaking the PM usage counter and leaving PM
runtime enabled indefinitely.
Fall through to execute the PM runtime cleanup block even if WMT errors.
Fixes: 7f3c563c575e ("Bluetooth: btmtksdio: Add runtime PM support to SDIO based Bluetooth")
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btmtksdio.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
index 0e8fb01981432..575bac139715b 100644
--- a/drivers/bluetooth/btmtksdio.c
+++ b/drivers/bluetooth/btmtksdio.c
@@ -1245,10 +1245,8 @@ static int btmtksdio_shutdown(struct hci_dev *hdev)
wmt_params.status = NULL;
err = mtk_hci_wmt_sync(hdev, &wmt_params);
- if (err < 0) {
+ if (err < 0)
bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
- return err;
- }
ignore_wmt_cmd:
pm_runtime_put_noidle(bdev->dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 137/877] Bluetooth: btintel_pcie: fix off-by-one bounds check in RX submit
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (135 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 136/877] Bluetooth: btmtksdio: Fix PM runtime reference leak in shutdown Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 138/877] Bluetooth: RFCOMM: avoid socket lock inversion in listener cleanup Greg Kroah-Hartman
` (747 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sai Teja Aluvala,
Luiz Augusto von Dentz, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sai Teja Aluvala <aluvala.sai.teja@intel.com>
[ Upstream commit 2ea5a87a5a7ae58cb2662b8a7d06f209383e1765 ]
btintel_pcie_submit_rx() used frbd_index > rxq->count to guard the
FRBD array access, allowing frbd_index == rxq->count to pass through
and index one element past the end of the array. Change the check to
>= rxq->count so every out-of-range index is rejected.
This issue was reported by Claude Mythos.
Fixes: c2b636b3f788 (Bluetooth: btintel_pcie: Add support for PCIe transport)
Signed-off-by: Sai Teja Aluvala <aluvala.sai.teja@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btintel_pcie.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index 8ebdfd9744ca0..bc87ebc46f4db 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -210,7 +210,7 @@ static int btintel_pcie_submit_rx(struct btintel_pcie_data *data)
frbd_index = data->ia.tr_hia[BTINTEL_PCIE_RXQ_NUM];
- if (frbd_index > rxq->count)
+ if (frbd_index >= rxq->count)
return -ERANGE;
/* Prepare for RX submit. It updates the FRBD with the address of DMA
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 138/877] Bluetooth: RFCOMM: avoid socket lock inversion in listener cleanup
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (136 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 137/877] Bluetooth: btintel_pcie: fix off-by-one bounds check in RX submit Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 139/877] pppoatm: ensure a writable skb header and linear data Greg Kroah-Hartman
` (746 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+0cece8fa7d83523f47a3,
Juan Perdomo, Luiz Augusto von Dentz, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Juan Perdomo <jcperdomo100@gmail.com>
[ Upstream commit 801fb950cae7048eb7d83b18857d1ca37b8cd5a4 ]
rfcomm_sock_cleanup_listen() closes unaccepted child sockets through
rfcomm_sock_close(), which takes the child socket lock before
rfcomm_dlc_close() acquires rfcomm_mutex. The RFCOMM worker takes these
locks in reverse order while handling connections and DLC state changes,
so lockdep reports a possible deadlock.
Close dequeued children without taking their socket lock. The accept queue
owns a reference to each child, and bt_accept_dequeue() locks the child
while unlinking it and clearing its parent pointer.
Dropping the child lock makes it important to prevent a concurrent
rfcomm_connect_ind() from enqueueing a new child after cleanup observes an
empty queue. Set a listening socket to BT_CLOSED while its lock is still
held, before dropping the lock and draining the queue. The state check in
rfcomm_connect_ind() then rejects new children once cleanup starts.
Reported-by: syzbot+0cece8fa7d83523f47a3@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=0cece8fa7d83523f47a3
Fixes: b7ce436a5d79 ("Bluetooth: switch to lock_sock in RFCOMM")
Signed-off-by: Juan Perdomo <jcperdomo100@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/rfcomm/sock.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 2286efef62f5b..037a7fcab3023 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -243,9 +243,7 @@ static void __rfcomm_sock_close(struct sock *sk)
*/
static void rfcomm_sock_close(struct sock *sk)
{
- lock_sock(sk);
__rfcomm_sock_close(sk);
- release_sock(sk);
}
static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
@@ -902,6 +900,7 @@ static int rfcomm_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsig
static int rfcomm_sock_shutdown(struct socket *sock, int how)
{
struct sock *sk = sock->sk;
+ bool cleanup_listen = false;
int err = 0;
BT_DBG("sock %p, sk %p", sock, sk);
@@ -912,9 +911,17 @@ static int rfcomm_sock_shutdown(struct socket *sock, int how)
lock_sock(sk);
if (!sk->sk_shutdown) {
sk->sk_shutdown = SHUTDOWN_MASK;
+ if (sk->sk_state == BT_LISTEN) {
+ /* Block new children before cleaning up without sk lock. */
+ sk->sk_state = BT_CLOSED;
+ cleanup_listen = true;
+ }
release_sock(sk);
- __rfcomm_sock_close(sk);
+ if (cleanup_listen)
+ rfcomm_sock_cleanup_listen(sk);
+ else
+ __rfcomm_sock_close(sk);
lock_sock(sk);
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 139/877] pppoatm: ensure a writable skb header and linear data
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (137 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 138/877] Bluetooth: RFCOMM: avoid socket lock inversion in listener cleanup Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 140/877] drop_monitor: synchronize tracepoint unregistration on error path Greg Kroah-Hartman
` (745 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Simon Horman,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit ecc7253683a3c55caa868ce0ee530fcb0044bd3c ]
In pppoatm_send(), LLC encapsulation checks whether there is sufficient
headroom for the 4-byte LLC header, but does not ensure that the skb header
is writable.
Normal transmit packets passing through ppp_start_xmit() have their header
unshared via skb_cow_head(). However, packets can also reach pppoatm_send()
via PPP channel bridging (PPPIOCBRIDGECHAN) without going through
ppp_start_xmit().
Use skb_cow_head() to ensure both sufficient headroom and a writable
header before pushing the LLC header.
While at it:
- Call pskb_may_pull(skb, 1) before inspecting skb->data[0] to prevent
out-of-bounds reads on zero-length or non-linear frames (e.g. from
bridging).
- Defer SC_COMP_PROT protocol compression until after pppoatm_may_send()
succeeds. This eliminates the temporary skb allocation on admission failure
and completely removes the fragile "undo" heuristic at the nospace label,
avoiding any risk of reading uninitialized headroom or performing an
unbalanced skb_push().
Fixes: 4cf476ced45d ("ppp: add PPPIOCBRIDGECHAN and PPPIOCUNBRIDGECHAN ioctls")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260912233048.3977192-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/atm/pppoatm.c | 42 +++++++++++++++++-------------------------
1 file changed, 17 insertions(+), 25 deletions(-)
diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c
index 3e4f17d335feb..b668a30b67a8d 100644
--- a/net/atm/pppoatm.c
+++ b/net/atm/pppoatm.c
@@ -292,10 +292,13 @@ static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)
struct atm_vcc *vcc;
int ret;
+ if (!pskb_may_pull(skb, 1)) {
+ kfree_skb(skb);
+ return DROP_PACKET;
+ }
+
ATM_SKB(skb)->vcc = pvcc->atmvcc;
pr_debug("(skb=0x%p, vcc=0x%p)\n", skb, pvcc->atmvcc);
- if (skb->data[0] == '\0' && (pvcc->flags & SC_COMP_PROT))
- (void) skb_pull(skb, 1);
vcc = ATM_SKB(skb)->vcc;
bh_lock_sock(sk_atm(vcc));
@@ -318,23 +321,13 @@ static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)
switch (pvcc->encaps) { /* LLC encapsulation needed */
case e_llc:
- if (skb_headroom(skb) < LLC_LEN) {
- struct sk_buff *n;
- n = skb_realloc_headroom(skb, LLC_LEN);
- if (n != NULL &&
- !pppoatm_may_send(pvcc, n->truesize)) {
- kfree_skb(n);
- goto nospace;
- }
- consume_skb(skb);
- skb = n;
- if (skb == NULL) {
- bh_unlock_sock(sk_atm(vcc));
- return DROP_PACKET;
- }
- } else if (!pppoatm_may_send(pvcc, skb->truesize))
+ if (skb_cow_head(skb, LLC_LEN)) {
+ bh_unlock_sock(sk_atm(vcc));
+ kfree_skb(skb);
+ return DROP_PACKET;
+ }
+ if (!pppoatm_may_send(pvcc, skb->truesize))
goto nospace;
- memcpy(skb_push(skb, LLC_LEN), pppllc, LLC_LEN);
break;
case e_vc:
if (!pppoatm_may_send(pvcc, skb->truesize))
@@ -347,6 +340,12 @@ static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)
return 1;
}
+ if (skb->data[0] == '\0' && (pvcc->flags & SC_COMP_PROT))
+ skb_pull(skb, 1);
+
+ if (pvcc->encaps == e_llc)
+ memcpy(skb_push(skb, LLC_LEN), pppllc, LLC_LEN);
+
atm_account_tx(vcc, skb);
pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n",
skb, ATM_SKB(skb)->vcc, ATM_SKB(skb)->vcc->dev);
@@ -356,13 +355,6 @@ static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)
return ret;
nospace:
bh_unlock_sock(sk_atm(vcc));
- /*
- * We don't have space to send this SKB now, but we might have
- * already applied SC_COMP_PROT compression, so may need to undo
- */
- if ((pvcc->flags & SC_COMP_PROT) && skb_headroom(skb) > 0 &&
- skb->data[-1] == '\0')
- (void) skb_push(skb, 1);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 140/877] drop_monitor: synchronize tracepoint unregistration on error path
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (138 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 139/877] pppoatm: ensure a writable skb header and linear data Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 141/877] drop_monitor: fix out-of-bounds write in reset_per_cpu_data() Greg Kroah-Hartman
` (744 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Hangbin Liu,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 6a038ef2b57922b6d9ca98ddac0df0681849b704 ]
If register_trace_napi_poll() fails in net_dm_trace_on_set(),
unregister_trace_kfree_skb() is called to roll back the kfree_skb
tracepoint registration.
However, tracepoint_synchronize_unregister() is omitted before calling
cancel_work_sync() and module_put(). An in-flight probe executing
concurrently on another CPU could call schedule_work() after
cancel_work_sync() has already returned, leaving a pending work item
scheduled after the module reference is dropped. If the module is then
unloaded, executing the work item triggers a kernel panic.
Add tracepoint_synchronize_unregister() after unregister_trace_kfree_skb()
in the error path, matching net_dm_trace_off_set() and
net_dm_hw_probe_unregister().
Fixes: 7c747838a558 ("drop_monitor: Split tracing enable / disable to different functions")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Link: https://patch.msgid.link/20260910204612.3762015-2-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/drop_monitor.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index 308e0fa8f723f..a9c604ef2c826 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -1174,6 +1174,7 @@ static int net_dm_trace_on_set(struct netlink_ext_ack *extack)
err_unregister_trace:
unregister_trace_kfree_skb(ops->kfree_skb_probe, NULL);
+ tracepoint_synchronize_unregister();
err_module_put:
for_each_possible_cpu(cpu) {
struct per_cpu_dm_data *data = &per_cpu(dm_cpu_data, cpu);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 141/877] drop_monitor: fix out-of-bounds write in reset_per_cpu_data()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (139 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 140/877] drop_monitor: synchronize tracepoint unregistration on error path Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 142/877] net: stmmac: do not overwrite phc_index when no PTP clock is registered Greg Kroah-Hartman
` (743 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Hangbin Liu,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 439f392084f8f7f59ab9d47a9579185accefe1d8 ]
In reset_per_cpu_data(), al is computed as:
al = sizeof(struct net_dm_alert_msg);
al += dm_hit_limit * sizeof(struct net_dm_drop_point);
al += sizeof(struct nlattr);
skb = genlmsg_new(al, GFP_KERNEL);
...
nla = nla_reserve(skb, NLA_UNSPEC, sizeof(struct net_dm_alert_msg));
...
msg = nla_data(nla);
memset(msg, 0, al);
Because al includes sizeof(struct nlattr) (the 4-byte attribute header),
genlmsg_new() allocates al bytes of tailroom starting at nla.
However, msg points to nla_data(nla), which is located
sizeof(struct nlattr) bytes past nla. Calling memset(msg, 0, al)
therefore writes al bytes starting from msg, exceeding the allocated
buffer by sizeof(struct nlattr) (4 bytes) and corrupting
skb_shared_info.
Fix this by letting al represent only the payload length, allocating
the skb with genlmsg_new(nla_total_size(al), GFP_KERNEL), and zeroing
al bytes from msg.
Fixes: 683703a26e46 ("drop_monitor: Update netlink protocol to include netlink attribute header in alert message")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Link: https://patch.msgid.link/20260910204612.3762015-5-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/drop_monitor.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index a9c604ef2c826..1ba281bef21e3 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -141,9 +141,8 @@ static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data)
al = sizeof(struct net_dm_alert_msg);
al += dm_hit_limit * sizeof(struct net_dm_drop_point);
- al += sizeof(struct nlattr);
- skb = genlmsg_new(al, GFP_KERNEL);
+ skb = genlmsg_new(nla_total_size(al), GFP_KERNEL);
if (!skb)
goto err;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 142/877] net: stmmac: do not overwrite phc_index when no PTP clock is registered
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (140 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 141/877] drop_monitor: fix out-of-bounds write in reset_per_cpu_data() Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 143/877] KVM: PPC: Book3S HV: fix use-after-free in kvmhv_emulate_tlbie_all_lpid() Greg Kroah-Hartman
` (742 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Maxime Chevallier, Rahul Rameshbabu,
Lorenzo Bianconi, Gal Pressman, Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
[ Upstream commit f0ef4b1eaed000a304726a43091588e8426ba08a ]
stmmac_get_ts_info() reports phc_index as 0 when hardware timestamping
is supported but no PTP clock has been registered yet (e.g. while the
interface is down). Zero is a valid PHC index and would make userspace
resolve the wrong clock; the absence of a clock should be reported as
-1.
The ethtool core already initializes phc_index to -1 before invoking
the get_ts_info callback (ethtool_init_tsinfo()), so just drop the
erroneous assignment.
Fixes: 9364fa7fcf12 ("net: stmmac: Remove setting of RX software timestamp")
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
Reviewed-by: Gal Pressman <gal@nvidia.com>
Link: https://patch.msgid.link/20260914-stmmac-fix-phc_index-v2-1-bf3d90373fe4@oss.qualcomm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 2a37592a62810..ca8712a573ea0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -1206,8 +1206,6 @@ static int stmmac_get_ts_info(struct net_device *dev,
if (priv->ptp_clock)
info->phc_index = ptp_clock_index(priv->ptp_clock);
- else
- info->phc_index = 0;
info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 143/877] KVM: PPC: Book3S HV: fix use-after-free in kvmhv_emulate_tlbie_all_lpid()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (141 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 142/877] net: stmmac: do not overwrite phc_index when no PTP clock is registered Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 144/877] KVM: PPC: Book3S HV: fix secure device page leak on uv_page_in() failure Greg Kroah-Hartman
` (741 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ritesh Harjani (IBM),
R Nageswara Sastry, Amit Machhiwal, Gautam Menghani,
Madhavan Srinivasan, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amit Machhiwal <amachhiw@linux.ibm.com>
[ Upstream commit 51938dfa8a51a4f85328413fca9b6e21f9d2d088 ]
kvmhv_emulate_tlbie_all_lpid() iterates the nested-guest IDR and drops
mmu_lock before calling kvmhv_emulate_tlbie_lpid(), but does not hold a
reference on the kvm_nested_guest pointer obtained from the IDR. A
concurrent vCPU issuing a single-LPID tlbie (is=2, ric=2) can race
through kvmhv_flush_nested() -> kvmhv_remove_nested() -> idr_remove /
--refcnt -> kvmhv_release_nested() -> kfree(gp) in that window, leaving
the iterating vCPU with a dangling pointer. The subsequent
mutex_lock(&gp->tlb_lock) and accesses to gp->shadow_pgtable,
gp->shadow_lpid and gp->l1_host all touch freed memory. The free path
is fully L1-controlled.
Fix this by incrementing gp->refcnt inside the loop before dropping
mmu_lock, mirroring what kvmhv_get_nested() does, and releasing the
reference with kvmhv_put_nested() after the per-guest work completes.
This is the same get/put discipline already used at every other
call site that drops mmu_lock while holding a nested-guest pointer.
Fixes: e3b6b4661527 ("KVM: PPC: Book3S HV: Implement H_TLB_INVALIDATE hcall")
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Tested-by: R Nageswara Sastry <rnsastry@linux.ibm.com>
Signed-off-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Signed-off-by: Gautam Menghani <gautam@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/kvm/book3s_hv_nested.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c
index 125440a606ee3..a4dd8d983ec76 100644
--- a/arch/powerpc/kvm/book3s_hv_nested.c
+++ b/arch/powerpc/kvm/book3s_hv_nested.c
@@ -1202,8 +1202,10 @@ static void kvmhv_emulate_tlbie_all_lpid(struct kvm_vcpu *vcpu, int ric)
spin_lock(&kvm->mmu_lock);
idr_for_each_entry(&kvm->arch.kvm_nested_guest_idr, gp, lpid) {
+ ++gp->refcnt;
spin_unlock(&kvm->mmu_lock);
kvmhv_emulate_tlbie_lpid(vcpu, gp, ric);
+ kvmhv_put_nested(gp);
spin_lock(&kvm->mmu_lock);
}
spin_unlock(&kvm->mmu_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 144/877] KVM: PPC: Book3S HV: fix secure device page leak on uv_page_in() failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (142 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 143/877] KVM: PPC: Book3S HV: fix use-after-free in kvmhv_emulate_tlbie_all_lpid() Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 145/877] powerpc/iommu: Fix the overflow validation in iommu_tce_check_ioba Greg Kroah-Hartman
` (740 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ritesh Harjani (IBM),
R Nageswara Sastry, Amit Machhiwal, Gautam Menghani,
Madhavan Srinivasan, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amit Machhiwal <amachhiw@linux.ibm.com>
[ Upstream commit 0a416ee20bcccddf91ca5b63696a23b9d11d73aa ]
In kvmppc_svm_page_in(), if uv_page_in() fails after
kvmppc_uvmem_get_page() has succeeded, the secure device page is never
released. kvmppc_uvmem_get_page() sets a bit in kvmppc_uvmem_bitmap,
allocates a kvmppc_uvmem_page_pvt struct, marks the GFN as
KVMPPC_GFN_UVMEM_PFN, and calls zone_device_page_init() which sets
refcount=1 and locks the page. The subsequent goto out_finalize skips
the *mig.dst assignment, so migrate_vma_finalize() is a no-op for the
page, and none of those resources are ever reclaimed.
Each occurrence permanently consumes one entry from the firmware-bounded
secure memory pool (kvmppc_uvmem_bitmap), leaks pvt, and leaves the GFN
marked as secure — making it unusable for the lifetime of the VM.
The twin __kvmppc_svm_page_out() already handles the analogous uv_page_out()
failure correctly with unlock_page(dpage); __free_page(dpage). Apply
the same pattern here: unlock_page() followed by put_page(), which
chains through free_zone_device_folio() into kvmppc_uvmem_folio_free()
to clear the bitmap bit, free pvt, and reset the GFN state.
Reachable whenever uv_page_in() returns an error (e.g. UV pool
exhaustion) on any POWER9/10 + Ultravisor/PEF system.
Fixes: ca9f4942670c ("KVM: PPC: Book3S HV: Support for running secure guests")
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Tested-by: R Nageswara Sastry <rnsastry@linux.ibm.com>
Signed-off-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Signed-off-by: Gautam Menghani <gautam@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/kvm/book3s_hv_uvmem.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c b/arch/powerpc/kvm/book3s_hv_uvmem.c
index 92f33115144b2..7ea0c58622274 100644
--- a/arch/powerpc/kvm/book3s_hv_uvmem.c
+++ b/arch/powerpc/kvm/book3s_hv_uvmem.c
@@ -779,8 +779,11 @@ static int kvmppc_svm_page_in(struct vm_area_struct *vma,
if (spage) {
ret = uv_page_in(kvm->arch.lpid, pfn << page_shift,
gpa, 0, page_shift);
- if (ret)
+ if (ret) {
+ unlock_page(dpage);
+ put_page(dpage);
goto out_finalize;
+ }
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 145/877] powerpc/iommu: Fix the overflow validation in iommu_tce_check_ioba
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (143 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 144/877] KVM: PPC: Book3S HV: fix secure device page leak on uv_page_in() failure Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 146/877] ASoC: ux500: Parenthesize MSP_{RX,TX}_CLKPOL_BIT() arguments Greg Kroah-Hartman
` (739 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ritesh Harjani (IBM),
R Nageswara Sastry, Shivaprasad G Bhat, Gautam Menghani,
Madhavan Srinivasan, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shivaprasad G Bhat <sbhat@linux.ibm.com>
[ Upstream commit 0b271f7d7f5ed45bc498a03ce0aa9cfd8402fc71 ]
The commit b1af23d836f8 ("KVM: PPC: iommu: Unify TCE checking") unified
IOBA parameter checking across KVM and VFIO into iommu_tce_check_ioba().
While doing so, the passed in argument npages is ignored and constant
value '1' is used leaving out a possible overflow as the callers can
legitimately be using npages > 1 for H_STUFF_TCE or H_PUT_TCE_INDIRECT
cases.
Fix this by accounting for 'npages', checking for arithmetic overflow,
and verifying that the entire requested range (ioba - offset + npages)
does not exceed the table capacity 'size'.
Fixes: b1af23d836f8 ("KVM: PPC: iommu: Unify TCE checking")
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Tested-by: R Nageswara Sastry <rnsastry@linux.ibm.com>
Signed-off-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Signed-off-by: Gautam Menghani <gautam@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/kernel/iommu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 0ebae6e4c19dd..50c180cd1fa31 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -1074,7 +1074,7 @@ int iommu_tce_check_ioba(unsigned long page_shift,
if (ioba < offset)
return -EINVAL;
- if ((ioba + 1) > (offset + size))
+ if ((ioba + npages < ioba) || (ioba - offset + npages > size))
return -EINVAL;
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 146/877] ASoC: ux500: Parenthesize MSP_{RX,TX}_CLKPOL_BIT() arguments
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (144 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 145/877] powerpc/iommu: Fix the overflow validation in iommu_tce_check_ioba Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 147/877] ASoC: hdmi-codec: Report a change when the channel status moves Greg Kroah-Hartman
` (738 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, kernel test robot, Sasha Levin,
Linus Walleij, Mark Brown
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
[ Upstream commit 11fc0048a6930f4fca44fe3bd16a0023e78846a2 ]
arm allmodconfig fails to build with gcc:
In file included from sound/soc/ux500/ux500_msp_i2s.c:20:
sound/soc/ux500/ux500_msp_i2s.h:151:38: error: suggest parentheses
around arithmetic in operand of '^' [-Werror=parentheses]
sound/soc/ux500/ux500_msp_i2s.c:204:21: note: in expansion of macro
'MSP_TX_CLKPOL_BIT'
cc1: all warnings being treated as errors
The macros never parenthesized their argument:
#define MSP_TX_CLKPOL_BIT(n) ((n & TCKPOL_MASK) << TCKPOL_SHIFT)
That went unnoticed while every caller passed a plain variable, but
configure_protocol() now passes an XOR expression, which binds as
"a ^ (b & MASK)" rather than "(a ^ b) & MASK", and gcc rightly
complains.
No functional change: tx_clk_pol and rx_clk_pol only ever hold
MSP_FALLING_EDGE (0) or MSP_RISING_EDGE (1), and bclk_inverted is a
bool, so masking before or after the XOR gives the same 0/1 result.
Parenthesize the argument anyway - it fixes the build and stops the
macros from silently mis-evaluating a future composite argument.
Fixes: 9ccbacf5a012 ("ASoC: ux500: Validate MSP DAI configuration")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202609051547.G9SJp8UQ-lkp@intel.com/
Assisted-by: LLM
Signed-off-by: Sasha Levin <sashal@kernel.org>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260913173132.1172003-1-sashal@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/ux500/ux500_msp_i2s.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h
index 2bf2699bdc49f..c66ef455e1380 100644
--- a/sound/soc/ux500/ux500_msp_i2s.h
+++ b/sound/soc/ux500/ux500_msp_i2s.h
@@ -147,8 +147,8 @@ enum msp_direction {
#define RCKPOL_MASK BIT(0)
#define TCKPOL_MASK BIT(0)
#define SPICKM_MASK (BIT(1) | BIT(0))
-#define MSP_RX_CLKPOL_BIT(n) ((n & RCKPOL_MASK) << RCKPOL_SHIFT)
-#define MSP_TX_CLKPOL_BIT(n) ((n & TCKPOL_MASK) << TCKPOL_SHIFT)
+#define MSP_RX_CLKPOL_BIT(n) (((n) & RCKPOL_MASK) << RCKPOL_SHIFT)
+#define MSP_TX_CLKPOL_BIT(n) (((n) & TCKPOL_MASK) << TCKPOL_SHIFT)
#define P1ELEN_SHIFT 0
#define P1FLEN_SHIFT 3
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 147/877] ASoC: hdmi-codec: Report a change when the channel status moves
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (145 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 146/877] ASoC: ux500: Parenthesize MSP_{RX,TX}_CLKPOL_BIT() arguments Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 148/877] net: netsec: fix device_node reference leak on phy_np Greg Kroah-Hartman
` (737 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, HyeongJun An, Mark Brown,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: HyeongJun An <sammiee5311@gmail.com>
[ Upstream commit c17ae8c26eac16ad244daef44044d714f68a2ddc ]
The put() callback of "IEC958 Playback Default" stores all 24 channel
status bytes and then returns 0. The core notifies userspace only on a
positive return, so a write that changes what the get() callback hands
back is never announced, and a mixer holding the control open keeps
showing the old value.
Compare the stored bytes and return 1 when they move, the way
snd_hda_spdif_default_put() does.
The same shape is in img-spdif-out and uniperif_player.
No board with this codec was to hand. The change is a comparison of
driver state with no hardware behaviour in it, and mixer-test counts the
missing notification as event_missing.
Fixes: 7a8e1d44211e ("ASoC: hdmi-codec: Add iec958 controls")
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Assisted-by: Claude:claude-opus-5
Link: https://patch.msgid.link/20260915092515.2638542-1-sammiee5311@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/hdmi-codec.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index d9df29a26f4f2..0ffc649c6ad21 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -423,10 +423,14 @@ static int hdmi_codec_iec958_default_put(struct snd_kcontrol *kcontrol,
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
+ if (!memcmp(hcp->iec_status, ucontrol->value.iec958.status,
+ sizeof(hcp->iec_status)))
+ return 0;
+
memcpy(hcp->iec_status, ucontrol->value.iec958.status,
sizeof(hcp->iec_status));
- return 0;
+ return 1;
}
static int hdmi_codec_iec958_mask_get(struct snd_kcontrol *kcontrol,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 148/877] net: netsec: fix device_node reference leak on phy_np
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (146 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 147/877] ASoC: hdmi-codec: Report a change when the channel status moves Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 149/877] net: lock the socket in sock_gettstamp() Greg Kroah-Hartman
` (736 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yige Jiang, Simon Horman,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yige Jiang <yigejiang86@gmail.com>
[ Upstream commit 5ae916fabca141b79b32e2e57f3c915c0f1e1b2e ]
netsec_of_probe() takes a reference on the PHY device_node with
of_parse_phandle() and stores it in priv->phy_np, but the driver never
drops it. One device_node reference is leaked per probe, on the success
path as well as on every error path reached after netsec_of_probe().
Neither consumer takes ownership. of_mdio_parse_addr() is a static
inline taking a const struct device_node * that only reads the "reg"
property. of_phy_connect() borrows as well: of_phy_get_and_connect() in
drivers/net/mdio/of_mdio.c brackets its own call with of_node_get() at
:364 and of_node_put() at :373, which would be a double put if
of_phy_connect() consumed the reference.
The node is still in use at netsec_netdev_open() time, where it is
passed to of_phy_connect(), so it has device lifetime. Release it at
the probe error label, which every failure path after the acquire
funnels through, and in netsec_remove(). Both releases precede
free_netdev(), since priv is netdev_priv(ndev). The ACPI probe path
leaves priv->phy_np NULL and of_node_put(NULL) is a no-op.
There is no end-user visible symptom on currently supported platforms:
a device_node is only freed once OF_DYNAMIC is enabled and the node has
been detached, so on a static device tree the imbalance is inert. It is
observable as a refcount that grows across bind/unbind cycles, and would
matter under device tree overlays.
Found by static analysis of reference acquire/release pairing rather
than from a runtime report. No reproducer was produced and the change
has not been runtime tested; it is compile-tested only (arm64,
CONFIG_SNI_NETSEC=m via COMPILE_TEST).
Fixes: 533dd11a12f6 ("net: socionext: Add Synquacer NetSec driver")
Signed-off-by: Yige Jiang <yigejiang86@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260913064102.37452-1-yigejiang86@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/socionext/netsec.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c
index 5ab8b81b84e6f..e96e22dd30808 100644
--- a/drivers/net/ethernet/socionext/netsec.c
+++ b/drivers/net/ethernet/socionext/netsec.c
@@ -2146,6 +2146,7 @@ static int netsec_probe(struct platform_device *pdev)
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
free_ndev:
+ of_node_put(priv->phy_np);
free_netdev(ndev);
dev_err(&pdev->dev, "init failed\n");
@@ -2163,6 +2164,7 @@ static void netsec_remove(struct platform_device *pdev)
netif_napi_del(&priv->napi);
pm_runtime_disable(&pdev->dev);
+ of_node_put(priv->phy_np);
free_netdev(priv->ndev);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 149/877] net: lock the socket in sock_gettstamp()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (147 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 148/877] net: netsec: fix device_node reference leak on phy_np Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 150/877] net: ethernet: cortina: Ack RX overrun interrupt correctly Greg Kroah-Hartman
` (735 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jungwoo Lee, Wongi Lee, Eric Dumazet,
Simon Horman, Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 9ed55f3dbef4f4adfe65eb03b0c35c53229a8490 ]
sk->sk_flags must only be changed while holding the socket lock,
because sock_set_flag() and sock_reset_flag() use non atomic
operations (__set_bit() and __clear_bit()).
sock_gettstamp() is one of the last places where a bit of sk->sk_flags
is changed from a syscall without owning the socket lock, through
sock_enable_timestamp(sk, SOCK_TIMESTAMP).
sk_set_memalloc() and sk_clear_memalloc() also change sk->sk_flags
without the socket lock, but their callers (nbd, iscsi_tcp, nvme-tcp,
sunrpc, wireguard) need a careful audit, this will be addressed in a
separate patch.
Jungwoo Lee and Wongi Lee reported an UDP socket use-after-free
caused by this bug: a SIOCGSTAMPNS_NEW ioctl racing with bind()
can cancel the SOCK_RCU_FREE bit that udp_lib_get_port() just set,
because both threads perform a read-modify-write on the same word.
CPU 0 (bind) CPU 1 (SIOCGSTAMPNS_NEW)
-------------------------------- ----------------------------
read sk_flags = F read sk_flags = F
compute F | BIT(SOCK_RCU_FREE) compute F | BIT(SOCK_TIMESTAMP)
store F | BIT(SOCK_RCU_FREE)
sk_add_node_rcu(sk, ...)
store F | BIT(SOCK_TIMESTAMP)
After the lost update, SOCK_RCU_FREE is clear while the socket is
visible to lockless UDP receive lookups. sk_destruct() then frees
the socket immediately instead of waiting for a RCU grace period,
while the receive path still holds a reference-less pointer to it:
BUG: KASAN: slab-use-after-free in ipv4_pktinfo_prepare+0x30/0x410
Read of size 8 at addr ffff888008806610 by task exploit/207
CPU: 0 UID: 1000 PID: 207 Comm: exploit Not tainted 6.12.95+ #1
ipv4_pktinfo_prepare+0x30/0x410
udp_queue_rcv_one_skb+0x51c/0x1180
udp_unicast_rcv_skb+0x109/0x350
ip_protocol_deliver_rcu+0x14b/0x310
ip_local_deliver_finish+0x29d/0x390
ip_local_deliver+0x24d/0x2a0
Only grab the socket lock when SOCK_TIMESTAMP has to be set,
to keep the common case lockless.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Jungwoo Lee <jwlee2217@gmail.com>
Reported-by: Wongi Lee <qw3rtyp0@gmail.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260915043055.3441600-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/sock.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/net/core/sock.c b/net/core/sock.c
index e8b03cf3a428c..08b3569ac7a18 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -3724,7 +3724,14 @@ int sock_gettstamp(struct socket *sock, void __user *userstamp,
struct sock *sk = sock->sk;
struct timespec64 ts;
- sock_enable_timestamp(sk, SOCK_TIMESTAMP);
+ /* sk->sk_flags must only be changed under the socket lock,
+ * because sock_set_flag() uses non atomic operations.
+ */
+ if (!sock_flag(sk, SOCK_TIMESTAMP)) {
+ lock_sock(sk);
+ sock_enable_timestamp(sk, SOCK_TIMESTAMP);
+ release_sock(sk);
+ }
ts = ktime_to_timespec64(sock_read_timestamp(sk));
if (ts.tv_sec == -1)
return -ENOENT;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 150/877] net: ethernet: cortina: Ack RX overrun interrupt correctly
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (148 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 149/877] net: lock the socket in sock_gettstamp() Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 151/877] net: stmmac: propagate FPE preemption-class mapping errors Greg Kroah-Hartman
` (734 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Linus Walleij, Jakub Kicinski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit 1dd85662fee6e2ac580b1c4f9a0c0a7ae6e31f0e ]
The RX overrun interrupt is reported in interrupt status register 4, but
gmac_irq() acknowledges it using the RX descriptor error bit from status
register 0. For GMAC0 this writes the GMAC1 overrun bit, while for GMAC1
the shift leaves no bit in the 32-bit register.
Acknowledge the same per-port RX overrun bit that was detected.
Fixes: 4d5ae32f5e1e ("net: ethernet: Add a driver for Gemini gigabit ethernet")
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260914-b4-gemini-ethernet-fixes-2-v2-1-5ab39a047b90@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/cortina/gemini.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index 96fd27545b29b..1b81798914acc 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -1798,7 +1798,7 @@ static irqreturn_t gmac_irq(int irq, void *data)
if (val & (GMAC0_RX_OVERRUN_INT_BIT << (netdev->dev_id * 8))) {
spin_lock(&geth->irq_lock);
- writel(GMAC0_RXDERR_INT_BIT << (netdev->dev_id * 8),
+ writel(GMAC0_RX_OVERRUN_INT_BIT << (netdev->dev_id * 8),
geth->base + GLOBAL_INTERRUPT_STATUS_4_REG);
u64_stats_update_begin(&port->ir_stats_syncp);
++port->stats.rx_fifo_errors;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 151/877] net: stmmac: propagate FPE preemption-class mapping errors
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (149 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 150/877] net: ethernet: cortina: Ack RX overrun interrupt correctly Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 152/877] net: macb: fix ordering around PTP timestamp read Greg Kroah-Hartman
` (733 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Bianconi, Jakub Kicinski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
[ Upstream commit 90e4b849dfa6fc8e6c050bcfe1b331b69c015d28 ]
stmmac_fpe_map_preemption_class() dispatches through the
stmmac_do_void_callback() helper, which forces the callback's return
value to 0 whenever the op pointer is populated. As a result the
-EINVAL returned by dwmac5_fpe_map_preemption_class() (e.g. when a
preemptible TC owns more than one TXQ under SP scheduling) is silently
swallowed by every caller.
Switch the dispatch macro to stmmac_do_callback() so the callback's real
result is propagated, and honour it in the taprio and mqprio qdisc
offload.
Note that the taprio "if (ret)" check in tc_taprio_configure() used to
be dead code and now becomes live: a preemptible TC spanning more than
one TXQ under SP scheduling cannot be programmed in hardware, so a
taprio or mqprio configuration that previously returned success while
leaving the preemption-class register unprogrammed now fails with
-EINVAL. For taprio, the failure also runs the disable path, tearing
down the schedule that was just installed; this is the intended
behaviour.
Fixes: 195e4f409a40 ("net: stmmac: support fp parameter of tc-mqprio")
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
Link: https://patch.msgid.link/20260911-stmmac-tc_setup_dwmac510_mqprio-error-path-v3-1-a76b1e2547c1@oss.qualcomm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/stmicro/stmmac/hwif.h | 2 +-
.../net/ethernet/stmicro/stmmac/stmmac_tc.c | 19 +++++++++----------
2 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index d5a9f01ecac53..31d7f9375d747 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -541,7 +541,7 @@ struct stmmac_ops {
#define stmmac_fpe_set_add_frag_size(__priv, __args...) \
stmmac_do_void_callback(__priv, mac, fpe_set_add_frag_size, __args)
#define stmmac_fpe_map_preemption_class(__priv, __args...) \
- stmmac_do_void_callback(__priv, mac, fpe_map_preemption_class, __args)
+ stmmac_do_callback(__priv, mac, fpe_map_preemption_class, __args)
/* PTP and HW Timer helpers */
struct stmmac_hwtimestamp {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
index 49f133dec810d..65085f9c9290e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
@@ -970,7 +970,7 @@ static int tc_taprio_configure(struct stmmac_priv *priv,
struct netlink_ext_ack *extack = qopt->mqprio.extack;
struct timespec64 time, current_time, qopt_time;
ktime_t current_time_ns;
- int i, ret = 0;
+ int err, i, ret = 0;
u64 ctr;
if (qopt->base_time < 0)
@@ -1119,9 +1119,9 @@ static int tc_taprio_configure(struct stmmac_priv *priv,
mutex_unlock(&priv->est_lock);
}
- stmmac_fpe_map_preemption_class(priv, priv->dev, extack, 0);
+ err = stmmac_fpe_map_preemption_class(priv, priv->dev, extack, 0);
- return ret;
+ return qopt->cmd == TAPRIO_CMD_DESTROY ? err : ret;
}
static void tc_taprio_stats(struct stmmac_priv *priv,
@@ -1234,14 +1234,15 @@ static int tc_query_caps(struct stmmac_priv *priv,
}
}
-static void stmmac_reset_tc_mqprio(struct net_device *ndev,
- struct netlink_ext_ack *extack)
+static int stmmac_reset_tc_mqprio(struct net_device *ndev,
+ struct netlink_ext_ack *extack)
{
struct stmmac_priv *priv = netdev_priv(ndev);
netdev_reset_tc(ndev);
netif_set_real_num_tx_queues(ndev, priv->plat->tx_queues_to_use);
- stmmac_fpe_map_preemption_class(priv, ndev, extack, 0);
+
+ return stmmac_fpe_map_preemption_class(priv, ndev, extack, 0);
}
static int tc_setup_dwmac510_mqprio(struct stmmac_priv *priv,
@@ -1254,10 +1255,8 @@ static int tc_setup_dwmac510_mqprio(struct stmmac_priv *priv,
u32 num_tc = qopt->num_tc;
int err;
- if (!num_tc) {
- stmmac_reset_tc_mqprio(ndev, extack);
- return 0;
- }
+ if (!num_tc)
+ return stmmac_reset_tc_mqprio(ndev, extack);
err = netdev_set_num_tc(ndev, num_tc);
if (err)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 152/877] net: macb: fix ordering around PTP timestamp read
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (150 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 151/877] net: stmmac: propagate FPE preemption-class mapping errors Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 153/877] net: mvpp2: prevent buffer overflow in page_pool allocation Greg Kroah-Hartman
` (732 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Théo Lebrun,
James Clark, Paolo Abeni, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Clark <jjc@jclark.com>
[ Upstream commit 9ca4ba24259183ce15665be86b2956cd896c4687 ]
PTP_SYS_OFFSET_EXTENDED returns system timestamps that do not correctly
bracket the PHC register read on MACB/GEM. On a Raspberry Pi 5, the
returned interval can be as short as 37 ns, while an ordered register
read takes approximately 1 us. This biases the midpoint used by phc2sys,
causing CLOCK_REALTIME to run approximately 0.5 us ahead when synchronized
to the PHC.
gem_tsu_get_time() reads the nanoseconds register using the driver's
relaxed MMIO accessor. On weakly ordered systems, the subsequent system
timestamp can be taken before the register read completes. The internal
smp_rmb() in the pre-timestamp path also does not guarantee ordering
against the subsequent MMIO read.
Add rmb() before and after the bracketed nanoseconds read in both the
normal and seconds rollover paths so the system timestamps bracket the
PHC read. Adding the post-read barrier increases the minimum interval on
the same Raspberry Pi 5 to approximately 1 us.
Fixes: e51bb5c2784c ("net: macb: ptp: Switch to gettimex64() interface")
Tested-by: Nicolai Buchwitz <nb@tipi-net.de> # Raspberry Pi CM5, min bracket 37 ns -> 981 ns
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Reviewed-by: Théo Lebrun <theo.lebrun@bootlin.com>
Assisted-by: LLM
Signed-off-by: James Clark <jjc@jclark.com>
Link: https://patch.msgid.link/20260915045823.76100-1-jjc@jclark.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/cadence/macb_ptp.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/net/ethernet/cadence/macb_ptp.c b/drivers/net/ethernet/cadence/macb_ptp.c
index f2b09100f710e..004c0b3b9181c 100644
--- a/drivers/net/ethernet/cadence/macb_ptp.c
+++ b/drivers/net/ethernet/cadence/macb_ptp.c
@@ -48,7 +48,12 @@ static int gem_tsu_get_time(struct ptp_clock_info *ptp, struct timespec64 *ts,
spin_lock_irqsave(&bp->tsu_clk_lock, flags);
ptp_read_system_prets(sts);
+ /* explicit barriers are needed because gem_readl() is relaxed */
+ if (sts)
+ rmb();
first = gem_readl(bp, TN);
+ if (sts)
+ rmb();
ptp_read_system_postts(sts);
secl = gem_readl(bp, TSL);
sech = gem_readl(bp, TSH);
@@ -60,7 +65,11 @@ static int gem_tsu_get_time(struct ptp_clock_info *ptp, struct timespec64 *ts,
* (assume all done within 1s)
*/
ptp_read_system_prets(sts);
+ if (sts)
+ rmb();
ts->tv_nsec = gem_readl(bp, TN);
+ if (sts)
+ rmb();
ptp_read_system_postts(sts);
secl = gem_readl(bp, TSL);
sech = gem_readl(bp, TSH);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 153/877] net: mvpp2: prevent buffer overflow in page_pool allocation
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (151 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 152/877] net: macb: fix ordering around PTP timestamp read Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 154/877] net: skbuff: do not leave stale header offsets after pskb_carve() Greg Kroah-Hartman
` (731 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dmitriy Okunev, Paolo Abeni,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitriy Okunev <dokunevdmitriy@gmail.com>
[ Upstream commit 14cb1e7702e5cb3c58888f6aed498381a73927d2 ]
The per‑processor buffering scheme is supported only if the
number of pools (nrxqs * 2) does not exceed MVPP2_BM_MAX_POOLS (8).
This is already checked in mvpp2_probe() during the initial
activation of percpu_pools.
However, mvpp2_change_mtu() may later call
mvpp2_bm_switch_buffers(priv, true) without this check, which can
lead to an out-of-bounds access in the priv->page_pool array in
mvpp2_bm_init(). The array is sized to hold MVPP2_PORT_MAX_RXQ
entries, and mvpp2_get_nrxqs() may return exactly that value. The
per-CPU scheme then doubles it to nrxqs * 2, exceeding the array
bounds.
Check that the hardware version is MVPP22 or newer and that the
number of pools (nrxqs * 2) does not exceed MVPP2_BM_MAX_POOLS
before switching to per-CPU mode.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: 7d04b0b13b11 ("mvpp2: percpu buffers")
Signed-off-by: Dmitriy Okunev <dokunevdmitriy@gmail.com>
Link: https://patch.msgid.link/20260914091557.71769-1-dokunevdmitriy@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 325a3a657249d..8096b46b654fd 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -5099,7 +5099,8 @@ static int mvpp2_change_mtu(struct net_device *dev, int mtu)
netdev_warn(dev, "mtu %d too high, switching to shared buffers", mtu);
mvpp2_bm_switch_buffers(priv, false);
}
- } else {
+ } else if (priv->hw_version >= MVPP22 &&
+ mvpp2_get_nrxqs(priv) * 2 <= MVPP2_BM_MAX_POOLS) {
bool jumbo = false;
int i;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 154/877] net: skbuff: do not leave stale header offsets after pskb_carve()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (152 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 153/877] net: mvpp2: prevent buffer overflow in page_pool allocation Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 155/877] drm/amdgpu: check ras and obj before dereference Greg Kroah-Hartman
` (730 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+586af68eb819833c2d91,
Xuanqiang Luo, Allison Henderson, rds-devel, Eric Dumazet,
Xuanqiang Luo, Paolo Abeni, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit a5117e1eccac6ee3bd4aed7cacf8ebcb6b3eb309 ]
pskb_carve_inside_header() and pskb_carve_inside_nonlinear() remove
the first bytes of a packet and reallocate skb->head.
All the headers that were present before the operation are gone,
but both functions call skb_headers_offset_update(skb, 0), which
is a no-op : skb->mac_header, skb->network_header,
skb->transport_header and skb->csum_start keep their old values and
now describe bytes which are no longer there.
Both helpers size the new head from the old skb_end_offset(), so the
stale offsets still land inside the new allocation. They point past
skb_tail_pointer() though, to bytes that were never initialized.
pskb_carve_inside_nonlinear() is the worst case, because it leaves a
zombie skb with an empty linear part (skb->data ==
skb_tail_pointer(skb), skb_headlen(skb) == 0), while
skb_mac_header_was_set() is still true and skb->mac_header is way
ahead of skb->data.
The only user of pskb_extract() is rds_tcp_data_recv(), and the
carved skb is queued on tinc->ti_skb_list. When the RDS incoming
message is released, rds_tcp_inc_free() calls skb_queue_purge(),
which frees the skbs with SKB_DROP_REASON_QUEUE_PURGE. This is
visible from drop_monitor, which then tries to pull back to the
(bogus) mac header :
skbuff: __skb_pull(len=234)
skb len=6968 data_len=6968 headroom=0 headlen=0 tailroom=0
end-tail=384 mac=(234,14) mac_len=14 net=(248,40) trans=288
shinfo(txflags=0 nr_frags=1 gso(size=1428 type=16 segs=5))
csum(0x100120 start=288 offset=16 ip_summed=3 complete_sw=0 valid=1 level=0)
hash(0x7b446c6c sw=0 l4=1) proto=0x86dd pkttype=0 iif=60
kernel BUG at ./include/linux/skbuff.h:2847!
Add skb_carve_reset_headers() to mark the mac and transport headers
as not set, reset the network header, clear skb->mac_len, and drop
a now meaningless CHECKSUM_PARTIAL (csum_start no longer describes
anything).
Invalidate the inner offsets as well. Unlike mac_header and
transport_header they have no "unset" sentinel, so a leftover
non-zero value still looks like a real header. Zero
skb->inner_mac_header, skb->inner_network_header,
skb->inner_transport_header, skb->inner_protocol and
skb->encapsulation, so that all the header state is invalidated in
one place.
v2: fixed an inaccurate changelog. The stale offsets stay inside the
new skb->head, which is never smaller than the old one, they
simply point past skb_tail_pointer() to bytes that are gone.
Thanks to Xuanqiang Luo for insisting on this.
Also invalidate the inner header state, as suggested by the
netdev AI review :
https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260911114922.621937-1-edumazet%40google.com
Fixes: 6fa01ccd8830 ("skbuff: Add pskb_extract() helper function")
Reported-by: syzbot+586af68eb819833c2d91@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/6aa3e9d3.f2639fcc.29487d.0028.GAE@google.com/
Cc: Xuanqiang Luo <xuanqiang.luo@linux.dev>
Cc: Allison Henderson <achender@kernel.org>
Cc: rds-devel@oss.oracle.com
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Link: https://patch.msgid.link/20260915130423.3956471-1-edumazet@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/skbuff.c | 32 ++++++++++++++++++++++++++++++--
1 file changed, 30 insertions(+), 2 deletions(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 449c84fa73539..1e4f7b8e952cc 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -6696,6 +6696,34 @@ struct sk_buff *alloc_skb_with_frags(unsigned long header_len,
}
EXPORT_SYMBOL(alloc_skb_with_frags);
+/* pskb_carve_inside_header() and pskb_carve_inside_nonlinear()
+ * remove the first bytes of a packet and reallocate skb->head.
+ *
+ * Whatever headers were present before the operation are gone,
+ * we must not leave stale offsets, otherwise users of this skb
+ * (skb_dump(), drop_monitor, taps, ...) would read or pull garbage.
+ */
+static void skb_carve_reset_headers(struct sk_buff *skb)
+{
+ skb_unset_mac_header(skb);
+ skb_unset_transport_header(skb);
+ skb_reset_network_header(skb);
+ skb->mac_len = 0;
+
+ /* Inner offsets have no "unset" marker, zero them so that
+ * skb_inner_network_header_was_set() becomes false and no
+ * consumer mistakes them for a real (and long gone) header.
+ */
+ skb->inner_mac_header = 0;
+ skb->inner_network_header = 0;
+ skb->inner_transport_header = 0;
+ skb->inner_protocol = 0;
+ skb->encapsulation = 0;
+
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ skb->ip_summed = CHECKSUM_NONE;
+}
+
/* carve out the first off bytes from skb when off < headlen */
static int pskb_carve_inside_header(struct sk_buff *skb, const u32 off,
const int headlen, gfp_t gfp_mask)
@@ -6751,7 +6779,7 @@ static int pskb_carve_inside_header(struct sk_buff *skb, const u32 off,
skb->head_frag = 0;
skb_set_end_offset(skb, size);
skb_set_tail_pointer(skb, skb_headlen(skb));
- skb_headers_offset_update(skb, 0);
+ skb_carve_reset_headers(skb);
skb->cloned = 0;
skb->hdr_len = 0;
skb->nohdr = 0;
@@ -6892,7 +6920,7 @@ static int pskb_carve_inside_nonlinear(struct sk_buff *skb, const u32 off,
skb->data = data;
skb_set_end_offset(skb, size);
skb_reset_tail_pointer(skb);
- skb_headers_offset_update(skb, 0);
+ skb_carve_reset_headers(skb);
skb->cloned = 0;
skb->hdr_len = 0;
skb->nohdr = 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 155/877] drm/amdgpu: check ras and obj before dereference
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (153 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 154/877] net: skbuff: do not leave stale header offsets after pskb_carve() Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 156/877] btrfs: abort transaction on failure to update inode for hole punching and reflinking Greg Kroah-Hartman
` (729 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tao Zhou, Dmitriy Chumachenko,
Alex Deucher, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitriy Chumachenko <Dmitry.Chumachenko@cyberprotect.ru>
[ Upstream commit 723d4dc628d764b19cf9efca14b82cca5ff020c9 ]
nbio_v7_9_handle_ras_controller_intr_no_bifring() dereferences ras and obj
without checking either for NULL. Both amdgpu_ras_get_context() and
amdgpu_ras_find_obj() can return NULL, e.g. during the window between
adev->nbio.ras being set (early in amdgpu_ras_init(), by design, to
enable the fatal-error interrupt as soon as possible) and the PCIE_BIF
ras object actually being created in RAS late_init. Any interrupt in that
window crashes in hard-IRQ context.
This is analogous to commit d190b459b2a4 ("drm/amdgpu: the warning
dereferencing obj for nbio_v7_4"), which fixed the same issue in the
nbio_v7_4 handler.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: 7692e1ee2446 ("drm/amdgpu: add RAS fatal error handler for NBIO v7.9")
Reviewed-by: Tao Zhou <tao.zhou1@amd.com>
Signed-off-by: Dmitriy Chumachenko <Dmitry.Chumachenko@cyberprotect.ru>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit c7071767a50a32ed727cf800ac84372429e3b4b3)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c
index 8e401f8b2a054..2b3a1b9f8efc0 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c
@@ -518,7 +518,7 @@ static void nbio_v7_9_handle_ras_controller_intr_no_bifring(struct amdgpu_device
RAS_CNTLR_INTERRUPT_CLEAR, 1);
WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_DOORBELL_INT_CNTL, bif_doorbell_intr_cntl);
- if (!ras->disable_ras_err_cnt_harvest) {
+ if (ras && !ras->disable_ras_err_cnt_harvest && obj) {
/*
* clear error status after ras_controller_intr
* according to hw team and count ue number
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 156/877] btrfs: abort transaction on failure to update inode for hole punching and reflinking
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (154 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 155/877] drm/amdgpu: check ras and obj before dereference Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 157/877] x86/fred: Reconstruct the #GP context for rejected INT instructions Greg Kroah-Hartman
` (728 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qu Wenruo, Filipe Manana,
David Sterba, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <fdmanana@suse.com>
[ Upstream commit 97fcd34aa9fd73cefe3120ac9a82ca9d7763922f ]
If we fail to update the inode we error out without aborting the
transaction, which can result in a persistent inconsistency if after
the failure the transaction is committed, as we have dropped file
extent items from a range and either punched a hole or insert a new file
extent item for that range (for reflinks).
So add the missing transaction abort.
Fixes: 2aaa66558172 ("Btrfs: add hole punching")
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/file.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 9c3b5ecb0b01e..5627e2f7dd64a 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -2545,8 +2545,10 @@ int btrfs_replace_file_extents(struct btrfs_inode *inode,
inode_set_ctime_current(&inode->vfs_inode));
ret = btrfs_update_inode(trans, inode);
- if (ret)
+ if (unlikely(ret)) {
+ btrfs_abort_transaction(trans, ret);
break;
+ }
btrfs_end_transaction(trans);
btrfs_btree_balance_dirty(fs_info);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 157/877] x86/fred: Reconstruct the #GP context for rejected INT instructions
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (155 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 156/877] btrfs: abort transaction on failure to update inode for hole punching and reflinking Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 158/877] mm/huge_memory: use folios memcg inside __folio_split() Greg Kroah-Hartman
` (727 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Paul Gofman, Matthew Schwartz,
Peter Zijlstra (Intel), H. Peter Anvin, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Schwartz <matthew.schwartz@linux.dev>
[ Upstream commit 93f53499d0b945e8ae447f497faf743d60069f61 ]
FRED event delivery does not use the IDT, so the gate DPL check that
rejects a user INT n falls to software (Intel FRED specification [1],
section 8.3). fred_intx() rejects the same vectors as IDT delivery, but
reports a zero error code and the IP after the INT. This breaks the
signal ABI. Wine uses the error code to recognize INT 0x2d, so the
changed context turns a handled breakpoint into an access violation in
Elden Ring.
Rewind IP using the instruction length in the augmented SS and
synthesize the IDT selector error code, (vector << 3) | 2. Set RF in the
saved flags, as the CPU does for a #GP fault. Section 5.2.1 defines the
saved vector, instruction length and RF state. The supplied length
handles prefixes without reading user memory. Limit the changes to
already-rejected software interrupts, preserving the accepted INT3, INT4
and enabled INT80 paths and hardware exceptions. With IA32 emulation
disabled, INT 0x80 now reports the same #GP as the DPL 0 gate IDT
installs there. The rewound IP also stops fixup_iopl_exception() from
inspecting the byte after the INT.
Also clear the software event flag. Section 6.2.3 specifies that ERETU
with this flag and TF set traps before executing any user instruction. A
tracer that suppresses SIGSEGV and resumes with TF set expects the next
instruction to run first, as after IRET. The sigreturn path clears the
same flag for this reason in prevent_single_step_upon_eretu().
[1] Intel Flexible Return and Event Delivery (FRED) Specification,
revision 9.0 (346446-009US), sections 5.2.1, 6.2.3 and 8.3.
Fixes: 14619d912b65 ("x86/fred: FRED entry/exit and dispatch code")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/work_items/15745
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/work_items/16132
Reported-by: Paul Gofman <pgofman@codeweavers.com>
Signed-off-by: Matthew Schwartz <matthew.schwartz@linux.dev>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: H. Peter Anvin <hpa@zytor.com>
Link: https://cdrdv2.intel.com/v1/dl/getContent/678938 # [1]
Link: https://patch.msgid.link/20260917230907.2080792-2-matthew.schwartz@linux.dev
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/entry/entry_fred.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/arch/x86/entry/entry_fred.c b/arch/x86/entry/entry_fred.c
index 9f50f0c1c00f5..c43c750fa26dc 100644
--- a/arch/x86/entry/entry_fred.c
+++ b/arch/x86/entry/entry_fred.c
@@ -10,6 +10,7 @@
#include <asm/desc.h>
#include <asm/fred.h>
#include <asm/idtentry.h>
+#include <asm/processor-flags.h>
#include <asm/syscall.h>
#include <asm/trapnr.h>
#include <asm/traps.h>
@@ -71,7 +72,15 @@ static noinstr void fred_intx(struct pt_regs *regs)
#endif
default:
- return exc_general_protection(regs, 0);
+ /*
+ * Reconstruct the #GP fault state that IDT delivery would produce.
+ * Clear the software event flag so ERETU with TF set does not trap
+ * before the resumed instruction. See prevent_single_step_upon_eretu().
+ */
+ regs->ip -= regs->fred_ss.insnlen;
+ regs->flags |= X86_EFLAGS_RF;
+ regs->fred_ss.swevent = 0;
+ return exc_general_protection(regs, (regs->fred_ss.vector << 3) | 2);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 158/877] mm/huge_memory: use folios memcg inside __folio_split()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (156 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 157/877] x86/fred: Reconstruct the #GP context for rejected INT instructions Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 159/877] wifi: rtw88: TX QOS Null data the same way as Null data Greg Kroah-Hartman
` (726 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zi Yan, Johannes Weiner, Baolin Wang,
Lorenzo Stoakes (ARM), Barry Song, David Hildenbrand, Dev Jain,
Lance Yang, Liam R. Howlett, Matthew Wilcox (Oracle),
Ryan Roberts, William Kucharski, Andrew Morton, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zi Yan <ziy@nvidia.com>
commit c299a2285d9d8bda4da024455de65e3d00de6f17 upstream.
Patch series "Honor XA_FLAGS_ACCOUNT in xas_split_alloc() and charge to
folio's memcg", v3.
__GFP_ACCOUNT is needed for xarray node allocation accounting when
XA_FLAGS_ACCOUNT is set. Commit 7b785645e8f13 ("mm: fix page cache
convergence regression") fixed a workingset regression with it.
xas_split_alloc() does not have it and needs to be fixed.
In addition, based on Sashiko's review[1] and Johannes' confirmation[2], to
charge the right memcg, folio's memcg needs to be active during folio
split. Add that before adding __GFP_ACCOUNT.
There is no workingset convergence regression related to missing
__GFP_ACCOUNT in xas_split_alloc() and the impact to userspace should be
minor.
This patch (of 2):
During a pagecache folio split, an xarray node allocation can happen and
needs to charge at folio's memcg instead of folio split invoker's memcg,
because for example folio split can happen during reclaim and reclaim's
active memcg might not be folio's memcg. Switch to folio's memcg at the
beginning and switch back afterwards.
Link: https://lore.kernel.org/20260804-add-gfp_account-to-xas_split_alloc-v3-0-38cb3ff325c5@nvidia.com
Link: https://lore.kernel.org/20260804-add-gfp_account-to-xas_split_alloc-v3-1-38cb3ff325c5@nvidia.com
Link: https://sashiko.dev/#/patchset/20260727-add-gfp_account-to-xas_split_alloc-v1-1-9fae6bf64838%40nvidia.com?part=1 [1]
Link: https://lore.kernel.org/all/amtcBZ-_QVRgCd6b@cmpxchg.org/ [2]
Fixes: 6b24ca4a1a8d ("mm: Use multi-index entries in the page cache")
Signed-off-by: Zi Yan <ziy@nvidia.com>
Suggested-by: Johannes Weiner <hannes@cmpxchg.org>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Cc: Barry Song <baohua@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Lance Yang <lance.yang@linux.dev>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: William Kucharski <william.kucharski@oracle.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
(cherry picked from commit c299a2285d9d8bda4da024455de65e3d00de6f17)
Signed-off-by: Zi Yan <ziy@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/huge_memory.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 6fc4e1fb88ae6..1a76a21724d40 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -3420,6 +3420,7 @@ int split_huge_page_to_list_to_order(struct page *page, struct list_head *list,
/* reset xarray order to new order after split */
XA_STATE_ORDER(xas, &folio->mapping->i_pages, folio->index, new_order);
bool is_anon = folio_test_anon(folio);
+ struct mem_cgroup *memcg, *old_memcg;
struct address_space *mapping = NULL;
struct anon_vma *anon_vma = NULL;
int order = folio_order(folio);
@@ -3483,6 +3484,13 @@ int split_huge_page_to_list_to_order(struct page *page, struct list_head *list,
if (folio_test_writeback(folio))
return -EBUSY;
+ /*
+ * switch to folio's memcg as xarray node allocation can happen and
+ * needs to charge to it.
+ */
+ memcg = folio_memcg(folio);
+ old_memcg = set_active_memcg(memcg);
+
if (is_anon) {
/*
* The caller does not necessarily hold an mmap_lock that would
@@ -3629,6 +3637,8 @@ int split_huge_page_to_list_to_order(struct page *page, struct list_head *list,
if (mapping)
i_mmap_unlock_read(mapping);
out:
+ /* restore to caller's old_memcg */
+ set_active_memcg(old_memcg);
xas_destroy(&xas);
if (order == HPAGE_PMD_ORDER)
count_vm_event(!ret ? THP_SPLIT_PAGE : THP_SPLIT_PAGE_FAILED);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 159/877] wifi: rtw88: TX QOS Null data the same way as Null data
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (157 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 158/877] mm/huge_memory: use folios memcg inside __folio_split() Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 160/877] wifi: rtw88: Fix the random "error beacon valid" messages for USB Greg Kroah-Hartman
` (725 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bitterblue Smith, Ping-Ke Shih,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
[ Upstream commit 737e980e12983bb7420a2c00b981a1e607079a84 ]
When filling out the TX descriptor, Null data frames are treated like
management frames, but QOS Null data frames are treated like normal
data frames. Somehow this causes a problem for the firmware.
When connected to a network in the 2.4 GHz band, wpa_supplicant (or
NetworkManager?) triggers a scan every five minutes. During these scans
mac80211 transmits many QOS Null frames in quick succession. Because
these frames are marked with IEEE80211_TX_CTL_REQ_TX_STATUS, rtw88
asks the firmware to report the TX ACK status for each of these frames.
Sometimes the firmware can't process the TX status requests quickly
enough, they add up, it only processes some of them, and then marks
every subsequent TX status report with the wrong number.
The symptom is that after a while the warning "failed to get tx report
from firmware" appears every five minutes.
This problem apparently happens only with the older RTL8723D, RTL8821A,
RTL8812A, and probably RTL8703B chips.
Treat QOS Null data frames the same way as Null data frames. This seems
to avoid the problem.
Tested with RTL8821AU, RTL8723DU, RTL8811CU, and RTL8812BU.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/2b53fb0d-b1ed-47b6-8caa-2bb9ae2acb80@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/realtek/rtw88/tx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c
index 662fb27224f3d..0c8817bf46c74 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.c
+++ b/drivers/net/wireless/realtek/rtw88/tx.c
@@ -421,7 +421,7 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev,
pkt_info->mac_id = rtwvif->mac_id;
}
- if (ieee80211_is_mgmt(fc) || ieee80211_is_nullfunc(fc))
+ if (ieee80211_is_mgmt(fc) || ieee80211_is_any_nullfunc(fc))
rtw_tx_mgmt_pkt_info_update(rtwdev, pkt_info, sta, skb);
else if (ieee80211_is_data(fc))
rtw_tx_data_pkt_info_update(rtwdev, pkt_info, sta, skb);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 160/877] wifi: rtw88: Fix the random "error beacon valid" messages for USB
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (158 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 159/877] wifi: rtw88: TX QOS Null data the same way as Null data Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 161/877] Input: xpad - add support for Victrix Pro BFG Controller Greg Kroah-Hartman
` (724 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bitterblue Smith, Ping-Ke Shih,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
[ Upstream commit f24d0d8c3cd7e4237f802c4d2f3bd4ac04572948 ]
All the USB devices have a problem in AP mode: uploading the updated
beacon to the chip's reserved page can randomly fail:
[34996.474304] rtw88_8723du 1-2:1.2: error beacon valid
[34996.474788] rtw88_8723du 1-2:1.2: failed to download drv rsvd page
[34999.956369] rtw88_8723du 1-2:1.2: error beacon valid
[34999.956846] rtw88_8723du 1-2:1.2: failed to download drv rsvd page
[34999.956855] rtw88_8723du 1-2:1.2: failed to download beacon
[35017.978296] rtw88_8723du 1-2:1.2: error beacon valid
[35017.978805] rtw88_8723du 1-2:1.2: failed to download drv rsvd page
[35017.978823] rtw88_8723du 1-2:1.2: failed to download beacon
[35023.200395] rtw88_8723du 1-2:1.2: error beacon valid
[35023.200869] rtw88_8723du 1-2:1.2: failed to download drv rsvd page
[35023.200875] rtw88_8723du 1-2:1.2: failed to download beacon
[35478.680547] rtw88_8723du 1-2:1.2: error beacon valid
[35478.681023] rtw88_8723du 1-2:1.2: failed to download drv rsvd page
Disable some beacon-related hardware functions before uploading the
beacon and enable them again after.
Tested with RTL8723DU, RTL8812BU, RTL8822CE.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/c248c40a-d432-47ed-90e0-d81ee6c32464@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/realtek/rtw88/fw.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
index 43e3df6a48369..fd3bcb4466209 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -1446,7 +1446,7 @@ void rtw_add_rsvd_page_sta(struct rtw_dev *rtwdev,
int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr,
u8 *buf, u32 size)
{
- u8 bckp[2];
+ u8 bckp[3];
u8 val;
u16 rsvd_pg_head;
u32 bcn_valid_addr;
@@ -1458,6 +1458,8 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr,
if (!size)
return -EINVAL;
+ bckp[2] = rtw_read8(rtwdev, REG_BCN_CTRL);
+
if (rtw_chip_wcpu_11n(rtwdev)) {
rtw_write32_set(rtwdev, REG_DWBCN0_CTRL, BIT_BCN_VALID);
} else {
@@ -1471,6 +1473,9 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr,
val |= BIT_ENSWBCN >> 8;
rtw_write8(rtwdev, REG_CR + 1, val);
+ rtw_write8(rtwdev, REG_BCN_CTRL,
+ (bckp[2] & ~BIT_EN_BCN_FUNCTION) | BIT_DIS_TSF_UDT);
+
if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) {
val = rtw_read8(rtwdev, REG_FWHW_TXQ_CTRL + 2);
bckp[1] = val;
@@ -1501,6 +1506,7 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr,
rsvd_pg_head = rtwdev->fifo.rsvd_boundary;
rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2,
rsvd_pg_head | BIT_BCN_VALID_V1);
+ rtw_write8(rtwdev, REG_BCN_CTRL, bckp[2]);
if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE)
rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 2, bckp[1]);
rtw_write8(rtwdev, REG_CR + 1, bckp[0]);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 161/877] Input: xpad - add support for Victrix Pro BFG Controller
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (159 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 160/877] wifi: rtw88: Fix the random "error beacon valid" messages for USB Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 162/877] Input: xpad - add support for Azeron devices Greg Kroah-Hartman
` (723 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Erich Sartison, Dmitry Torokhov
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Erich Sartison <byt.es@mailbox.org>
commit 971fa7ea8621e123feb9c8d7dc61be1c656bd945 upstream.
The controller doesn't currently work via USB-cable.
Signed-off-by: Erich Sartison <byt.es@mailbox.org>
Link: https://patch.msgid.link/20260903103137.630170-1-byt.es@mailbox.org
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/joystick/xpad.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -256,6 +256,7 @@ static const struct xpad_device {
{ 0x0e6f, 0x0213, "Afterglow Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
{ 0x0e6f, 0x021f, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
{ 0x0e6f, 0x0246, "Rock Candy Gamepad for Xbox One 2015", 0, XTYPE_XBOXONE },
+ { 0x0e6f, 0x024c, "PDP Victrix Pro BFG Wired Controller for Xbox", 0, XTYPE_XBOXONE },
{ 0x0e6f, 0x02a0, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
{ 0x0e6f, 0x02a1, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
{ 0x0e6f, 0x02a2, "PDP Wired Controller for Xbox One - Crimson Red", 0, XTYPE_XBOXONE },
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 162/877] Input: xpad - add support for Azeron devices
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (160 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 161/877] Input: xpad - add support for Victrix Pro BFG Controller Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 163/877] Input: xpad - fix PDP Marvel Xbox 360 controller Greg Kroah-Hartman
` (722 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Roberts Kursitis, Dmitry Torokhov
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roberts Kursitis <roberts.kursitis@azeron.eu>
commit cba76c0f47af1a389d718c5bb69e75cbd67bba98 upstream.
Azeron controllers (Cyro, Cyborg, Classic/Compact, Cyro Lefty,
Cyborg II and Keyzen) present a standard Xbox 360 controller
interface, so they work with the existing xpad driver once their
USB IDs are added.
The 0x16d0 vendor ID is a shared block, but this is safe because
xpad only binds interfaces that match the Xbox 360 signature.
Tested with an Azeron Keyzen.
Signed-off-by: Roberts Kursitis <roberts.kursitis@azeron.eu>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260906143040.162418-1-roberts.kursitis@azeron.eu
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/joystick/xpad.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -321,6 +321,12 @@ static const struct xpad_device {
{ 0x1689, 0xfd00, "Razer Onza Tournament Edition", 0, XTYPE_XBOX360 },
{ 0x1689, 0xfd01, "Razer Onza Classic Edition", 0, XTYPE_XBOX360 },
{ 0x1689, 0xfe00, "Razer Sabertooth", 0, XTYPE_XBOX360 },
+ { 0x16d0, 0x1103, "Azeron Cyro", 0, XTYPE_XBOX360 },
+ { 0x16d0, 0x113c, "Azeron Cyborg", 0, XTYPE_XBOX360 },
+ { 0x16d0, 0x1192, "Azeron Classic/Compact", 0, XTYPE_XBOX360 },
+ { 0x16d0, 0x1212, "Azeron Cyro Lefty", 0, XTYPE_XBOX360 },
+ { 0x16d0, 0x12f7, "Azeron Cyborg II", 0, XTYPE_XBOX360 },
+ { 0x16d0, 0x13ea, "Azeron Keyzen", 0, XTYPE_XBOX360 },
{ 0x17ef, 0x6182, "Lenovo Legion Controller for Windows", 0, XTYPE_XBOX360 },
{ 0x1949, 0x041a, "Amazon Game Controller", 0, XTYPE_XBOX360 },
{ 0x1a86, 0xe310, "Legion Go S", 0, XTYPE_XBOX360 },
@@ -555,6 +561,7 @@ static const struct usb_device_id xpad_t
XPAD_XBOX360_VENDOR(0x15e4), /* Numark Xbox 360 controllers */
XPAD_XBOX360_VENDOR(0x162e), /* Joytech Xbox 360 controllers */
XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */
+ XPAD_XBOX360_VENDOR(0x16d0), /* Azeron controllers */
XPAD_XBOX360_VENDOR(0x17ef), /* Lenovo */
XPAD_XBOX360_VENDOR(0x1949), /* Amazon controllers */
XPAD_XBOX360_VENDOR(0x1a86), /* Nanjing Qinheng Microelectronics (WCH) */
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 163/877] Input: xpad - fix PDP Marvel Xbox 360 controller
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (161 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 162/877] Input: xpad - add support for Azeron devices Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 164/877] ALSA: core: Fix potential UAF after asynchronous card release Greg Kroah-Hartman
` (721 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jeremy Nyberg, Dmitry Torokhov
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeremy Nyberg <slickstretch3.0@gmail.com>
commit 7bc369cb3d3f3656eb77285628ee264264d28ad4 upstream.
The PDP Marvel Xbox 360 controller with USB ID 0e6f:0147 is
incorrectly classified as an Xbox One controller.
With the current XTYPE_XBOXONE classification, the controller is
detected but produces no input, while its four player LEDs continue
blinking indefinitely.
Classify USB ID 0e6f:0147 as an Xbox 360 controller instead.
Tested on a PDP Marvel Xbox 360 controller with USB ID 0e6f:0147.
All inputs register correctly and the player LED indicates the
current player.
Fixes: c225370e01b8 ("Input: xpad - sync supported devices with 360Controller")
Cc: stable@vger.kernel.org
Signed-off-by: Jeremy Nyberg <SlickStretch3.0@gmail.com>
Link: https://patch.msgid.link/20260910071627.236014-1-SlickStretch3.0@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/joystick/xpad.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -244,7 +244,7 @@ static const struct xpad_device {
{ 0x0e6f, 0x0139, "Afterglow Prismatic Wired Controller", 0, XTYPE_XBOXONE },
{ 0x0e6f, 0x013a, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
{ 0x0e6f, 0x0146, "Rock Candy Wired Controller for Xbox One", 0, XTYPE_XBOXONE },
- { 0x0e6f, 0x0147, "PDP Marvel Xbox One Controller", 0, XTYPE_XBOXONE },
+ { 0x0e6f, 0x0147, "PDP Marvel Xbox 360 Controller", 0, XTYPE_XBOX360 },
{ 0x0e6f, 0x015c, "PDP Xbox One Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
{ 0x0e6f, 0x015d, "PDP Mirror's Edge Official Wired Controller for Xbox One", 0, XTYPE_XBOXONE },
{ 0x0e6f, 0x0161, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 164/877] ALSA: core: Fix potential UAF after asynchronous card release
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (162 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 163/877] Input: xpad - fix PDP Marvel Xbox 360 controller Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 165/877] ALSA: virtio: reset device before deleting virtqueues Greg Kroah-Hartman
` (720 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Farhad Alemi, Takashi Iwai
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <tiwai@suse.de>
commit fd95e68df6fe66344161a1329cbe5e5805e7b704 upstream.
Usually a sound driver releases the resources assigned to the card via
snd_card_free(), and it synchronizes with the whole release procedure.
However, when the card is released asynchronously via
snd_card_free_when_closed() like USB-audio driver, the situation is
slightly different; although the snd_card_disconnect() call at the
disconnection guarantees that any newer accesses will be gated, the
in-flight tasks might be still accessing to the underlying card->dev
device even after the disconnection, which would cause a
use-after-free in the end, as reported by fuzzers.
For addressing the bug above, this patch takes the refcount of
card->dev at initialization of the card object, and releases at its
destructor. This assures the availability of the card->dev in its
whole lifecycle.
Reported-by: Farhad Alemi <farhad.alemi@berkeley.edu>
Closes: https://lore.kernel.org/CA+0ovChexj4TrZL_2iG_P0WBEbZc5+73GfB3DkciQi=R8pZOnA@mail.gmail.com
Closes: https://lore.kernel.org/CA+0ovCgQUQNN=Z1tJTouiCsDaXR5M-3-SQEGk-cpPXQkM5Xh+w@mail.gmail.com
Cc: <stable@vger.kernel.org>
Link: https://patch.msgid.link/20260912162150.455144-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/core/init.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -309,7 +309,7 @@ static int snd_card_init(struct snd_card
kfree(card); /* manually free here, as no destructor called */
return err;
}
- card->dev = parent;
+ card->dev = get_device(parent);
card->number = idx;
WARN_ON(IS_MODULE(CONFIG_SND) && !module);
card->module = module;
@@ -593,6 +593,7 @@ static int snd_card_do_free(struct snd_c
dev_warn(card->dev, "unable to free card info\n");
/* Not fatal error */
}
+ put_device(card->dev);
if (card->release_completion)
complete(card->release_completion);
if (!managed)
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 165/877] ALSA: virtio: reset device before deleting virtqueues
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (163 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 164/877] ALSA: core: Fix potential UAF after asynchronous card release Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 166/877] ASoC: codecs: rt712-sdca-dmic: fix uninitialized stream_config->type Greg Kroah-Hartman
` (719 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Yuho Choi, Takashi Iwai
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuho Choi <oss.patchbox@gmail.com>
commit 6c05d00af307560e6a9f1631d6270d3df5aa2272 upstream.
virtsnd_remove() and virtsnd_freeze() delete the virtqueues before
resetting the device. del_vqs() frees the vring backing, but does not
provide a generic device quiesce operation. In particular, modern
virtio-pci keeps enabled queues active until the device is reset.
Reset the device before deleting the virtqueues so it can no longer
access the vring memory when that memory is released. This also covers
probe failures after DRIVER_OK, which unwind through virtsnd_remove().
Fixes: de3a9980d8c3 ("ALSA: virtio: add virtio sound driver")
Fixes: 575483e90a32 ("ALSA: virtio: introduce device suspend/resume support")
Cc: stable@vger.kernel.org
Signed-off-by: Yuho Choi <oss.patchbox@gmail.com>
Link: https://patch.msgid.link/20260911031121.1542502-1-oss.patchbox@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/virtio/virtio_card.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/sound/virtio/virtio_card.c
+++ b/sound/virtio/virtio_card.c
@@ -359,8 +359,8 @@ static void virtsnd_remove(struct virtio
if (snd->card)
snd_card_free(snd->card);
- vdev->config->del_vqs(vdev);
virtio_reset_device(vdev);
+ vdev->config->del_vqs(vdev);
for (i = 0; snd->substreams && i < snd->nsubstreams; ++i) {
struct virtio_pcm_substream *vss = &snd->substreams[i];
@@ -388,8 +388,8 @@ static int virtsnd_freeze(struct virtio_
virtsnd_disable_event_vq(snd);
virtsnd_ctl_msg_cancel_all(snd);
- vdev->config->del_vqs(vdev);
virtio_reset_device(vdev);
+ vdev->config->del_vqs(vdev);
for (i = 0; i < snd->nsubstreams; ++i)
cancel_work_sync(&snd->substreams[i].elapsed_period);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 166/877] ASoC: codecs: rt712-sdca-dmic: fix uninitialized stream_config->type
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (164 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 165/877] ALSA: virtio: reset device before deleting virtqueues Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 167/877] ata: libahci: clear PxCLBU and PxFBU for AHCI_HFLAG_32BIT_ONLY Greg Kroah-Hartman
` (718 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jiangshan Yi, Pierre-Louis Bossart,
Mark Brown
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiangshan Yi <yijiangshan@kylinos.cn>
commit 03a5699a0a04309c597683967aaaf25d1e555ea2 upstream.
stream_config is not initialized before being passed to
sdw_stream_add_slave(). The type field may contain garbage and is
later copied to stream->type by sdw_config_stream().
Zero-initialize stream_config so type defaults to SDW_STREAM_PCM.
While at it, use snd_sdw_params_to_config() helper instead of
open-coding the same logic.
Fixes: 63a511284c9e ("ASoC: rt712-sdca: Add RT712 SDCA driver for Mic topology")
Cc: stable@vger.kernel.org
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
Link: https://patch.msgid.link/20260914104712.379574-1-yijiangshan@kylinos.cn
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/soc/codecs/rt712-sdca-dmic.c | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
--- a/sound/soc/codecs/rt712-sdca-dmic.c
+++ b/sound/soc/codecs/rt712-sdca-dmic.c
@@ -14,6 +14,7 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
+#include <sound/sdw.h>
#include <sound/tlv.h>
#include "rt712-sdca.h"
#include "rt712-sdca-dmic.h"
@@ -641,10 +642,10 @@ static int rt712_sdca_dmic_hw_params(str
{
struct snd_soc_component *component = dai->component;
struct rt712_sdca_dmic_priv *rt712 = snd_soc_component_get_drvdata(component);
- struct sdw_stream_config stream_config;
+ struct sdw_stream_config stream_config = {0};
struct sdw_port_config port_config;
struct sdw_stream_runtime *sdw_stream;
- int retval, num_channels;
+ int retval;
unsigned int sampling_rate;
dev_dbg(dai->dev, "%s %s", __func__, dai->name);
@@ -656,13 +657,8 @@ static int rt712_sdca_dmic_hw_params(str
if (!rt712->slave)
return -EINVAL;
- stream_config.frame_rate = params_rate(params);
- stream_config.ch_count = params_channels(params);
- stream_config.bps = snd_pcm_format_width(params_format(params));
- stream_config.direction = SDW_DATA_DIR_TX;
-
- num_channels = params_channels(params);
- port_config.ch_mask = GENMASK(num_channels - 1, 0);
+ /* SoundWire specific configuration */
+ snd_sdw_params_to_config(substream, params, &stream_config, &port_config);
port_config.num = 2;
retval = sdw_stream_add_slave(rt712->slave, &stream_config,
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 167/877] ata: libahci: clear PxCLBU and PxFBU for AHCI_HFLAG_32BIT_ONLY
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (165 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 166/877] ASoC: codecs: rt712-sdca-dmic: fix uninitialized stream_config->type Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 168/877] ata: libahci_platform: Fix device reference leak in ahci_platform_get_resources() Greg Kroah-Hartman
` (717 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Roland Waltersson, Damien Le Moal,
Niklas Cassel
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niklas Cassel <cassel@kernel.org>
commit 82e47533221d4746947b74d2e79a478c36c6433a upstream.
A user reported that commit 105c42566a55 ("ata: ahci: force 32-bit DMA for
JMicron JMB582/JMB585") made the JMicron JMB585 unusable on his board.
The failure is seen as soon as the ahci driver is probed, and booting with
iommu=off does not solve the problem.
Looking at the AHCI specification, PxCLBU and PxFBU are both read only '0'
for HBAs that do not support 64-bit addressing.
For HBAs that do support 64-bit addressing, the registers are read write,
with a reset value that is Implementation Specific.
When using the AHCI_HFLAG_32BIT_ONLY flag, the HBA does support 64-bit
addressing, and a 32-bit DMA mask is set by simply clearing HOST_CAP_64.
Thus, in this case, we need to explicitly clear the registers to 0.
Fixes: 105c42566a55 ("ata: ahci: force 32-bit DMA for JMicron JMB582/JMB585")
Fixes: c7a42156d99b ("ahci: disable 64bit dma on sb600")
Cc: stable@vger.kernel.org
Reported-by: Roland Waltersson <roland.waltersson@netinsight.net>
Closes: https://lore.kernel.org/linux-ide/IA0PR17MB668730A4ECCD65F7A1DC3EDC9EB62@IA0PR17MB6687.namprd17.prod.outlook.com/
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Link: https://lore.kernel.org/r/20260904134310.1465051-2-cassel@kernel.org
Signed-off-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/ata/libahci.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -748,15 +748,28 @@ void ahci_start_fis_rx(struct ata_port *
struct ahci_port_priv *pp = ap->private_data;
u32 tmp;
- /* set FIS registers */
+ /*
+ * On HBAs that only support 32-bit addressing PxCLBU is read only '0'.
+ * When applying the AHCI_HFLAG_32BIT_ONLY quirk, PxCLBU is RW, and the
+ * reset value is Implementation Specific, so we need to clear it to 0.
+ */
if (hpriv->cap & HOST_CAP_64)
writel((pp->cmd_slot_dma >> 16) >> 16,
port_mmio + PORT_LST_ADDR_HI);
+ else if (hpriv->flags & AHCI_HFLAG_32BIT_ONLY)
+ writel(0, port_mmio + PORT_LST_ADDR_HI);
writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR);
+ /*
+ * On HBAs that only support 32-bit addressing PxFBU is read only '0'.
+ * When applying the AHCI_HFLAG_32BIT_ONLY quirk, PxFBU is RW, and the
+ * reset value is Implementation Specific, so we need to clear it to 0.
+ */
if (hpriv->cap & HOST_CAP_64)
writel((pp->rx_fis_dma >> 16) >> 16,
port_mmio + PORT_FIS_ADDR_HI);
+ else if (hpriv->flags & AHCI_HFLAG_32BIT_ONLY)
+ writel(0, port_mmio + PORT_FIS_ADDR_HI);
writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR);
/* enable FIS reception */
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 168/877] ata: libahci_platform: Fix device reference leak in ahci_platform_get_resources()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (166 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 167/877] ata: libahci: clear PxCLBU and PxFBU for AHCI_HFLAG_32BIT_ONLY Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 169/877] cifs: Fix server use-after-free in cifs_chan_skip_or_disable() Greg Kroah-Hartman
` (716 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Wentao Liang, Damien Le Moal,
Niklas Cassel
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit 0d1cb83337f13af082afb68b28d3fdfe29cde7fb upstream.
of_find_device_by_node() takes a reference on the port platform device,
which is only used to look up its port regulator and is never released,
neither on success nor on the error paths. Drop the reference with
put_device() once the regulator has been obtained, which covers both the
success and error paths.
Fixes: c7d7ddee7e24 ("ata: libahci: Allow using multiple regulators")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Link: https://lore.kernel.org/r/20260915065933.1733061-1-vulab@iscas.ac.cn
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/ata/libahci_platform.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/ata/libahci_platform.c
+++ b/drivers/ata/libahci_platform.c
@@ -623,10 +623,10 @@ struct ahci_host_priv *ahci_platform_get
of_platform_device_create(child, NULL, NULL);
port_dev = of_find_device_by_node(child);
-
if (port_dev) {
rc = ahci_platform_get_regulator(hpriv, port,
&port_dev->dev);
+ put_device(&port_dev->dev);
if (rc == -EPROBE_DEFER)
goto err_out;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 169/877] cifs: Fix server use-after-free in cifs_chan_skip_or_disable()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (167 preceding siblings ...)
2026-09-30 15:17 ` [PATCH 6.12 168/877] ata: libahci_platform: Fix device reference leak in ahci_platform_get_resources() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 170/877] exec: Cleanup POSIX timers right after de_thread() Greg Kroah-Hartman
` (715 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Paulo Alcantara
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit 717e0a25036b6c92cecace30913b2d874a4c22b8 upstream.
When a secondary channel is no longer supported by the server,
cifs_chan_skip_or_disable() drops the channel reference with
cifs_put_tcp_session() and then continues to use the server pointer by
calling cifs_signal_cifsd_for_reconnect() on it and reading its
primary_server pointer. cifs_put_tcp_session() can drop the last
reference of the channel and tear it down, so both the channel and the
primary server (whose reference is also dropped by
cifs_put_tcp_session()) can be freed before they are signaled for
reconnect.
Signal the channel and the primary server and capture the primary
server pointer before dropping the channel reference with
cifs_put_tcp_session().
Fixes: f591062bdbf4 ("cifs: handle servers that still advertise multichannel after disabling")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/smb2pdu.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -188,18 +188,19 @@ cifs_chan_skip_or_disable(struct cifs_se
spin_unlock(&ses->chan_lock);
/*
- * the above reference of server by channel
- * needs to be dropped without holding chan_lock
- * as cifs_put_tcp_session takes a higher lock
- * i.e. cifs_tcp_ses_lock
+ * signal the channel and its primary server to
+ * reconnect before dropping the above reference of
+ * server by channel, which is done without holding
+ * chan_lock as cifs_put_tcp_session takes a higher
+ * lock i.e. cifs_tcp_ses_lock
*/
- cifs_put_tcp_session(server, from_reconnect);
-
cifs_signal_cifsd_for_reconnect(server, false);
/* mark primary server as needing reconnect */
pserver = server->primary_server;
cifs_signal_cifsd_for_reconnect(pserver, false);
+
+ cifs_put_tcp_session(server, from_reconnect);
skip_terminate:
return -EHOSTDOWN;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 170/877] exec: Cleanup POSIX timers right after de_thread()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (168 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 169/877] cifs: Fix server use-after-free in cifs_chan_skip_or_disable() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 171/877] rds: ib: use rds_conn_drop() on protocol version mismatch Greg Kroah-Hartman
` (714 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hyunwoo Kim, Thomas Gleixner,
Kijo Park, Oleg Nesterov, Frederic Weisbecker
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hyunwoo Kim <imv4bel@gmail.com>
commit acb03d3881818581052924a9bbbe92b8741ed448 upstream.
A per-thread CPU timer holds a reference to the PID of the thread it is
attached to and, while it is armed, its node is queued in that thread's
posix_cputimers. The task is looked up by that PID.
When a non-leader thread exec()s, de_thread() changes which task owns
that PID. pid_task(timer->it.cpu.pid, PIDTYPE_PID) then returns NULL,
but the node is still queued on tsk, which is alive. timer_lock_sighand()
takes a failed lookup to mean that the node is already dequeued, so it
has nothing to undo.
begin_new_exec() calls posix_cpu_timers_exit(me) right after
exec_task_namespaces() and that removes the leftover node, so the state
normally stays invisible. But bprm->point_of_no_return is set before
de_thread(), so if unshare_files(), set_mm_exe_file(), exec_mmap() or
exec_task_namespaces() fails, the task dies before it gets there.
exit_itimers() then frees the k_itimer while its node is still queued,
and reaping tsk later erases that freed node from the rbtree.
In short:
the non-leader thread B the parent
timer_create(CLOCK_THREAD_CPUTIME_ID)
timer_settime()
arm_timer() // the node is queued on B
execve()
de_thread(B)
exchange_tids(B, leader) // B's PID now belongs to the leader
release_task(leader)
__exit_signal(leader)
posix_cpu_timers_exit(leader) // cleans leader's queue, not B's
__unhash_process(leader) // that PID has no task anymore
exec_mmap()
mmap_read_lock_killable(old_mm)
kill(B, SIGKILL)
// -EINTR
get_signal()
do_exit()
exit_itimers()
posix_timer_delete()
posix_cpu_timer_del()
posix_timer_unhash_and_free() // freed while still queued
wait4()
release_task(B)
posix_cpu_timers_exit(B)
cleanup_timerqueue()
timerqueue_del() // use-after-free
Move the POSIX timer cleanup right after de_thread() before any of the
later failure conditions brings the task into do_exit().
[ tglx: Move the cleanup right after de_thread() ]
Fixes: 55e8c8eb2c7b ("posix-cpu-timers: Store a reference to a pid not a task")
Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Tested-by: Kijo Park <red993688@gmail.com>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/ao7Q8miiuLAPVnWv@v4bel
Link: https://patch.msgid.link/20260911090541.627712075@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/exec.c | 29 +++++++++++++++++++++--------
1 file changed, 21 insertions(+), 8 deletions(-)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1217,6 +1217,17 @@ void __set_task_comm(struct task_struct
perf_event_comm(tsk, exec);
}
+static void posixtimer_exec(struct task_struct *me)
+{
+#ifdef CONFIG_POSIX_TIMERS
+ spin_lock_irq(&me->sighand->siglock);
+ posix_cpu_timers_exit(me);
+ spin_unlock_irq(&me->sighand->siglock);
+ exit_itimers(me);
+ flush_itimer_signals();
+#endif
+}
+
/*
* Calling this is the point of no return. None of the failures will be
* seen by userspace since either the process is already taking a fatal
@@ -1250,6 +1261,16 @@ int begin_new_exec(struct linux_binprm *
retval = de_thread(me);
if (retval)
goto out;
+
+ /*
+ * This must be done here to ensure that POSIX CPU timers which were
+ * armed on the current task are dequeued from me::posix_cputimers.
+ * Otherwise in case of a TID switch the deletion of the related POSIX
+ * timer would not remove an enqueued timer because the TID lookup
+ * of the old TID fails.
+ */
+ posixtimer_exec(me);
+
/* see the comment in check_unsafe_exec() */
current->fs->in_exec = 0;
/*
@@ -1304,14 +1325,6 @@ int begin_new_exec(struct linux_binprm *
if (retval)
goto out_unlock;
-#ifdef CONFIG_POSIX_TIMERS
- spin_lock_irq(&me->sighand->siglock);
- posix_cpu_timers_exit(me);
- spin_unlock_irq(&me->sighand->siglock);
- exit_itimers(me);
- flush_itimer_signals();
-#endif
-
/*
* Make the signal table private.
*/
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 171/877] rds: ib: use rds_conn_drop() on protocol version mismatch
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (169 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 170/877] exec: Cleanup POSIX timers right after de_thread() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 172/877] x86/microcode/intel: Reject problematic loading on Granite Rapids systems Greg Kroah-Hartman
` (713 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, TencentOS Corvus AI,
Allison Henderson, Aohan Mei, Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aohan Mei <henrymei@tencent.com>
commit f97d8c7bab7843631206a114986c9059da03efeb upstream.
rds_ib_cm_connect_complete() runs from the RDMA-CM event handler with
conn->c_cm_lock held. When the peer negotiates a protocol version
older than RDS_PROTOCOL_COMPAT_VERSION, the handler calls
rds_conn_destroy(), which is only safe in the rmmod path: it
synchronously tears the connection down and flush_work()es the
shutdown work cp_down_w.
That shutdown work (rds_conn_shutdown()) needs cp_cm_lock, which is
the very lock the event handler still holds, so the flush never
completes: the two workers wait on each other and the RDS connection
workqueues stall for good.
All other RDMA-CM failure paths (REJECTED, CONNECT_ERROR,
DISCONNECTED) use rds_conn_drop(), which marks the connection
RDS_CONN_ERROR and schedules the shutdown work asynchronously. Use
it here as well.
Fixes: f147dd9ecabf ("RDS/IB: Disallow connections less than RDS 3.1")
Reported-by: TencentOS Corvus AI <corvus@tencent.com>
Cc: stable@vger.kernel.org
Reviewed-by: Allison Henderson <achender@kernel.org>
Signed-off-by: Aohan Mei <henrymei@tencent.com>
Link: https://patch.msgid.link/20260911073436.3542080-1-ljp1205831794@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/rds/ib_cm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/rds/ib_cm.c
+++ b/net/rds/ib_cm.c
@@ -115,7 +115,7 @@ void rds_ib_cm_connect_complete(struct r
&conn->c_laddr, &conn->c_faddr,
RDS_PROTOCOL_MAJOR(conn->c_version),
RDS_PROTOCOL_MINOR(conn->c_version));
- rds_conn_destroy(conn);
+ rds_conn_drop(conn);
return;
}
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 172/877] x86/microcode/intel: Reject problematic loading on Granite Rapids systems
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (170 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 171/877] rds: ib: use rds_conn_drop() on protocol version mismatch Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 173/877] tcp: exclude old ACKs from tcp fast path Greg Kroah-Hartman
` (712 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chang S. Bae, Borislav Petkov (AMD),
Dave Hansen
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chang S. Bae <chang.seok.bae@intel.com>
commit e7d3e2f46dd5a69046e6d95a0f189155a5516b93 upstream.
Microcode updates can usually jump revisions. However, there is an erratum on
Granite Rapids systems. If they "jump over" revision 0x1000405, they result in
an #MC. Avoid it.
Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260916225939.1144524-1-chang.seok.bae@intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/kernel/cpu/microcode/intel.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -257,6 +257,26 @@ static void save_microcode_patch(struct
pr_err("Unable to allocate microcode memory size: %u\n", size);
}
+static bool revision_is_safe(struct cpu_signature *sig, u32 rev)
+{
+ u32 vfm = IFM(x86_family(sig->sig), x86_model(sig->sig));
+
+ /*
+ * Erratum GNR98 can cause #MCs if "jumping over" revision 0x1000405.
+ * Avoid the jumps.
+ */
+ if (vfm == INTEL_GRANITERAPIDS_X &&
+ x86_stepping(sig->sig) == 1 &&
+ sig->pf & 0x95 &&
+ sig->rev < 0x1000405 &&
+ rev > 0x1000405) {
+ pr_err_once("Erratum GNR98: skipping revision 0x%x.\n", rev);
+ return false;
+ }
+
+ return true;
+}
+
/* Scan blob for microcode matching the boot CPUs family, model, stepping */
static __init struct microcode_intel *scan_microcode(void *data, size_t size,
struct ucode_cpu_info *uci,
@@ -278,6 +298,9 @@ static __init struct microcode_intel *sc
if (!intel_find_matching_signature(data, &uci->cpu_sig))
continue;
+ if (!revision_is_safe(&uci->cpu_sig, mc_header->rev))
+ continue;
+
/*
* For saving the early microcode, find the matching revision which
* was loaded on the BSP.
@@ -540,6 +563,9 @@ static enum ucode_state parse_microcode_
if (!intel_find_matching_signature(mc, &uci->cpu_sig))
continue;
+ if (!revision_is_safe(&uci->cpu_sig, mc_header.rev))
+ continue;
+
is_safe = ucode_validate_minrev(&mc_header);
if (force_minrev && !is_safe)
continue;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 173/877] tcp: exclude old ACKs from tcp fast path
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (171 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 172/877] x86/microcode/intel: Reject problematic loading on Granite Rapids systems Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 174/877] RDMA/ucma: Serialize join and leave on copy_to_user failure Greg Kroah-Hartman
` (711 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Amit Klein, Tamir Shahar,
Inbal Schussheim, Eric Dumazet, Paolo Abeni
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Inbal Schussheim <inbal.lipshtat@mail.huji.ac.il>
commit f81e6c3fb06327bc49cdd6e559845293ba06a704 upstream.
Exclude old ACKs before SND.UNA from the tcp fast path
as well as ACKs after SND.NXT.
Such ACKs will fall through to the slow path, where tcp_ack()
performs the appropriate validation and challenge ACK handling
according to RFC5961 and Commit 3d501dd326fb1c7 ("tcp: do not
accept ACK of bytes we never sent").
This prevents old ACKs from being accepted
or modifying connection state as part of the fast path before
appropriate ACK validation is applied.
In particular, this prevents payload carried by a segment with
an excessively old ACK from advancing RCV.NXT before the ACK
is rejected.
Fixes: 31770e34e43d ("tcp: Revert "tcp: remove header prediction"")
Reported-by: Amit Klein <amit.klein@mail.huji.ac.il>
Reported-by: Tamir Shahar <tamir.shahar1@mail.huji.ac.il>
Reported-by: Inbal Schussheim <inbal.lipshtat@mail.huji.ac.il>
Suggested-by: Eric Dumazet <edumazet@google.com>
Cc: stable@vger.kernel.org
Signed-off-by: Inbal Schussheim <inbal.lipshtat@mail.huji.ac.il>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260914090408.1435080-2-inbal.lipshtat@mail.huji.ac.il
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/tcp_input.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -6138,6 +6138,7 @@ reset:
* or pure receivers (this means either the sequence number or the ack
* value must stay constant)
* - Unexpected TCP option.
+ * - ACK sequence number is outside [SND.UNA, SND.NXT].
*
* When these conditions are not satisfied it drops into a standard
* receive procedure patterned after RFC793 to handle all cases.
@@ -6186,7 +6187,7 @@ void tcp_rcv_established(struct sock *sk
if ((tcp_flag_word(th) & TCP_HP_BITS) == tp->pred_flags &&
TCP_SKB_CB(skb)->seq == tp->rcv_nxt &&
- !after(TCP_SKB_CB(skb)->ack_seq, tp->snd_nxt)) {
+ between(TCP_SKB_CB(skb)->ack_seq, tp->snd_una, tp->snd_nxt)) {
int tcp_header_len = tp->tcp_header_len;
/* Timestamp header prediction: tcp_header_len
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 174/877] RDMA/ucma: Serialize join and leave on copy_to_user failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (172 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 173/877] tcp: exclude old ACKs from tcp fast path Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 175/877] RDMA/core: fix refcount bug in iwpm_get_nlmsg_request() Greg Kroah-Hartman
` (710 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+a6ffe86390c8a6afc818,
Quanye Yang, Leon Romanovsky
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Quanye Yang <quanyeyang@proton.me>
commit 662ade4de9ff5eceb0820a9f8e9fac70ba6a815b upstream.
rdma_join_multicast() queues RoCE work that later reads the ucma_multicast
through event->param.ud.private_data, then list_add()s the CMA multicast
at the head of id_priv->mc_list. rdma_leave_multicast() matches only by
sockaddr and destroys the first hit.
ucma_process_join() used to drop ctx->mutex after a successful join and
retake it only if copy_to_user() failed. Two concurrent JOIN_MCAST calls
with the same address can therefore insert a second CMA entry before the
first thread's leave. leave then cancels the newer work and the older
worker still dereferences the ucma_multicast that the first thread frees.
Keep ctx->mutex held from rdma_join_multicast() through copy_to_user() and,
on -EFAULT, through rdma_leave_multicast() so leave cannot miss this join.
Do not leave if join itself failed: that path never published this address
on mc_list, and a leave-by-addr would destroy an earlier successful join.
Reported-by: syzbot+a6ffe86390c8a6afc818@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=a6ffe86390c8a6afc818
Fixes: fe454dc31e84 ("RDMA/ucma: Fix use-after-free bug in ucma_create_uevent")
Cc: stable@vger.kernel.org
Signed-off-by: Quanye Yang <quanyeyang@proton.me>
Link: https://patch.msgid.link/20260831-rdma-ucma-mc-uaf-v1-1-b8eeb7046aff@proton.me
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/infiniband/core/ucma.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -1487,9 +1487,10 @@ static ssize_t ucma_process_join(struct
mutex_lock(&ctx->mutex);
ret = rdma_join_multicast(ctx->cm_id, (struct sockaddr *)&mc->addr,
join_state, mc);
- mutex_unlock(&ctx->mutex);
- if (ret)
+ if (ret) {
+ mutex_unlock(&ctx->mutex);
goto err_xa_erase;
+ }
resp.id = mc->id;
if (copy_to_user(u64_to_user_ptr(cmd->response),
@@ -1497,6 +1498,7 @@ static ssize_t ucma_process_join(struct
ret = -EFAULT;
goto err_leave_multicast;
}
+ mutex_unlock(&ctx->mutex);
xa_store(&multicast_table, mc->id, mc, 0);
@@ -1504,7 +1506,6 @@ static ssize_t ucma_process_join(struct
return 0;
err_leave_multicast:
- mutex_lock(&ctx->mutex);
rdma_leave_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr);
mutex_unlock(&ctx->mutex);
ucma_cleanup_mc_events(mc);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 175/877] RDMA/core: fix refcount bug in iwpm_get_nlmsg_request()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (173 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 174/877] RDMA/ucma: Serialize join and leave on copy_to_user failure Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 176/877] openvswitch: avoid reallocating confirmed conntrack labels Greg Kroah-Hartman
` (709 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+bd317784d628820741b5,
Jeffin Philip, Leon Romanovsky
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeffin Philip <jeffinphilip14@gmail.com>
commit 33fb59da49c4c3f5c2ec9f9d4447a56857a02c02 upstream.
iwpm_get_nlmsg_request() initializes refcount _after_ list_add_tail()
making it accessible to global list where another CPU can kref_get()
on nlmsg_request causing a refcount "addition on 0" bug. Fix this
by initializing kref _before_ list_add_tail() so refcount for
nlmsg_request can be incremented/decremented normally. In addition,
also initialize every field before list_add_tail().
Reported-by: syzbot+bd317784d628820741b5@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=bd317784d628820741b5
Fixes: 30dc5e63d6a5 ("RDMA/core: Add support for iWARP Port Mapper user space service")
Cc: stable@vger.kernel.org
Signed-off-by: Jeffin Philip <jeffinphilip14@gmail.com>
Link: https://patch.msgid.link/20260904131437.12917-1-jeffinphilip14@gmail.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/infiniband/core/iwpm_util.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
--- a/drivers/infiniband/core/iwpm_util.c
+++ b/drivers/infiniband/core/iwpm_util.c
@@ -314,10 +314,6 @@ struct iwpm_nlmsg_request *iwpm_get_nlms
if (!nlmsg_request)
return NULL;
- spin_lock_irqsave(&iwpm_nlmsg_req_lock, flags);
- list_add_tail(&nlmsg_request->inprocess_list, &iwpm_nlmsg_req_list);
- spin_unlock_irqrestore(&iwpm_nlmsg_req_lock, flags);
-
kref_init(&nlmsg_request->kref);
kref_get(&nlmsg_request->kref);
nlmsg_request->nlmsg_seq = nlmsg_seq;
@@ -326,6 +322,11 @@ struct iwpm_nlmsg_request *iwpm_get_nlms
nlmsg_request->err_code = 0;
sema_init(&nlmsg_request->sem, 1);
down(&nlmsg_request->sem);
+
+ spin_lock_irqsave(&iwpm_nlmsg_req_lock, flags);
+ list_add_tail(&nlmsg_request->inprocess_list, &iwpm_nlmsg_req_list);
+ spin_unlock_irqrestore(&iwpm_nlmsg_req_lock, flags);
+
return nlmsg_request;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 176/877] openvswitch: avoid reallocating confirmed conntrack labels
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (174 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 175/877] RDMA/core: fix refcount bug in iwpm_get_nlmsg_request() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 177/877] net: xfrm: reject unrepresentable espintcp transport headers Greg Kroah-Hartman
` (708 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Zhiling Zou, Ilya Maximets,
Aaron Conole, Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhiling Zou <zhilinz@nebusec.ai>
commit 3f118c8217c109fd13ca61caa301d72c483897ef upstream.
ovs_ct_get_conn_labels() adds the labels extension when a conntrack
entry does not have one. Confirmed conntracks can be read locklessly,
so adding an extension may reallocate and free the extension block
while another CPU accesses it.
Only add the extension for unconfirmed conntracks. A confirmed
conntrack without labels now fails the caller's label operation instead
of reallocating its extension storage.
Fixes: c2ac66735870 ("openvswitch: Allow matching on conntrack label")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Reviewed-by: Ilya Maximets <i.maximets@ovn.org>
Reviewed-by: Aaron Conole <aconole@redhat.com>
Link: https://patch.msgid.link/372fbb062b40ae6723684f55484be86ff0064f8e.1789218015.git.zhilinz@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/openvswitch/conntrack.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -366,7 +366,7 @@ static struct nf_conn_labels *ovs_ct_get
struct nf_conn_labels *cl;
cl = nf_ct_labels_find(ct);
- if (!cl) {
+ if (!cl && !nf_ct_is_confirmed(ct)) {
nf_ct_labels_ext_add(ct);
cl = nf_ct_labels_find(ct);
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 177/877] net: xfrm: reject unrepresentable espintcp transport headers
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (175 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 176/877] openvswitch: avoid reallocating confirmed conntrack labels Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 178/877] HID: logitech-hidpp: fix race condition when accessing stale stack pointer Greg Kroah-Hartman
` (707 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Wyatt Feng, Ren Wei,
Steffen Klassert
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wyatt Feng <wf.kernel.dev@gmail.com>
commit 96f01b53c2d05e003b040892256de54a586e8529 upstream.
ESP-in-TCP can hand xfrm packets whose transport header offset no longer
fits after the stream parser trims the TCP envelope. The plain transport
header reset truncates that offset and triggers the skb warning path.
Use the careful transport-header helper and drop the skb through the
existing XFRM error path when the offset cannot be represented.
Fixes: e27cca96cd68 ("xfrm: add espintcp (RFC 8229)")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: Codex:GPT-5.4
Signed-off-by: Wyatt Feng <wf.kernel.dev@gmail.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/xfrm/espintcp.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/net/xfrm/espintcp.c
+++ b/net/xfrm/espintcp.c
@@ -33,7 +33,11 @@ static void handle_esp(struct sk_buff *s
{
struct tcp_skb_cb *tcp_cb = (struct tcp_skb_cb *)skb->cb;
- skb_reset_transport_header(skb);
+ if (!skb_reset_transport_header_careful(skb)) {
+ XFRM_INC_STATS(sock_net(sk), LINUX_MIB_XFRMINERROR);
+ kfree_skb(skb);
+ return;
+ }
/* restore IP CB, we need at least IP6CB->nhoff */
memmove(skb->cb, &tcp_cb->header, sizeof(tcp_cb->header));
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 178/877] HID: logitech-hidpp: fix race condition when accessing stale stack pointer
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (176 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 177/877] net: xfrm: reject unrepresentable espintcp transport headers Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 179/877] kselftest/arm64: Fix size of thread_data values for pthread_join() Greg Kroah-Hartman
` (706 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Benoît Sevens, Jiri Kosina,
Lee Jones
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benoît Sevens <bsevens@google.com>
commit e2aaf2d3ad92ac4a8afa6b69ad4c38e7747d3d6e upstream.
The driver uses hidpp->send_receive_buf to point to a stack-allocated
buffer in the synchronous command path (__do_hidpp_send_message_sync).
However, this pointer is not cleared when the function returns.
If an event is processed (e.g. by a different thread) while the
send_mutex is held by a new command, but before that command has
updated send_receive_buf, the handler (hidpp_raw_hidpp_event) will
observe that the mutex is locked and dereference the stale pointer.
This results in an out-of-bounds access on a different thread's kernel
stack (or a NULL pointer dereference on the very first command).
Fix this by:
1. Clearing hidpp->send_receive_buf to NULL before releasing the mutex
in the synchronous command path.
2. Moving the assignment of the local 'question' and 'answer' pointers
inside the mutex_is_locked() block in the handler, and adding
a NULL check before dereferencing.
Signed-off-by: Benoît Sevens <bsevens@google.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Cc: Lee Jones <lee@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hid/hid-logitech-hidpp.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -305,21 +305,22 @@ static int __do_hidpp_send_message_sync(
if (ret) {
dbg_hid("__hidpp_send_report returned err: %d\n", ret);
memset(response, 0, sizeof(struct hidpp_report));
- return ret;
+ goto out;
}
if (!wait_event_timeout(hidpp->wait, hidpp->answer_available,
5*HZ)) {
dbg_hid("%s:timeout waiting for response\n", __func__);
memset(response, 0, sizeof(struct hidpp_report));
- return -ETIMEDOUT;
+ ret = -ETIMEDOUT;
+ goto out;
}
if (response->report_id == REPORT_ID_HIDPP_SHORT &&
response->rap.sub_id == HIDPP_ERROR) {
ret = response->rap.params[1];
dbg_hid("%s:got hidpp error %02X\n", __func__, ret);
- return ret;
+ goto out;
}
if ((response->report_id == REPORT_ID_HIDPP_LONG ||
@@ -327,10 +328,14 @@ static int __do_hidpp_send_message_sync(
response->fap.feature_index == HIDPP20_ERROR) {
ret = response->fap.params[1];
dbg_hid("%s:got hidpp 2.0 error %02X\n", __func__, ret);
- return ret;
+ goto out;
}
- return 0;
+ ret = 0;
+
+out:
+ hidpp->send_receive_buf = NULL;
+ return ret;
}
/*
@@ -3866,8 +3871,7 @@ static int hidpp_input_configured(struct
static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data,
int size)
{
- struct hidpp_report *question = hidpp->send_receive_buf;
- struct hidpp_report *answer = hidpp->send_receive_buf;
+ struct hidpp_report *question, *answer;
struct hidpp_report *report = (struct hidpp_report *)data;
int ret;
int last_online;
@@ -3877,6 +3881,12 @@ static int hidpp_raw_hidpp_event(struct
* previously sent command.
*/
if (unlikely(mutex_is_locked(&hidpp->send_mutex))) {
+ question = hidpp->send_receive_buf;
+ answer = hidpp->send_receive_buf;
+
+ if (!question)
+ return 0;
+
/*
* Check for a correct hidpp20 answer or the corresponding
* error
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 179/877] kselftest/arm64: Fix size of thread_data values for pthread_join()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (177 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 178/877] HID: logitech-hidpp: fix race condition when accessing stale stack pointer Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 180/877] arm64: hibernate: pass HVC_SET_VECTORS args to the resume hvc Greg Kroah-Hartman
` (705 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Thomas Huth, Will Deacon
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Huth <thuth@redhat.com>
commit 3d1ba5cbfb622025690c218d8f20da92a9ecb383 upstream.
pthread_join() stores the thread's return value (a "void *", i.e.
8 bytes on 64 bit computers) into the address that is passed as second
parameter. However, the entries of thread_data are only normal "int"s,
i.e. only 4 bytes. The additional 4 bytes of the return value clobber
whatever is adjacent on the stack, i.e. other members of the thread_data
array (which will be re-written in the next iteration of the for-loop,
so that nobody noticed this problem), or another other local variable
on the stack for the last iteration. Use "intptr_t" to declare the
thread_data array entries with the correct size.
Fixes: 29f080881601c ("kselftest/arm64: check GCR_EL1 after context switch")
Cc: stable@vger.kernel.org
Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
tools/testing/selftests/arm64/mte/check_gcr_el1_cswitch.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/tools/testing/selftests/arm64/mte/check_gcr_el1_cswitch.c
+++ b/tools/testing/selftests/arm64/mte/check_gcr_el1_cswitch.c
@@ -69,7 +69,7 @@ fail:
int execute_test(pid_t pid)
{
pthread_t thread_id[MAX_THREADS];
- int thread_data[MAX_THREADS];
+ intptr_t thread_data[MAX_THREADS];
for (int i = 0; i < MAX_THREADS; i++)
pthread_create(&thread_id[i], NULL,
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 180/877] arm64: hibernate: pass HVC_SET_VECTORS args to the resume hvc
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (178 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 179/877] kselftest/arm64: Fix size of thread_data values for pthread_join() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 181/877] arm64: dts: renesas: r8a779f0: Set UFS lane count Greg Kroah-Hartman
` (704 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bradley Morgan, Vladimir Murzin,
Mark Rutland, Will Deacon
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bradley Morgan <include@grrlz.net>
commit 955d86e5f3b95b731991fdb84966c50b16314629 upstream.
swsusp_arch_suspend_exit() reinstalls the restored kernel's hyp stub
vectors with an hvc, but never passes the arguments. x0 is not set to
HVC_SET_VECTORS and x1 is not set to the vector address, so the stub
dispatch falls through and returns without writing vbar_el2. EL2 is
left pointing at the trans_pgd copy of the vectors, a page that
swsusp_free() releases right after resume.
Set the arguments up the same way __hyp_set_vectors() does.
Without this fix, Vladimir was able to trigger a hang when resuming from
hibernation with CONFIG_PAGE_POISONING=y and page_poison=on.
Fixes: 788bfdd97434 ("arm64: trans_pgd: hibernate: Add trans_pgd_copy_el2_vectors")
Cc: stable@vger.kernel.org
Signed-off-by: Bradley Morgan <include@grrlz.net>
Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com>
Tested-by: Vladimir Murzin <vladimir.murzin@arm.com>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arm64/kernel/hibernate-asm.S | 2 ++
1 file changed, 2 insertions(+)
--- a/arch/arm64/kernel/hibernate-asm.S
+++ b/arch/arm64/kernel/hibernate-asm.S
@@ -89,6 +89,8 @@ alternative_insn "dc cvau, x4", "dc civ
isb
cbz x24, 3f /* Do we need to re-initialise EL2? */
+ mov x1, x24
+ mov x0, #HVC_SET_VECTORS
hvc #0
3: ret
SYM_CODE_END(swsusp_arch_suspend_exit)
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 181/877] arm64: dts: renesas: r8a779f0: Set UFS lane count
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (179 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 180/877] arm64: hibernate: pass HVC_SET_VECTORS args to the resume hvc Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 182/877] arm64: percpu: Fix this_cpu_write() casting Greg Kroah-Hartman
` (703 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Koichiro Den, Geert Uytterhoeven
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Koichiro Den <den@valinux.co.jp>
commit 8dc2615d5702059b2b71fca6f93c0d7d10ae54cb upstream.
Since commit e72323f3b09f ("scsi: ufs: core: Configure only active lanes
during link"), the following error is observed on R-Car S4:
ufshcd-renesas e6860000.ufs: Tx lane mismatch [config,reported] [2,1]
ufshcd-renesas e6860000.ufs: link startup failed -67
ufshcd-renesas e6860000.ufs: error -ENOLINK: Initialization failed with error -67
ufshcd-renesas e6860000.ufs: probe with driver ufshcd-renesas failed with error -67
R-Car S4 has one UFS lane per direction, as described in section 152.1
of its hardware manual. Without lanes-per-direction, the UFS platform
driver defaults to two lanes.
Previously, the core used PA_CONNECTEDRXDATALANES and
PA_CONNECTEDTXDATALANES to configure the link without checking them
against lanes-per-direction, so the missing property did not prevent
initialization.
Explicitly set lanes-per-direction to 1, now that the validation is in
place.
Fixes: 5235d551779d ("arm64: dts: renesas: r8a779f0: Add UFS node")
Cc: stable@vger.kernel.org # 7.2+
Signed-off-by: Koichiro Den <den@valinux.co.jp>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/20260911073058.253000-1-den@valinux.co.jp
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arm64/boot/dts/renesas/r8a779f0.dtsi | 1 +
1 file changed, 1 insertion(+)
--- a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
@@ -876,6 +876,7 @@
clocks = <&cpg CPG_MOD 1514>, <&ufs30_clk>;
clock-names = "fck", "ref_clk";
freq-table-hz = <200000000 200000000>, <38400000 38400000>;
+ lanes-per-direction = <1>;
power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>;
resets = <&cpg 1514>;
status = "disabled";
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 182/877] arm64: percpu: Fix this_cpu_write() casting
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (180 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 181/877] arm64: dts: renesas: r8a779f0: Set UFS lane count Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 183/877] arm64: percpu: Fix this_cpu_and() mask generation Greg Kroah-Hartman
` (702 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Laight, Mark Rutland,
Jinjie Ruan, Muhammad Usama Anjum, Christopher Lameter (Ampere),
Ada Couprie Diaz, Ard Biesheuvel, Catalin Marinas, James Morse,
Marc Zyngier, Peter Zijlstra, Vladimir Murzin, Will Deacon,
Yang Shi, Lorenzo Stoakes (ARM)
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <mark.rutland@arm.com>
commit 885bff055a0f251a51a0d4fd4f0a7b525582a3de upstream.
The arm64 implementation of this_cpu_write() casts 'val' to unsigned
long. This is necessary to handle cases where 'val' is a pointer type,
and to avoid spurious compiler warnings for the (unreachable!) cases
where the pointer type would be cast to a smaller integer type.
Unfortunately, the cast is applied to 'val' rather than '(val)', which
won't always generate the expected value when 'val' is an expression.
For example, for this_cpu_write(pcp, zero - 1), where 'pcp' is a u64 and
'zero' is a u32:
* 'zero' ===> (u32) 0x00000000
* 'zero - 1' ===> (u32) 0xffffffff
* '(unsigned long)zero - 1' ===> (u64) 0xffffffffffffffff
* '(unsigned long)(zero - 1)' ===> (u64) 0x00000000ffffffff
Fix this by adding brackets around 'val'.
Fixes: 959bf2fd03b5 ("arm64: percpu: Rewrite per-cpu ops to allow use of LSE atomics")
Reported-by: David Laight <david.laight.linux@gmail.com>
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: David Laight <david.laight.linux@gmail.com>
Reviewed-by: Jinjie Ruan <ruanjinjie@huawei.com>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Acked-by: Christopher Lameter (Ampere) <cl@gentwo.org>
Cc: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Vladimir Murzin <vladimir.murzin@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Yang Shi <yang@os.amperecomputing.com>
Cc: stable@vger.kernel.org
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arm64/include/asm/percpu.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/arch/arm64/include/asm/percpu.h
+++ b/arch/arm64/include/asm/percpu.h
@@ -172,13 +172,13 @@ PERCPU_RET_OP(add, add, ldadd)
_pcp_protect_return(__percpu_read_64, pcp)
#define this_cpu_write_1(pcp, val) \
- _pcp_protect(__percpu_write_8, pcp, (unsigned long)val)
+ _pcp_protect(__percpu_write_8, pcp, (unsigned long)(val))
#define this_cpu_write_2(pcp, val) \
- _pcp_protect(__percpu_write_16, pcp, (unsigned long)val)
+ _pcp_protect(__percpu_write_16, pcp, (unsigned long)(val))
#define this_cpu_write_4(pcp, val) \
- _pcp_protect(__percpu_write_32, pcp, (unsigned long)val)
+ _pcp_protect(__percpu_write_32, pcp, (unsigned long)(val))
#define this_cpu_write_8(pcp, val) \
- _pcp_protect(__percpu_write_64, pcp, (unsigned long)val)
+ _pcp_protect(__percpu_write_64, pcp, (unsigned long)(val))
#define this_cpu_add_1(pcp, val) \
_pcp_protect(__percpu_add_case_8, pcp, val)
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 183/877] arm64: percpu: Fix this_cpu_and() mask generation
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (181 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 182/877] arm64: percpu: Fix this_cpu_write() casting Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 184/877] Bluetooth: btusb: fix NXP IW610 composite device handling Greg Kroah-Hartman
` (701 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mark Rutland, Jinjie Ruan,
Muhammad Usama Anjum, Christopher Lameter (Ampere),
Ada Couprie Diaz, Ard Biesheuvel, Catalin Marinas, James Morse,
Marc Zyngier, Peter Zijlstra, Vladimir Murzin, Will Deacon,
Yang Shi
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <mark.rutland@arm.com>
commit 44274c657256b4911de82f8104e9e22f054cf742 upstream.
The arm64 implementation of this_cpu_and(pcp, val) is built in terms of
ANDNOT operations, which requires the 'val' argument to be bitwise
negated. The bitwise negation is not implemented correctly, with two
bugs described below.
(1) The bitwise negation is performed as '~val' rather than '~(val)'.
This won't always generate the expected value when 'val' is an
expression.
For example, for this_cpu_and(pcp, 1 - 1):
* 'val' is '1 - 1' ===> (int) 0x00000000
* '~val' is '~1 - 1' ===> (int) 0xfffffffd
* '~(val)' is '~(1 - 1)' ===> (int) 0xffffffff
... and thus bit[1] of 'pcp' would be preserved unexpectedly by the
ANDNOT operation.
(2) The bitwise negation is performed on 'val' before it has been cast
to (at least) the width of 'pcp'. This won't always generate the
expected value for the upper bits.
For example, for this_cpu_and(pcp, zero), where 'pcp' is a u64 and
'zero' is a u32:
* 'zero' ===> (u32) 0x00000000
* '~(zero)' ===> (u32) 0xffffffff
* '(u64)~(zero)' ===> (u64) 0x00000000ffffffff
* '~((u64)(zero))' ===> (u64) 0xffffffffffffffff
... and thus bits[63:32] of 'pcp' would be preserved unexpectedly by
the ANDNOT operation.
Fix these issues by adding brackets around 'val', and by casting 'val'
to an appropriately-sized type before bitwise negation.
Fixes: 959bf2fd03b5 ("arm64: percpu: Rewrite per-cpu ops to allow use of LSE atomics")
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Jinjie Ruan <ruanjinjie@huawei.com>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Acked-by: Christopher Lameter (Ampere) <cl@gentwo.org>
Cc: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Vladimir Murzin <vladimir.murzin@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Yang Shi <yang@os.amperecomputing.com>
Cc: stable@vger.kernel.org
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arm64/include/asm/percpu.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/arch/arm64/include/asm/percpu.h
+++ b/arch/arm64/include/asm/percpu.h
@@ -199,13 +199,13 @@ PERCPU_RET_OP(add, add, ldadd)
_pcp_protect_return(__percpu_add_return_case_64, pcp, val)
#define this_cpu_and_1(pcp, val) \
- _pcp_protect(__percpu_andnot_case_8, pcp, ~val)
+ _pcp_protect(__percpu_andnot_case_8, pcp, ~(u8)(val))
#define this_cpu_and_2(pcp, val) \
- _pcp_protect(__percpu_andnot_case_16, pcp, ~val)
+ _pcp_protect(__percpu_andnot_case_16, pcp, ~(u16)(val))
#define this_cpu_and_4(pcp, val) \
- _pcp_protect(__percpu_andnot_case_32, pcp, ~val)
+ _pcp_protect(__percpu_andnot_case_32, pcp, ~(u32)(val))
#define this_cpu_and_8(pcp, val) \
- _pcp_protect(__percpu_andnot_case_64, pcp, ~val)
+ _pcp_protect(__percpu_andnot_case_64, pcp, ~(u64)(val))
#define this_cpu_or_1(pcp, val) \
_pcp_protect(__percpu_or_case_8, pcp, val)
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 184/877] Bluetooth: btusb: fix NXP IW610 composite device handling
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (182 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 183/877] arm64: percpu: Fix this_cpu_and() mask generation Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 185/877] Bluetooth: eir: validate service data length before reading UUID Greg Kroah-Hartman
` (700 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Nicolas Thibert,
Luiz Augusto von Dentz
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolas Thibert <nithibert@gmail.com>
commit 2b50adefed9808a56d84d1de803cad882cc787fa upstream.
The NXP IW610 module exposes itself as a composite USB device
(0471:0215) with three interfaces: two real Bluetooth HCI interfaces
(class 0xe0) and one vendor-specific WiFi interface (class 0xff) used
by mwifiex-nxp.
The composite device's whole USB descriptor reports class 0xe0/01/01
(Bluetooth), so btusb_table's generic USB_DEVICE_INFO(0xe0, 0x01, 0x01)
entry matches every interface, not just the two real HCI ones -- btusb
ends up binding the WiFi interface too, and mwifiex-nxp never gets it.
Fix:
1. In btusb_table (the table the USB core actually matches against),
explicitly ignore the WiFi interface via BTUSB_IGNORE, ahead of the
generic entry.
2. In quirks_table, scope the existing BTUSB_MARVELL entry to the BT
interface class instead of matching the whole device by VID/PID
(harmless either way since quirks_table isn't consulted for initial
binding, but keep it correct).
Not upstream anywhere: checked NXP's own i.MX kernel fork
(nxp-imx/linux-imx), no IW610 references in btusb.c on any branch --
their reference designs wire this chip differently (WiFi over SDIO
per their release notes), so they never hit this.
Signed-off-by: Nicolas Thibert <nithibert@gmail.com>
Cc: stable@vger.kernel.org
Assisted-by: LLM (Claude Sonnet 5, Anthropic)
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/bluetooth/btusb.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -68,6 +68,15 @@ static struct usb_driver btusb_driver;
#define BTUSB_BARROT BIT(28)
static const struct usb_device_id btusb_table[] = {
+ /*
+ * NXP IW610 (0471:0215): the composite device reports Bluetooth
+ * class at the whole-device level, so the generic entry below
+ * would also match this WiFi vendor interface. Ignore it here
+ * first so mwifiex-nxp can bind it instead.
+ */
+ { USB_DEVICE_AND_INTERFACE_INFO(0x0471, 0x0215, 0xff, 0xff, 0xff),
+ .driver_info = BTUSB_IGNORE },
+
/* Generic Bluetooth USB device */
{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
@@ -470,6 +479,14 @@ static const struct usb_device_id quirks
{ USB_DEVICE(0x1286, 0x2046), .driver_info = BTUSB_MARVELL },
{ USB_DEVICE(0x1286, 0x204e), .driver_info = BTUSB_MARVELL },
+ /*
+ * NXP IW610 BT interfaces (Marvell-lineage silicon, same quirk as
+ * the 0x1286 entries above). Scoped to the BT interface class,
+ * not just VID/PID -- see the btusb_table entry above.
+ */
+ { USB_DEVICE_AND_INTERFACE_INFO(0x0471, 0x0215, 0xe0, 0x01, 0x01),
+ .driver_info = BTUSB_MARVELL },
+
/* Intel Bluetooth devices */
{ USB_DEVICE(0x8087, 0x0025), .driver_info = BTUSB_INTEL_COMBINED },
{ USB_DEVICE(0x8087, 0x0026), .driver_info = BTUSB_INTEL_COMBINED },
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 185/877] Bluetooth: eir: validate service data length before reading UUID
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (183 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 184/877] Bluetooth: btusb: fix NXP IW610 composite device handling Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 186/877] Bluetooth: hci_codec: validate vendor codec count length Greg Kroah-Hartman
` (699 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Aamir Ahmed, Luiz Augusto von Dentz
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aamir Ahmed <elb12345@hotmail.co.uk>
commit e8241766794cf551d787fa3a77c0d54bbea6f6aa upstream.
eir_get_service_data() reads a 16-bit UUID from the service data using
get_unaligned_le16() without first checking that the data is long enough
to hold a UUID16 (2 bytes). If a malformed EIR entry has a service data
field with only 1 byte of payload (field_len=2), eir_get_data() returns
dlen=1. The subsequent get_unaligned_le16() then reads 1 byte past the
field boundary.
Additionally, if the corrupted UUID happens to match, the length
calculation "dlen - 2" underflows to SIZE_MAX since dlen is size_t.
Current callers either pass NULL for the length parameter or bounds-check
the returned length, but future callers may not.
Add a check that dlen >= sizeof(u16) and skip fields that are too short
to contain a valid UUID16.
Fixes: 8f9ae5b3ae80 ("Bluetooth: eir: Add helpers for managing service data")
Cc: stable@vger.kernel.org
Signed-off-by: Aamir Ahmed <elb12345@hotmail.co.uk>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/eir.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
--- a/net/bluetooth/eir.c
+++ b/net/bluetooth/eir.c
@@ -373,7 +373,15 @@ void *eir_get_service_data(u8 *eir, size
size_t dlen;
while ((eir = eir_get_data(eir, eir_len, EIR_SERVICE_DATA, &dlen))) {
- u16 value = get_unaligned_le16(eir);
+ u16 value;
+
+ if (dlen < sizeof(value)) {
+ eir += dlen;
+ eir_len = eir_end - eir;
+ continue;
+ }
+
+ value = get_unaligned_le16(eir);
if (uuid == value) {
if (len)
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 186/877] Bluetooth: hci_codec: validate vendor codec count length
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (184 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 185/877] Bluetooth: eir: validate service data length before reading UUID Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 187/877] Bluetooth: hci_sync: Serialize local codec list cleanup Greg Kroah-Hartman
` (698 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Luiz Augusto von Dentz,
Laxman Acharya Padhya, Luiz Augusto von Dentz
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laxman Acharya Padhya <acharyalaxman8848@gmail.com>
commit d0795cfd6f655f4de84868a4f4bb41a03f037b3d upstream.
The Read Local Supported Codecs parsers consume the variable-sized
standard codec array before parsing the vendor codec count. Although the
initial reply-size check includes a vendor count byte in the fixed layout,
it does not guarantee that the byte remains after the standard codec array.
If a controller reply ends immediately after that array, calculating the
vendor codec array size reads vnd_codecs->num beyond the skb data. Use
skb_pull_data() to validate and consume each codec header before using its
count in both command variants.
Fixes: 8961987f3f5f ("Bluetooth: Enumerate local supported codec and cache details")
Fixes: 9ae664028a9e ("Bluetooth: Add support for Read Local Supported Codecs V2")
Cc: stable@vger.kernel.org
Suggested-by: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
Signed-off-by: Laxman Acharya Padhya <acharyalaxman8848@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/hci_codec.c | 36 ++++++++++++++++++------------------
1 file changed, 18 insertions(+), 18 deletions(-)
--- a/net/bluetooth/hci_codec.c
+++ b/net/bluetooth/hci_codec.c
@@ -145,11 +145,12 @@ void hci_read_supported_codecs(struct hc
skb_pull(skb, sizeof(rp->status));
- std_codecs = (void *)skb->data;
+ std_codecs = skb_pull_data(skb, sizeof(*std_codecs));
+ if (!std_codecs)
+ goto error;
/* validate codecs length before accessing */
- if (skb->len < flex_array_size(std_codecs, codec, std_codecs->num)
- + sizeof(std_codecs->num))
+ if (skb->len < flex_array_size(std_codecs, codec, std_codecs->num))
goto error;
/* enumerate codec capabilities of standard codecs */
@@ -161,15 +162,14 @@ void hci_read_supported_codecs(struct hc
LOCAL_CODEC_ACL_MASK | LOCAL_CODEC_SCO_MASK, &caps);
}
- skb_pull(skb, flex_array_size(std_codecs, codec, std_codecs->num)
- + sizeof(std_codecs->num));
+ skb_pull(skb, flex_array_size(std_codecs, codec, std_codecs->num));
- vnd_codecs = (void *)skb->data;
+ vnd_codecs = skb_pull_data(skb, sizeof(*vnd_codecs));
+ if (!vnd_codecs)
+ goto error;
/* validate vendor codecs length before accessing */
- if (skb->len <
- flex_array_size(vnd_codecs, codec, vnd_codecs->num)
- + sizeof(vnd_codecs->num))
+ if (skb->len < flex_array_size(vnd_codecs, codec, vnd_codecs->num))
goto error;
/* enumerate vendor codec capabilities */
@@ -214,11 +214,12 @@ void hci_read_supported_codecs_v2(struct
skb_pull(skb, sizeof(rp->status));
- std_codecs = (void *)skb->data;
+ std_codecs = skb_pull_data(skb, sizeof(*std_codecs));
+ if (!std_codecs)
+ goto error;
/* check for payload data length before accessing */
- if (skb->len < flex_array_size(std_codecs, codec, std_codecs->num)
- + sizeof(std_codecs->num))
+ if (skb->len < flex_array_size(std_codecs, codec, std_codecs->num))
goto error;
memset(&caps, 0, sizeof(caps));
@@ -229,15 +230,14 @@ void hci_read_supported_codecs_v2(struct
&caps);
}
- skb_pull(skb, flex_array_size(std_codecs, codec, std_codecs->num)
- + sizeof(std_codecs->num));
+ skb_pull(skb, flex_array_size(std_codecs, codec, std_codecs->num));
- vnd_codecs = (void *)skb->data;
+ vnd_codecs = skb_pull_data(skb, sizeof(*vnd_codecs));
+ if (!vnd_codecs)
+ goto error;
/* check for payload data length before accessing */
- if (skb->len <
- flex_array_size(vnd_codecs, codec, vnd_codecs->num)
- + sizeof(vnd_codecs->num))
+ if (skb->len < flex_array_size(vnd_codecs, codec, vnd_codecs->num))
goto error;
for (i = 0; i < vnd_codecs->num; i++) {
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 187/877] Bluetooth: hci_sync: Serialize local codec list cleanup
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (185 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 186/877] Bluetooth: hci_codec: validate vendor codec count length Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 188/877] dmaengine: sun6i: fix non-atomic read of DMA position registers Greg Kroah-Hartman
` (697 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Luiz Augusto von Dentz
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
commit 9a10987a2f160a44a638c9a35994ca6e3089696e upstream.
hci_dev_close_sync() clears hdev->local_codecs after releasing hdev->lock.
Codec list additions and both traversals in sco_sock_getsockopt() use that
lock, but the close path does not. A close and BT_CODEC query can therefore
interleave as follows:
hci_dev_close_sync() sco_sock_getsockopt()
hci_dev_lock()
fetch codec entry
hci_codec_list_clear()
kfree(entry)
read entry->id
The reader then accesses an entry which the close path has freed. KASAN
reported:
BUG: KASAN: slab-use-after-free in sco_sock_getsockopt+0xfa0/0xfe0
Read of size 1 at addr ffff8881001c3450
Call Trace:
sco_sock_getsockopt+0xfa0/0xfe0
do_sock_getsockopt+0x537/0x7b0
__sys_getsockopt+0xf2/0x170
Allocated by task 92:
hci_codec_list_add.isra.0+0x2c/0x440
hci_read_codec_capabilities+0x224/0x590
hci_read_supported_codecs+0x2c2/0x640
Freed by task 92:
kfree+0x131/0x3c0
hci_codec_list_clear+0xd8/0x160
hci_dev_close_sync+0x92a/0xfa0
Take hdev->lock around the clear operation at its existing point in the
close path. This makes the clear wait for active readers and prevents a new
traversal until the list is empty without changing teardown ordering.
Fixes: b938790e7054 ("Bluetooth: hci_codec: Fix leaking content of local_codecs")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/hci_sync.c | 2 ++
1 file changed, 2 insertions(+)
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -5480,7 +5480,9 @@ int hci_dev_close_sync(struct hci_dev *h
memset(hdev->eir, 0, sizeof(hdev->eir));
memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
bacpy(&hdev->random_addr, BDADDR_ANY);
+ hci_dev_lock(hdev);
hci_codec_list_clear(&hdev->local_codecs);
+ hci_dev_unlock(hdev);
hci_dev_put(hdev);
return err;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 188/877] dmaengine: sun6i: fix non-atomic read of DMA position registers
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (186 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 187/877] Bluetooth: hci_sync: Serialize local codec list cleanup Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 189/877] dmaengine: sun6i: fix undefined behaviour in sun6i_dma_tx_status Greg Kroah-Hartman
` (696 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Lugnberg, Frank Li,
Vinod Koul
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Lugnberg <christian.lugnberg@soundtrack.io>
commit c90b6973daa37f4c283342dff881ae001dea4fe6 upstream.
sun6i_get_chan_size() reads DMA_CHAN_LLI_ADDR and DMA_CHAN_CUR_CNT in two
separate readl() calls with no synchronisation between them:
pos = readl(pchan->base + DMA_CHAN_LLI_ADDR);
bytes = readl(pchan->base + DMA_CHAN_CUR_CNT);
DMA_CHAN_LLI_ADDR holds the physical address of the *next* descriptor the
engine will load once the current one completes. DMA_CHAN_CUR_CNT holds the
remaining byte count for the *current* descriptor. If the DMA engine
advances to the next LLI entry between the two reads, pos becomes stale: it
still points to what was the next descriptor at the time of the first read,
but that descriptor is now the current one and CUR_CNT reflects its initial
(full) byte count. The subsequent virtual-chain walk starts one entry too
early and accumulates an extra full period's worth of bytes into the
residue estimate.
Fix this by re-reading DMA_CHAN_LLI_ADDR after DMA_CHAN_CUR_CNT and
retrying if the value changed. This double-read pattern guarantees that
both registers were sampled during the same descriptor interval. The cost
is at most one extra readl() pair per call in the racy case, which occurs
only at descriptor boundaries (~every 2 ms) and is negligible.
Fixes: a90e173f3faf ("dmaengine: sun6i: Add cyclic capability")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Christian Lugnberg <christian.lugnberg@soundtrack.io>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260817135723.12807-2-christian.lugnberg@soundtrack.io
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/dma/sun6i-dma.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -353,8 +353,10 @@ static size_t sun6i_get_chan_size(struct
size_t bytes;
dma_addr_t pos;
- pos = readl(pchan->base + DMA_CHAN_LLI_ADDR);
- bytes = readl(pchan->base + DMA_CHAN_CUR_CNT);
+ do {
+ pos = readl(pchan->base + DMA_CHAN_LLI_ADDR);
+ bytes = readl(pchan->base + DMA_CHAN_CUR_CNT);
+ } while (pos != readl(pchan->base + DMA_CHAN_LLI_ADDR));
if (pos == LLI_LAST_ITEM)
return bytes;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 189/877] dmaengine: sun6i: fix undefined behaviour in sun6i_dma_tx_status
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (187 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 188/877] dmaengine: sun6i: fix non-atomic read of DMA position registers Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 190/877] dmaengine: ti: k3-udma-glue: fix NULL dereference in k3_udma_glue_release_rx_chn() Greg Kroah-Hartman
` (695 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Lugnberg, Frank Li,
Vinod Koul
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Lugnberg <christian.lugnberg@soundtrack.io>
commit 9096bdc8d930147f7c39a493a859acbd3a8485d8 upstream.
sun6i_dma_tx_status() calls vchan_find_desc() to look up the virtual
descriptor for a given cookie, before checking whether the pointer
vd is NULL:
vd = vchan_find_desc(&vchan->vc, cookie);
txd = to_sun6i_desc(&vd->tx); /* vd may be NULL here */
if (vd) {
for (lli = txd->v_lli; ...)
vchan_find_desc() returns NULL when the descriptor has already been
completed or is in-flight on a physical channel and no longer present
in the virtual channel's descriptor list. When vd is NULL,
to_sun6i_desc() is called unconditionally on &vd->tx before the NULL
check, which is undefined behaviour. Move the call inside the if (vd)
guard to ensure it is only reached with a valid pointer.
vd = vchan_find_desc(&vchan->vc, cookie);
if (vd) {
struct sun6i_desc *txd = to_sun6i_desc(&vd->tx);
for (lli = txd->v_lli; ...)
Fixes: 555859308723 ("dmaengine: sun6i: Add driver for the Allwinner A31 DMA controller")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Christian Lugnberg <christian.lugnberg@soundtrack.io>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260817135723.12807-3-christian.lugnberg@soundtrack.io
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/dma/sun6i-dma.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -970,7 +970,6 @@ static enum dma_status sun6i_dma_tx_stat
struct sun6i_pchan *pchan = vchan->phy;
struct sun6i_dma_lli *lli;
struct virt_dma_desc *vd;
- struct sun6i_desc *txd;
enum dma_status ret;
unsigned long flags;
size_t bytes = 0;
@@ -982,9 +981,9 @@ static enum dma_status sun6i_dma_tx_stat
spin_lock_irqsave(&vchan->vc.lock, flags);
vd = vchan_find_desc(&vchan->vc, cookie);
- txd = to_sun6i_desc(&vd->tx);
if (vd) {
+ struct sun6i_desc *txd = to_sun6i_desc(&vd->tx);
for (lli = txd->v_lli; lli != NULL; lli = lli->v_lli_next)
bytes += lli->len;
} else if (!pchan || !pchan->desc) {
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 190/877] dmaengine: ti: k3-udma-glue: fix NULL dereference in k3_udma_glue_release_rx_chn()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (188 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 189/877] dmaengine: sun6i: fix undefined behaviour in sun6i_dma_tx_status Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 191/877] ipv6: xfrm: use full sockets in local error paths Greg Kroah-Hartman
` (694 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pavel Zhigulin, Alexander Chesnokov,
Frank Li, Vinod Koul
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Chesnokov <Alexander.Chesnokov@kaspersky.com>
commit 0294b6dd515256c03ea2dbf508ddd3826d788579 upstream.
If devm_kcalloc() for rx_chn->flows fails in a channel request function,
the error path calls k3_udma_glue_release_rx_chn(), which dereferences
the NULL rx_chn->flows pointer in k3_udma_glue_release_rx_flow().
Skip the flow release loop in k3_udma_glue_release_rx_chn() when
rx_chn->flows is not allocated.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: d70241913413 ("dmaengine: ti: k3-udma: Add glue layer for non DMAengine users")
Cc: stable@vger.kernel.org
Reported-by: Pavel Zhigulin <Pavel.Zhigulin@kaspersky.com>
Signed-off-by: Alexander Chesnokov <Alexander.Chesnokov@kaspersky.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260812053426.3521589-1-Alexander.Chesnokov@kaspersky.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/dma/ti/k3-udma-glue.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/dma/ti/k3-udma-glue.c
+++ b/drivers/dma/ti/k3-udma-glue.c
@@ -1236,8 +1236,9 @@ void k3_udma_glue_release_rx_chn(struct
rx_chn->psil_paired = false;
}
- for (i = 0; i < rx_chn->flow_num; i++)
- k3_udma_glue_release_rx_flow(rx_chn, i);
+ if (rx_chn->flows)
+ for (i = 0; i < rx_chn->flow_num; i++)
+ k3_udma_glue_release_rx_flow(rx_chn, i);
if (xudma_rflow_is_gp(rx_chn->common.udmax, rx_chn->flow_id_base))
xudma_free_gp_rflow_range(rx_chn->common.udmax,
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 191/877] ipv6: xfrm: use full sockets in local error paths
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (189 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 190/877] dmaengine: ti: k3-udma-glue: fix NULL dereference in k3_udma_glue_release_rx_chn() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 192/877] net: lan743x: fix RX checksum use-after-free Greg Kroah-Hartman
` (693 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Vega, Zhiling Zou, Steffen Klassert
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhiling Zou <zhilinz@nebusec.ai>
commit 6973a21ee73c5567f883813c8ef414774b45892f upstream.
xfrm6_local_rxpmtu() and xfrm6_local_error() dereference skb->sk as if it
always pointed at a full IPv6 socket.
That is not guaranteed. TCP SYN-ACK skbs can be owned by a
TCP_NEW_SYN_RECV request_sock while the output path itself is driven by the
full listener. If rerouting selects an IPv6 XFRM tunnel route with a lower
MTU, the local PMTU/error handling path can reach these callbacks with that
mini-socket still attached to the skb.
The callbacks then miscast the request socket as a full inet/IPv6 socket and
can read beyond the request_sock allocation when they access inet_sock or
ipv6_pinfo state.
Resolve the owner with skb_to_full_sk() in both callbacks and bail out when
no full socket is attached. This matches the surrounding XFRM IPv6 PMTU/error
logic, which already reasons about full sockets with skb_to_full_sk().
Fixes: dd767856a36e ("xfrm6: Don't call icmpv6_send on local error")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv6/xfrm6_output.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -19,7 +19,10 @@
void xfrm6_local_rxpmtu(struct sk_buff *skb, u32 mtu)
{
struct flowi6 fl6;
- struct sock *sk = skb->sk;
+ struct sock *sk = skb_to_full_sk(skb);
+
+ if (!sk)
+ return;
fl6.flowi6_oif = sk->sk_bound_dev_if;
fl6.daddr = ipv6_hdr(skb)->daddr;
@@ -31,7 +34,10 @@ void xfrm6_local_error(struct sk_buff *s
{
struct flowi6 fl6;
const struct ipv6hdr *hdr;
- struct sock *sk = skb->sk;
+ struct sock *sk = skb_to_full_sk(skb);
+
+ if (!sk)
+ return;
hdr = skb->encapsulation ? inner_ipv6_hdr(skb) : ipv6_hdr(skb);
fl6.fl6_dport = inet_sk(sk)->inet_dport;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 192/877] net: lan743x: fix RX checksum use-after-free
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (190 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 191/877] ipv6: xfrm: use full sockets in local error paths Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 193/877] net: wwan: t7xx: validate the netif index in t7xx_ccmni_recv_skb() Greg Kroah-Hartman
` (692 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mark Amirkan, Chenguang Zhao,
Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Amirkan <markdamirkan@gmail.com>
commit a9ce4053dc945c5372dedba5017ee675b30dc0c5 upstream.
lan743x_rx_process_buffer() adds each non-first receive buffer to the
head skb's frag_list. On the last descriptor, lan743x_rx_trim_skb()
linearizes the head and frees the fragment skb metadata.
The checksum-success path then writes ip_summed through the local skb
pointer, which still points to the final fragment. This causes a
use-after-free write when a packet spans more than one receive buffer.
Set ip_summed on the surviving head skb instead. Multi-buffer receive
can occur after a live MTU increase because existing ring entries keep
their old buffer size until they are replenished.
A KUnit test invoking lan743x_rx_process_buffer() with a two-buffer
packet produced a one-byte KASAN use-after-free write before this change.
The same test passed after the change. The driver object also builds
with W=1. This was not tested on physical LAN743x hardware.
Fixes: cd6910501cfd ("net: lan743x: Add support for Rx IP & TCP checksum offload")
Cc: stable@vger.kernel.org
Signed-off-by: Mark Amirkan <markdamirkan@gmail.com>
Reviewed-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
Link: https://patch.msgid.link/20260913-b4-send-lan743x-uaf-v1-1-73d563d08ba9@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/microchip/lan743x_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/ethernet/microchip/lan743x_main.c
+++ b/drivers/net/ethernet/microchip/lan743x_main.c
@@ -2587,7 +2587,7 @@ process_extension:
rx->adapter->netdev);
if (rx->adapter->netdev->features & NETIF_F_RXCSUM) {
if (!is_ice && !is_tce && !is_icsm)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
+ rx->skb_head->ip_summed = CHECKSUM_UNNECESSARY;
}
netdev_dbg(netdev, "sending %d byte frame to OS",
rx->skb_head->len);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 193/877] net: wwan: t7xx: validate the netif index in t7xx_ccmni_recv_skb()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (191 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 192/877] net: lan743x: fix RX checksum use-after-free Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 194/877] net: wwan: mhi_wwan_mbim: guard against a cyclic NDP chain Greg Kroah-Hartman
` (691 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guanglei Zhu, Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guanglei Zhu <zhugl3@xiaopeng.com>
commit c7ead9704249d57d4693a04697e3bbd285138fa9 upstream.
The netif index carried in the DPMAIF PIT header is five bits wide,
but ccmni_inst[] only has room for NIC_DEV_MAX (21) entries.
t7xx_ccmni_recv_skb() indexes the array without a bounds check, so
indexes 21 to 31 read past it. The out-of-bounds value lands in the
callback table that follows the array, which is never NULL, so the
existing !ccmni check does not catch it and the driver dereferences
whatever sits there as a struct t7xx_ccmni.
Drop the skb when the index is out of range.
Fixes: 05d19bf500f8 ("net: wwan: t7xx: Add WWAN network interface")
Cc: stable@vger.kernel.org
Signed-off-by: Guanglei Zhu <zhugl3@xiaopeng.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Verified in a QEMU guest with a fault injector setting the netif
index to 25: the unpatched driver reads a value past ccmni_inst[],
which lands in the callback table, and dereferences it far enough to
queue the skb. With this check the packet is dropped. Well-formed
traffic on index 0 is unaffected.
Changes in v2: none.
Link: https://patch.msgid.link/20260911021734.1396599-3-zhugl3@xiaopeng.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/wwan/t7xx/t7xx_netdev.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/net/wwan/t7xx/t7xx_netdev.c
+++ b/drivers/net/wwan/t7xx/t7xx_netdev.c
@@ -420,6 +420,10 @@ static void t7xx_ccmni_recv_skb(struct t
skb_cb = T7XX_SKB_CB(skb);
netif_id = skb_cb->netif_idx;
+ if (netif_id >= NIC_DEV_MAX) {
+ dev_kfree_skb(skb);
+ return;
+ }
ccmni = READ_ONCE(ccmni_ctlb->ccmni_inst[netif_id]);
if (!ccmni) {
dev_kfree_skb(skb);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 194/877] net: wwan: mhi_wwan_mbim: guard against a cyclic NDP chain
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (192 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 193/877] net: wwan: t7xx: validate the netif index in t7xx_ccmni_recv_skb() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 195/877] net: wwan: mhi_wwan_mbim: check skb_copy_bits() return value Greg Kroah-Hartman
` (690 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Loic Poulain, Guanglei Zhu,
Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guanglei Zhu <zhugl3@xiaopeng.com>
commit 5d063822ac5184939c1ed377a339a01d8ae814e8 upstream.
The NDP traversal in mhi_mbim_rx() only stops when wNextNdpIndex is
zero. Nothing requires the offsets to advance, so a modem that
points an NDP at itself, or at an earlier NDP, keeps the loop
spinning forever on one CPU.
Break out when the next NDP offset is not larger than the current
one.
Fixes: aa730a9905b7 ("net: wwan: Add MHI MBIM network driver")
Cc: stable@vger.kernel.org
Suggested-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
Signed-off-by: Guanglei Zhu <zhugl3@xiaopeng.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Verified in a QEMU guest with a fault injector feeding the driver's
receive callback an NTB whose single NDP points at itself: the
unpatched driver spins in mhi_mbim_rx() with one CPU pinned at 100%
and the thread never returns. With this check the loop terminates
within one iteration.
Changes in v2: move the non-increasing check to the wNextNdpIndex
retrieval site, as suggested by Loic Poulain, instead of tracking
the previous offset in a separate variable.
Link: https://patch.msgid.link/20260911021734.1396599-1-zhugl3@xiaopeng.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/wwan/mhi_wwan_mbim.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
--- a/drivers/net/wwan/mhi_wwan_mbim.c
+++ b/drivers/net/wwan/mhi_wwan_mbim.c
@@ -350,9 +350,13 @@ static void mhi_mbim_rx(struct mhi_mbim_
unlock:
rcu_read_unlock();
next_ndp:
- /* Other NDP to process? */
- ndpoffset = (int)le16_to_cpu(ndp16.wNextNdpIndex);
- if (!ndpoffset)
+ /* Other NDP to process? The offsets must advance, or a
+ * self-referencing NDP keeps the loop spinning forever.
+ */
+ n = (int)le16_to_cpu(ndp16.wNextNdpIndex);
+ if (n > ndpoffset)
+ ndpoffset = n;
+ else
break;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 195/877] net: wwan: mhi_wwan_mbim: check skb_copy_bits() return value
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (193 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 194/877] net: wwan: mhi_wwan_mbim: guard against a cyclic NDP chain Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 196/877] net/sched: act_api: release tail references on DELACTION failure Greg Kroah-Hartman
` (689 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Loic Poulain, Guanglei Zhu,
Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guanglei Zhu <zhugl3@xiaopeng.com>
commit 31550d585589fde1ae95bf7f7a8188b2d2fdf1c7 upstream.
mhi_mbim_rx() ignores the return value of skb_copy_bits() when it
copies each datagram out of the NTB. The datagram offset and length
come from the DPE, which is only checked to lie within the NTB
itself, so a modem can point a datagram outside the received skb.
The copy then fails and the freshly allocated skbn is passed to
netif_rx() with its uninitialized contents still in place, leaking
kernel heap memory into the network stack.
Free the skb and account an error when the copy fails.
Fixes: aa730a9905b7 ("net: wwan: Add MHI MBIM network driver")
Cc: stable@vger.kernel.org
Suggested-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
Signed-off-by: Guanglei Zhu <zhugl3@xiaopeng.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Verified in a QEMU guest with a fault injector pointing a DPE
outside the received NTB: the copy fails, and the unpatched driver
hands the uninitialized skbn to the network stack (observed as
"unknown protocol" on bytes that were never written). With this
check the failed datagram is dropped and counted as an rx error.
Changes in v2: factor the free-and-count sequence out into
mhi_mbim_rx_drop(), shared with the unknown-protocol path, as
suggested by Loic Poulain.
Link: https://patch.msgid.link/20260911021734.1396599-2-zhugl3@xiaopeng.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/wwan/mhi_wwan_mbim.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
--- a/drivers/net/wwan/mhi_wwan_mbim.c
+++ b/drivers/net/wwan/mhi_wwan_mbim.c
@@ -252,6 +252,14 @@ static int mbim_rx_verify_ndp16(struct s
return ret;
}
+static void mhi_mbim_rx_drop(struct mhi_mbim_link *link, struct sk_buff *skb)
+{
+ dev_kfree_skb_any(skb);
+ u64_stats_update_begin(&link->rx_syncp);
+ u64_stats_inc(&link->rx_errors);
+ u64_stats_update_end(&link->rx_syncp);
+}
+
static void mhi_mbim_rx(struct mhi_mbim_context *mbim, struct sk_buff *skb)
{
int ndpoffset;
@@ -321,7 +329,10 @@ static void mhi_mbim_rx(struct mhi_mbim_
continue;
skb_put(skbn, dgram_len);
- skb_copy_bits(skb, dgram_offset, skbn->data, dgram_len);
+ if (skb_copy_bits(skb, dgram_offset, skbn->data, dgram_len)) {
+ mhi_mbim_rx_drop(link, skbn);
+ continue;
+ }
switch (skbn->data[0] & 0xf0) {
case 0x40:
@@ -333,10 +344,7 @@ static void mhi_mbim_rx(struct mhi_mbim_
default:
net_err_ratelimited("%s: unknown protocol\n",
link->ndev->name);
- dev_kfree_skb_any(skbn);
- u64_stats_update_begin(&link->rx_syncp);
- u64_stats_inc(&link->rx_errors);
- u64_stats_update_end(&link->rx_syncp);
+ mhi_mbim_rx_drop(link, skbn);
continue;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 196/877] net/sched: act_api: release tail references on DELACTION failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (194 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 195/877] net: wwan: mhi_wwan_mbim: check skb_copy_bits() return value Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 197/877] net/sched: hhf: cap hh_flows_limit at change time Greg Kroah-Hartman
` (688 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Xuanqiang Luo, Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
commit 6e05e46fa821a5c1b281355f1f622ac76cb6080a upstream.
A batched RTM_DELACTION request takes a temporary reference on each
action before attempting any deletion. tcf_action_delete() clears
each processed slot and drops its temporary reference before attempting
the deletion. If deletion fails, tca_action_gd() calls
tcf_action_put_many() to release the remaining references, but its
tcf_act_for_each_action() iterator stops at the first NULL slot.
When a batch stops at an action bound to a filter, this leaks a
reference on each subsequent action. A later delete of an unbound
action can then return success without removing it from the IDR.
Walk the full array in tcf_action_put_many() and skip NULL slots to
release the references held on the unprocessed actions.
Fixes: a0e947c9ccff ("net/sched: act_api: avoid non-contiguous action array")
Cc: stable@vger.kernel.org
Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Link: https://patch.msgid.link/20260910093413.34509-2-xuanqiang.luo@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/sched/act_api.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -1165,11 +1165,16 @@ static int tcf_action_put(struct tc_acti
static void tcf_action_put_many(struct tc_action *actions[])
{
- struct tc_action *a;
int i;
- tcf_act_for_each_action(i, a, actions) {
- const struct tc_action_ops *ops = a->ops;
+ /* Deletion may have cleared entries before failing. */
+ for (i = 0; i < TCA_ACT_MAX_PRIO; i++) {
+ struct tc_action *a = actions[i];
+ const struct tc_action_ops *ops;
+
+ if (!a)
+ continue;
+ ops = a->ops;
if (tcf_action_put(a))
module_put(ops->owner);
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 197/877] net/sched: hhf: cap hh_flows_limit at change time
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (195 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 196/877] net/sched: act_api: release tail references on DELACTION failure Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 198/877] net/packet: clear RX owner on VNET header error Greg Kroah-Hartman
` (687 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko (gemini), Victor Nogueira,
hybris, Jamal Hadi Salim, Simon Horman, Paolo Abeni
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
commit 2cef2588c995722a901368def30befeef9ae55c6 upstream.
hhf_change() stores TCA_HHF_HH_FLOWS_LIMIT with no upper bound. A huge
hh_flows_limit lets each new heavy-hitter flow pass the
hh_flows_current_cnt check in alloc_new_hh() and forces a fixed-size
kzalloc(GFP_ATOMIC) per flow under spoofed traffic, for unbounded memory
growth.
Bound the attribute with NLA_POLICY_MAX() at 2*HH_FLOWS_CNT (the
hhf_init() default) and report the rejected value via extack. The
deprecated nested parse is kept: legacy tc does not set NLA_F_NESTED on
TCA_OPTIONS. Configs relying on hh_limit above the default were relying
on unbounded, unsafe behaviour and are not supported going forward.
hhf_init() also ran hhf_change() before setting the default
hh_flows_limit, so a user-supplied hh_limit at add time was clobbered
back to 2048. Set the default before hhf_change() so the configured
value sticks.
This is a follow-up to commit eb56a495f59b ("net/sched: hhf: clamp
quantum in change and init paths"), which bounded the quantum of the
same qdisc; the hh_flows_limit bound is the remaining unbounded knob of
that series' scope.
Conditions to recreate the bug: CAP_NET_ADMIN in a user namespace;
tc qdisc change dev X root hhf hh_limit 4294967295 succeeds and the
value is echoed by tc qdisc show, unbounding heavy-hitter flow
allocations; also tc qdisc add dev X root hhf hh_limit 500 stores 2048
instead of 500.
Fixes: 10239edf86f1 ("net-qdisc-hhf: Heavy-Hitter Filter (HHF) qdisc")
Cc: stable@vger.kernel.org
Reported-by: Sashiko (gemini) <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260822195509.112717-1-jhs@mojatatu.com
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Tested-by: hybris <hybris@mojatatu.ai>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/QDISC-B855.v1.20260911153152@mojatatu.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/sched/sch_hhf.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
--- a/net/sched/sch_hhf.c
+++ b/net/sched/sch_hhf.c
@@ -526,7 +526,7 @@ static void hhf_destroy(struct Qdisc *sc
static const struct nla_policy hhf_policy[TCA_HHF_MAX + 1] = {
[TCA_HHF_BACKLOG_LIMIT] = { .type = NLA_U32 },
[TCA_HHF_QUANTUM] = { .type = NLA_U32 },
- [TCA_HHF_HH_FLOWS_LIMIT] = { .type = NLA_U32 },
+ [TCA_HHF_HH_FLOWS_LIMIT] = NLA_POLICY_MAX(NLA_U32, 2 * HH_FLOWS_CNT),
[TCA_HHF_RESET_TIMEOUT] = { .type = NLA_U32 },
[TCA_HHF_ADMIT_BYTES] = { .type = NLA_U32 },
[TCA_HHF_EVICT_TIMEOUT] = { .type = NLA_U32 },
@@ -545,7 +545,7 @@ static int hhf_change(struct Qdisc *sch,
u32 new_hhf_non_hh_weight = q->hhf_non_hh_weight;
err = nla_parse_nested_deprecated(tb, TCA_HHF_MAX, opt, hhf_policy,
- NULL);
+ extack);
if (err < 0)
return err;
@@ -621,6 +621,9 @@ static int hhf_init(struct Qdisc *sch, s
q->hhf_evict_timeout = HZ; /* 1 sec */
q->hhf_non_hh_weight = 2;
+ /* Cap max active HHs at twice len of hh_flows table. */
+ q->hh_flows_limit = 2 * HH_FLOWS_CNT;
+
if (opt) {
int err = hhf_change(sch, opt, extack);
@@ -637,8 +640,6 @@ static int hhf_init(struct Qdisc *sch, s
for (i = 0; i < HH_FLOWS_CNT; i++)
INIT_LIST_HEAD(&q->hh_flows[i]);
- /* Cap max active HHs at twice len of hh_flows table. */
- q->hh_flows_limit = 2 * HH_FLOWS_CNT;
q->hh_flows_overlimit = 0;
q->hh_flows_total_cnt = 0;
q->hh_flows_current_cnt = 0;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 198/877] net/packet: clear RX owner on VNET header error
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (196 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 197/877] net/sched: hhf: cap hh_flows_limit at change time Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 199/877] net/packet: avoid truncating TPACKET_V3 private size Greg Kroah-Hartman
` (686 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mark Amirkan, Willem de Bruijn,
Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Amirkan <markdamirkan@gmail.com>
commit 33ff111d7ba3beb86e28938d6382bb5beabd865a upstream.
Commit 61fad6816fc1 ("net/packet: tpacket_rcv: avoid a producer race
condition") added rx_owner_map and made tpacket_rcv() claim a V1 or V2
ring slot before converting the virtio-net header. If the conversion
fails, the drop path leaves the slot claimed.
With a one-frame TPACKET_V2 ring, an unsupported UDP GSO packet leaves
the only slot unavailable, so the ring also drops the next valid packet.
Clear the ownership bit on this error path. TPACKET_V3 already clears
its block state here.
Fixes: 61fad6816fc1 ("net/packet: tpacket_rcv: avoid a producer race condition")
Cc: stable@vger.kernel.org
Signed-off-by: Mark Amirkan <markdamirkan@gmail.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260913-b4-send-packet-vnet-v1-1-5545ffb528ae@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/packet/af_packet.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2436,7 +2436,9 @@ static int tpacket_rcv(struct sk_buff *s
virtio_net_hdr_from_skb(skb, h.raw + macoff -
sizeof(struct virtio_net_hdr),
vio_le(), true, 0)) {
- if (po->tp_version == TPACKET_V3)
+ if (po->tp_version <= TPACKET_V2)
+ __clear_bit(slot_id, po->rx_ring.rx_owner_map);
+ else
prb_clear_blk_fill_status(&po->rx_ring);
goto drop_n_account;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 199/877] net/packet: avoid truncating TPACKET_V3 private size
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (197 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 198/877] net/packet: clear RX owner on VNET header error Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 200/877] scsi: core: Validate MODE SENSE lengths in scsi_cdl_enable() Greg Kroah-Hartman
` (685 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mark Amirkan, Willem de Bruijn,
Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Amirkan <markdamirkan@gmail.com>
commit 37213e61120297920ae4c937fcb326a360da5084 upstream.
tpacket_req3.tp_sizeof_priv is an unsigned int, and packet_set_ring()
validates the full value against the block size. init_prb_bdqc() then
stores it in the unsigned short blk_sizeof_priv field.
Commit 2b6867c2ce76 ("net/packet: fix overflow in check for priv area
size") fixed the validation arithmetic, but an accepted value above
USHRT_MAX still narrows when it is stored.
For a 131072-byte block, tp_sizeof_priv=65536 is valid. The narrowing
makes offset_to_first_pkt 48 instead of 65584, so packet records can be
placed in the private area that userspace asked the kernel to preserve.
blk_sizeof_priv is internal state, so widen it to hold the validated
UAPI value.
Fixes: f6fb8f100b80 ("af-packet: TPACKET_V3 flexible buffer implementation.")
Cc: stable@vger.kernel.org
Signed-off-by: Mark Amirkan <markdamirkan@gmail.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260913-b4-send-packet-private-v1-1-925eab2cd388@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/packet/internal.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/packet/internal.h
+++ b/net/packet/internal.h
@@ -21,7 +21,7 @@ struct tpacket_kbdq_core {
unsigned char reset_pending_on_curr_blk;
unsigned char delete_blk_timer;
unsigned short kactive_blk_num;
- unsigned short blk_sizeof_priv;
+ unsigned int blk_sizeof_priv;
/* last_kactive_blk_num:
* trick to see if user-space has caught up
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 200/877] scsi: core: Validate MODE SENSE lengths in scsi_cdl_enable()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (198 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 199/877] net/packet: avoid truncating TPACKET_V3 private size Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 201/877] xfrm: serialize state GC with device state flush Greg Kroah-Hartman
` (684 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko AI Review,
Pimen Flavian Dei (Drivesec S.r.l.),
Alberto Carboneri (Drivesec S.r.l.), Damien Le Moal,
Martin K. Petersen (Oracle)
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alberto Carboneri <acarboneri@drivesec.com>
commit 3d676e458fe0c566f5a62753dc696b6a862fc412 upstream.
scsi_cdl_enable() uses length fields returned by MODE SENSE to locate
the ATA feature mode page in a 64-byte stack buffer. A target can report
a total length shorter than its mode header and block descriptors. The
unsigned subtraction used for the MODE SELECT length can wrap, and the
separately computed buf_data can point beyond buf.
During automatic scan, enable is false, so the read-modify-write of
buf_data[4] can clear the low two bits of a target-selected
out-of-bounds stack byte. scsi_mode_select() can then copy up to 64
bytes from outside the buffer into the outgoing MODE SELECT payload,
disclosing stack contents to the target.
This is reachable while scanning a USB storage device that identifies as
an ATA device and advertises CDL support. No filesystem mount or
userspace access to the block device is required.
On upstream commit cee9395acd80 ("Linux 7.3-rc1"), a build-specific,
one-vCPU QEMU/Raw Gadget proof using QEMU-only multi-UDC allocator
sampling executed a fixed proof command inside the guest and created a
UID-0-owned marker during automatic enumeration, with KASLR and NX
enabled.
The issue was independently found during security research at Drivesec
S.r.l.
Cap the available length to the buffer size. Validate and consume the
mode header and block descriptor lengths before using the page, and
require the five bytes needed to access the CDL field.
Fixes: 1b22cfb14142 ("scsi: core: Allow enabling and disabling command duration limits")
Reported-by: Sashiko AI Review <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/linux-scsi/20260717192313.93D791F000E9@smtp.kernel.org/
Link: https://lore.kernel.org/linux-scsi/20260717222931.AC4EE1F000E9@smtp.kernel.org/
Link: https://lore.kernel.org/linux-scsi/df13ec87ac9b28e3b0a2d9eb26477e276ff0278a.camel@HansenPartnership.com/
Cc: stable@vger.kernel.org
Assisted-by: LLM
Co-developed-by: Pimen Flavian Dei (Drivesec S.r.l.) <fdei@drivesec.com>
Signed-off-by: Pimen Flavian Dei (Drivesec S.r.l.) <fdei@drivesec.com>
Signed-off-by: Alberto Carboneri (Drivesec S.r.l.) <acarboneri@drivesec.com>
Link: https://lore.kernel.org/linux-scsi/20260717192313.93D791F000E9@smtp.kernel.org/
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Link: https://patch.msgid.link/20260904135410.360314-1-acarboneri@drivesec.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/scsi/scsi.c | 24 +++++++++++++++++++-----
1 file changed, 19 insertions(+), 5 deletions(-)
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -713,6 +713,7 @@ int scsi_cdl_enable(struct scsi_device *
struct scsi_mode_data data;
struct scsi_sense_hdr sshdr;
char *buf_data;
+ size_t avail, offset;
int len;
ret = scsi_mode_sense(sdev, 0x08, 0x0a, 0xf2, buf, sizeof(buf),
@@ -721,11 +722,24 @@ int scsi_cdl_enable(struct scsi_device *
return -EINVAL;
/* Enable or disable CDL using the ATA feature page */
- len = min_t(size_t, sizeof(buf),
- data.length - data.header_length -
- data.block_descriptor_length);
- buf_data = buf + data.header_length +
- data.block_descriptor_length;
+ avail = min_t(size_t, data.length, sizeof(buf));
+ if (data.header_length > avail)
+ return -EINVAL;
+
+ offset = data.header_length;
+ avail -= data.header_length;
+
+ if (data.block_descriptor_length > avail)
+ return -EINVAL;
+
+ offset += data.block_descriptor_length;
+ avail -= data.block_descriptor_length;
+
+ if (avail < 5)
+ return -EINVAL;
+
+ buf_data = buf + offset;
+ len = avail;
/*
* If we want to enable CDL and CDL is already enabled on the
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 201/877] xfrm: serialize state GC with device state flush
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (199 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 200/877] scsi: core: Validate MODE SENSE lengths in scsi_cdl_enable() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 202/877] xfrm: use hlist_del_init_rcu for state_cache and state_cache_input Greg Kroah-Hartman
` (683 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Steffen Klassert
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
commit 89fefad9f971bc637fb22373078144f2563c4be9 upstream.
The deferred-device pass in xfrm_dev_state_flush() finds states under
xfrm_state_dev_gc_lock, but drops the lock before calling
xfrm_dev_state_free() because the driver callback may sleep. The device
GC list does not hold an xfrm_state reference, so the state GC worker can
destroy the same state concurrently.
The race can proceed as follows:
CPU 0 CPU 1
find x on the device GC list
drop xfrm_state_dev_gc_lock
read x->xso.dev
xfrm_state_gc_destroy(x)
xfrm_dev_state_free(x)
xfrm_state_free(x)
continue xfrm_dev_state_free(x)
Both paths can invoke the driver callback and drop the device reference.
CPU 0 can also access the xfrm_state after CPU 1 has freed it.
KASAN reported:
BUG: KASAN: slab-use-after-free in xfrm_dev_state_free+0x24c/0x2a0
Read of size 8 at addr ffff88810bbaa960 by task poc/102
Call Trace:
xfrm_dev_state_free+0x24c/0x2a0
xfrm_dev_state_flush+0x353/0x400
xfrm_dev_event+0x26d/0x3a0
notifier_call_chain+0xc0/0x280
__dev_notify_flags+0x169/0x250
netif_change_flags+0xe7/0x160
dev_change_flags+0x96/0x220
devinet_ioctl+0x7f4/0x1880
Allocated by task 87:
xfrm_state_alloc+0x1e/0x5c0
xfrm_add_sa+0xe7f/0x5820
xfrm_user_rcv_msg+0x4f3/0x940
Freed by task 57:
kmem_cache_free+0xcb/0x3d0
xfrm_state_gc_task+0x4a8/0x650
process_one_work+0x63a/0x1070
Serialize xfrm_state destruction against the deferred-device pass with a
mutex. Keep xfrm_state_dev_gc_lock limited to list operations and retain
the existing callback and device-reference release ordering.
Fixes: 07b87f9eea0c ("xfrm: Fix unregister netdevice hang on hardware offload.")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/xfrm/xfrm_state.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -226,6 +226,7 @@ static struct xfrm_state_afinfo __rcu *x
static DEFINE_SPINLOCK(xfrm_state_gc_lock);
static DEFINE_SPINLOCK(xfrm_state_dev_gc_lock);
+static DEFINE_MUTEX(xfrm_state_gc_mutex);
int __xfrm_state_delete(struct xfrm_state *x);
@@ -570,8 +571,10 @@ static void xfrm_state_gc_task(struct wo
synchronize_rcu();
+ mutex_lock(&xfrm_state_gc_mutex);
hlist_for_each_entry_safe(x, tmp, &gc_list, gclist)
xfrm_state_gc_destroy(x);
+ mutex_unlock(&xfrm_state_gc_mutex);
}
static enum hrtimer_restart xfrm_timer_handler(struct hrtimer *me)
@@ -937,6 +940,7 @@ restart:
out:
spin_unlock_bh(&net->xfrm.xfrm_state_lock);
+ mutex_lock(&xfrm_state_gc_mutex);
spin_lock_bh(&xfrm_state_dev_gc_lock);
restart_gc:
hlist_for_each_entry_safe(x, tmp, &xfrm_state_dev_gc_list, dev_gclist) {
@@ -951,6 +955,7 @@ restart_gc:
}
spin_unlock_bh(&xfrm_state_dev_gc_lock);
+ mutex_unlock(&xfrm_state_gc_mutex);
xfrm_flush_gc();
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 202/877] xfrm: use hlist_del_init_rcu for state_cache and state_cache_input
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (200 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 201/877] xfrm: serialize state GC with device state flush Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 203/877] memstick: ms_block: destroy io_queue workqueue on removal Greg Kroah-Hartman
` (682 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Siwei Zhang, Steffen Klassert
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Siwei Zhang <fourdizhang@tencent.com>
commit 2afb8dc1f4390f164db8352f8e685e126e9db566 upstream.
Commit 14acf9652e56 ("xfrm: defensively unhash xfrm_state lists in
__xfrm_state_delete") converted bydst/bysrc/byseq/byspi from
hlist_del_rcu() to hlist_del_init_rcu() so that a second
__xfrm_state_delete() on the same object becomes a no-op rather than a
write through LIST_POISON pprev. It missed state_cache and
state_cache_input, which kept hlist_del_rcu():
- hlist_del_rcu() leaves pprev = LIST_POISON2 (non-NULL), so
hlist_unhashed() returns false.
- hlist_del_init_rcu() leaves pprev = NULL, so hlist_unhashed()
returns true.
A second __xfrm_state_delete() therefore enters __hlist_del() on the
already-deleted state_cache/state_cache_input nodes and does
WRITE_ONCE(*pprev, next) through LIST_POISON2 — a write use-after-free
once the slab is reused. The corruption can in turn cause a subsequent
hlist_for_each_entry_rcu traversal to follow a dangling next pointer,
producing the read use-after-free reported in xfrm_input_state_lookup().
Switch state_cache and state_cache_input to hlist_del_init_rcu() to
match the other four lists, closing the write use-after-free and, with
it, the read use-after-free it spawns.
Assisted-by: CodeBuddy:GLM-5.2
Fixes: 0045e3d80613 ("xfrm: Cache used outbound xfrm states at the policy.")
Fixes: 81a331a0e72d ("xfrm: Add an inbound percpu state cache.")
Cc: stable@vger.kernel.org
Signed-off-by: Siwei Zhang <fourdizhang@tencent.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/xfrm/xfrm_state.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -763,9 +763,9 @@ int __xfrm_state_delete(struct xfrm_stat
if (!hlist_unhashed(&x->byseq))
hlist_del_init_rcu(&x->byseq);
if (!hlist_unhashed(&x->state_cache))
- hlist_del_rcu(&x->state_cache);
+ hlist_del_init_rcu(&x->state_cache);
if (!hlist_unhashed(&x->state_cache_input))
- hlist_del_rcu(&x->state_cache_input);
+ hlist_del_init_rcu(&x->state_cache_input);
if (!hlist_unhashed(&x->byspi))
hlist_del_init_rcu(&x->byspi);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 203/877] memstick: ms_block: destroy io_queue workqueue on removal
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (201 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 202/877] xfrm: use hlist_del_init_rcu for state_cache and state_cache_input Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 204/877] mm/mlock: use the IRQ-safe accessor for NR_MLOCK in __munlock_folio() Greg Kroah-Hartman
` (681 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Yifei Gao, Ulf Hansson
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yifei Gao <gyf161023@gmail.com>
commit 90af7fde083e1b22c349c3a8b1626728e44e474c upstream.
msb_init_disk() creates the per-card ordered workqueue msb->io_queue with
alloc_ordered_workqueue(). It is torn down with destroy_workqueue() only
on the init error path; msb_remove() never destroys it. msb_stop() merely
flushes the queue, and neither msb_data_clear() nor put_disk() free it. As
a result every card insert/remove cycle leaks the workqueue and its
kworker, exhausting kernel memory over repeated cycles.
Destroy the workqueue in msb_remove() after the disk has been removed and
the queue drained.
Fixes: 0ab30494bc4f ("memstick: add support for legacy memorysticks")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Yifei Gao <gyf161023@gmail.com>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/memstick/core/ms_block.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/memstick/core/ms_block.c
+++ b/drivers/memstick/core/ms_block.c
@@ -2206,6 +2206,8 @@ static void msb_remove(struct memstick_d
msb_data_clear(msb);
mutex_unlock(&msb_disk_lock);
+ destroy_workqueue(msb->io_queue);
+
put_disk(msb->disk);
memstick_set_drvdata(card, NULL);
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 204/877] mm/mlock: use the IRQ-safe accessor for NR_MLOCK in __munlock_folio()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (202 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 203/877] memstick: ms_block: destroy io_queue workqueue on removal Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 205/877] KEYS: encrypted: fix integer overflow of datablob_len Greg Kroah-Hartman
` (680 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shakeel Butt,
syzbot+cd2073ee6d958a8d0fcd, Hugh Dickins, Jann Horn,
Liam R. Howlett, Lorenzo Stoakes, Matthew Wilcox (Oracle),
Pedro Falcato, Vlastimil Babka, Andrew Morton
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shakeel Butt <shakeel.butt@linux.dev>
commit e14a3454806468b086fe2e4ca2e1bff95b528531 upstream.
NR_MLOCK is updated from interrupt context. __free_pages_prepare() clears
a stray PG_mlocked and adjusts NR_MLOCK, and a folio can reach it with the
flag still set from a bio completion handler:
__free_pages_ok+0x6af/0x7a0
<IRQ>
__bio_release_pages+0xde/0x260
__iomap_dio_bio_end_io+0x16e/0x1a0
blk_update_request+0x14b/0x3d0
blk_mq_end_request+0x18/0x30
blk_done_softirq+0x49/0x60
The folio gets there like this. A MAP_SHARED file mapping is mlocked, so
its page cache folios carry PG_mlocked, and an O_DIRECT write sourced from
that mapping GUP-pins those same folios. munlock() then runs
mlock_vma_pages_range(), which clears VM_LOCKED before walking the page
tables to munlock each folio. A concurrent hole punch reaches the folio
through the rmap (i_mmap_rwsem, not mmap_lock) and can land inside that
window: __folio_remove_rmap() -> munlock_vma_folio() sees VM_LOCKED
already clear, so it neither queues the folio on the mlock batch nor takes
a reference, and the pte it clears makes the pending mlock_pte_range()
walk skip the folio at its !pte_present() check. filemap_remove_folio()
then drops the page cache reference, leaving the bio's pin as the last
one, released from the completion handler above.
So __zone_stat_mod_folio() here needs interrupts disabled, not merely
preemption, and __munlock_folio() has a path where they are not: when the
folio has already been taken off the LRU by somebody else the function
jumps straight to the counter update without taking the lruvec lock. The
read-modify-write of the per-CPU NR_MLOCK diff can then be interrupted by
the softirq above, and one of the two decrements is lost, leaving Mlocked
in /proc/meminfo permanently overstated.
Use zone_stat_mod_folio(). mod_zone_state()'s this_cpu_try_cmpxchg() is
atomic against a same-CPU interrupt and retries, and on the path where the
lruvec lock is held its cost is negligible next to the lock itself.
The UNEVICTABLE_PG* events are deliberately left on the __ accessors: they
occupy different vm_event_states slots from the UNEVICTABLE_PGCLEARED that
__free_pages_prepare() bumps, and nothing updates those two from interrupt
context.
Link: https://lore.kernel.org/20260901180109.3797944-1-shakeel.butt@linux.dev
Fixes: 2fbb0c10d1e8 ("mm/munlock: mlock_page() munlock_page() batch by pagevec")
Signed-off-by: Shakeel Butt <shakeel.butt@linux.dev>
Reported-by: syzbot+cd2073ee6d958a8d0fcd@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/linux-mm/6a931c5a.08e933ee.dbf97.0093.GAE@google.com/
Acked-by: Hugh Dickins <hughd@google.com>
Cc: Jann Horn <jannh@google.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Pedro Falcato <pfalcato@suse.de>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
mm/mlock.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -141,7 +141,7 @@ static struct lruvec *__munlock_folio(st
munlock:
if (folio_test_clear_mlocked(folio)) {
- __zone_stat_mod_folio(folio, NR_MLOCK, -nr_pages);
+ zone_stat_mod_folio(folio, NR_MLOCK, -nr_pages);
if (isolated || !folio_test_unevictable(folio))
__count_vm_events(UNEVICTABLE_PGMUNLOCKED, nr_pages);
else
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 205/877] KEYS: encrypted: fix integer overflow of datablob_len
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (203 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 204/877] mm/mlock: use the IRQ-safe accessor for NR_MLOCK in __munlock_folio() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 206/877] keys: translate request_key_auth pid for the reading procfs instance Greg Kroah-Hartman
` (679 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cen Zhang, Francis Perron,
Jarkko Sakkinen, R Nageswara Sastry
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cen Zhang <cenzhang@linux.microsoft.com>
commit 8697c431e297eb0d0ab13dda6bc172b48a34f05c upstream.
encrypted_key_alloc() stores datablob_len in a u16. It is computed from
multiple string and payload lengths. If the result exceeds U16_MAX, the
assignment truncates the allocation size. KASAN reports a 32760-byte
slab-out-of-bounds write when __ekey_init() copies the master key
description into the undersized buffer.
The total payload length stored in key->datalen is also a u16. Use
check_add_overflow() to reject values that do not fit either destination,
and use kzalloc_flex() for the flexible-array allocation.
Fixes: 7e70cb497850 ("keys: add new key-type encrypted")
Cc: stable@vger.kernel.org
Assisted-by: GitHub-Copilot:claude-opus-4.6
Signed-off-by: Cen Zhang <cenzhang@linux.microsoft.com>
Signed-off-by: Francis Perron <francis@akrites.dev>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Tested-by: R Nageswara Sastry <rnsastry@linux.ibm.com>
Link: https://lore.kernel.org/r/20260909153433.83117-1-cenzhang@linux.microsoft.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
security/keys/encrypted-keys/encrypted.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
--- a/security/keys/encrypted-keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -18,6 +18,7 @@
#include <linux/parser.h>
#include <linux/string.h>
#include <linux/err.h>
+#include <linux/overflow.h>
#include <keys/user-type.h>
#include <keys/trusted-type.h>
#include <keys/encrypted-type.h>
@@ -606,6 +607,7 @@ static struct encrypted_key_payload *enc
{
struct encrypted_key_payload *epayload = NULL;
unsigned short datablob_len;
+ unsigned short payload_totallen;
unsigned short decrypted_datalen;
unsigned short payload_datalen;
unsigned int encrypted_datalen;
@@ -659,16 +661,22 @@ static struct encrypted_key_payload *enc
encrypted_datalen = roundup(decrypted_datalen, blksize);
- datablob_len = format_len + 1 + strlen(master_desc) + 1
- + strlen(datalen) + 1 + ivsize + 1 + encrypted_datalen;
+ if (check_add_overflow(format_len + 1 + strlen(master_desc) + 1
+ + strlen(datalen) + 1 + ivsize + 1,
+ encrypted_datalen, &datablob_len))
+ return ERR_PTR(-EINVAL);
+
+ if (check_add_overflow(datablob_len,
+ payload_datalen + HASH_SIZE + 1,
+ &payload_totallen))
+ return ERR_PTR(-EINVAL);
- ret = key_payload_reserve(key, payload_datalen + datablob_len
- + HASH_SIZE + 1);
+ ret = key_payload_reserve(key, payload_totallen);
if (ret < 0)
return ERR_PTR(ret);
- epayload = kzalloc(sizeof(*epayload) + payload_datalen +
- datablob_len + HASH_SIZE + 1, GFP_KERNEL);
+ epayload = kzalloc_flex(*epayload, payload_data, payload_totallen,
+ GFP_KERNEL);
if (!epayload)
return ERR_PTR(-ENOMEM);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 206/877] keys: translate request_key_auth pid for the reading procfs instance
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (204 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 205/877] KEYS: encrypted: fix integer overflow of datablob_len Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 207/877] KEYS: trusted: Fix tpm2_load_cmd() boundary check Greg Kroah-Hartman
` (678 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Maoyi Xie, Jarkko Sakkinen
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maoyi Xie <maoyixie.tju@gmail.com>
commit 0d6a4268b06084baafd8ee5d66955c7e1c2e053b upstream.
request_key_auth_describe() prints rka->pid into /proc/keys as a raw
pid_t in the initial pid namespace. A reader can open /proc/keys through
a mount in another pid namespace. That reader sees a number with no
meaning there. The number can even name an unrelated task. The line
needs VIEW on the key. So the reader either shares the key owner's uid
or possesses the key.
The fix keeps a struct pid. Commit 4f82f45730c6 ("net ip6 flowlabel:
Make owner a union of struct pid * and kuid_t") gave
/proc/net/ip6_flowlabel the same storage. The print goes through
pid_nr_ns(). It renders against the pid namespace of the procfs instance
the line is read through. Commit ad08978ab41c ("ipv6/flowlabel: simplify
pid namespace lookup") moved that print to the same anchor. Output
through an initial namespace /proc does not change. The line shows 0 for
a requestor with no number in that namespace.
Translating at read time was the alternative. find_pid_ns() can resolve
a recycled number. The line would then name a live task with no
connection to the key. A stored struct pid gives 0 instead when the
requestor has no number there.
Link: https://lore.kernel.org/keyrings/20260809110202.2180410-1-maoyixie.tju@gmail.com/
Fixes: 78b7280cce23 ("KEYS: Improve /proc/keys")
Cc: stable@vger.kernel.org # v5.10+
Assisted-by: Claude:claude-opus-5 codeql
Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
Link: https://lore.kernel.org/r/20260821095935.1864998-1-maoyixie.tju@gmail.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/keys/request_key_auth-type.h | 2 +-
security/keys/request_key_auth.c | 12 +++++++++---
2 files changed, 10 insertions(+), 4 deletions(-)
--- a/include/keys/request_key_auth-type.h
+++ b/include/keys/request_key_auth-type.h
@@ -22,7 +22,7 @@ struct request_key_auth {
const struct cred *cred;
void *callout_info;
size_t callout_len;
- pid_t pid;
+ struct pid *pid;
char op[8];
} __randomize_layout;
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -9,6 +9,8 @@
#include <linux/sched.h>
#include <linux/err.h>
+#include <linux/pid.h>
+#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
@@ -73,7 +75,10 @@ static void request_key_auth_describe(co
seq_puts(m, "key:");
seq_puts(m, key->description);
if (key_is_positive(key))
- seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len);
+ seq_printf(m, " pid:%d ci:%zu",
+ pid_nr_ns(rka->pid,
+ proc_pid_ns(file_inode(m->file)->i_sb)),
+ rka->callout_len);
}
/*
@@ -113,6 +118,7 @@ static void free_request_key_auth(struct
if (rka->cred)
put_cred(rka->cred);
kfree(rka->callout_info);
+ put_pid(rka->pid);
kfree(rka);
}
@@ -226,14 +232,14 @@ struct key *request_key_auth_new(struct
irka = cred->request_key_auth->payload.data[0];
rka->cred = get_cred(irka->cred);
- rka->pid = irka->pid;
+ rka->pid = get_pid(irka->pid);
up_read(&cred->request_key_auth->sem);
}
else {
/* it isn't - use this process as the context */
rka->cred = get_cred(cred);
- rka->pid = current->pid;
+ rka->pid = get_pid(task_pid(current));
}
rka->target_key = key_get(target);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 207/877] KEYS: trusted: Fix tpm2_load_cmd() boundary check
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (205 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 206/877] keys: translate request_key_auth pid for the reading procfs instance Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 208/877] i2c: at91: release DMA channels on remove and probe error Greg Kroah-Hartman
` (677 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, co+6a581c4284f721d4,
Stefano Garzarella, Srish Srinivasan, Jarkko Sakkinen
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jarkko Sakkinen <jarkko@kernel.org>
commit 114f00d738f15dd8c7318369edcdc53dd6d08763 upstream.
tpm2_load_cmd() does boundary checks against the ASN.1 size i.e.,
payload->blob_len. Address this by passing the decoded blob size to
tpm2_load_cmd(), and use it for the boundary checks.
Cc: stable@vger.kernel.org # v5.13+
Fixes: f2219745250f ("security: keys: trusted: use ASN.1 TPM2 key format for the blobs")
Reported-by: co+6a581c4284f721d4@bugs.sh
Closes: https://bugs.sh/b/6a581c4284f721d4/
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Tested-by: Srish Srinivasan <ssrish@linux.ibm.com>
Link: https://lore.kernel.org/r/20260901205809.2028454-1-jarkko@kernel.org
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
security/keys/trusted-keys/trusted_tpm2.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
--- a/security/keys/trusted-keys/trusted_tpm2.c
+++ b/security/keys/trusted-keys/trusted_tpm2.c
@@ -108,7 +108,7 @@ struct tpm2_key_context {
static int tpm2_key_decode(struct trusted_key_payload *payload,
struct trusted_key_options *options,
- u8 **buf)
+ u8 **buf, unsigned int *blob_len)
{
int ret;
struct tpm2_key_context ctx;
@@ -129,6 +129,7 @@ static int tpm2_key_decode(struct truste
return -ENOMEM;
*buf = blob;
+ *blob_len = ctx.priv_len + ctx.pub_len;
options->keyhandle = ctx.parent;
memcpy(blob, ctx.priv, ctx.priv_len);
@@ -402,10 +403,11 @@ static int tpm2_load_cmd(struct tpm_chip
int rc;
u32 attrs;
- rc = tpm2_key_decode(payload, options, &blob);
+ rc = tpm2_key_decode(payload, options, &blob, &blob_len);
if (rc) {
/* old form */
blob = payload->blob;
+ blob_len = payload->blob_len;
payload->old_format = 1;
} else {
/* Bind for cleanup: */
@@ -417,17 +419,17 @@ static int tpm2_load_cmd(struct tpm_chip
return -EINVAL;
/* must be big enough for at least the two be16 size counts */
- if (payload->blob_len < 4)
+ if (blob_len < 4)
return -EINVAL;
private_len = get_unaligned_be16(blob);
/* must be big enough for following public_len */
- if (private_len + 2 + 2 > (payload->blob_len))
+ if (private_len + 2 + 2 > blob_len)
return -E2BIG;
public_len = get_unaligned_be16(blob + 2 + private_len);
- if (private_len + 2 + public_len + 2 > payload->blob_len)
+ if (private_len + 2 + public_len + 2 > blob_len)
return -E2BIG;
pub = blob + 2 + private_len + 2;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 208/877] i2c: at91: release DMA channels on remove and probe error
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (206 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 207/877] KEYS: trusted: Fix tpm2_load_cmd() boundary check Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 209/877] i2c: atr: fix dangling adapter pointer on add failure Greg Kroah-Hartman
` (676 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shengzhuo Wei, Mukesh Kumar Savaliya,
Andi Shyti
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengzhuo Wei <me@cherr.cc>
commit f7eeb1af8537b05953fb1c88ab8b59d94059a381 upstream.
at91_twi_configure_dma() requests exclusive tx/rx DMA channels, but
nothing ever releases them on driver detach, and the probe error path
after the channels are acquired (i2c_add_numbered_adapter() failure)
returns without releasing them either, because the remove callback is
not invoked after a failed probe.
Move the release into a helper, call it from the existing
configure-failure path, the adapter-registration failure path, and
at91_twi_remove().
Fixes: 60937b2cdbf9 ("i2c: at91: add dma support")
Assisted-by: GLM:5.3
Signed-off-by: Shengzhuo Wei <me@cherr.cc>
Cc: <stable@vger.kernel.org> # v3.8+
Acked-by: Mukesh Kumar Savaliya <mukesh.savaliya@oss.qualcomm.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://patch.msgid.link/20260827-i2c-dma-channel-leak-v1-1-271d4adc03a0@cherr.cc
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/i2c/busses/i2c-at91-core.c | 3 +++
drivers/i2c/busses/i2c-at91-master.c | 12 +++++++++++-
drivers/i2c/busses/i2c-at91.h | 1 +
3 files changed, 15 insertions(+), 1 deletion(-)
--- a/drivers/i2c/busses/i2c-at91-core.c
+++ b/drivers/i2c/busses/i2c-at91-core.c
@@ -255,6 +255,7 @@ static int at91_twi_probe(struct platfor
if (rc) {
pm_runtime_disable(dev->dev);
pm_runtime_set_suspended(dev->dev);
+ at91_twi_dma_release(dev);
return rc;
}
@@ -270,6 +271,8 @@ static void at91_twi_remove(struct platf
i2c_del_adapter(&dev->adapter);
+ at91_twi_dma_release(dev);
+
pm_runtime_disable(dev->dev);
pm_runtime_set_suspended(dev->dev);
}
--- a/drivers/i2c/busses/i2c-at91-master.c
+++ b/drivers/i2c/busses/i2c-at91-master.c
@@ -817,11 +817,21 @@ static int at91_twi_configure_dma(struct
error:
if (ret != -EPROBE_DEFER)
dev_info(dev->dev, "can't get DMA channel, continue without DMA support\n");
+ at91_twi_dma_release(dev);
+ return ret;
+}
+
+void at91_twi_dma_release(struct at91_twi_dev *dev)
+{
+ struct at91_twi_dma *dma = &dev->dma;
+
if (dma->chan_rx)
dma_release_channel(dma->chan_rx);
if (dma->chan_tx)
dma_release_channel(dma->chan_tx);
- return ret;
+ dma->chan_rx = NULL;
+ dma->chan_tx = NULL;
+ dev->use_dma = false;
}
static int at91_init_twi_recovery_gpio(struct platform_device *pdev,
--- a/drivers/i2c/busses/i2c-at91.h
+++ b/drivers/i2c/busses/i2c-at91.h
@@ -172,6 +172,7 @@ void at91_twi_irq_restore(struct at91_tw
void at91_init_twi_bus(struct at91_twi_dev *dev);
void at91_init_twi_bus_master(struct at91_twi_dev *dev);
+void at91_twi_dma_release(struct at91_twi_dev *dev);
int at91_twi_probe_master(struct platform_device *pdev, u32 phy_addr,
struct at91_twi_dev *dev);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 209/877] i2c: atr: fix dangling adapter pointer on add failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (207 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 208/877] i2c: at91: release DMA channels on remove and probe error Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 210/877] i2c: imx: release DMA channels on probe error Greg Kroah-Hartman
` (675 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Linkai Gong, Andy Shevchenko,
Andi Shyti
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linkai Gong <gonglinkai@kylinos.cn>
commit ad34235808b63a70ca4989b7a2852923193d06ef upstream.
i2c_atr_add_adapter() stores atr->adapter[chan_id] before
i2c_add_adapter() so that the I2C bus notifier can match child clients
during registration. On failure the channel is freed but the slot was
left pointing at freed memory, which can lead to use-after-free in
i2c_atr_del_adapter() / cleanup and also block reuse with -EEXIST.
Clear the slot on the i2c_add_adapter() error path before freeing chan.
Fixes: a076a860acae ("media: i2c: add I2C Address Translator (ATR) support")
Signed-off-by: Linkai Gong <gonglinkai@kylinos.cn>
Cc: <stable@vger.kernel.org> # v6.6+
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://patch.msgid.link/20260907071102.1080840-1-gonglinkai@kylinos.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/i2c/i2c-atr.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/i2c/i2c-atr.c
+++ b/drivers/i2c/i2c-atr.c
@@ -632,6 +632,7 @@ int i2c_atr_add_adapter(struct i2c_atr *
ret = i2c_add_adapter(&chan->adap);
if (ret) {
+ atr->adapter[chan_id] = NULL;
dev_err(dev, "failed to add atr-adapter %u (error=%d)\n",
chan_id, ret);
goto err_fwnode_put;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 210/877] i2c: imx: release DMA channels on probe error
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (208 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 209/877] i2c: atr: fix dangling adapter pointer on add failure Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 211/877] i2c: imx: disable autosuspend on remove Greg Kroah-Hartman
` (674 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Shengzhuo Wei, Frank Li, Andi Shyti
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengzhuo Wei <me@cherr.cc>
commit e9f03b9625e2eeaca357b065c92d5b14064a1583 upstream.
i2c_imx_dma_request() acquires exclusive tx/rx DMA channels and is
optional: on errors other than -EPROBE_DEFER the driver falls back to
PIO mode and probe continues. If i2c_add_numbered_adapter() then fails,
probe returns through clk_notifier_unregister without releasing the
channels, because the remove callback is not invoked after a failed
probe.
Release the channels on the probe error path, mirroring
i2c_imx_remove().
Fixes: ce1a78840ff7 ("i2c: imx: add DMA support for freescale i2c driver")
Assisted-by: GLM:5.3
Signed-off-by: Shengzhuo Wei <me@cherr.cc>
Cc: <stable@vger.kernel.org> # v3.19+
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://patch.msgid.link/20260827-i2c-dma-channel-leak-v1-2-271d4adc03a0@cherr.cc
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/i2c/busses/i2c-imx.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -1557,6 +1557,8 @@ static int i2c_imx_probe(struct platform
clk_notifier_unregister:
clk_notifier_unregister(i2c_imx->clk, &i2c_imx->clk_change_nb);
+ if (i2c_imx->dma)
+ i2c_imx_dma_free(i2c_imx);
free_irq(irq, i2c_imx);
rpm_disable:
pm_runtime_put_noidle(&pdev->dev);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 211/877] i2c: imx: disable autosuspend on remove
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (209 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 210/877] i2c: imx: release DMA channels on probe error Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 212/877] IB/mlx4: Fix use-after-free on pkey sysfs registration failure Greg Kroah-Hartman
` (673 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Frank Li, Andi Shyti
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <lgs201920130244@gmail.com>
commit e0c3e9d76adbe522dd420a766ce42d03ce887c29 upstream.
i2c_imx_probe() enables runtime PM autosuspend with
pm_runtime_use_autosuspend(). The probe error path correctly undoes
this setting with pm_runtime_dont_use_autosuspend(), but the normal
remove path only disables runtime PM.
The runtime PM API requires pm_runtime_use_autosuspend() to be undone
with pm_runtime_dont_use_autosuspend() at driver exit unless runtime PM
was enabled with devm_pm_runtime_enable(). Leaving the autosuspend flag
set therefore leaves the runtime PM state incompletely cleaned up after
the driver is unbound.
Add the missing pm_runtime_dont_use_autosuspend() call to the remove
path.
This issue was found by manual code inspection.
Fixes: 588eb93ea49f ("i2c: imx: add runtime pm support to improve the performance")
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Cc: <stable@vger.kernel.org> # v4.5+
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://patch.msgid.link/20260914091544.1667137-1-lgs201920130244@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/i2c/busses/i2c-imx.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -1599,6 +1599,7 @@ static void i2c_imx_remove(struct platfo
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
}
static int i2c_imx_runtime_suspend(struct device *dev)
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 212/877] IB/mlx4: Fix use-after-free on pkey sysfs registration failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (210 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 211/877] i2c: imx: disable autosuspend on remove Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 213/877] IB/hfi1: Resolve the credit-return buffer through the send contexts node Greg Kroah-Hartman
` (672 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Shuangpeng Bai, Leon Romanovsky
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
commit 1af874e9f4ce22ccf8b10ab5462f32c70d3be21a upstream.
register_pkey_tree() ignores errors from register_one_pkey_tree() and
continues registering the remaining slaves. The per-slave error path has
already released the pkey parent kobjects, but their pointers remain
stored in the device. A later device cleanup therefore passes the stale
pointers to kobject_put(), causing a use-after-free.
Clear the parent pointers after releasing a failed slave tree and skip
unregistered trees during device cleanup. This preserves the existing
best-effort registration behavior while preventing a second cleanup of
the failed tree.
Fixes: c1e7e466120b ("IB/mlx4: Add iov directory in sysfs under the ib device")
Cc: stable@vger.kernel.org
Signed-off-by: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
Link: https://patch.msgid.link/20260816044510.3848996-1-shuangpeng.kernel@gmail.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/infiniband/hw/mlx4/sysfs.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/infiniband/hw/mlx4/sysfs.c
+++ b/drivers/infiniband/hw/mlx4/sysfs.c
@@ -753,11 +753,13 @@ err_add:
kobject_put(p);
}
kobject_put(dev->dev_ports_parent[slave]);
+ dev->dev_ports_parent[slave] = NULL;
err_ports:
kobject_put(dev->pkeys.device_parent[slave]);
/* extra put for the device_parent create_and_add */
kobject_put(dev->pkeys.device_parent[slave]);
+ dev->pkeys.device_parent[slave] = NULL;
fail_dev:
kobject_put(dev->iov_parent);
@@ -787,6 +789,8 @@ static void unregister_pkey_tree(struct
return;
for (slave = device->dev->persist->num_vfs; slave >= 0; --slave) {
+ if (!device->pkeys.device_parent[slave])
+ continue;
list_for_each_entry_safe(p, t,
&device->pkeys.pkey_port_list[slave],
entry) {
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 213/877] IB/hfi1: Resolve the credit-return buffer through the send contexts node
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (211 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 212/877] IB/mlx4: Fix use-after-free on pkey sysfs registration failure Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 214/877] IB/hfi1: Fix the PIO_CRED credit-return mmap Greg Kroah-Hartman
` (671 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Shuhei Takeshita, Leon Romanovsky
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shuhei Takeshita <jyohuku.alterego@gmail.com>
commit 975396b9e5a4028e649f4b9a6a5ca5dfb76a824b upstream.
hfi1_file_mmap()'s PIO_CRED case derives this context's credit-return
page offset, and the DMA handle for it, from dd->cr_base[uctxt->numa_id].
uctxt->numa_id is the node of whichever CPU the process happened to be
running on, but the entry itself lives in the credit-return allocation of
the send context's own node:
sc->hw_free = &sc->dd->cr_base[sc->node].va[gc].cr[index];
and user send contexts are allocated with sc_alloc(dd, SC_USER, ...,
dd->node), the HFI-local node. On a multi-socket host with the process
running off that node the two allocations differ, so the subtraction
produces an offset into an unrelated buffer and the DMA handle belongs to
the wrong allocation.
Use the send context's own node for all three references. The
continuation lines are reindented at the same time; they mixed spaces and
tabs.
Fixes: 7724105686e7 ("IB/hfi1: add driver files")
Cc: stable@vger.kernel.org
Signed-off-by: Shuhei Takeshita <jyohuku.alterego@gmail.com>
Link: https://patch.msgid.link/20260809032743.2671579-2-jyohuku.alterego@gmail.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/infiniband/hw/hfi1/file_ops.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/infiniband/hw/hfi1/file_ops.c
+++ b/drivers/infiniband/hw/hfi1/file_ops.c
@@ -382,10 +382,10 @@ static int hfi1_file_mmap(struct file *f
* of enabled contexts > 64 and 128 respectively).
*/
cr_page_offset = ((u64)uctxt->sc->hw_free -
- (u64)dd->cr_base[uctxt->numa_id].va) &
- PAGE_MASK;
- memvirt = dd->cr_base[uctxt->numa_id].va + cr_page_offset;
- memdma = dd->cr_base[uctxt->numa_id].dma + cr_page_offset;
+ (u64)dd->cr_base[uctxt->sc->node].va) &
+ PAGE_MASK;
+ memvirt = dd->cr_base[uctxt->sc->node].va + cr_page_offset;
+ memdma = dd->cr_base[uctxt->sc->node].dma + cr_page_offset;
memlen = PAGE_SIZE;
flags &= ~VM_MAYWRITE;
flags |= VM_DONTCOPY | VM_DONTEXPAND;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 214/877] IB/hfi1: Fix the PIO_CRED credit-return mmap
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (212 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 213/877] IB/hfi1: Resolve the credit-return buffer through the send contexts node Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 215/877] selinux: preserve user SID across nested backing files Greg Kroah-Hartman
` (670 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Shuhei Takeshita, Leon Romanovsky
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shuhei Takeshita <jyohuku.alterego@gmail.com>
commit 62f0f34fbd2b2d5653d33d3b9d42fdcabb1c0101 upstream.
hfi1_file_mmap()'s PIO_CRED case must hand user space the single
credit-return page that holds this context's entry. That page is the
second or third page of the per-node credit-return allocation once the
hardware send context index reaches 64 or 128, so the failure below is
intermittent: when the entry lands on the first page the offset is zero
and everything works.
Two things are wrong.
First, cr_page_offset is a byte offset but .va is a struct
credit_return *, so adding it is pointer arithmetic and scales the offset
by sizeof(struct credit_return) == 64. memvirt then lands 256 KiB or
512 KiB past a 10240-byte allocation. With an IOMMU translating, that
address is inside the vmalloc range but in no vm_area, so
dma_mmap_coherent() -> iommu_dma_mmap() finds no pages, vmalloc_to_pfn()
returns page_to_pfn(NULL), and remap_pfn_range() installs a frame above
MAXPHYADDR. The first user read then takes:
psm2_ep_open_pr: Corrupted page table at address 7a14d007e000
PGD 800000013886a067 P4D 800000013886a067 PUD 13886b067 PMD 13886c067
PTE 800049168e911235
Oops: Bad pagetable: 000d [#1] SMP PTI
Second, and still wrong once the arithmetic is corrected,
dma_mmap_coherent() describes a whole coherent buffer and selects the
page within it with vma->vm_pgoff. Offsetting cpu_addr has no effect:
for a vmap'd allocation iommu_dma_mmap() uses cpu_addr only to locate the
vm_area and then maps pages[vm_pgoff], which hfi1_file_mmap() has just
set to 0. User space therefore always receives the first credit-return
page, every credit read is for the wrong context, and send PIO stalls
forever.
Use the DMA API as intended: pass the base of the allocation with its
full length and select the page with vm_pgoff. A separate length is
needed because memlen must keep describing the VMA for the existing size
check. The dma-direct path stays correct as well, since dma_direct_mmap()
adds the same vm_pgoff to the base pfn.
Tested on a Dell T7610 (Xeon E5-2650 v2, Intel IOMMU in DMA-FQ mode)
against a Threadripper PRO 3995WX peer, both Omni-Path 100. Before this
change psm2_ep_open() Oopses the kernel; with only the arithmetic
corrected psm2_ep_open() succeeds but any transfer that uses send PIO
hangs, PSM2_SDMA=2 (send PIO disabled) completing normally while
PSM2_SDMA=0 (send PIO only) hangs every time. With this change send PIO,
send DMA and the default mixed mode all work.
Fixes: 1ec82317a1da ("IB/hfi1: Use dma_mmap_coherent for matching buffers")
Cc: stable@vger.kernel.org
Signed-off-by: Shuhei Takeshita <jyohuku.alterego@gmail.com>
Link: https://patch.msgid.link/20260809032743.2671579-3-jyohuku.alterego@gmail.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/infiniband/hw/hfi1/file_ops.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
--- a/drivers/infiniband/hw/hfi1/file_ops.c
+++ b/drivers/infiniband/hw/hfi1/file_ops.c
@@ -326,6 +326,7 @@ static int hfi1_file_mmap(struct file *f
void *memvirt = NULL;
dma_addr_t memdma = 0;
u8 subctxt, mapio = 0, vmf = 0, type;
+ size_t memdmalen = 0;
ssize_t memlen = 0;
int ret = 0;
u16 ctxt;
@@ -371,7 +372,9 @@ static int hfi1_file_mmap(struct file *f
mapio = 1;
break;
case PIO_CRED: {
+ struct credit_return_base *cr = &dd->cr_base[uctxt->sc->node];
u64 cr_page_offset;
+
if (flags & VM_WRITE) {
ret = -EPERM;
goto done;
@@ -381,11 +384,18 @@ static int hfi1_file_mmap(struct file *f
* second or third page allocated for credit returns (if number
* of enabled contexts > 64 and 128 respectively).
*/
- cr_page_offset = ((u64)uctxt->sc->hw_free -
- (u64)dd->cr_base[uctxt->sc->node].va) &
+ cr_page_offset = ((u64)uctxt->sc->hw_free - (u64)cr->va) &
PAGE_MASK;
- memvirt = dd->cr_base[uctxt->sc->node].va + cr_page_offset;
- memdma = dd->cr_base[uctxt->sc->node].dma + cr_page_offset;
+ /*
+ * dma_mmap_coherent() describes the whole coherent buffer and
+ * selects the page within it with vma->vm_pgoff, so pass the
+ * base of the allocation and its length and let vm_pgoff pick
+ * the page.
+ */
+ vma->vm_pgoff = cr_page_offset >> PAGE_SHIFT;
+ memvirt = cr->va;
+ memdma = cr->dma;
+ memdmalen = TXE_NUM_CONTEXTS * sizeof(struct credit_return);
memlen = PAGE_SIZE;
flags &= ~VM_MAYWRITE;
flags |= VM_DONTCOPY | VM_DONTEXPAND;
@@ -567,7 +577,8 @@ static int hfi1_file_mmap(struct file *f
ret = 0;
} else if (memdma) {
ret = dma_mmap_coherent(&dd->pcidev->dev, vma,
- memvirt, memdma, memlen);
+ memvirt, memdma,
+ memdmalen ? memdmalen : memlen);
} else if (mapio) {
ret = io_remap_pfn_range(vma, vma->vm_start,
PFN_DOWN(memaddr),
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 215/877] selinux: preserve user SID across nested backing files
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (213 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 214/877] IB/hfi1: Fix the PIO_CRED credit-return mmap Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 216/877] selinux: recheck intermediate backing files on mprotect() Greg Kroah-Hartman
` (669 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Amir Goldstein,
Stephen Smalley, Paul Moore
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
commit 8c0c602202b9a4909b00bc3354e3c0355bc69e65 upstream.
SELinux saves the user file SID in a backing-file security blob so it
remains available after mmap() replaces vma->vm_file with a backing file.
For nested backing files (overlayfs over overlayfs, or FUSE passthrough
backed by overlayfs), user_file may itself be a backing file. Its
fsec->sid is the SID of the mounter that opened it, rather than the user
that opened the top-level file. mprotect() then checks fd { use } against
the mounter SID. This can incorrectly deny access without a domain
transition, or check the wrong target SID after one.
Copy the saved user SID when user_file is a backing file. Keep using the
regular file SID for the first backing layer.
With two nested overlayfs mounts and SELinux enforcing,
mprotect(PROT_READ) returns EACCES with an fd { use } denial against the
mounter SID. With this change, mprotect() succeeds.
Tested on arm64 QEMU with a small BusyBox initramfs and a purpose-built
SELinux policy. The original test was also repeated with Fedora Cloud
Base 44 userspace and gave the same result.
Cc: stable@vger.kernel.org
Fixes: 82544d36b172 ("selinux: fix overlayfs mmap() and mprotect() access checks")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
security/selinux/hooks.c | 9 ++++++++-
security/selinux/include/objsec.h | 2 +-
2 files changed, 9 insertions(+), 2 deletions(-)
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3676,13 +3676,20 @@ static int selinux_file_alloc_security(s
return 0;
}
+static inline u32 selinux_file_user_sid(const struct file *file)
+{
+ if (unlikely(file->f_mode & FMODE_BACKING))
+ return selinux_backing_file(file)->uf_sid;
+ return selinux_file(file)->sid;
+}
+
static int selinux_backing_file_alloc(struct file *backing_file,
const struct file *user_file)
{
struct backing_file_security_struct *bfsec;
bfsec = selinux_backing_file(backing_file);
- bfsec->uf_sid = selinux_file(user_file)->sid;
+ bfsec->uf_sid = selinux_file_user_sid(user_file);
return 0;
}
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -62,7 +62,7 @@ struct file_security_struct {
};
struct backing_file_security_struct {
- u32 uf_sid; /* associated user file fsec->sid */
+ u32 uf_sid; /* top-level user file fsec->sid */
};
struct superblock_security_struct {
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 216/877] selinux: recheck intermediate backing files on mprotect()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (214 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 215/877] selinux: preserve user SID across nested backing files Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 217/877] selinux: always fill AVC decision in avc_has_perm_noaudit() Greg Kroah-Hartman
` (668 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Stephen Smalley,
Paul Moore
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
commit 78fc54b934bfb2c18aad8154c7302067146946f9 upstream.
mprotect() can be used to bypass the SELinux checks that mmap() performs
against the intermediate layers of a stacked filesystem.
mmap() checks every backing layer as the request descends through the
stack. mprotect() only has the lowest backing file in vma->vm_file, so it
rechecks the top-level user and the lowest mounter, but skips the mounters
of every layer in between. With two nested overlayfs mounts and a policy
denying mounter_t -> middle_file_t:file { execute }, a direct
mmap(PROT_EXEC) is denied:
avc: denied { execute } for pid=71 comm="nested_exec"
path="/payload" dev="overlay" ino=9
scontext=user_u:base_r:mounter_t
tcontext=user_u:object_r:middle_file_t tclass=file permissive=0
while mmap(PROT_NONE) followed by mprotect(PROT_EXEC) succeeds.
Preserve each intermediate path, mounter SID and file-description SID in
the backing-file security blob, copying the saved entries when another
backing layer is opened. Allocate the array only for nested backing files,
and release it and the path references in the backing_file_free hook.
During mprotect(), recheck fd { use } and the requested inode permissions
for every saved mounter, and include the intermediate layers in the execmod
checks. Policy for nested stacking may then need to grant intermediate
mounters what a direct mmap() already requires, and execmod on intermediate
labels for binaries using text relocations.
Tested on arm64 QEMU with a small BusyBox initramfs and a purpose-built
SELinux policy, on a mainline tree containing
commit f2381b546e7e ("fs: fix user path of nested backing files").
Cc: stable@vger.kernel.org
Fixes: 82544d36b172 ("selinux: fix overlayfs mmap() and mprotect() access checks")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Stephen Smalley <stephen.smalley.work@gmail.com>
[PM: subject tweak]
Signed-off-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
security/selinux/hooks.c | 141 +++++++++++++++++++++++++++++++++-----
security/selinux/include/objsec.h | 8 ++
2 files changed, 133 insertions(+), 16 deletions(-)
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1656,26 +1656,32 @@ static int cred_has_capability(const str
return rc;
}
-/* Check whether a task has a particular permission to an inode.
- The 'adp' parameter is optional and allows other audit
- data to be passed (e.g. the dentry). */
-static int inode_has_perm(const struct cred *cred,
- struct inode *inode,
- u32 perms,
- struct common_audit_data *adp)
+/*
+ * Check whether a SID has a particular permission to an inode. The 'adp'
+ * parameter is optional and allows other audit data to be passed (e.g. the
+ * dentry).
+ */
+static int inode_sid_has_perm(u32 sid, struct inode *inode, u32 perms,
+ struct common_audit_data *adp)
{
struct inode_security_struct *isec;
- u32 sid;
if (unlikely(IS_PRIVATE(inode)))
return 0;
- sid = cred_sid(cred);
isec = selinux_inode(inode);
return avc_has_perm(sid, isec->sid, isec->sclass, perms, adp);
}
+static int inode_has_perm(const struct cred *cred,
+ struct inode *inode,
+ u32 perms,
+ struct common_audit_data *adp)
+{
+ return inode_sid_has_perm(cred_sid(cred), inode, perms, adp);
+}
+
/* Same as inode_has_perm, but pass explicit audit data containing
the dentry to help the auditing code to more easily generate the
pathname if needed. */
@@ -3687,13 +3693,63 @@ static int selinux_backing_file_alloc(st
const struct file *user_file)
{
struct backing_file_security_struct *bfsec;
+ const struct backing_file_security_struct *ubfsec;
+ struct backing_file_security_layer *layer;
+ u32 i;
bfsec = selinux_backing_file(backing_file);
bfsec->uf_sid = selinux_file_user_sid(user_file);
+ if (!(user_file->f_mode & FMODE_BACKING))
+ return 0;
+
+ ubfsec = selinux_backing_file(user_file);
+ /* a wrapped count would make kmalloc_array() return ZERO_SIZE_PTR */
+ if (unlikely(ubfsec->layer_count == U32_MAX))
+ return -EOVERFLOW;
+
+ /*
+ * The final VMA only retains the lowest backing file, so record the
+ * whole chain here rather than in the mmap hook, where concurrent
+ * mappings would have to be serialized. Size it dynamically: erofs
+ * inode sharing adds a backing file without bumping s_stack_depth.
+ */
+ bfsec->layers = kmalloc_array(ubfsec->layer_count + 1,
+ sizeof(*bfsec->layers), GFP_KERNEL);
+ if (!bfsec->layers)
+ return -ENOMEM;
+
+ for (i = 0; i < ubfsec->layer_count; i++) {
+ layer = &bfsec->layers[i];
+ *layer = ubfsec->layers[i];
+ path_get(&layer->path);
+ }
+
+ /* f_path, not file_user_path(): this layer, not the top-level file */
+ layer = &bfsec->layers[i];
+ layer->path = user_file->f_path;
+ layer->mounter_sid = cred_sid(user_file->f_cred);
+ layer->fd_sid = selinux_file(user_file)->sid;
+ path_get(&layer->path);
+ bfsec->layer_count = ubfsec->layer_count + 1;
return 0;
}
+static void selinux_backing_file_free(struct file *backing_file)
+{
+ struct backing_file_security_struct *bfsec;
+
+ /* security_backing_file_free() may be called twice after an error */
+ if (!backing_file_security(backing_file))
+ return;
+
+ bfsec = selinux_backing_file(backing_file);
+ while (bfsec->layer_count)
+ path_put(&bfsec->layers[--bfsec->layer_count].path);
+ kfree(bfsec->layers);
+ bfsec->layers = NULL;
+}
+
/*
* Check whether a task has the ioctl permission and cmd
* operation to an inode.
@@ -3811,6 +3867,53 @@ static int selinux_file_ioctl_compat(str
static int default_noexec __ro_after_init;
+static u32 file_map_prot_to_av(unsigned long prot, bool shared)
+{
+ u32 av = FILE__READ;
+
+ if (shared && (prot & PROT_WRITE))
+ av |= FILE__WRITE;
+ if (prot & PROT_EXEC)
+ av |= FILE__EXECUTE;
+
+ return av;
+}
+
+static int backing_mounters_has_perm(const struct file *file, u32 av)
+{
+ const struct backing_file_security_struct *bfsec;
+ const struct backing_file_security_layer *layer;
+ struct common_audit_data ad;
+ struct inode *inode;
+ u32 i;
+ int rc;
+
+ if (WARN_ON_ONCE(!(file->f_mode & FMODE_BACKING)))
+ return -EIO;
+
+ bfsec = selinux_backing_file(file);
+ for (i = 0; i < bfsec->layer_count; i++) {
+ layer = &bfsec->layers[i];
+ inode = d_inode(layer->path.dentry);
+
+ ad.type = LSM_AUDIT_DATA_PATH;
+ ad.u.path = layer->path;
+
+ if (layer->mounter_sid != layer->fd_sid) {
+ rc = avc_has_perm(layer->mounter_sid, layer->fd_sid,
+ SECCLASS_FD, FD__USE, &ad);
+ if (rc)
+ return rc;
+ }
+
+ rc = inode_sid_has_perm(layer->mounter_sid, inode, av, &ad);
+ if (rc)
+ return rc;
+ }
+
+ return 0;
+}
+
static int __file_map_prot_check(const struct file *file, unsigned long prot,
bool shared, bool mounter_check,
bool bf_user_file)
@@ -3844,14 +3947,10 @@ static int __file_map_prot_check(const s
if (file) {
const struct cred *cred = mounter_check ?
file->f_cred : current_cred();
- /* "read" always possible, "write" only if shared */
- u32 av = FILE__READ;
- if (shared && prot_write)
- av |= FILE__WRITE;
- if (prot_exec)
- av |= FILE__EXECUTE;
- return __file_has_perm(cred, file, av, bf_user_file);
+ return __file_has_perm(cred, file,
+ file_map_prot_to_av(prot, shared),
+ bf_user_file);
}
return 0;
@@ -3946,6 +4045,7 @@ static int selinux_file_mprotect(struct
int rc;
const struct cred *cred = current_cred();
u32 sid = cred_sid(cred);
+ u32 av;
const struct file *file = vma->vm_file;
bool backing_file;
bool shared = vma->vm_flags & VM_SHARED;
@@ -3989,6 +4089,10 @@ static int selinux_file_mprotect(struct
if (rc)
return rc;
if (backing_file) {
+ rc = backing_mounters_has_perm(file,
+ FILE__EXECMOD);
+ if (rc)
+ return rc;
rc = file_has_perm(file->f_cred, file,
FILE__EXECMOD);
if (rc)
@@ -4001,6 +4105,10 @@ static int selinux_file_mprotect(struct
if (rc)
return rc;
if (backing_file) {
+ av = file_map_prot_to_av(prot, shared);
+ rc = backing_mounters_has_perm(file, av);
+ if (rc)
+ return rc;
rc = file_map_prot_check(file, prot, shared, true);
if (rc)
return rc;
@@ -7309,6 +7417,7 @@ static struct security_hook_list selinux
LSM_HOOK_INIT(file_permission, selinux_file_permission),
LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security),
LSM_HOOK_INIT(backing_file_alloc, selinux_backing_file_alloc),
+ LSM_HOOK_INIT(backing_file_free, selinux_backing_file_free),
LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl),
LSM_HOOK_INIT(file_ioctl_compat, selinux_file_ioctl_compat),
LSM_HOOK_INIT(mmap_file, selinux_mmap_file),
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -61,8 +61,16 @@ struct file_security_struct {
u32 pseqno; /* Policy seqno at the time of file open */
};
+struct backing_file_security_layer {
+ struct path path; /* this layer's real path */
+ u32 mounter_sid; /* SID of the mounter that opened it */
+ u32 fd_sid; /* SID of its open file description */
+};
+
struct backing_file_security_struct {
u32 uf_sid; /* top-level user file fsec->sid */
+ u32 layer_count; /* number of intermediate backing files */
+ struct backing_file_security_layer *layers;
};
struct superblock_security_struct {
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 217/877] selinux: always fill AVC decision in avc_has_perm_noaudit()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (215 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 216/877] selinux: recheck intermediate backing files on mprotect() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 218/877] power: sequencing: dont call .post_enable() if pwrseq_unit_enable() failed Greg Kroah-Hartman
` (667 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Göttsche,
Stephen Smalley, Paul Moore
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Göttsche <cgzones@googlemail.com>
commit 8861db305103107199b1426f25fde1fb6d465583 upstream.
avc_has_perm_noaudit() is documented to return a copy of the access
decision in @avd, but its early return for an empty requested permission
set leaves the buffer untouched. All callers pass an uninitialized
stack variable and afterwards feed it to avc_audit(), and the inode hook
even stores it in the per-task decision cache.
Fill in a deny-all, audit-all decision, similar to avd_init(), so every
caller receives a defined value at no cost on the hot path.
Cc: stable@vger.kernel.org
Fixes: e6f2f381e4015386 ("selinux: replace BUG_ONs with WARN_ONs in avc.c")
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Reviewed-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
security/selinux/avc.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -1143,8 +1143,11 @@ inline int avc_has_perm_noaudit(u32 ssid
u32 denied;
struct avc_node *node;
- if (WARN_ON(!requested))
+ if (WARN_ON(!requested)) {
+ /* Provide a deny-all, audit-all decision to the caller. */
+ *avd = (struct av_decision){ .auditdeny = 0xffffffff };
return -EACCES;
+ }
rcu_read_lock();
node = avc_lookup(ssid, tsid, tclass);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 218/877] power: sequencing: dont call .post_enable() if pwrseq_unit_enable() failed
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (216 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 217/877] selinux: always fill AVC decision in avc_has_perm_noaudit() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 219/877] power: sequencing: fix NULL-pointer dereference in pwrseq_unit_new() Greg Kroah-Hartman
` (666 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bartosz Golaszewski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
commit 5f90f85eae4e9d2e9628b2019870994ba830b533 upstream.
If the call to pwrseq_unit_enable() failed in pwrseq_enable(), bail out
instead of calling target->post_enable() which assumes the target was
successfully enabled.
Fixes: 249ebf3f65f8 ("power: sequencing: implement the pwrseq core")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260909-pwrseq-kunit-v2-1-ef496afc89d2@oss.qualcomm.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/power/sequencing/core.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/power/sequencing/core.c
+++ b/drivers/power/sequencing/core.c
@@ -913,6 +913,8 @@ int pwrseq_power_on(struct pwrseq_desc *
if (!ret)
desc->powered_on = true;
}
+ if (ret)
+ return ret;
if (target->post_enable) {
ret = target->post_enable(pwrseq);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 219/877] power: sequencing: fix NULL-pointer dereference in pwrseq_unit_new()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (217 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 218/877] power: sequencing: dont call .post_enable() if pwrseq_unit_enable() failed Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 220/877] power: sequencing: fix NULL-pointer dereference in pwrseq_device_register() Greg Kroah-Hartman
` (665 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, sashiko-bot, Bartosz Golaszewski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
commit 115b303e8e093d964089ec6f3c40d984d77b33d0 upstream.
If memory allocation fails in pwrseq_unit_setup_deps(), pwrseq_unit_put()
is called to release the partially initialized unit. However, we've
never initialized unit->list and pwrseq_unit_release() will
unconditionally call list_del() on it. Initialize unit->list right after
allocating the unit struct.
Fixes: 249ebf3f65f8 ("power: sequencing: implement the pwrseq core")
Cc: stable@vger.kernel.org
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260903-pwrseq-kunit-v1-0-1f893d2cabc2%40oss.qualcomm.com?part=1
Link: https://patch.msgid.link/20260909-pwrseq-kunit-v2-2-ef496afc89d2@oss.qualcomm.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/power/sequencing/core.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/power/sequencing/core.c
+++ b/drivers/power/sequencing/core.c
@@ -101,6 +101,7 @@ static struct pwrseq_unit *pwrseq_unit_n
}
kref_init(&unit->ref);
+ INIT_LIST_HEAD(&unit->list);
INIT_LIST_HEAD(&unit->deps);
unit->enable = data->enable;
unit->disable = data->disable;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 220/877] power: sequencing: fix NULL-pointer dereference in pwrseq_device_register()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (218 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 219/877] power: sequencing: fix NULL-pointer dereference in pwrseq_unit_new() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 221/877] mmc: core: Cancel SDIO IRQ work before freeing host Greg Kroah-Hartman
` (664 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, sashiko-bot, Bartosz Golaszewski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
commit 242da4318d97380741516b595af3920207b2f0f1 upstream.
If dev_set_name() fails in pwrseq_device_register(), we jump to the
err_put_pwrseq label before initializing pwrseq->targets.
pwrseq_release() will try to iterate over targets unconditionally and
subsequently dereference an invalid pointer. Move the call to
dev_set_name() after the list head is initialized.
Fixes: 249ebf3f65f8 ("power: sequencing: implement the pwrseq core")
Cc: stable@vger.kernel.org
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260903-pwrseq-kunit-v1-0-1f893d2cabc2%40oss.qualcomm.com?part=2
Link: https://patch.msgid.link/20260909-pwrseq-kunit-v2-3-ef496afc89d2@oss.qualcomm.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/power/sequencing/core.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/power/sequencing/core.c b/drivers/power/sequencing/core.c
index 7751ce8cd8f5..392d72537485 100644
--- a/drivers/power/sequencing/core.c
+++ b/drivers/power/sequencing/core.c
@@ -505,10 +505,6 @@ pwrseq_device_register(const struct pwrseq_config *config)
*/
device_initialize(&pwrseq->dev);
- ret = dev_set_name(&pwrseq->dev, "pwrseq.%d", pwrseq->id);
- if (ret)
- goto err_put_pwrseq;
-
pwrseq->owner = config->owner ?: THIS_MODULE;
pwrseq->match = config->match;
@@ -517,6 +513,10 @@ pwrseq_device_register(const struct pwrseq_config *config)
INIT_LIST_HEAD(&pwrseq->targets);
INIT_LIST_HEAD(&pwrseq->units);
+ ret = dev_set_name(&pwrseq->dev, "pwrseq.%d", pwrseq->id);
+ if (ret)
+ goto err_put_pwrseq;
+
ret = pwrseq_setup_targets(config->targets, pwrseq);
if (ret)
goto err_put_pwrseq;
--
2.55.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 221/877] mmc: core: Cancel SDIO IRQ work before freeing host
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (219 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 220/877] power: sequencing: fix NULL-pointer dereference in pwrseq_device_register() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 222/877] mmc: core: Fix OF node reference leak on card add failure Greg Kroah-Hartman
` (663 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu, Ulf Hansson
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
commit 6feadbecdae60a6324c967f3b1493741083793a3 upstream.
A host controller that uses sdio_signal_irq() schedules host->sdio_irq_work
from its interrupt handler. That work is only cancelled on the suspend
path (mmc_sdio_suspend()), not on the remove/free path, so a worker armed
just before the controller freed its IRQ can run after
mmc_host_classdev_release() has freed the host and dereference it through
container_of().
Cancel host->sdio_irq_work in mmc_free_host(), like the existing
host->detect drain added by commit 1036f69e2513 ("mmc: core: Cancel
delayed work before releasing host").
This issue was found by an in-house static analysis tool.
Fixes: 682696605c70 ("mmc: sdio: Add API to manage SDIO IRQs from a workqueue")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/core/host.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -690,6 +690,7 @@ EXPORT_SYMBOL(mmc_remove_host);
void mmc_free_host(struct mmc_host *host)
{
cancel_delayed_work_sync(&host->detect);
+ cancel_work_sync(&host->sdio_irq_work);
mmc_pwrseq_free(host);
put_device(&host->class_dev);
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 222/877] mmc: core: Fix OF node reference leak on card add failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (220 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 221/877] mmc: core: Cancel SDIO IRQ work before freeing host Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 223/877] mmc: hsq: Fix use-after-free in retry work Greg Kroah-Hartman
` (662 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Zhu Ling, Shawn Lin, Ulf Hansson
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhu Ling <zhuling0805@qq.com>
commit 08b54e16d547d5c1aa61bf7a3595bb1620975eeb upstream.
mmc_of_find_child_device() returns a device node with its reference count
incremented. mmc_add_card() stores the reference before calling
device_add(), while the card is marked present only after device_add()
succeeds.
If device_add() fails, the callers release the card through
mmc_remove_card(). However, mmc_remove_card() only drops the OF node
reference for a present card, leaking the reference on this error path.
Move of_node_put() outside the present-card conditional so the reference
is released for both registered cards and card-add failures.
Fixes: 25185f3f31c9 ("mmc: Add SDIO function devicetree subnode parsing")
Cc: stable@vger.kernel.org
Signed-off-by: Zhu Ling <zhuling0805@qq.com>
Reviewed-by: Shawn Lin <shawn.lin@linux.dev>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/core/bus.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -399,8 +399,8 @@ void mmc_remove_card(struct mmc_card *ca
mmc_hostname(card->host), card->rca);
}
device_del(&card->dev);
- of_node_put(card->dev.of_node);
}
+ of_node_put(card->dev.of_node);
if (host->cqe_enabled) {
host->cqe_ops->cqe_disable(host);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 223/877] mmc: hsq: Fix use-after-free in retry work
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (221 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 222/877] mmc: core: Fix OF node reference leak on card add failure Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 224/877] mmc: mmci: Fix use-after-free in busy-timeout work Greg Kroah-Hartman
` (661 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu, Ulf Hansson
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
commit 5d132990475f02cfa1debe03d50b479432864ebd upstream.
mmc_hsq_pump_requests() queues retry_work when request_atomic() returns
-EBUSY; today sdhci-sprd is the only consumer that implements
request_atomic(). The work is embedded in a devm-allocated mmc_hsq, but
is never cancelled during driver removal. Work still pending at unbind
can therefore run after the devm allocation has been released and
dereference hsq->mmc and hsq->mrq.
Use devm_work_autocancel() to cancel and drain retry_work before the devm
allocation is released. By the time devres cleanup begins,
mmc_remove_host() has already stopped the host, so no new requests can
arm the work.
This issue was found by an in-house static analysis tool.
Fixes: 6db96e5810e0 ("mmc: host: Introduce the request_atomic() for the host")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/host/mmc_hsq.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
--- a/drivers/mmc/host/mmc_hsq.c
+++ b/drivers/mmc/host/mmc_hsq.c
@@ -7,6 +7,7 @@
* Author: Baolin Wang <baolin.wang@linaro.org>
*/
+#include <linux/devm-helpers.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
#include <linux/module.h>
@@ -345,6 +346,7 @@ static const struct mmc_cqe_ops mmc_hsq_
int mmc_hsq_init(struct mmc_hsq *hsq, struct mmc_host *mmc)
{
+ int ret;
int i;
hsq->num_slots = HSQ_NUM_SLOTS;
hsq->next_tag = HSQ_INVALID_TAG;
@@ -363,7 +365,11 @@ int mmc_hsq_init(struct mmc_hsq *hsq, st
for (i = 0; i < HSQ_NUM_SLOTS; i++)
hsq->tag_slot[i] = HSQ_INVALID_TAG;
- INIT_WORK(&hsq->retry_work, mmc_hsq_retry_handler);
+ ret = devm_work_autocancel(mmc_dev(mmc), &hsq->retry_work,
+ mmc_hsq_retry_handler);
+ if (ret)
+ return ret;
+
spin_lock_init(&hsq->lock);
init_waitqueue_head(&hsq->wait_queue);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 224/877] mmc: mmci: Fix use-after-free in busy-timeout work
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (222 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 223/877] mmc: hsq: Fix use-after-free in retry work Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 225/877] mmc: mxcmmc: cancel data work and watchdog on remove Greg Kroah-Hartman
` (660 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu, Linus Walleij, Ulf Hansson
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
commit 2b19cf3e50cddaff07b657dae1a8f30f06032852 upstream.
ux500_busy_complete() can queue ux500_busy_timeout_work for an R1b
command, but mmci_remove() never cancels it. The work can subsequently
dereference the devm-allocated mmci_host after it has been released.
Mask the controller interrupts and disable the delayed work during
removal. This drains any queued instance and stops an IRQ handler that
is still in progress from queueing the work again once it has been
disabled.
This issue was found by an in-house static analysis tool.
Fixes: b1a665932dc2 ("mmc: mmci: Add support for SW busy-end timeouts")
Cc: stable@vger.kernel.org # v6.10+
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/host/mmci.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -2520,6 +2520,9 @@ static void mmci_remove(struct amba_devi
writel(0, host->base + MMCICOMMAND);
writel(0, host->base + MMCIDATACTRL);
+ if (variant->busy_detect)
+ disable_delayed_work_sync(&host->ux500_busy_timeout_work);
+
mmci_dma_release(host);
clk_disable_unprepare(host->clk);
mmc_free_host(mmc);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 225/877] mmc: mxcmmc: cancel data work and watchdog on remove
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (223 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 224/877] mmc: mmci: Fix use-after-free in busy-timeout work Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 226/877] mmc: rtsx_pci_sdmmc: ignore broken write-protect on ThinkPad X260 Greg Kroah-Hartman
` (659 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu, Ulf Hansson
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
commit d3a421c82412344022982d5b91ba23194a0a6f29 upstream.
mxcmci_remove() frees the host through the devm tail, but neither it nor
mmc_remove_host() drains the driver's own asynchronous state.
host->watchdog, a 10 s timer armed on the DMA path in mxcmci_setup_data(),
is deleted only by the DMA- and IRQ-complete paths, which the remove path
does not explicitly drain; it can therefore fire after the host is freed
and dereference it in mxcmci_watchdog(). host->datawork, armed from the
IRQ handler on the PIO path, is not cancelled by the remove path either.
Free the devm-registered IRQ, then cancel datawork and delete the watchdog
in mxcmci_remove(), before dma_release_channel(). Freeing the IRQ first
keeps a trailing handler from re-arming datawork between the cancel and
the host free. Both callbacks are non-self-rearming.
This issue was found by an in-house static analysis tool.
Fixes: f6ad0a481342 ("mmc: mxcmmc: fix bug that may block a data transfer forever")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/host/mxcmmc.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -1182,6 +1182,10 @@ static void mxcmci_remove(struct platfor
mmc_remove_host(mmc);
+ devm_free_irq(&pdev->dev, platform_get_irq(pdev, 0), host);
+ cancel_work_sync(&host->datawork);
+ timer_delete_sync(&host->watchdog);
+
if (host->pdata && host->pdata->exit)
host->pdata->exit(&pdev->dev, mmc);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 226/877] mmc: rtsx_pci_sdmmc: ignore broken write-protect on ThinkPad X260
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (224 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 225/877] mmc: mxcmmc: cancel data work and watchdog on remove Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 227/877] mmc: sdhci-of-aspeed: Remove children before releasing SDC resources Greg Kroah-Hartman
` (658 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Florian Maillard, Ulf Hansson
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Maillard <florian.maillard@mailoo.org>
commit 9c182bc5d7817437a7d04ab96133f9191846d93d upstream.
The Realtek RTS522A card reader in the Lenovo ThinkPad X260
(subsystem 17aa:504a) incorrectly reports inserted SD cards as
write-protected.
This causes the MMC core to expose the card as read-only:
mmcblk0: mmc0:aaaa SN256 238 GiB (ro)
and /sys/block/mmcblk0/ro reports 1.
Setting MMC_CAP2_NO_WRITE_PROTECT makes the card writable again.
Limit the quirk to the affected Lenovo subsystem.
Assisted-by: ChatGPT:GPT-5.6 Sol
Signed-off-by: Florian Maillard <florian.maillard@mailoo.org>
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/host/rtsx_pci_sdmmc.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -1503,6 +1503,11 @@ static void realtek_init_host(struct rea
mmc->caps = mmc->caps | MMC_CAP_AGGRESSIVE_PM;
mmc->caps2 = MMC_CAP2_NO_PRESCAN_POWERUP | MMC_CAP2_FULL_PWR_CYCLE |
MMC_CAP2_NO_SDIO;
+
+ if (pcr->pci->device == 0x522a &&
+ pcr->pci->subsystem_vendor == PCI_VENDOR_ID_LENOVO &&
+ pcr->pci->subsystem_device == 0x504a)
+ mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT;
mmc->max_current_330 = 400;
mmc->max_current_180 = 800;
mmc->ops = &realtek_pci_sdmmc_ops;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 227/877] mmc: sdhci-of-aspeed: Remove children before releasing SDC resources
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (225 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 226/877] mmc: rtsx_pci_sdmmc: ignore broken write-protect on ThinkPad X260 Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 228/877] mmc: sdio_uart: fix xmit_fifo leak when the port table is full Greg Kroah-Hartman
` (657 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ijae Kim, Myeonghun Pak, Ulf Hansson
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <mhun512@gmail.com>
commit 4396d70bb7fec531bcf934fed016b2f3300c670b upstream.
Probe failure and removal leave SDHCI child devices registered after the
parent clock and managed resources are released.
Unregister the OF children in reverse order before disabling the parent
clock on both paths. Use of_platform_device_destroy() because manual
child creation does not set the flag required by of_platform_depopulate().
This issue was identified during our ongoing static-analysis research
while reviewing kernel code.
Fixes: bb7b8ec62dfb ("mmc: sdhci-of-aspeed: Add support for the ASPEED SD controller")
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Assisted-by: OpenAI:GPT-5.6
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/host/sdhci-of-aspeed.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/mmc/host/sdhci-of-aspeed.c
+++ b/drivers/mmc/host/sdhci-of-aspeed.c
@@ -561,12 +561,14 @@ static int aspeed_sdc_probe(struct platf
if (!cpdev) {
of_node_put(child);
ret = -ENODEV;
- goto err_clk;
+ goto err_children;
}
}
return 0;
+err_children:
+ device_for_each_child_reverse(&pdev->dev, NULL, of_platform_device_destroy);
err_clk:
clk_disable_unprepare(sdc->clk);
return ret;
@@ -576,6 +578,7 @@ static void aspeed_sdc_remove(struct pla
{
struct aspeed_sdc *sdc = dev_get_drvdata(&pdev->dev);
+ device_for_each_child_reverse(&pdev->dev, NULL, of_platform_device_destroy);
clk_disable_unprepare(sdc->clk);
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 228/877] mmc: sdio_uart: fix xmit_fifo leak when the port table is full
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (226 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 227/877] mmc: sdhci-of-aspeed: Remove children before releasing SDC resources Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 229/877] mmc: sh_mmcif: initialize IRQ-thread mutex before requesting interrupt Greg Kroah-Hartman
` (656 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Felix Gu, Ulf Hansson
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <ustc.gu@gmail.com>
commit 53823e25793a97d07e6e98e0904bbf74cac8bc76 upstream.
sdio_uart_add_port() allocates the transmit fifo before claiming a
slot in sdio_uart_table[]. When all UART_NR slots are taken, it
returns -EBUSY with the fifo still allocated, but the probe error
path only kfree()s the port, leaking the transmit fifo.
Free the fifo in the failure path of sdio_uart_add_port() itself so
the function retains nothing on error.
Fixes: 8b197a5ce7a7 ("sdio_uart: Use kfifo instead of the messy circ stuff")
Signed-off-by: Felix Gu <ustc.gu@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/core/sdio_uart.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/mmc/core/sdio_uart.c
+++ b/drivers/mmc/core/sdio_uart.c
@@ -104,6 +104,9 @@ static int sdio_uart_add_port(struct sdi
}
spin_unlock(&sdio_uart_table_lock);
+ if (ret)
+ kfifo_free(&port->xmit_fifo);
+
return ret;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 229/877] mmc: sh_mmcif: initialize IRQ-thread mutex before requesting interrupt
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (227 preceding siblings ...)
2026-09-30 15:18 ` [PATCH 6.12 228/877] mmc: sdio_uart: fix xmit_fifo leak when the port table is full Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 230/877] mmc: spi: reset bytes_xfered before retrying CRC failures Greg Kroah-Hartman
` (655 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Runyu Xiao, Ulf Hansson
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Runyu Xiao <runyu.xiao@seu.edu.cn>
commit d5ea0d226e8f0801d78702142a124d78c317d822 upstream.
The threaded IRQ handler can run before devm_request_threaded_irq()
returns, but thread_lock was initialized afterwards. Initialize it before
requesting either interrupt.
Fixes: 8047310ee984 ("mmc: sh_mmcif: fix a race, causing an Oops on SMP")
Cc: stable@vger.kernel.org
Assisted-by: Codex:GPT-5
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/host/sh_mmcif.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -1461,6 +1461,7 @@ static int sh_mmcif_probe(struct platfor
host->pd = pdev;
spin_lock_init(&host->lock);
+ mutex_init(&host->thread_lock);
mmc->ops = &sh_mmcif_ops;
sh_mmcif_init_ocr(host);
@@ -1521,8 +1522,6 @@ static int sh_mmcif_probe(struct platfor
}
}
- mutex_init(&host->thread_lock);
-
ret = mmc_add_host(mmc);
if (ret < 0)
goto err_clk;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 230/877] mmc: spi: reset bytes_xfered before retrying CRC failures
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (228 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 229/877] mmc: sh_mmcif: initialize IRQ-thread mutex before requesting interrupt Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 231/877] mmc: sdhci_am654: Move tuning_loop to local variable Greg Kroah-Hartman
` (654 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Xu Rao, Ulf Hansson
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xu Rao <raoxu@uniontech.com>
commit 8b0cc8707f65e0f51912e764e1b309b2559db1ec upstream.
mmc_spi_data_do() updates data->bytes_xfered after each block has been
transferred successfully. If a later block in the same data request
fails with a CRC error, data->bytes_xfered may therefore contain the
number of bytes completed before the failing block.
mmc_spi_request() has a private recovery path for such CRC failures. It
sends STOP_TRANSMISSION, clears data->error and jumps back to
crc_recover to issue the same command and data request again. However,
it does not clear data->bytes_xfered before the retry.
If the retry succeeds, the request is completed with the bytes from the
failed attempt still included in data->bytes_xfered. For a multi-block
request this can make the completed request report more bytes than were
transferred by the successful retry, and can even exceed the request size
when most blocks completed before the CRC error.
This is most likely to be observed on MMC-over-SPI systems where long
multi-block transfers occasionally hit a data CRC error but the
mmc_spi-internal retry succeeds. The data itself is retried, but the
completion accounting is not.
Clear data->bytes_xfered together with data->error before repeating the
request so the final completion reports only the bytes transferred by the
successful attempt.
Fixes: 061c6c847eeb ("mmc_spi: Recover from CRC errors for r/w operation over SPI.")
Cc: stable@vger.kernel.org
Signed-off-by: Xu Rao <raoxu@uniontech.com>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/host/mmc_spi.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -952,6 +952,7 @@ crc_recover:
status = mmc_spi_command_send(host, mrq, &stop, 0);
crc_retry--;
mrq->data->error = 0;
+ mrq->data->bytes_xfered = 0;
goto crc_recover;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 231/877] mmc: sdhci_am654: Move tuning_loop to local variable
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (229 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 230/877] mmc: spi: reset bytes_xfered before retrying CRC failures Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 232/877] mmc: sdhci_am654: Reset command and data lines on failed tuning Greg Kroah-Hartman
` (653 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Diogo Ivo (Schneider Electric),
Judith Mendez, Adrian Hunter, Ulf Hansson
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Diogo Ivo (Schneider Electric) <diogo.ivo@bootlin.com>
commit ff894dced1a7ad7523f9c65dbdb53d02474cca0f upstream.
The tuning_loop field in struct sdhci_am654_data is only used within
sdhci_am654_platform_execute_tuning() as a loop counter that is
initialized to 0 in sdhci_am654_init(). Since it shouldn't persist across
function calls, otherwise every failure expends its "budget", move it to a
local variable and remove the struct field along with the now-unnecessary
initialization.
Signed-off-by: Diogo Ivo (Schneider Electric) <diogo.ivo@bootlin.com>
Reviewed-by: Judith Mendez <jm@ti.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Fixes: de31f6ab68a3 ("mmc: sdhci_am654: Reset Command and Data line after tuning")
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/host/sdhci_am654.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
--- a/drivers/mmc/host/sdhci_am654.c
+++ b/drivers/mmc/host/sdhci_am654.c
@@ -152,7 +152,6 @@ struct sdhci_am654_data {
u32 flags;
u32 quirks;
bool dll_enable;
- u32 tuning_loop;
#define SDHCI_AM654_QUIRK_FORCE_CDTEST BIT(0)
#define SDHCI_AM654_QUIRK_DISABLE_HS400 BIT(1)
@@ -552,13 +551,14 @@ static int sdhci_am654_platform_execute_
struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
unsigned char timing = host->mmc->ios.timing;
struct device *dev = mmc_dev(host->mmc);
+ unsigned int tuning_loop = 0;
int itapdly;
do {
itapdly = sdhci_am654_do_tuning(host, opcode);
if (itapdly >= 0)
break;
- } while (++sdhci_am654->tuning_loop < RETRY_TUNING_MAX);
+ } while (++tuning_loop < RETRY_TUNING_MAX);
if (itapdly < 0) {
dev_err(dev, "Failed to find itapdly, fail tuning\n");
@@ -776,9 +776,6 @@ static int sdhci_am654_init(struct sdhci
regmap_update_bits(sdhci_am654->base, CTL_CFG_3, TUNINGFORSDR50_MASK,
TUNINGFORSDR50_MASK);
- /* Use to re-execute tuning */
- sdhci_am654->tuning_loop = 0;
-
ret = sdhci_setup_host(host);
if (ret)
return ret;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 232/877] mmc: sdhci_am654: Reset command and data lines on failed tuning
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (230 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 231/877] mmc: sdhci_am654: Move tuning_loop to local variable Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 233/877] mmc: sdhci_am654: Clear ITAPDLY on tuning failure Greg Kroah-Hartman
` (652 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Diogo Ivo (Schneider Electric),
Judith Mendez, Adrian Hunter, Ulf Hansson
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Diogo Ivo (Schneider Electric) <diogo.ivo@bootlin.com>
commit 7197d9107d9545730153b82ea5a411c5208b443f upstream.
The CMD/DATA reset after tuning should be performed regardless of
whether tuning succeeded or failed, since tuning data may remain in
the buffer in either case. Move the error return after the reset so
that the controller is always cleaned up.
Fixes: de31f6ab68a3 ("mmc: sdhci_am654: Reset Command and Data line after tuning")
Cc: stable@vger.kernel.org
Signed-off-by: Diogo Ivo (Schneider Electric) <diogo.ivo@bootlin.com>
Reviewed-by: Judith Mendez <jm@ti.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/host/sdhci_am654.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
--- a/drivers/mmc/host/sdhci_am654.c
+++ b/drivers/mmc/host/sdhci_am654.c
@@ -418,15 +418,13 @@ static int sdhci_am654_execute_tuning(st
struct sdhci_host *host = mmc_priv(mmc);
int err = sdhci_execute_tuning(mmc, opcode);
- if (err)
- return err;
/*
* Tuning data remains in the buffer after tuning.
* Do a command and data reset to get rid of it
*/
sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
- return 0;
+ return err;
}
static u32 sdhci_am654_cqhci_irq(struct sdhci_host *host, u32 intmask)
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 233/877] mmc: sdhci_am654: Clear ITAPDLY on tuning failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (231 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 232/877] mmc: sdhci_am654: Reset command and data lines on failed tuning Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 234/877] mmc: sdhci_am654: Fallback to DT-provided itap delay on DDR50 " Greg Kroah-Hartman
` (651 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Diogo Ivo (Schneider Electric),
Judith Mendez, Adrian Hunter, Ulf Hansson
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Diogo Ivo (Schneider Electric) <diogo.ivo@bootlin.com>
commit c9f47cc8c37f7659897142ffe216c250fbc1d4ed upstream.
When tuning fails, stale ITAPDLY values can persist and interfere with
subsequent I/O accesses, for example in DDR50 mode in cards with no tuning
support. Move the ITAPDLY enable setting out of the tuning loop to after
successful tuning, and explicitly clear ITAPDLY (delay and enable) when
tuning fails so that we are sure only working values are actually left in
hardware.
Fixes: 901d16e46296 ("mmc: sdhci_am654: Add retry tuning")
Cc: stable@vger.kernel.org
Signed-off-by: Diogo Ivo (Schneider Electric) <diogo.ivo@bootlin.com>
Reviewed-by: Judith Mendez <jm@ti.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/host/sdhci_am654.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
--- a/drivers/mmc/host/sdhci_am654.c
+++ b/drivers/mmc/host/sdhci_am654.c
@@ -503,7 +503,6 @@ static int sdhci_am654_do_tuning(struct
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
- unsigned char timing = host->mmc->ios.timing;
struct window fail_window[ITAPDLY_LENGTH];
struct device *dev = mmc_dev(host->mmc);
u8 curr_pass, itap;
@@ -512,11 +511,8 @@ static int sdhci_am654_do_tuning(struct
memset(fail_window, 0, sizeof(fail_window));
- /* Enable ITAPDLY */
- sdhci_am654->itap_del_ena[timing] = 0x1;
-
for (itap = 0; itap < ITAPDLY_LENGTH; itap++) {
- sdhci_am654_write_itapdly(sdhci_am654, itap, sdhci_am654->itap_del_ena[timing]);
+ sdhci_am654_write_itapdly(sdhci_am654, itap, 0x1);
curr_pass = !mmc_send_tuning(host->mmc, opcode, NULL);
@@ -560,10 +556,16 @@ static int sdhci_am654_platform_execute_
if (itapdly < 0) {
dev_err(dev, "Failed to find itapdly, fail tuning\n");
+ sdhci_am654_write_itapdly(sdhci_am654, 0, 0);
+ sdhci_am654->itap_del_ena[timing] = 0;
+ sdhci_am654->itap_del_sel[timing] = 0;
return -1;
}
dev_dbg(dev, "Passed tuning, final itapdly=%d\n", itapdly);
+
+ /* Enable ITAPDLY */
+ sdhci_am654->itap_del_ena[timing] = 0x1;
sdhci_am654_write_itapdly(sdhci_am654, itapdly, sdhci_am654->itap_del_ena[timing]);
/* Save ITAPDLY */
sdhci_am654->itap_del_sel[timing] = itapdly;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 234/877] mmc: sdhci_am654: Fallback to DT-provided itap delay on DDR50 tuning failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (232 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 233/877] mmc: sdhci_am654: Clear ITAPDLY on tuning failure Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 235/877] Input: adp5588-keys - cache GPIO state before registering the gpiochip Greg Kroah-Hartman
` (650 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Diogo Ivo (Schneider Electric),
Adrian Hunter, Judith Mendez, Ulf Hansson
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Diogo Ivo (Schneider Electric) <diogo.ivo@bootlin.com>
commit 308d05225281d86150d88141990d6caf8c902349 upstream.
DDR50 mode is not required to support the tuning command CMD19, meaning
that calibration may fail on cards that do not implement it, in which
case a known-good itap delay value should be programmed into the host
controller.
Do this by reading the (already defined) itap delay DT property for DDR50
and, if tuning fails for this mode, fall back to the DT-provided itap delay
value. If the DT does not provide a value for DDR50 fallback then this
simply disables using itapdly.
Fixes: 901d16e46296 ("mmc: sdhci_am654: Add retry tuning")
Cc: stable@vger.kernel.org
Signed-off-by: Diogo Ivo (Schneider Electric) <diogo.ivo@bootlin.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Judith Mendez <jm@ti.com>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/host/sdhci_am654.c | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
--- a/drivers/mmc/host/sdhci_am654.c
+++ b/drivers/mmc/host/sdhci_am654.c
@@ -127,7 +127,7 @@ static const struct timing_data td[] = {
NULL,
MMC_CAP_UHS_SDR104},
[MMC_TIMING_UHS_DDR50] = {"ti,otap-del-sel-ddr50",
- NULL,
+ "ti,itap-del-sel-ddr50",
MMC_CAP_UHS_DDR50},
[MMC_TIMING_MMC_DDR52] = {"ti,otap-del-sel-ddr52",
"ti,itap-del-sel-ddr52",
@@ -145,6 +145,8 @@ struct sdhci_am654_data {
u32 otap_del_sel[ARRAY_SIZE(td)];
u32 itap_del_sel[ARRAY_SIZE(td)];
u32 itap_del_ena[ARRAY_SIZE(td)];
+ u32 itap_del_sel_dt_ddr50;
+ u32 itap_del_ena_dt_ddr50;
int clkbuf_sel;
int trm_icp;
int drv_strength;
@@ -555,10 +557,19 @@ static int sdhci_am654_platform_execute_
} while (++tuning_loop < RETRY_TUNING_MAX);
if (itapdly < 0) {
- dev_err(dev, "Failed to find itapdly, fail tuning\n");
- sdhci_am654_write_itapdly(sdhci_am654, 0, 0);
- sdhci_am654->itap_del_ena[timing] = 0;
- sdhci_am654->itap_del_sel[timing] = 0;
+ if (timing == MMC_TIMING_UHS_DDR50) {
+ dev_dbg(dev, "Failed DDR50 tuning, fallback to DT ITAP\n");
+ sdhci_am654->itap_del_sel[timing] = sdhci_am654->itap_del_sel_dt_ddr50;
+ sdhci_am654->itap_del_ena[timing] = sdhci_am654->itap_del_ena_dt_ddr50;
+ } else {
+ dev_err(dev, "Failed to find itapdly, fail tuning\n");
+ sdhci_am654->itap_del_ena[timing] = 0;
+ sdhci_am654->itap_del_sel[timing] = 0;
+ }
+
+ sdhci_am654_write_itapdly(sdhci_am654,
+ sdhci_am654->itap_del_sel[timing],
+ sdhci_am654->itap_del_ena[timing]);
return -1;
}
@@ -728,6 +739,11 @@ static int sdhci_am654_get_otap_delay(st
}
}
+ sdhci_am654->itap_del_sel_dt_ddr50 =
+ sdhci_am654->itap_del_sel[MMC_TIMING_UHS_DDR50];
+ sdhci_am654->itap_del_ena_dt_ddr50 =
+ sdhci_am654->itap_del_ena[MMC_TIMING_UHS_DDR50];
+
return 0;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 235/877] Input: adp5588-keys - cache GPIO state before registering the gpiochip
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (233 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 234/877] mmc: sdhci_am654: Fallback to DT-provided itap delay on DDR50 " Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 236/877] Input: atkbd - skip deactivate for Xiaomi Redmi Book Pro 16 2026 Greg Kroah-Hartman
` (649 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alvin Šipraga, Nuno Sá,
Dmitry Torokhov
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alvin Šipraga <alvin.sipraga@analog.com>
commit 21efadc62272cabee9bec27777ae75d84a9ca8a8 upstream.
So as not to clobber any pre-programmed GPIO state in the execution
of its gpiochip ops, the driver caches things during probe time.
However, since those ops can be called both during and immediately after
the call to devm_gpiochip_add_data(), it is imperative that things are
cached before that. That's not the case right now, so reorder the two
steps to prevent any clobbering.
In the concrete example which motivated this change, a bootloader was
preconfiguring an important GPIO output to HIGH before booting the
kernel. Linux would then inadvertently set that output to LOW while
configuring a GPIO hog on a discrete GPIO line within the same 8-bit
bank (because the cached value was 0=LOW).
Fixes: ba9f507a1bea ("Input: adp5588-keys - export unused GPIO pins")
Signed-off-by: Alvin Šipraga <alvin.sipraga@analog.com>
Reviewed-by: Nuno Sá <nuno.sa@analog.com>
Link: https://patch.msgid.link/20260818-adp5588-gpio-cache-v1-1-650a2674fc0d@analog.com
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/keyboard/adp5588-keys.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
--- a/drivers/input/keyboard/adp5588-keys.c
+++ b/drivers/input/keyboard/adp5588-keys.c
@@ -446,12 +446,6 @@ static int adp5588_gpio_add(struct adp55
mutex_init(&kpad->gpio_lock);
- error = devm_gpiochip_add_data(dev, &kpad->gc, kpad);
- if (error) {
- dev_err(dev, "gpiochip_add failed: %d\n", error);
- return error;
- }
-
for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) {
kpad->dat_out[i] = adp5588_read(kpad->client,
GPIO_DAT_OUT1 + i);
@@ -459,6 +453,12 @@ static int adp5588_gpio_add(struct adp55
kpad->pull_dis[i] = adp5588_read(kpad->client, GPIO_PULL1 + i);
}
+ error = devm_gpiochip_add_data(dev, &kpad->gc, kpad);
+ if (error) {
+ dev_err(dev, "gpiochip_add failed: %d\n", error);
+ return error;
+ }
+
return 0;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 236/877] Input: atkbd - skip deactivate for Xiaomi Redmi Book Pro 16 2026
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (234 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 235/877] Input: adp5588-keys - cache GPIO state before registering the gpiochip Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 237/877] Input: cyttsp5 - clamp the HID report size before memcpy Greg Kroah-Hartman
` (648 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Alexei Turtanov, Dmitry Torokhov
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexei Turtanov <9alexei9@gmail.com>
commit aefbda23eeba234c3ff0f135dc5be6e294bd25a6 upstream.
The internal keyboard of the Xiaomi Redmi Book Pro 16 2026 (board TM2425)
does not work: atkbd_probe() succeeds and every command is ACKed, but no
scancodes ever arrive afterwards.
Testing on the hardware through serio_raw shows that ATKBD_CMD_RESET_DIS
(0xF5) is the culprit. After 0xF5 the embedded controller keeps ACKing
commands but stops delivering scancodes, and neither ATKBD_CMD_ENABLE
(0xF4) nor ATKBD_CMD_RESET_BAT (0xFF) bring them back. Only re-enabling
the keyboard interface at the controller level (i8042 command 0xAE, or
rewriting the command byte as i8042_port_close() does) revives it.
Running the init sequence without 0xF5 (0xED 0x00, 0xF3 0x00, 0xF4)
keeps the keyboard working.
'i8042.dumbkbd=1' also works around this, but then the driver never
writes to the keyboard and the LEDs cannot be controlled. Use the
existing atkbd_deactivate_fixup quirk instead, as done for the sibling
TM2424 by commit 3a046db33bb9 ("Input: atkbd - skip deactivate for
Xiaomi Book Pro 14's internal keyboard"). Tested on v7.2: keyboard,
Caps Lock LED and s2idle suspend/resume all work.
DMI: XIAOMI REDMI Book Pro 16 2026/TM2425, BIOS RMAPT6B0P0909 05/22/2026
Fixes: 9cf6e24c9fbf ("Input: atkbd - do not skip atkbd_deactivate() when skipping ATKBD_CMD_GETID")
Cc: stable@vger.kernel.org
Signed-off-by: Alexei Turtanov <9alexei9@gmail.com>
Link: https://patch.msgid.link/20260828112239.18081-1-9alexei9@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/keyboard/atkbd.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -1975,6 +1975,14 @@ static const struct dmi_system_id atkbd_
},
.callback = atkbd_deactivate_fixup,
},
+ {
+ /* Xiaomi Redmi Book Pro 16 2026 (TM2425) */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "XIAOMI"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "REDMI Book Pro 16 2026"),
+ },
+ .callback = atkbd_deactivate_fixup,
+ },
{ }
};
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 237/877] Input: cyttsp5 - clamp the HID report size before memcpy
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (235 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 236/877] Input: atkbd - skip deactivate for Xiaomi Redmi Book Pro 16 2026 Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 238/877] Input: evdev - zero absinfo before partial copy in EVIOCSABS Greg Kroah-Hartman
` (647 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linkai Gong, Dmitry Torokhov
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linkai Gong <gonglinkai@kylinos.cn>
commit 85f080fb87ed5cd3e46121be677f52c82f26a0ab upstream.
The size field comes from the device and is used as the memcpy()
length into response_buf, which is CY_MAX_INPUT bytes.
Fixes: 5b0c03e24a06 ("Input: Add driver for Cypress Generation 5 touchscreen")
Signed-off-by: Linkai Gong <gonglinkai@kylinos.cn>
Link: https://patch.msgid.link/20260901122649.1173066-1-gonglinkai@kylinos.cn
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/touchscreen/cyttsp5.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/input/touchscreen/cyttsp5.c
+++ b/drivers/input/touchscreen/cyttsp5.c
@@ -711,6 +711,7 @@ static irqreturn_t cyttsp5_handle_irq(in
size = 2;
} else {
report_id = ts->input_buf[2];
+ size = min(size, CY_MAX_INPUT);
}
switch (report_id) {
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 238/877] Input: evdev - zero absinfo before partial copy in EVIOCSABS
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (236 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 237/877] Input: cyttsp5 - clamp the HID report size before memcpy Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 239/877] Input: i8042 - add quirk for Acer Aspire Go 15 AG15-42P Greg Kroah-Hartman
` (646 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Iván Ezequiel Rodriguez,
Dmitry Torokhov
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Iván Ezequiel Rodriguez <ivanrwcm25@gmail.com>
commit 8b852965b8eaf910c314dc346967ed82c8d4f235 upstream.
The EVIOCSABS handler copies at most the user supplied ioctl size into
an uninitialized on-stack struct input_absinfo:
if (copy_from_user(&abs, p, min_t(size_t,
size, sizeof(struct input_absinfo))))
The size comes from _IOC_SIZE() of the ioctl command and is therefore
fully controlled by userspace. A short size leaves the trailing part of
the structure holding whatever was on the kernel stack, and the whole
structure is then stored into the device:
dev->absinfo[t] = abs;
EVIOCGABS hands that back to userspace, disclosing the stale stack
bytes. Only the resolution field is currently cleared, which covers the
legacy struct layout but not an arbitrarily short size.
Zero the structure before the copy so any part not supplied by the
caller reads back as zero. The existing resolution fixup is kept, since
it also handles a size that partially overlaps that field.
Fixes: 448cd1664a57 ("Input: evdev - rearrange ioctl handling")
Cc: stable@vger.kernel.org
Signed-off-by: Iván Ezequiel Rodriguez <ivanrwcm25@gmail.com>
Link: https://patch.msgid.link/20260901130629.24078-2-ivanrwcm25@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/evdev.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -1229,6 +1229,8 @@ static long evdev_do_ioctl(struct file *
t = _IOC_NR(cmd) & ABS_MAX;
+ memset(&abs, 0, sizeof(abs));
+
if (copy_from_user(&abs, p, min_t(size_t,
size, sizeof(struct input_absinfo))))
return -EFAULT;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 239/877] Input: i8042 - add quirk for Acer Aspire Go 15 AG15-42P
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (237 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 238/877] Input: evdev - zero absinfo before partial copy in EVIOCSABS Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 240/877] Input: rmi_smbus - fix out-of-bounds read in rmi_smb_write_block() Greg Kroah-Hartman
` (645 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chris Sommers, Dmitry Torokhov
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Sommers <chris.sommers@icloud.com>
commit 25e424eb4ae1a662d9c3573218d06ac32f797fc5 upstream.
On the Acer Aspire Go 15 (AG15-42P), the internal keyboard drops out
~5 seconds after boot on both Linux and Linux-LTS kernels. Keystrokes on
the built-in keyboard stop registering while the trackpad and external
keyboards remain functional.
Testing confirms that booting with the i8042.reset kernel parameter
resolves the issue and keeps the internal keyboard responsive.
Add SERIO_QUIRK_RESET_ALWAYS to i8042_dmi_quirk_table for the Acer
Aspire AG15-42P to automatically apply this quirk on boot.
Signed-off-by: Chris Sommers <chris.sommers@icloud.com>
Link: https://patch.msgid.link/20260907182723.2709981-1-chris.sommers@icloud.com
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/serio/i8042-acpipnpio.h | 7 +++++++
1 file changed, 7 insertions(+)
--- a/drivers/input/serio/i8042-acpipnpio.h
+++ b/drivers/input/serio/i8042-acpipnpio.h
@@ -261,6 +261,13 @@ static const struct dmi_system_id i8042_
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire AG15-42P"),
+ },
+ .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-132"),
},
.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 240/877] Input: rmi_smbus - fix out-of-bounds read in rmi_smb_write_block()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (238 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 239/877] Input: i8042 - add quirk for Acer Aspire Go 15 AG15-42P Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 241/877] Input: soc_button_array - fix MS Surface Pro 11 probe failure Greg Kroah-Hartman
` (644 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, sashiko-bot, Dmitry Torokhov
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
commit 51cfe54f815ae175c7d1126b983d4d7c89715004 upstream.
When chunking writes into SMBus blocks in rmi_smb_write_block(), the
loop calculates block_len using the original total length (len) instead
of the remaining length (cur_len).
If len is greater than 32 bytes (SMB_MAX_COUNT), block_len remains 32
for every iteration, even on the final partial chunk where fewer than 32
bytes remain. This causes smb_block_write() to read 32 bytes from the
advanced data buffer pointer, reading past the end of the input buffer.
Fix this by calculating block_len using cur_len and advancing the buffer
and address pointers by block_len.
Fixes: 82264d0cf7ae ("Input: synaptics-rmi4 - add SMBus support")
Cc: stable@vger.kernel.org
Reported-by: sashiko-bot@kernel.org
Assisted-by: LLM
Link: https://patch.msgid.link/anLFSMKSoKyyZ272@google.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/rmi4/rmi_smbus.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
--- a/drivers/input/rmi4/rmi_smbus.c
+++ b/drivers/input/rmi4/rmi_smbus.c
@@ -140,7 +140,7 @@ static int rmi_smb_write_block(struct rm
u8 commandcode;
struct rmi_smb_xport *rmi_smb =
container_of(xport, struct rmi_smb_xport, xport);
- int cur_len = (int)len;
+ size_t cur_len = len;
mutex_lock(&rmi_smb->page_mutex);
@@ -148,7 +148,7 @@ static int rmi_smb_write_block(struct rm
/*
* break into 32 bytes chunks to write get command code
*/
- int block_len = min_t(int, len, SMB_MAX_COUNT);
+ int block_len = min_t(size_t, cur_len, SMB_MAX_COUNT);
retval = rmi_smb_get_command_code(xport, rmiaddr, block_len,
false, &commandcode);
@@ -161,9 +161,9 @@ static int rmi_smb_write_block(struct rm
goto exit;
/* prepare to write next block of bytes */
- cur_len -= SMB_MAX_COUNT;
- databuff += SMB_MAX_COUNT;
- rmiaddr += SMB_MAX_COUNT;
+ cur_len -= block_len;
+ databuff += block_len;
+ rmiaddr += block_len;
}
exit:
mutex_unlock(&rmi_smb->page_mutex);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 241/877] Input: soc_button_array - fix MS Surface Pro 11 probe failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (239 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 240/877] Input: rmi_smbus - fix out-of-bounds read in rmi_smb_write_block() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 242/877] Input: soc_button_array - check btns_desc->package.count Greg Kroah-Hartman
` (643 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sergey Lebedev, Hans de Goede,
Dmitry Torokhov
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <johannes.goede@oss.qualcomm.com>
commit ed22ad5fdbdbf9b4cb4ad3003f60314b5a5eb89d upstream.
On the MS Surface Pro 11 soc_button_array probing races with the GPIO
driver probing. If soc_button_array wins the race then gpiod_get() returns
EPROBE_DEFER, which should normally take care of retrying later, but
the soc_button_array code deliberately ignores EPROBE_DEFER causing it
to fail its probe() which causes the volume and power buttons to now work.
The ignoring of EPROBE_DEFER is there to deal with a problem specific to
older Bay Trail (BYT) and Cherry Trail (CHT) tablets which often use this
driver. Modify the error handling to only ignore EPROBE_DEFER on BYT and
CHT platforms and propagate EPROBE_DEFER normally on other platforms.
Fixes: bcf059578980 ("Input: soc_button_array - partial revert of support for newer surface devices")
Cc: stable@vger.kernel.org
Reported-by: Sergey Lebedev <lsa.uz@pm.me>
Closes: https://lore.kernel.org/lkml/20260830141355.55898-1-lsa.uz@pm.me/
Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Tested-by: Sergey Lebedev <lsa.uz@pm.me>
Link: https://patch.msgid.link/20260909093934.29411-1-johannes.goede@oss.qualcomm.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/misc/soc_button_array.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
--- a/drivers/input/misc/soc_button_array.c
+++ b/drivers/input/misc/soc_button_array.c
@@ -16,6 +16,7 @@
#include <linux/gpio/consumer.h>
#include <linux/gpio_keys.h>
#include <linux/gpio.h>
+#include <linux/platform_data/x86/soc.h>
#include <linux/platform_device.h>
static bool use_low_level_irq;
@@ -160,7 +161,7 @@ soc_button_device_create(struct platform
struct gpio_keys_platform_data *gpio_keys_pdata;
const struct dmi_system_id *dmi_id;
int invalid_acpi_index = -1;
- int error, gpio, irq;
+ int error, gpio, irq = 0;
int n_buttons = 0;
for (info = button_info; info->name; info++)
@@ -191,8 +192,9 @@ soc_button_device_create(struct platform
error = soc_button_lookup_gpio(&pdev->dev, info->acpi_index, &gpio, &irq);
if (error || irq < 0) {
/*
- * Skip GPIO if not present. Note we deliberately
- * ignore -EPROBE_DEFER errors here. On some devices
+ * Propagate -EPROBE_DEFER, skip button on other errors.
+ *
+ * -EPROBE_DEFER is ignored on Bay & Cherry Trail. Here
* Intel is using so called virtual GPIOs which are not
* GPIOs at all but some way for AML code to check some
* random status bits without need a custom opregion.
@@ -201,6 +203,12 @@ soc_button_device_create(struct platform
* we do not have a driver for these so they will never
* show up, therefore we ignore -EPROBE_DEFER.
*/
+ if ((error == -EPROBE_DEFER || irq == -EPROBE_DEFER) &&
+ !(soc_intel_is_byt() || soc_intel_is_cht())) {
+ error = -EPROBE_DEFER;
+ goto err_free_mem;
+ }
+
continue;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 242/877] Input: soc_button_array - check btns_desc->package.count
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (240 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 241/877] Input: soc_button_array - fix MS Surface Pro 11 probe failure Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 243/877] Input: synaptics - disable InterTouch on ThinkPad T440p (board id 2722) Greg Kroah-Hartman
` (642 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shashiko, Hans de Goede,
Dmitry Torokhov
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <johannes.goede@oss.qualcomm.com>
commit fb5022278b6ea7f1838e3ef78028d5d5e3375f65 upstream.
Check that btns_desc->package.count is not 0 before accessing
btns_desc->package.elements[0].
Fixes: 4c3362f44980 ("Input: soc_button_array - add support for ACPI 6.0 Generic Button Device")
Cc: stable@vger.kernel.org
Reported-by: Shashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/linux-input/20260909091440.3384C1F00A3A@smtp.kernel.org/
Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Link: https://patch.msgid.link/20260909093934.29411-2-johannes.goede@oss.qualcomm.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/misc/soc_button_array.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/input/misc/soc_button_array.c
+++ b/drivers/input/misc/soc_button_array.c
@@ -377,7 +377,7 @@ static struct soc_button_info *soc_butto
}
}
- if (!btns_desc) {
+ if (!btns_desc || !btns_desc->package.count) {
dev_err(dev, "ACPI Button Descriptors not found\n");
button_info = ERR_PTR(-ENODEV);
goto out;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 243/877] Input: synaptics - disable InterTouch on ThinkPad T440p (board id 2722)
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (241 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 242/877] Input: soc_button_array - check btns_desc->package.count Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 244/877] Input: synaptics-rmi4 - fix GPF in suspend and resume when unbound Greg Kroah-Hartman
` (641 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Raphaël Larocque,
Dmitry Torokhov
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Raphaël Larocque <rlarocque@disroot.org>
commit 26eb3d92c7a4d7adb1ae1740ca6e8e100b11d1ec upstream.
The Lenovo ThinkPad T440p (PNP ID LEN0036, board id 2722) has a
Synaptics touchpad whose SMBus companion is not ready at boot and
takes roughly 200 seconds to appear. During this window the touchpad
and TrackPoint are completely unresponsive on approximately 50% of
boots, making the machine unusable until the companion finally
registers.
The device is in the topbuttonpad_pnp_ids[] SMBus allowlist, so the
kernel attempts to use SMBus/RMI4 mode by default. When the companion
is not ready, psmouse_smbus_init() leaves breadcrumbs and returns
-EAGAIN, the PS/2 fallback path is taken, but the device does not
function properly until the companion appears and RMI4 takes over.
Disable SMBus InterTouch for board id 2722 so the touchpad and
TrackPoint work immediately via PS/2 from boot. Users can still force
SMBus with psmouse.synaptics_intertouch=1 if needed.
Tested-by: Raphaël Larocque <rlarocque@disroot.org>
Signed-off-by: Raphaël Larocque <rlarocque@disroot.org>
Link: https://patch.msgid.link/20260910164425.12832-1-rlarocque@disroot.org
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/mouse/synaptics.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -1837,6 +1837,14 @@ static int synaptics_setup_intertouch(st
return -ENXIO;
}
+
+ /* Disable intertouch on known-broken board revisions */
+ if (info->board_id == 2722) {
+ psmouse_info(psmouse,
+ "Disabling intertouch for board id %u\n",
+ info->board_id);
+ return -ENXIO;
+ }
}
psmouse_info(psmouse, "Trying to set up SMBus access\n");
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 244/877] Input: synaptics-rmi4 - fix GPF in suspend and resume when unbound
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (242 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 243/877] Input: synaptics - disable InterTouch on ThinkPad T440p (board id 2722) Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 245/877] Input: zero ff_effect before compat copy in input_ff_effect_from_user Greg Kroah-Hartman
` (640 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+09103639e39c989e3ed3,
Dmitry Torokhov
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
commit fe10579b6dc3f0dac61e51e1797cacbba5039ac2 upstream.
Transport drivers (such as rmi_i2c and rmi_spi) invoke
rmi_driver_suspend() and rmi_driver_resume() on their child rmi_dev
device during system power management events. However, transport drivers
are fully registered and operational even if the physical RMI driver
failed to bind or probe the rmi_dev device.
When rmi_driver_suspend() or rmi_driver_resume() is called on an unbound
rmi_dev, dev_get_drvdata() returns NULL. Calling rmi_disable_irq() or
rmi_enable_irq() without driver data attached causes a NULL pointer
dereference and General Protection Fault when attempting to lock
data->enabled_mutex.
Fix this by checking if driver data is attached to rmi_dev in
rmi_driver_suspend() and rmi_driver_resume(), exiting early if
no driver data is present.
Fixes: 2b6a321da9a2 ("Input: synaptics-rmi4 - add support for Synaptics RMI4 devices")
Reported-by: syzbot+09103639e39c989e3ed3@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=09103639e39c989e3ed3
Cc: stable@vger.kernel.org
Assisted-by: LLM
Link: https://patch.msgid.link/anQe8UiyUR4x0flD@google.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/rmi4/rmi_driver.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -946,6 +946,15 @@ int rmi_driver_suspend(struct rmi_device
{
int retval;
+ /*
+ * Transport driver will try to suspend RMI device even if physical
+ * driver did not bind to the RMI device, because transport device
+ * (I2C, SPI) is fully registered and operational. Exit early if
+ * there is no driver data attached to the RMI device.
+ */
+ if (!dev_get_drvdata(&rmi_dev->dev))
+ return 0;
+
retval = rmi_suspend_functions(rmi_dev);
if (retval)
dev_warn(&rmi_dev->dev, "Failed to suspend functions: %d\n",
@@ -960,6 +969,10 @@ int rmi_driver_resume(struct rmi_device
{
int retval;
+ /* Skip if not fully bound to RMI driver */
+ if (!dev_get_drvdata(&rmi_dev->dev))
+ return 0;
+
rmi_enable_irq(rmi_dev, clear_wake);
retval = rmi_resume_functions(rmi_dev);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 245/877] Input: zero ff_effect before compat copy in input_ff_effect_from_user
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (243 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 244/877] Input: synaptics-rmi4 - fix GPF in suspend and resume when unbound Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 246/877] hwmon: (hp-wmi-sensors) Fix use-after-free in fungible_show() Greg Kroah-Hartman
` (639 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Iván Ezequiel Rodriguez,
Dmitry Torokhov
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Iván Ezequiel Rodriguez <ivanrwcm25@gmail.com>
commit f84819ef8d66931ee3998fee3c4f03230f4cb6cc upstream.
In the compat path input_ff_effect_from_user() aliases the caller's
native struct ff_effect with the smaller struct ff_effect_compat and
copies only the compat sized prefix:
compat_effect = (struct ff_effect_compat *)effect;
if (copy_from_user(compat_effect, buffer,
sizeof(struct ff_effect_compat)))
The tail of the native structure is never written. Callers pass an
uninitialized on-stack object, for example evdev_do_ioctl() for
EVIOCSFF, so those bytes keep their previous stack contents.
input_ff_upload() then stores the full native structure in
ff->effects[id], from where a uinput based force feedback daemon can
read it back via UI_BEGIN_FF_UPLOAD, disclosing kernel stack memory to
userspace.
Zero the effect before the compat copy.
Fixes: 2d56f3a32c0e ("Input: refactor evdev 32bit compat to be shareable with uinput")
Cc: stable@vger.kernel.org
Signed-off-by: Iván Ezequiel Rodriguez <ivanrwcm25@gmail.com>
Link: https://patch.msgid.link/20260901130629.24078-3-ivanrwcm25@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/input-compat.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/input/input-compat.c
+++ b/drivers/input/input-compat.c
@@ -75,6 +75,8 @@ int input_ff_effect_from_user(const char
*/
compat_effect = (struct ff_effect_compat *)effect;
+ memset(effect, 0, sizeof(*effect));
+
if (copy_from_user(compat_effect, buffer,
sizeof(struct ff_effect_compat)))
return -EFAULT;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 246/877] hwmon: (hp-wmi-sensors) Fix use-after-free in fungible_show()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (244 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 245/877] Input: zero ff_effect before compat copy in input_ff_effect_from_user Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 247/877] hwmon: (pmbus/core) increase number of phases and add new mask Greg Kroah-Hartman
` (638 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Muhammad Bilal, James Seo,
Guenter Roeck
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muhammad Bilal <meatuni001@gmail.com>
commit e6cb0b4d4ecb8e71fd2200d907ab2e9663356f69 upstream.
nsensor->current_state is dynamically replaced as the sensor's state
changes. update_numeric_sensor_from_wobj() does this by freeing the
old string and installing a new one:
if (strcmp(trimmed, nsensor->current_state)) {
new_string = hp_wmi_strdup(dev, trimmed);
if (new_string) {
devm_kfree(dev, nsensor->current_state);
nsensor->current_state = new_string;
}
}
This function is only ever called from hp_wmi_update_info() while
state->lock is held, so the free-and-replace itself is properly
serialized against concurrent updates.
fungible_show(), however, reads the same pointer after the lock has
already been dropped:
err = hp_wmi_update_info(state, info);
if (err)
return err;
switch (prop) {
...
case HP_WMI_PROPERTY_CURRENT_STATE:
seq_printf(seqf, "%s\n", nsensor->current_state);
break;
hp_wmi_update_info() takes state->lock internally and releases it
before returning, so by the time fungible_show() dereferences
nsensor->current_state in seq_printf(), no lock is held. Two
processes reading a sensor's current_state debugfs entry at
overlapping times (or one reading it while another read of the same
sensor triggers a refresh) can race: one thread's seq_printf() can
be part-way through printing the string at the moment another
thread's call into update_numeric_sensor_from_wobj() frees it with
devm_kfree() and installs a new pointer, causing a use-after-free
read.
Take state->lock around the read in fungible_show() as well, so it
can never run concurrently with the free-and-replace in
update_numeric_sensor_from_wobj().
Fixes: 23902f98f8d4 ("hwmon: add HP WMI Sensors driver")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Acked-by: James Seo <james@equiv.tech>
Link: https://patch.msgid.link/20260916002926.161595-1-meatuni001@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hwmon/hp-wmi-sensors.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/hwmon/hp-wmi-sensors.c
+++ b/drivers/hwmon/hp-wmi-sensors.c
@@ -1247,7 +1247,9 @@ static int fungible_show(struct seq_file
break;
case HP_WMI_PROPERTY_CURRENT_STATE:
+ mutex_lock(&state->lock);
seq_printf(seqf, "%s\n", nsensor->current_state);
+ mutex_unlock(&state->lock);
break;
case HP_WMI_PROPERTY_UNIT_MODIFIER:
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 247/877] hwmon: (pmbus/core) increase number of phases and add new mask
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (245 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 246/877] hwmon: (hp-wmi-sensors) Fix use-after-free in fungible_show() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 248/877] hwmon: (pmbus/tps53679) Fix TPS53676 phase page decoding Greg Kroah-Hartman
` (637 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Nuno Sá, Guenter Roeck
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nuno Sá <nuno.sa@analog.com>
commit 06bd6794b5fd2163880ac3bfe973d4cc61f359f3 upstream.
Increase the number of phases to 16 as a new upcoming device supports
such a number.
While at it, add a new mask for controlling the source of the output
voltage.
Note (groeck):
This patch was meant to prepare for support of MAX20826 and compatible
devices, which support more than 10 phases per page. However, Sashiko
reports that the mp2975 driver already supports up to 14 phases, and the
mp2856 driver supports up to 12 phases. This already has the potential for
out-of-bounds writes when probing the affected chips, making this patch a
bug fix.
Fixes: 2c6fcbb21149 ("hwmon: (pmbus) Add support for MPS Multi-phase mp2975 controller")
Fixes: f9e5f289b686 ("hwmon: (pmbus) Add support for MPS Multi-phase mp2856/mp2857 controller")
Signed-off-by: Nuno Sá <nuno.sa@analog.com>
Link: https://patch.msgid.link/20260911-hwmon-max20826-support-v2-1-5e30cbd97d84@analog.com
Cc: stable@vger.kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hwmon/pmbus/pmbus.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/hwmon/pmbus/pmbus.h
+++ b/drivers/hwmon/pmbus/pmbus.h
@@ -241,6 +241,7 @@ enum pmbus_regs {
/*
* OPERATION
*/
+#define PB_OPERATION_CONTROL_V_SRC GENMASK(5, 4)
#define PB_OPERATION_CONTROL_ON BIT(7)
/*
@@ -385,7 +386,7 @@ enum pmbus_sensor_classes {
};
#define PMBUS_PAGES 32 /* Per PMBus specification */
-#define PMBUS_PHASES 10 /* Maximum number of phases per page */
+#define PMBUS_PHASES 16 /* Maximum number of phases per page */
/* Functionality bit mask */
#define PMBUS_HAVE_VIN BIT(0)
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 248/877] hwmon: (pmbus/tps53679) Fix TPS53676 phase page decoding
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (246 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 247/877] hwmon: (pmbus/core) increase number of phases and add new mask Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 249/877] hwmon: (pmbus/tps53679) Select page 0 for single-page TPS53676 Greg Kroah-Hartman
` (636 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sanman Pradhan, Guenter Roeck
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sanman Pradhan <psanman@juniper.net>
commit 1d12fb94ac0975566545871dda100df34df5f845 upstream.
tps53676_identify() reads the USER_DATA_03 phase configuration to count
the phases assigned to each channel and derive the number of PMBus pages.
In each 16-bit phase descriptor the channel (PAGE) is encoded in bit 4 and
the firing order in bits 3:0, but the code tested bit 3 (0x08), which is
part of the firing-order field.
TPS53676 supports up to seven phases, so firing-order bit 3 is never set.
As a result the existing test classifies every enabled phase as channel A.
On a dual-channel configuration the phases assigned to channel B are
therefore miscounted as channel A and page 1 is not exposed.
Test the PAGE field (bit 4) instead.
Fixes: cb3d37b59012 ("hwmon: (pmbus/tps53679) Add support for TI TPS53676")
Cc: stable@vger.kernel.org
Signed-off-by: Sanman Pradhan <psanman@juniper.net>
Link: https://patch.msgid.link/20260915164823.160977-2-sanman.pradhan@hpe.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hwmon/pmbus/tps53679.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/hwmon/pmbus/tps53679.c
+++ b/drivers/hwmon/pmbus/tps53679.c
@@ -168,7 +168,7 @@ static int tps53676_identify(struct i2c_
return -EIO;
for (i = 0; i < 2 * TPS53676_MAX_PHASES; i += 2) {
if (buf[i + 1] & 0x80) {
- if (buf[i] & 0x08)
+ if (buf[i] & BIT(4))
phases_b++;
else
phases_a++;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 249/877] hwmon: (pmbus/tps53679) Select page 0 for single-page TPS53676
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (247 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 248/877] hwmon: (pmbus/tps53679) Fix TPS53676 phase page decoding Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 250/877] hwmon: (w83791d) remove fan/pwm 4-5 sysfs group on remove Greg Kroah-Hartman
` (635 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sanman Pradhan, Guenter Roeck
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sanman Pradhan <psanman@juniper.net>
commit 089070b51ccbac411462a30a454690274c6e4270 upstream.
tps53676_identify() derives the number of PMBus pages but does not
ensure that page 0 is selected for single-page configurations.
pmbus_set_page() does not update the PAGE register when info->pages is
1, so if boot firmware leaves PAGE set to another value subsequent
register accesses may target the wrong page.
For single-page devices, select page 0 explicitly.
Fixes: cb3d37b59012 ("hwmon: (pmbus/tps53679) Add support for TI TPS53676")
Cc: stable@vger.kernel.org
Signed-off-by: Sanman Pradhan <psanman@juniper.net>
Link: https://patch.msgid.link/20260916235406.681131-2-sanman.pradhan@hpe.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hwmon/pmbus/tps53679.c | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/drivers/hwmon/pmbus/tps53679.c
+++ b/drivers/hwmon/pmbus/tps53679.c
@@ -181,6 +181,15 @@ static int tps53676_identify(struct i2c_
if (phases_b > 0) {
info->pages = 2;
info->phases[1] = phases_b;
+ } else {
+ /*
+ * pmbus_set_page() does not update the PAGE register on
+ * single-page devices, so select page 0 explicitly in case
+ * the boot firmware left the device on another page.
+ */
+ ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
+ if (ret < 0)
+ return ret;
}
return 0;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 250/877] hwmon: (w83791d) remove fan/pwm 4-5 sysfs group on remove
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (248 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 249/877] hwmon: (pmbus/tps53679) Select page 0 for single-page TPS53676 Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 251/877] hwmon: (w83793) release probe data through kref Greg Kroah-Hartman
` (634 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Guenter Roeck
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <lgs201920130244@gmail.com>
commit 0ff9c7775e51ac6d47b1bb5c46f06b1434fe58a8 upstream.
When the fan/pwm 4-5 pins are not used as GPIO, w83791d_probe()
creates the w83791d_group_fanpwm45 sysfs group on the I2C client
device.
The probe error path removes this group when a later initialization
step fails, but the normal remove path only removes w83791d_group.
As a result, the optional fan/pwm 4-5 sysfs files can remain after the
driver is unbound.
The callbacks associated with these files access the driver data,
which is devm allocated and released after driver unbind. Leaving the
sysfs files behind can therefore result in accesses to stale driver
data.
Remove w83791d_group_fanpwm45 during normal teardown as well.
This issue was found by manual code inspection.
Fixes: 6e1ecd9b8f13 ("hwmon: (w83791d) fan 4/5 pins can also be used for gpio")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Link: https://patch.msgid.link/20260914062809.1650538-1-lgs201920130244@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hwmon/w83791d.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/hwmon/w83791d.c
+++ b/drivers/hwmon/w83791d.c
@@ -1415,6 +1415,7 @@ static void w83791d_remove(struct i2c_cl
struct w83791d_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &w83791d_group_fanpwm45);
sysfs_remove_group(&client->dev.kobj, &w83791d_group);
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 251/877] hwmon: (w83793) release probe data through kref
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (249 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 250/877] hwmon: (w83791d) remove fan/pwm 4-5 sysfs group on remove Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 252/877] watchdog: da9063: fix suspend/resume handling of HW_RUNNING watchdog Greg Kroah-Hartman
` (633 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Guenter Roeck
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <lgs201920130244@gmail.com>
commit c702a5f18b780e477eccbbab558e590e9673e4cb upstream.
w83793_probe() initializes data->kref to manage the lifetime of the
driver data. The normal remove path drops the driver-owned reference
with kref_put(), while watchdog users take and release additional
references through the same kref.
However, the probe error path still frees data directly with kfree().
This bypasses the kref-managed lifetime and discards the initial
reference without a matching kref_put(), leaving the reference
accounting unbalanced.
Drop the probe-owned reference with kref_put() instead and let
w83793_release_resources() perform the final free, matching the normal
remove path.
This issue was found by manual code inspection.
Fixes: 5852f9609d21 ("hwmon: (w83793) Add watchdog functionality")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Link: https://patch.msgid.link/20260914073638.1662500-1-lgs201920130244@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hwmon/w83793.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/hwmon/w83793.c
+++ b/drivers/hwmon/w83793.c
@@ -1928,7 +1928,9 @@ exit_remove:
for (i = 0; i < ARRAY_SIZE(w83793_temp); i++)
device_remove_file(dev, &w83793_temp[i].dev_attr);
free_mem:
- kfree(data);
+ mutex_lock(&watchdog_data_mutex);
+ kref_put(&data->kref, w83793_release_resources);
+ mutex_unlock(&watchdog_data_mutex);
exit:
return err;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 252/877] watchdog: da9063: fix suspend/resume handling of HW_RUNNING watchdog
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (250 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 251/877] hwmon: (w83793) release probe data through kref Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 253/877] watchdog: digicolor: Avoid division by zero Greg Kroah-Hartman
` (632 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Li Jun, Guenter Roeck
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Jun <lijun01@kylinos.cn>
commit 7cb575b71ab98194d2e040bded3a7281e089c5ed upstream.
da9063_wdt_suspend() and da9063_wdt_resume() only check watchdog_active(),
when the watchdog is left running by the driver sets
WDOG_HW_RUNNING in da9063_wdt_probe() but userspace never opens the
device, so WDOG_ACTIVE remains cleared, the wdt_disable() will not be
executed in da9063_wdt_suspend. In this case, the suspend callback is
a no-op and the watchdog keeps counting during system suspend,
leading to an unexpected system reset.
Check WDOG_HW_RUNNING and wdd,can fix this issue.
Fixes: a7ceca4398bc8 ("watchdog: da9063: optionally disable watchdog during suspend")
Cc: stable@vger.kernel.org
Signed-off-by: Li Jun <lijun01@kylinos.cn>
Link: https://patch.msgid.link/20260917013710.2754679-1-lijun01@kylinos.cn
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/watchdog/da9063_wdt.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/watchdog/da9063_wdt.c
+++ b/drivers/watchdog/da9063_wdt.c
@@ -271,7 +271,7 @@ static int __maybe_unused da9063_wdt_sus
if (!use_sw_pm)
return 0;
- if (watchdog_active(wdd))
+ if (watchdog_active(wdd) || watchdog_hw_running(wdd))
return da9063_wdt_stop(wdd);
return 0;
@@ -284,7 +284,7 @@ static int __maybe_unused da9063_wdt_res
if (!use_sw_pm)
return 0;
- if (watchdog_active(wdd))
+ if (watchdog_active(wdd) || watchdog_hw_running(wdd))
return da9063_wdt_start(wdd);
return 0;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 253/877] watchdog: digicolor: Avoid division by zero
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (251 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 252/877] watchdog: da9063: fix suspend/resume handling of HW_RUNNING watchdog Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 254/877] watchdog: msc313e: Fix premature reset during timeout update Greg Kroah-Hartman
` (631 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tzung-Bi Shih, Baruch Siach,
Guenter Roeck
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tzung-Bi Shih <tzungbi@kernel.org>
commit 400cb663ca019bae6eb878f06f1094ddf7c0b0df upstream.
clk_get_rate() could return 0. Avoid a division by zero panic.
Since get_timeleft() cannot propagate errors, check the clock rate early
in probe() and cache the rate in the driver data as it is unlikely to
change at runtime.
Fixes: 336694a01dae ("watchdog: digicolor: driver for Conexant Digicolor CX92755 SoC")
Cc: stable@vger.kernel.org
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Acked-by: Baruch Siach <baruch@tkos.co.il>
Link: https://patch.msgid.link/20260913064851.8239-2-tzungbi@kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/watchdog/digicolor_wdt.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
--- a/drivers/watchdog/digicolor_wdt.c
+++ b/drivers/watchdog/digicolor_wdt.c
@@ -25,6 +25,7 @@ struct dc_wdt {
void __iomem *base;
struct clk *clk;
spinlock_t lock;
+ unsigned long rate;
};
static unsigned timeout;
@@ -61,7 +62,7 @@ static int dc_wdt_start(struct watchdog_
{
struct dc_wdt *wdt = watchdog_get_drvdata(wdog);
- dc_wdt_set(wdt, wdog->timeout * clk_get_rate(wdt->clk));
+ dc_wdt_set(wdt, wdog->timeout * wdt->rate);
return 0;
}
@@ -79,7 +80,7 @@ static int dc_wdt_set_timeout(struct wat
{
struct dc_wdt *wdt = watchdog_get_drvdata(wdog);
- dc_wdt_set(wdt, t * clk_get_rate(wdt->clk));
+ dc_wdt_set(wdt, t * wdt->rate);
wdog->timeout = t;
return 0;
@@ -90,7 +91,7 @@ static unsigned int dc_wdt_get_timeleft(
struct dc_wdt *wdt = watchdog_get_drvdata(wdog);
uint32_t count = readl_relaxed(wdt->base + TIMER_A_COUNT);
- return count / clk_get_rate(wdt->clk);
+ return count / wdt->rate;
}
static const struct watchdog_ops dc_wdt_ops = {
@@ -130,7 +131,11 @@ static int dc_wdt_probe(struct platform_
wdt->clk = devm_clk_get(dev, NULL);
if (IS_ERR(wdt->clk))
return PTR_ERR(wdt->clk);
- dc_wdt_wdd.max_timeout = U32_MAX / clk_get_rate(wdt->clk);
+
+ wdt->rate = clk_get_rate(wdt->clk);
+ if (!wdt->rate)
+ return -EINVAL;
+ dc_wdt_wdd.max_timeout = U32_MAX / wdt->rate;
dc_wdt_wdd.timeout = dc_wdt_wdd.max_timeout;
dc_wdt_wdd.parent = dev;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 254/877] watchdog: msc313e: Fix premature reset during timeout update
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (252 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 253/877] watchdog: digicolor: Avoid division by zero Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 255/877] watchdog: msc313e: Propagate error code in resume() Greg Kroah-Hartman
` (630 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Tzung-Bi Shih, Guenter Roeck
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tzung-Bi Shih <tzungbi@kernel.org>
commit 22737cfced627ffcb4b5c36d63bb3d4476f63213 upstream.
Updating the 32-bit hardware timeout requires writing to two 16-bit
registers sequentially. If the watchdog is actively running, this
non-atomic update might trigger a premature system reset.
Clear the watchdog counter before updating the registers to prevent the
timer from timing out prematurely against an intermediate threshold.
Fixes: e9800b799464 ("watchdog: Add Mstar MSC313e WDT driver")
Cc: stable@vger.kernel.org
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://patch.msgid.link/20260913065126.8350-1-tzungbi@kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/watchdog/msc313e_wdt.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/drivers/watchdog/msc313e_wdt.c
+++ b/drivers/watchdog/msc313e_wdt.c
@@ -47,6 +47,9 @@ static void msc313e_wdt_set_hw_timeout(s
{
u32 t = timeout * clk_get_rate(priv->clk);
+ /* Clear before to prevent premature reset during non-atomic updates. */
+ writew(1, priv->base + REG_WDT_CLR);
+
writew(t & 0xffff, priv->base + REG_WDT_MAX_PRD_L);
writew((t >> 16) & 0xffff, priv->base + REG_WDT_MAX_PRD_H);
writew(1, priv->base + REG_WDT_CLR);
@@ -77,6 +80,9 @@ static int msc313e_wdt_stop(struct watch
{
struct msc313e_wdt_priv *priv = watchdog_get_drvdata(wdev);
+ /* Clear before to prevent premature reset during non-atomic updates. */
+ writew(1, priv->base + REG_WDT_CLR);
+
writew(0, priv->base + REG_WDT_MAX_PRD_L);
writew(0, priv->base + REG_WDT_MAX_PRD_H);
writew(0, priv->base + REG_WDT_CLR);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 255/877] watchdog: msc313e: Propagate error code in resume()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (253 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 254/877] watchdog: msc313e: Fix premature reset during timeout update Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 256/877] watchdog: rtd119x: Avoid division by zero Greg Kroah-Hartman
` (629 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Tzung-Bi Shih, Guenter Roeck
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tzung-Bi Shih <tzungbi@kernel.org>
commit 1d9763f34a85680db1e8233d654fdb85e5f897cc upstream.
If msc313e_wdt_start() fails during system resume, the error is
currently ignored. Consequently, the watchdog isn't running without the
user's knowledge.
Propagate the error code and print a message if msc313e_wdt_start()
fails.
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Fixes: e9800b7994642 ("watchdog: Add Mstar MSC313e WDT driver")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260912163334.28636-1-tzungbi@kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/watchdog/msc313e_wdt.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
--- a/drivers/watchdog/msc313e_wdt.c
+++ b/drivers/watchdog/msc313e_wdt.c
@@ -198,11 +198,15 @@ static int __maybe_unused msc313e_wdt_su
static int __maybe_unused msc313e_wdt_resume(struct device *dev)
{
struct msc313e_wdt_priv *priv = dev_get_drvdata(dev);
+ int ret = 0;
- if (watchdog_active(&priv->wdev) || watchdog_hw_running(&priv->wdev))
- msc313e_wdt_start(&priv->wdev);
+ if (watchdog_active(&priv->wdev) || watchdog_hw_running(&priv->wdev)) {
+ ret = msc313e_wdt_start(&priv->wdev);
+ if (ret)
+ dev_err(dev, "Failed to restart watchdog (err=%d)\n", ret);
+ }
- return 0;
+ return ret;
}
static SIMPLE_DEV_PM_OPS(msc313e_wdt_pm_ops, msc313e_wdt_suspend, msc313e_wdt_resume);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 256/877] watchdog: rtd119x: Avoid division by zero
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (254 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 255/877] watchdog: msc313e: Propagate error code in resume() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 257/877] watchdog: sp5100_tco: Fix pci_dev reference leak in sp5100_tco_init() Greg Kroah-Hartman
` (628 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Tzung-Bi Shih, Guenter Roeck
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tzung-Bi Shih <tzungbi@kernel.org>
commit 5af7d2cbd20f893def03c8310a460ade66a5d822 upstream.
clk_get_rate() could return 0. Avoid a division by zero panic.
Fixes: 2bdf6acbfead ("watchdog: Add Realtek RTD1295")
Cc: stable@vger.kernel.org
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://patch.msgid.link/20260913064851.8239-3-tzungbi@kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/watchdog/rtd119x_wdt.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
--- a/drivers/watchdog/rtd119x_wdt.c
+++ b/drivers/watchdog/rtd119x_wdt.c
@@ -98,6 +98,7 @@ static int rtd119x_wdt_probe(struct plat
{
struct device *dev = &pdev->dev;
struct rtd119x_watchdog_device *data;
+ unsigned long rate;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
@@ -111,10 +112,14 @@ static int rtd119x_wdt_probe(struct plat
if (IS_ERR(data->clk))
return PTR_ERR(data->clk);
+ rate = clk_get_rate(data->clk);
+ if (!rate)
+ return -EINVAL;
+
data->wdt_dev.info = &rtd119x_wdt_info;
data->wdt_dev.ops = &rtd119x_wdt_ops;
data->wdt_dev.timeout = 120;
- data->wdt_dev.max_timeout = 0xffffffff / clk_get_rate(data->clk);
+ data->wdt_dev.max_timeout = 0xffffffff / rate;
data->wdt_dev.min_timeout = 1;
data->wdt_dev.parent = dev;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 257/877] watchdog: sp5100_tco: Fix pci_dev reference leak in sp5100_tco_init()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (255 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 256/877] watchdog: rtd119x: Avoid division by zero Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 258/877] watchdog: starfive-wdt: Fix runtime PM leak in starfive_wdt_pm_start() Greg Kroah-Hartman
` (627 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Guenter Roeck
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit 88f113634028ca90a857031837d8061d1a9e1a7b upstream.
sp5100_tco_init() stores the PCI device matched by for_each_pci_dev()
in the global sp5100_tco_pci and keeps its reference for the lifetime
of the driver, but neither sp5100_tco_exit() nor the error paths of
sp5100_tco_init() call pci_dev_put(), leaking the reference on driver
registration failure and on every module load/unload cycle.
Drop the reference when the platform driver or device registration
fails and when the module is unloaded.
Fixes: 15e28bf13008 ("watchdog: Add support for sp5100 chipset TCO")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Link: https://patch.msgid.link/20260916170511.2086199-1-vulab@iscas.ac.cn
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/watchdog/sp5100_tco.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/watchdog/sp5100_tco.c
+++ b/drivers/watchdog/sp5100_tco.c
@@ -605,8 +605,10 @@ static int __init sp5100_tco_init(void)
pr_info("SP5100/SB800 TCO WatchDog Timer Driver\n");
err = platform_driver_register(&sp5100_tco_driver);
- if (err)
+ if (err) {
+ pci_dev_put(sp5100_tco_pci);
return err;
+ }
sp5100_tco_platform_device =
platform_device_register_simple(TCO_DRIVER_NAME, -1, NULL, 0);
@@ -619,6 +621,7 @@ static int __init sp5100_tco_init(void)
unreg_platform_driver:
platform_driver_unregister(&sp5100_tco_driver);
+ pci_dev_put(sp5100_tco_pci);
return err;
}
@@ -626,6 +629,7 @@ static void __exit sp5100_tco_exit(void)
{
platform_device_unregister(sp5100_tco_platform_device);
platform_driver_unregister(&sp5100_tco_driver);
+ pci_dev_put(sp5100_tco_pci);
}
module_init(sp5100_tco_init);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 258/877] watchdog: starfive-wdt: Fix runtime PM leak in starfive_wdt_pm_start()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (256 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 257/877] watchdog: sp5100_tco: Fix pci_dev reference leak in sp5100_tco_init() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 259/877] wifi: brcmsmac: fix UAF in brcms_free_timer() Greg Kroah-Hartman
` (626 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Guenter Roeck
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit 8f0ca55016a7647109ae2bc91bcb346fc8b13785 upstream.
starfive_wdt_pm_start() takes a runtime PM reference with
pm_runtime_get_sync(), which increments the usage counter even when it
fails, and returns the error without dropping it again. The watchdog
core does not invoke the stop callback when start fails, so the
reference taken on the error path is leaked.
Use pm_runtime_resume_and_get() instead, which keeps the usage counter
balanced when the resume fails.
Fixes: db728ea9c7be ("drivers: watchdog: Add StarFive Watchdog driver")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Link: https://patch.msgid.link/20260916170704.2086331-1-vulab@iscas.ac.cn
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/watchdog/starfive-wdt.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/watchdog/starfive-wdt.c
+++ b/drivers/watchdog/starfive-wdt.c
@@ -371,7 +371,7 @@ static void starfive_wdt_stop(struct sta
static int starfive_wdt_pm_start(struct watchdog_device *wdd)
{
struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
- int ret = pm_runtime_get_sync(wdd->parent);
+ int ret = pm_runtime_resume_and_get(wdd->parent);
if (ret < 0)
return ret;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 259/877] wifi: brcmsmac: fix UAF in brcms_free_timer()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (257 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 258/877] watchdog: starfive-wdt: Fix runtime PM leak in starfive_wdt_pm_start() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 260/877] wifi: iwlegacy: fix broadcast stations deallocation Greg Kroah-Hartman
` (625 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jiangshan Yi, Arend van Spriel,
Johannes Berg
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiangshan Yi <yijiangshan@kylinos.cn>
commit 1eeca1d5e0920fbdad6449768fd2d4364e714180 upstream.
brcms_free_timer() calls brcms_del_timer() which uses the non-synchronous
cancel_delayed_work() to cancel the timer's underlying delayed work. If
the work callback (_brcms_timer) is already running, cancel_delayed_work()
returns false without waiting, and brcms_free_timer() proceeds to kfree(t)
while the callback still accesses t through container_of().
Add an explicit cancel_delayed_work_sync() after brcms_del_timer() to
guarantee that any in-flight callback has completed before the timer
structure is freed.
Fixes: 5b435de0d786 ("net: wireless: add brcm80211 drivers")
Cc: stable@vger.kernel.org
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Link: https://patch.msgid.link/20260815121043.938414-1-yijiangshan@kylinos.cn
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
@@ -1569,6 +1569,10 @@ void brcms_free_timer(struct brcms_timer
/* delete the timer in case it is active */
brcms_del_timer(t);
+ /* Ensure the callback has finished before freeing the timer
+ * structure, since brcms_del_timer() uses non-synchronous cancel.
+ */
+ cancel_delayed_work_sync(&t->dly_wrk);
if (wl->timers == t) {
wl->timers = wl->timers->next;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 260/877] wifi: iwlegacy: fix broadcast stations deallocation
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (258 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 259/877] wifi: brcmsmac: fix UAF in brcms_free_timer() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 261/877] wifi: libertas_tf: fix UAF in lbtf_free_adapter() Greg Kroah-Hartman
` (624 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Stanislaw Gruszka, Johannes Berg,
Martin-Éric Racine
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stanislaw Gruszka <stf_xl@wp.pl>
commit b5526b780f8b297a76030410b96ba29153afb98f upstream.
On the error path of __il4965_up(), il_dealloc_bcast_stations() clears
only IL_STA_UCODE_ACTIVE, leaving IL_STA_BCAST set. This causes the
same broadcast stations to be deallocated again by __il4965_down().
This can occur when RF_KILL is toggled during driver startup.
To fix clear the entire 'used' field, since we will not do any
other operations on the station.
Reported-and-tested-by: Martin-Éric Racine <martin-eric.racine+kernel-bugzilla@iki.fi>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221733
Fixes: c2fd34469d16 ("iwl4965: Fix a memory leak in error handling code of __il4965_up")
Cc: <stable@vger.kernel.org> # 7.1.x: 57aa1718d595 wifi: iwlegacy: replace BUG_ON() with WARN_ON() on num_stations check
Cc: <stable@vger.kernel.org> # 6.x.x: 57aa1718d595 wifi: iwlegacy: replace BUG_ON() with WARN_ON() on num_stations check
Cc: <stable@vger.kernel.org> # 5.x.x: 57aa1718d595 wifi: iwlegacy: replace BUG_ON() with WARN_ON() on num_stations check
Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl>
Link: https://patch.msgid.link/20260820093059.18779-1-stf_xl@wp.pl
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/intel/iwlegacy/common.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/wireless/intel/iwlegacy/common.c
+++ b/drivers/net/wireless/intel/iwlegacy/common.c
@@ -2327,7 +2327,7 @@ il_dealloc_bcast_stations(struct il_priv
if (!(il->stations[i].used & IL_STA_BCAST))
continue;
- il->stations[i].used &= ~IL_STA_UCODE_ACTIVE;
+ il->stations[i].used = 0;
il->num_stations--;
BUG_ON(il->num_stations < 0);
kfree(il->stations[i].lq);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 261/877] wifi: libertas_tf: fix UAF in lbtf_free_adapter()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (259 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 260/877] wifi: iwlegacy: fix broadcast stations deallocation Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 262/877] wifi: rsi: fix heap OOB write on key removal Greg Kroah-Hartman
` (623 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jiangshan Yi, Johannes Berg
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiangshan Yi <yijiangshan@kylinos.cn>
commit bbb9a0ab96d44a64529aafc7a16de460a1712f6a upstream.
lbtf_free_adapter() calls lbtf_free_cmd_buffer() to free the command
buffers before calling timer_delete_sync() to wait for the command
timer callback. If the timer callback (command_timer_fn) is already
running when lbtf_free_cmd_buffer() frees the command array, the
callback dereferences priv->cur_cmd->cmdbuf which points to freed
memory.
Swap the order so that timer_delete_sync() runs first, ensuring any
in-flight callback has completed before the command buffers are freed.
Fixes: 06b16ae53192 ("libertas_tf: main.c, data paths and mac80211 handlers")
Cc: stable@vger.kernel.org
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Link: https://patch.msgid.link/20260815115724.920628-1-yijiangshan@kylinos.cn
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/marvell/libertas_tf/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/wireless/marvell/libertas_tf/main.c
+++ b/drivers/net/wireless/marvell/libertas_tf/main.c
@@ -173,8 +173,8 @@ static int lbtf_init_adapter(struct lbtf
static void lbtf_free_adapter(struct lbtf_private *priv)
{
lbtf_deb_enter(LBTF_DEB_MAIN);
- lbtf_free_cmd_buffer(priv);
timer_delete_sync(&priv->command_timer);
+ lbtf_free_cmd_buffer(priv);
lbtf_deb_leave(LBTF_DEB_MAIN);
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 262/877] wifi: rsi: fix heap OOB write on key removal
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (260 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 261/877] wifi: libertas_tf: fix UAF in lbtf_free_adapter() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 263/877] wifi: wlcore: release runtime PM ref on regdomain config failure Greg Kroah-Hartman
` (622 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Tianchu Chen, Johannes Berg
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tianchu Chen <flynnnchen@tencent.com>
commit e6c5ed7a98d7bc8b0f7918246f1c90ddb3f79dfa upstream.
When a key is removed (data == NULL), rsi_hal_load_key() runs:
memset(&set_key[FRAME_DESC_SZ], 0, frame_len - FRAME_DESC_SZ);
set_key is a struct rsi_set_key *, so the subscript is scaled by
sizeof(struct rsi_set_key) (160 bytes): &set_key[FRAME_DESC_SZ] is
skb->data + 2560, and the memset writes 144 zero bytes starting
2.4KB past the end of the 160-byte skb data buffer, corrupting
unrelated heap objects. The intended byte offset would have been
(u8 *)set_key + FRAME_DESC_SZ.
The write fires on every DISABLE_KEY callback, so plain disconnects,
roams and interface teardowns trigger it on real networks.
The memset is redundant: the whole buffer is zeroed right after
allocation, so the frame sent to the device is byte-identical
without it. Drop the else branch; normal operation is unaffected.
Discovered by Atuin - Automated Vulnerability Discovery Engine.
Fixes: dad0d04fa7ba ("rsi: Add RS9113 wireless driver")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Tianchu Chen <flynnnchen@tencent.com>
Link: https://patch.msgid.link/90bb2b07007942064c04aa3729cedd9eb1e930b1@linux.dev
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/rsi/rsi_91x_mgmt.c | 2 --
1 file changed, 2 deletions(-)
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -852,8 +852,6 @@ int rsi_hal_load_key(struct rsi_common *
memcpy(set_key->tx_mic_key, &data[16], 8);
memcpy(set_key->rx_mic_key, &data[24], 8);
}
- } else {
- memset(&set_key[FRAME_DESC_SZ], 0, frame_len - FRAME_DESC_SZ);
}
skb_put(skb, frame_len);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 263/877] wifi: wlcore: release runtime PM ref on regdomain config failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (261 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 262/877] wifi: rsi: fix heap OOB write on key removal Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 264/877] wifi: wilc1000: fix out-of-bounds read in P2P public action frames Greg Kroah-Hartman
` (621 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Runyu Xiao, Johannes Berg
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Runyu Xiao <runyu.xiao@seu.edu.cn>
commit 8a1f3cf89ddcc700e25afe42cfad333059adcc94 upstream.
wlcore_regdomain_config() gets a runtime PM reference before sending
the regulatory-domain command. When
wlcore_cmd_regdomain_config_locked() fails, the function queues recovery
and returns without dropping that reference.
Release the reference after handling the command result so both success
and failure paths balance the preceding
pm_runtime_resume_and_get(). The recovery worker takes a separate
runtime PM reference and cannot release the reference held here.
Fixes: fa2648a34e73 ("wlcore: Add support for runtime PM")
Cc: stable@vger.kernel.org
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Link: https://patch.msgid.link/20260820125126.12757-1-runyu.xiao@seu.edu.cn
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/ti/wlcore/main.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -3718,10 +3718,8 @@ void wlcore_regdomain_config(struct wl12
goto out;
ret = wlcore_cmd_regdomain_config_locked(wl);
- if (ret < 0) {
+ if (ret < 0)
wl12xx_queue_recovery_work(wl);
- goto out;
- }
pm_runtime_mark_last_busy(wl->dev);
pm_runtime_put_autosuspend(wl->dev);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 264/877] wifi: wilc1000: fix out-of-bounds read in P2P public action frames
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (262 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 263/877] wifi: wlcore: release runtime PM ref on regdomain config failure Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 265/877] wifi: wilc1000: fix RX buffer OOB-write in wilc_wlan_handle_isr_ext() Greg Kroah-Hartman
` (620 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ali Ahmet Memis, Johannes Berg
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ali Ahmet Memis <ali@iusegentoo.com>
commit ba6cb7c0868a412c2eb68e8efd5aa38bfb258a14 upstream.
wilc_wfi_p2p_rx() and mgmt_tx() start parsing a frame once
ieee80211_is_public_action() returns true. That helper only verifies the
frame is long enough for the action category field, that is
offsetofend(struct ieee80211_mgmt, u.action.category), 25 bytes. Both
functions then read the P2P public action header up to oui_subtype at
offset 30 and pass "size - ie_offset" to cfg80211_find_vendor_ie(), where
ie_offset is offsetof(struct ieee80211_mgmt, u) + sizeof(*d), i.e. 32.
A public action frame of 25 to 31 bytes passes the check but is shorter
than that 32 byte header, so oui_subtype can be read out of bounds, and
because the length is unsigned, "size - ie_offset" underflows to a value
close to 4 GiB. cfg80211_find_vendor_ie() takes an unsigned int length,
so even the size_t subtraction in mgmt_tx() is truncated to the same
value. It then walks far past the buffer searching for a vendor element
until it reaches unmapped memory.
In the receive path the frame arrives over the air and needs no
association, so a nearby unauthenticated device can crash the host while
it is in P2P listen. Reject frames shorter than the P2P public action
header in both paths before dereferencing it.
Fixes: 4fb8b5aa2a11 ("staging: wilc1000: refactor p2p action frames handling API's")
Cc: stable@vger.kernel.org
Signed-off-by: Ali Ahmet Memis <ali@iusegentoo.com>
Link: https://patch.msgid.link/20260807115230.136767-1-ali@iusegentoo.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/microchip/wilc1000/cfg80211.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
--- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c
+++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
@@ -1066,6 +1066,13 @@ void wilc_wfi_p2p_rx(struct wilc_vif *vi
if (!ieee80211_is_public_action((struct ieee80211_hdr *)buff, size))
goto out_rx_mgmt;
+ /* ieee80211_is_public_action() only validates up to the category
+ * byte, so reject frames too short for the P2P public action header
+ * before dereferencing it or computing size - ie_offset.
+ */
+ if (size < ie_offset)
+ goto out_rx_mgmt;
+
d = (struct wilc_p2p_pub_act_frame *)(&mgmt->u.action);
if (d->oui_subtype != GO_NEG_REQ && d->oui_subtype != GO_NEG_RSP &&
d->oui_subtype != P2P_INV_REQ && d->oui_subtype != P2P_INV_RSP)
@@ -1214,6 +1221,13 @@ static int mgmt_tx(struct wiphy *wiphy,
goto out_set_timeout;
}
+ /* ieee80211_is_public_action() only validates up to the category
+ * byte, so reject frames too short for the P2P public action header
+ * before dereferencing it or computing len - ie_offset.
+ */
+ if (len < ie_offset)
+ goto out_set_timeout;
+
d = (struct wilc_p2p_pub_act_frame *)(&mgmt->u.action);
if (d->oui_type != WLAN_OUI_TYPE_WFA_P2P ||
d->oui_subtype != GO_NEG_CONF) {
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 265/877] wifi: wilc1000: fix RX buffer OOB-write in wilc_wlan_handle_isr_ext()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (263 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 264/877] wifi: wilc1000: fix out-of-bounds read in P2P public action frames Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 266/877] wifi: p54: validate curve data length in the calibration curve converters Greg Kroah-Hartman
` (619 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Tianchu Chen, Johannes Berg
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tianchu Chen <flynnnchen@tencent.com>
commit c1ba7f7f18465e259cf1b4d9c73fc73853d7f790 upstream.
wilc_wlan_handle_isr_ext() takes the RX transfer size from the
device-reported interrupt status register (a 15-bit field shifted left by 2,
up to 131068 bytes) and reads that many bytes from the device into
rx_buffer, which is only WILC_RX_BUFF_SIZE (96K) large. The wrap
check only handles the current offset; the size itself is never
compared against the buffer, so a bogus SDIO device can make the driver
OOB-write rx_buffer by up to ~32K with data it controls.
The oversized transfer also leaves rx_buffer_offset past the end of
the buffer, after which the unsigned wrap check stops working and
the overflow can repeat.
Drop any transfer whose size exceeds the RX buffer, acknowledging
the data interrupt and re-arming the RX engine so the bogus frame is
discarded and reception can continue. This also restores the
rx_buffer_offset <= WILC_RX_BUFF_SIZE invariant the wrap check
relies on.
This is not expected to change driver behavior in most cases:
without this check, an oversized transfer would most likely
corrupt neighboring kernel memory instead of completing anyway, and
the drop path performs the same interrupt acknowledgment and RX
engine re-arming as the normal path, so subsequent transfers are
received unaffected.
Discovered by Atuin - Automated Vulnerability Discovery Engine.
Fixes: c5c77ba18ea6 ("staging: wilc1000: Add SDIO/SPI 802.11 driver")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Tianchu Chen <flynnnchen@tencent.com>
Link: https://patch.msgid.link/7c971924c6bdccf6c2f75704a5a746e9303aaf64@linux.dev
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/microchip/wilc1000/wlan.c | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/drivers/net/wireless/microchip/wilc1000/wlan.c
+++ b/drivers/net/wireless/microchip/wilc1000/wlan.c
@@ -1035,6 +1035,15 @@ static void wilc_wlan_handle_isr_ext(str
if (size <= 0)
return;
+ /* A size exceeding the RX buffer is bogus; drop the transfer
+ * instead of overflowing the buffer.
+ */
+ if (size > WILC_RX_BUFF_SIZE) {
+ wilc->hif_func->hif_clear_int_ext(wilc,
+ DATA_INT_CLR | ENABLE_RX_VMM);
+ return;
+ }
+
if (WILC_RX_BUFF_SIZE - offset < size)
offset = 0;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 266/877] wifi: p54: validate curve data length in the calibration curve converters
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (264 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 265/877] wifi: wilc1000: fix RX buffer OOB-write in wilc_wlan_handle_isr_ext() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 267/877] wifi: p54: require a full exp_if record in PDR_INTERFACE_LIST Greg Kroah-Hartman
` (618 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Shengzhuo Wei, Johannes Berg
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengzhuo Wei <me@cherr.cc>
commit ce858fa6b8a214dee5adb82358885fa024cdd887 upstream.
p54_convert_rev0() and p54_convert_rev1() read calibration curve
data from the device-supplied EEPROM entry using channel and
points-per-channel counts taken verbatim from that same entry, so
an entry that declares more data than it carries drives an
out-of-bounds read past the EEPROM buffer (verified with a KASAN
reproducer of the conversion loop). The sibling converters
p54_convert_output_limits() and p54_convert_db() already validate
their counts against the entry length; this path was missed.
Reject the entry when the counts do not fit in the entry data.
Fixes: eff1a59c48e3 ("[P54]: add mac80211-based driver for prism54 softmac hardware")
Cc: stable@vger.kernel.org
Assisted-by: GLM:5.3
Signed-off-by: Shengzhuo Wei <me@cherr.cc>
Link: https://patch.msgid.link/20260831-p54-pda-validation-v2-1-dae566b388c8@cherr.cc
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/intersil/p54/eeprom.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
--- a/drivers/net/wireless/intersil/p54/eeprom.c
+++ b/drivers/net/wireless/intersil/p54/eeprom.c
@@ -418,17 +418,22 @@ free:
}
static int p54_convert_rev0(struct ieee80211_hw *dev,
- struct pda_pa_curve_data *curve_data)
+ struct pda_pa_curve_data *curve_data, size_t len)
{
struct p54_common *priv = dev->priv;
struct p54_pa_curve_data_sample *dst;
struct pda_pa_curve_data_sample_rev0 *src;
+ size_t needed = curve_data->channels *
+ (sizeof(*src) * curve_data->points_per_channel + 2);
size_t cd_len = sizeof(*curve_data) +
(curve_data->points_per_channel*sizeof(*dst) + 2) *
curve_data->channels;
unsigned int i, j;
void *source, *target;
+ if (len < sizeof(*curve_data) + needed)
+ return -EINVAL;
+
priv->curve_data = kmalloc(sizeof(*priv->curve_data) + cd_len,
GFP_KERNEL);
if (!priv->curve_data)
@@ -470,17 +475,22 @@ static int p54_convert_rev0(struct ieee8
}
static int p54_convert_rev1(struct ieee80211_hw *dev,
- struct pda_pa_curve_data *curve_data)
+ struct pda_pa_curve_data *curve_data, size_t len)
{
struct p54_common *priv = dev->priv;
struct p54_pa_curve_data_sample *dst;
struct pda_pa_curve_data_sample_rev1 *src;
+ size_t needed = curve_data->channels *
+ (sizeof(*src) * curve_data->points_per_channel + 3);
size_t cd_len = sizeof(*curve_data) +
(curve_data->points_per_channel*sizeof(*dst) + 2) *
curve_data->channels;
unsigned int i, j;
void *source, *target;
+ if (len < sizeof(*curve_data) + needed)
+ return -EINVAL;
+
priv->curve_data = kzalloc(cd_len + sizeof(*priv->curve_data),
GFP_KERNEL);
if (!priv->curve_data)
@@ -767,6 +777,7 @@ int p54_parse_eeprom(struct ieee80211_hw
case PDR_PRISM_PA_CAL_CURVE_DATA: {
struct pda_pa_curve_data *curve_data =
(struct pda_pa_curve_data *)entry->data;
+
if (data_len < sizeof(*curve_data)) {
err = -EINVAL;
goto err;
@@ -774,10 +785,10 @@ int p54_parse_eeprom(struct ieee80211_hw
switch (curve_data->cal_method_rev) {
case 0:
- err = p54_convert_rev0(dev, curve_data);
+ err = p54_convert_rev0(dev, curve_data, data_len);
break;
case 1:
- err = p54_convert_rev1(dev, curve_data);
+ err = p54_convert_rev1(dev, curve_data, data_len);
break;
default:
wiphy_err(dev->wiphy,
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 267/877] wifi: p54: require a full exp_if record in PDR_INTERFACE_LIST
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (265 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 266/877] wifi: p54: validate curve data length in the calibration curve converters Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 268/877] wifi: mwifiex: bound the pairwise-cipher OUI walk to the IE length Greg Kroah-Hartman
` (617 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Lamparter, Shengzhuo Wei,
Johannes Berg
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengzhuo Wei <me@cherr.cc>
commit d8efd84f49379ed28624098821f80e992657d935 upstream.
The PDR_INTERFACE_LIST loop only checks that the record start is within
the entry before reading an entire struct exp_if from it. A truncated
trailing record makes the if_id/variant reads cross the entry boundary
into the heap beyond the EEPROM buffer (verified with a KASAN
reproducer of the loop). The variant also feeds the synth front-end
selection, so this is not only a leak.
Advance only while a full record still fits in the entry.
Fixes: eff1a59c48e3 ("[P54]: add mac80211-based driver for prism54 softmac hardware")
Cc: stable@vger.kernel.org
Acked-by: Christian Lamparter <chunkeey@gmail.com>
Assisted-by: GLM:5.3
Signed-off-by: Shengzhuo Wei <me@cherr.cc>
Link: https://patch.msgid.link/20260831-p54-pda-validation-v2-2-dae566b388c8@cherr.cc
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/intersil/p54/eeprom.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/net/wireless/intersil/p54/eeprom.c
+++ b/drivers/net/wireless/intersil/p54/eeprom.c
@@ -816,7 +816,8 @@ int p54_parse_eeprom(struct ieee80211_hw
break;
case PDR_INTERFACE_LIST:
tmp = entry->data;
- while ((u8 *)tmp < entry->data + data_len) {
+ while ((u8 *)tmp + sizeof(struct exp_if) <=
+ entry->data + data_len) {
struct exp_if *exp_if = tmp;
if (exp_if->if_id == cpu_to_le16(IF_ID_ISL39000))
synth = le16_to_cpu(exp_if->variant);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 268/877] wifi: mwifiex: bound the pairwise-cipher OUI walk to the IE length
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (266 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 267/877] wifi: p54: require a full exp_if record in PDR_INTERFACE_LIST Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 269/877] wifi: mwifiex: validate scan response extents Greg Kroah-Hartman
` (616 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Doruk Tan Ozturk, Johannes Berg
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Doruk Tan Ozturk <doruk@0sec.ai>
commit e667aee1c192d67d27c803007bfa9c6e0873e959 upstream.
mwifiex_search_oui_in_ie() reads a pairwise-cipher (PTK) count from a
beacon/probe-response RSN or WPA information element and then walks that
many 4-byte OUIs, comparing each with memcmp(). The count comes straight
from the (attacker-supplied) IE and is never checked against the
element's own length, and the callers admit the element on element_id
alone (has_ieee_hdr() / has_vendor_hdr(), no length check). A crafted
RSN/WPA IE with a large pairwise count therefore makes the walk read up
to 255 * 4 bytes past the element -- an out-of-bounds read of the
kmemdup()'d beacon buffer, reachable from any AP whose beacon/probe
response is processed during scan-result parsing.
Pass the number of IE bytes available at the OUI list and bound the walk
to the element. Keep the length signed and reject a negative value
before any unsigned arithmetic, so a small or zero IE length cannot
underflow to a large size_t and defeat the bound.
Found by 0sec automated security-research tooling (https://0sec.ai).
Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver")
Cc: stable@vger.kernel.org
Assisted-by: 0sec:multi-model
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
Link: https://patch.msgid.link/20260814134704.85902-1-doruk@0sec.ai
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/marvell/mwifiex/scan.c | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
--- a/drivers/net/wireless/marvell/mwifiex/scan.c
+++ b/drivers/net/wireless/marvell/mwifiex/scan.c
@@ -104,12 +104,24 @@ has_vendor_hdr(struct ieee_types_vendor_
* a given oui in PTK.
*/
static u8
-mwifiex_search_oui_in_ie(struct ie_body *iebody, u8 *oui)
+mwifiex_search_oui_in_ie(struct ie_body *iebody, u8 *oui, int ie_len)
{
+ const size_t ptk_body_offset = offsetof(struct ie_body, ptk_body);
u8 count;
+ /* ie_len is the number of bytes available at iebody. Keep it signed
+ * and reject a negative (underflowed) length before the unsigned
+ * comparisons below, so a small or zero IE length cannot wrap.
+ */
+ if (ie_len < 0 || (size_t)ie_len < ptk_body_offset)
+ return MWIFIEX_OUI_NOT_PRESENT;
+
count = iebody->ptk_cnt[0];
+ /* Reject an OUI count whose list would run past the element. */
+ if (ptk_body_offset + count * sizeof(iebody->ptk_body) > (size_t)ie_len)
+ return MWIFIEX_OUI_NOT_PRESENT;
+
/* There could be multiple OUIs for PTK hence
1) Take the length.
2) Check all the OUIs for AES.
@@ -143,11 +155,14 @@ mwifiex_is_rsn_oui_present(struct mwifie
u8 ret = MWIFIEX_OUI_NOT_PRESENT;
if (has_ieee_hdr(bss_desc->bcn_rsn_ie, WLAN_EID_RSN)) {
+ int ie_len = (int)bss_desc->bcn_rsn_ie->ieee_hdr.len -
+ RSN_GTK_OUI_OFFSET;
+
iebody = (struct ie_body *)
(((u8 *) bss_desc->bcn_rsn_ie->data) +
RSN_GTK_OUI_OFFSET);
oui = &mwifiex_rsn_oui[cipher][0];
- ret = mwifiex_search_oui_in_ie(iebody, oui);
+ ret = mwifiex_search_oui_in_ie(iebody, oui, ie_len);
if (ret)
return ret;
}
@@ -169,10 +184,14 @@ mwifiex_is_wpa_oui_present(struct mwifie
u8 ret = MWIFIEX_OUI_NOT_PRESENT;
if (has_vendor_hdr(bss_desc->bcn_wpa_ie, WLAN_EID_VENDOR_SPECIFIC)) {
+ int ie_len = (int)bss_desc->bcn_wpa_ie->vend_hdr.len -
+ (int)sizeof(bss_desc->bcn_wpa_ie->vend_hdr.oui) -
+ WPA_GTK_OUI_OFFSET;
+
iebody = (struct ie_body *)((u8 *)bss_desc->bcn_wpa_ie->data +
WPA_GTK_OUI_OFFSET);
oui = &mwifiex_wpa_oui[cipher][0];
- ret = mwifiex_search_oui_in_ie(iebody, oui);
+ ret = mwifiex_search_oui_in_ie(iebody, oui, ie_len);
if (ret)
return ret;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 269/877] wifi: mwifiex: validate scan response extents
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (267 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 268/877] wifi: mwifiex: bound the pairwise-cipher OUI walk to the IE length Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 270/877] wifi: mwifiex: prevent authentication frame length truncation Greg Kroah-Hartman
` (615 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Pengpeng Hou, Johannes Berg
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <pengpeng@iscas.ac.cn>
commit 3687d7d48070838cc2953431b3a27717cab0aaf6 upstream.
mwifiex_ret_802_11_scan() subtracts the fixed response fields and the
firmware-provided BSS length from resp->size without first proving that
either extent fits. A short response or oversized BSS length can
therefore underflow tlv_buf_size and make the TLV parser walk beyond the
command response.
Compute the fixed extent from the selected normal or background scan
response. Validate that the fixed fields and BSS data fit before deriving
the TLV extent and entering the parser.
Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260815135227.50392-1-pengpeng@iscas.ac.cn
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/marvell/mwifiex/scan.c | 29 ++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)
--- a/drivers/net/wireless/marvell/mwifiex/scan.c
+++ b/drivers/net/wireless/marvell/mwifiex/scan.c
@@ -2117,6 +2117,7 @@ int mwifiex_ret_802_11_scan(struct mwifi
u32 bytes_left;
u32 idx;
u32 tlv_buf_size;
+ size_t fixed_size;
struct mwifiex_ie_types_chan_band_list_param_set *chan_band_tlv;
struct chan_band_param_set *chan_band;
u8 is_bgscan_resp;
@@ -2132,6 +2133,14 @@ int mwifiex_ret_802_11_scan(struct mwifi
else
scan_rsp = &resp->params.scan_resp;
+ scan_resp_size = le16_to_cpu(resp->size);
+ fixed_size = scan_rsp->bss_desc_and_tlv_buffer - (u8 *)resp;
+ if (scan_resp_size < fixed_size) {
+ mwifiex_dbg(adapter, ERROR,
+ "SCAN_RESP: response is too short\n");
+ ret = -1;
+ goto check_next_scan;
+ }
if (scan_rsp->number_of_sets > MWIFIEX_MAX_AP) {
mwifiex_dbg(adapter, ERROR,
@@ -2149,8 +2158,6 @@ int mwifiex_ret_802_11_scan(struct mwifi
"info: SCAN_RESP: bss_descript_size %d\n",
bytes_left);
- scan_resp_size = le16_to_cpu(resp->size);
-
mwifiex_dbg(adapter, INFO,
"info: SCAN_RESP: returned %d APs before parsing\n",
scan_rsp->number_of_sets);
@@ -2158,15 +2165,17 @@ int mwifiex_ret_802_11_scan(struct mwifi
bss_info = scan_rsp->bss_desc_and_tlv_buffer;
/*
- * The size of the TLV buffer is equal to the entire command response
- * size (scan_resp_size) minus the fixed fields (sizeof()'s), the
- * BSS Descriptions (bss_descript_size as bytesLef) and the command
- * response header (S_DS_GEN)
+ * The TLV buffer follows the command-specific fixed fields and the BSS
+ * descriptions. Background-scan responses have an additional fixed
+ * field before scan_rsp, which is included in fixed_size.
*/
- tlv_buf_size = scan_resp_size - (bytes_left
- + sizeof(scan_rsp->bss_descript_size)
- + sizeof(scan_rsp->number_of_sets)
- + S_DS_GEN);
+ if (bytes_left > scan_resp_size - fixed_size) {
+ mwifiex_dbg(adapter, ERROR,
+ "SCAN_RESP: BSS data exceeds response\n");
+ ret = -1;
+ goto check_next_scan;
+ }
+ tlv_buf_size = scan_resp_size - fixed_size - bytes_left;
tlv_data = (struct mwifiex_ie_types_data *) (scan_rsp->
bss_desc_and_tlv_buffer +
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 270/877] wifi: mwifiex: prevent authentication frame length truncation
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (268 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 269/877] wifi: mwifiex: validate scan response extents Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 271/877] wifi: mwifiex: validate action frame fixed fields Greg Kroah-Hartman
` (614 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linmao Li, Johannes Berg
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linmao Li <lilinmao@kylinos.cn>
commit fa00193eb991f92b007aefe7afb6a7566976dacf upstream.
mwifiex_cfg80211_authenticate() derives the authentication frame length
from req->ie_len and req->auth_data_len, both of type size_t, but stores
it in a u16.
NL80211_ATTR_AUTH_DATA only has a minimum length policy. Since nla_len is
a u16, a single attribute can carry up to 65531 bytes of payload, so the
sum can exceed U16_MAX before it is assigned to pkt_len. The truncated
pkt_len determines the skb frame area, while the copy length remains
req->auth_data_len - 4, resulting in a heap buffer overflow.
For example, with auth_data_len equal to 65510 and no IEs, the sum is
65546. It is truncated to 10 and then reduced by four to 6. The driver
appends only six bytes to the skb with skb_put(), but then copies 65506
user-provided bytes into the authentication body.
Reaching this path requires CAP_NET_ADMIN in the user namespace owning
the network namespace, an up station netdev, and a suitable BSS/SAE
authentication request.
Compute the length in size_t, reject values that cannot be represented by
the firmware's u16 frame length field, and only then assign it to pkt_len.
Fixes: 36995892c271 ("wifi: mwifiex: add host mlme for client mode")
Cc: stable@vger.kernel.org # 6.12+
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
Link: https://patch.msgid.link/20260820062155.3981976-1-lilinmao@kylinos.cn
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/marvell/mwifiex/cfg80211.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -4278,6 +4278,7 @@ mwifiex_cfg80211_authenticate(struct wip
struct mwifiex_adapter *adapter = priv->adapter;
struct sk_buff *skb;
u16 pkt_len, auth_alg;
+ size_t frame_len;
int ret;
struct mwifiex_ieee80211_mgmt *mgmt;
struct mwifiex_txinfo *tx_info;
@@ -4350,10 +4351,17 @@ mwifiex_cfg80211_authenticate(struct wip
mwifiex_cancel_scan(adapter);
- pkt_len = (u16)req->ie_len + req->auth_data_len +
+ frame_len = req->ie_len + req->auth_data_len +
MWIFIEX_MGMT_HEADER_LEN + MWIFIEX_AUTH_BODY_LEN;
if (req->auth_data_len >= 4)
- pkt_len -= 4;
+ frame_len -= 4;
+
+ if (frame_len > U16_MAX) {
+ mwifiex_dbg(priv->adapter, ERROR,
+ "auth frame too long: %zu bytes\n", frame_len);
+ return -EINVAL;
+ }
+ pkt_len = frame_len;
skb = dev_alloc_skb(MWIFIEX_MIN_DATA_HEADER_LEN +
MWIFIEX_MGMT_FRAME_HEADER_SIZE +
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 271/877] wifi: mwifiex: validate action frame fixed fields
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (269 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 270/877] wifi: mwifiex: prevent authentication frame length truncation Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 272/877] wifi: mac80211: avoid WARN in set_bitrate_mask when sdata not in driver Greg Kroah-Hartman
` (613 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Johannes Berg, Brian Norris, Zhao Li,
Johannes Berg
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Li <enderaoelyther@gmail.com>
commit 1c25bfad93e69ce13f744a2fb919f02ea396a985 upstream.
mwifiex_process_mgmt_packet() accepts an rx_pkt_length as small as a
four-address struct ieee80211_hdr plus the two-byte firmware length prefix.
After stripping the prefix, mwifiex_parse_mgmt_packet() can receive a
frame equal to sizeof(struct ieee80211_hdr).
For action frames, the parser reads the category byte immediately after
that header and, for a public action frame, reads the following action
code byte without verifying that either field is present. A truncated frame
can therefore make the parser consume up to two bytes past the
firmware-declared frame length. If those bytes look like a TDLS discovery
response, the malformed frame can spuriously update peer signal state.
Require the category and public action-code fields before reading them.
Use sizeof(*ieee_hdr) so the checks and field accesses directly match the
firmware four-address layout being parsed before address4 is removed.
Suggested-by: Johannes Berg <johannes@sipsolutions.net>
Suggested-by: Brian Norris <briannorris@chromium.org>
Fixes: 72e5aa8d2a6d ("mwifiex: support for parsing TDLS discovery frames")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/all/66f148d83eb9f0970b9abbccc85d1b61244e54ad.camel@sipsolutions.net/
Link: https://lore.kernel.org/all/20260708195911.84365-8-enderaoelyther@gmail.com/
Link: https://lore.kernel.org/all/20260723011013.76968-1-enderaoelyther@gmail.com/
Link: https://lore.kernel.org/all/20260723202257.688-1-enderaoelyther@gmail.com/
Link: https://lore.kernel.org/all/anuWyiPQja6_5vly@google.com/
Assisted-by: Codex:gpt-5
Assisted-by: Kimi:K3
Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
Link: https://patch.msgid.link/20260825112523.95774-1-enderaoelyther@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/marvell/mwifiex/util.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
--- a/drivers/net/wireless/marvell/mwifiex/util.c
+++ b/drivers/net/wireless/marvell/mwifiex/util.c
@@ -335,10 +335,16 @@ mwifiex_parse_mgmt_packet(struct mwifiex
switch (stype) {
case IEEE80211_STYPE_ACTION:
- category = *(payload + sizeof(struct ieee80211_hdr));
+ if (len < sizeof(*ieee_hdr) + 1)
+ return -1;
+
+ category = *(payload + sizeof(*ieee_hdr));
switch (category) {
case WLAN_CATEGORY_PUBLIC:
- action_code = *(payload + sizeof(struct ieee80211_hdr)
+ if (len < sizeof(*ieee_hdr) + 2)
+ return -1;
+
+ action_code = *(payload + sizeof(*ieee_hdr)
+ 1);
if (action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) {
addr2 = ieee_hdr->addr2;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 272/877] wifi: mac80211: avoid WARN in set_bitrate_mask when sdata not in driver
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (270 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 271/877] wifi: mwifiex: validate action frame fixed fields Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 273/877] drm/gud: fix out-of-bounds write in gud_plane_atomic_check() Greg Kroah-Hartman
` (612 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+af177aa139efdd13a9da,
Rik van Riel, syzbot+dcaca020ca8377e7ced0, Johannes Berg
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rik van Riel <riel@surriel.com>
commit da2ca406f45a6e21760243152ed8d2e8e72915c2 upstream.
ieee80211_set_bitrate_mask() checks if the interface is running via
ieee80211_sdata_running(), but it does not check if the interface is
still present in the driver.
When sdata is running but IEEE80211_SDATA_IN_DRIVER is not set, the
call reaches drv_set_bitrate_mask() in driver-ops.h which hits
wlan1: Failed check-sdata-in-driver check, flags: 0x0
WARNING: net/mac80211/driver-ops.h:884 at drv_set_bitrate_mask
Syzkaller triggers this via wext SIOCSIWRATE ioctl. The Call Trace shows
wext_ioctl_dispatch() in wext-core.c dispatching the ioctl, calling
ioctl_standard_call() for SIOCSIWRATE, which calls cfg80211_wext_siwrate()
in wext-compat.c. That builds a bitrate mask and calls
rdev_set_bitrate_mask() which ends up in ieee80211_set_bitrate_mask() in
cfg.c. The interface is marked running via SDATA_STATE_RUNNING but
flags is 0, so check_sdata_in_driver() fails.
When the interface is being torn down, or when wext ioctl is issued
during interface bringup before drv_add_interface() sets IN_DRIVER, the
running check passes while IN_DRIVER is clear.
Check IEEE80211_SDATA_IN_DRIVER in ieee80211_set_bitrate_mask() before
calling the driver, returning -ENETDOWN. This avoids the WARN_ONCE in
driver-ops.h and matches other cfg.c operations that bail early when not
in driver.
This change should be safe because wiphy mutex is held in
cfg80211_wext_siwrate() via guard(wiphy), and IN_DRIVER is set/cleared
under RTNL and wiphy paths in drv_add_interface() and
drv_remove_interface() in driver-ops.c, so the check is race-free
against driver add/remove. Returning -ENETDOWN is the same error other
not-running paths use and does not introduce new locking.
Reported-by: syzbot+af177aa139efdd13a9da@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=af177aa139efdd13a9da
Link: https://lore.kernel.org/all/6a75205c.59b6c763.2bba34.00c3.GAE@google.com/
Fixes: 554a43d5e77e ("mac80211: check sdata_running on ieee80211_set_bitrate_mask")
Cc: stable@vger.kernel.org
Assisted-by: Hermes:muse-spark-1.2 syzkaller
Signed-off-by: Rik van Riel <riel@surriel.com>
Link: https://patch.msgid.link/20260808104755.319c686e@fangorn
Reported-by: syzbot+dcaca020ca8377e7ced0@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=dcaca020ca8377e7ced0
[also add second syzbot report]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/mac80211/cfg.c | 3 +++
1 file changed, 3 insertions(+)
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3426,6 +3426,9 @@ static int ieee80211_set_bitrate_mask(st
if (!ieee80211_sdata_running(sdata))
return -ENETDOWN;
+ if (!(sdata->flags & IEEE80211_SDATA_IN_DRIVER))
+ return -ENETDOWN;
+
/*
* If active validate the setting and reject it if it doesn't leave
* at least one basic rate usable, since we really have to be able
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 273/877] drm/gud: fix out-of-bounds write in gud_plane_atomic_check()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (271 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 272/877] wifi: mac80211: avoid WARN in set_bitrate_mask when sdata not in driver Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 274/877] drm/msm/adreno: fix autosuspend cleanup during teardown Greg Kroah-Hartman
` (611 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sashiko, Sajal Gupta, Ruben Wauters
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sajal Gupta <sajal2005gupta@gmail.com>
commit 59ced288fcba9e91bd38e61a972ad782c4edb7d0 upstream.
The plane property loop uses req->properties[num_properties + i] as write
index while simultaneously incrementing `num_properties` inside the loop.
At iteration i, num_properties has also incremented by i, so the write
is done at `initial_num_properties + 2*i`, skipping every other index and
advancing by 2 per iteration.
With just 2 connector and 32 plane properties the last write happens at
index 64, one slot past the end of the 64-slot (indices 0–63)
allocation. A USB device can trigger OOB by advertising the maximum
number of properties.
Fix by dropping the redundant `+ i`; num_properties is already the correct
running index, as gud_connector_fill_properties() fills the preceding
slots.
Fixes: 40e1a70b4aed ("drm: Add GUD USB Display driver")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://sashiko.dev/#/patchset/20260821071812.16500-1-sajal2005gupta%40gmail.com?part=1
Signed-off-by: Sajal Gupta <sajal2005gupta@gmail.com>
Cc: <stable@vger.kernel.org>
Acked-by: Ruben Wauters <rubenru09@aol.com>
Signed-off-by: Ruben Wauters <rubenru09@aol.com>
Link: https://patch.msgid.link/20260902123254.36987-1-sajal2005gupta@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/gud/gud_pipe.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/gud/gud_pipe.c
+++ b/drivers/gpu/drm/gud/gud_pipe.c
@@ -544,8 +544,8 @@ int gud_pipe_check(struct drm_simple_dis
goto out;
}
- req->properties[num_properties + i].prop = cpu_to_le16(prop);
- req->properties[num_properties + i].val = cpu_to_le64(val);
+ req->properties[num_properties].prop = cpu_to_le16(prop);
+ req->properties[num_properties].val = cpu_to_le64(val);
num_properties++;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 274/877] drm/msm/adreno: fix autosuspend cleanup during teardown
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (272 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 273/877] drm/gud: fix out-of-bounds write in gud_plane_atomic_check() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 275/877] drm/msm/hdmi_phy: fix runtime PM cleanup on probe failure Greg Kroah-Hartman
` (610 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Dmitry Baryshkov
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <lgs201920130244@gmail.com>
commit 6fbbf1e152f34ad3913e4a6476680aba672c5068 upstream.
adreno_gpu_init() calls pm_runtime_use_autosuspend(), but
adreno_gpu_cleanup() does not call the matching
pm_runtime_dont_use_autosuspend() during teardown.
If the autosuspend delay is set to a negative value while autosuspend
is enabled, the runtime PM core increments usage_count to prevent
runtime suspend. Without calling pm_runtime_dont_use_autosuspend()
during teardown, this reference is not dropped and usage_count remains
unbalanced.
The documentation for pm_runtime_use_autosuspend() also notes that it
is important to undo it with pm_runtime_dont_use_autosuspend() at
driver exit time, unless runtime PM was initially enabled with
devm_pm_runtime_enable().
Add the missing pm_runtime_dont_use_autosuspend() call to
adreno_gpu_cleanup().
This issue was found by manual code inspection.
Fixes: eeb754746b14 ("drm/msm/gpu: use pm-runtime")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Patchwork: https://patchwork.freedesktop.org/patch/745110/
Link: https://lore.kernel.org/r/20260808131624.2854412-1-lgs201920130244@gmail.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/msm/adreno/adreno_gpu.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -1141,6 +1141,8 @@ void adreno_gpu_cleanup(struct adreno_gp
for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++)
release_firmware(adreno_gpu->fw[i]);
+ pm_runtime_dont_use_autosuspend(&gpu->pdev->dev);
+
if (priv && pm_runtime_enabled(&priv->gpu_pdev->dev))
pm_runtime_disable(&priv->gpu_pdev->dev);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 275/877] drm/msm/hdmi_phy: fix runtime PM cleanup on probe failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (273 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 274/877] drm/msm/adreno: fix autosuspend cleanup during teardown Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 276/877] smb: client: cancel reconnect work in clean_demultiplex_info() Greg Kroah-Hartman
` (609 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Krzysztof Kozlowski,
Dmitry Baryshkov
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <lgs201920130244@gmail.com>
commit f4fae975db08a9aeec0b15e145c7d4d0fe02a0ec upstream.
msm_hdmi_phy_probe() enables runtime PM before enabling the PHY
resources and initializing the PLL, but failures from either operation
return without calling the matching pm_runtime_disable().
The remove path disables runtime PM, but it is not called when probe
fails. As a result, runtime PM remains enabled after an unsuccessful
probe.
Route failures after pm_runtime_enable() through a common error path
and disable runtime PM before returning.
This issue was found by manual code inspection.
Fixes: 15b4a4523859 ("drm/msm/hdmi: Create a separate HDMI PHY driver")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Patchwork: https://patchwork.freedesktop.org/patch/753043/
Link: https://lore.kernel.org/r/20260913085814.1509352-1-lgs201920130244@gmail.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/msm/hdmi/hdmi_phy.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c
@@ -164,13 +164,13 @@ static int msm_hdmi_phy_probe(struct pla
ret = msm_hdmi_phy_resource_enable(phy);
if (ret)
- return ret;
+ goto err_pm_disable;
ret = msm_hdmi_phy_pll_init(pdev, phy->cfg->type);
if (ret) {
DRM_DEV_ERROR(dev, "couldn't init PLL\n");
msm_hdmi_phy_resource_disable(phy);
- return ret;
+ goto err_pm_disable;
}
msm_hdmi_phy_resource_disable(phy);
@@ -178,6 +178,10 @@ static int msm_hdmi_phy_probe(struct pla
platform_set_drvdata(pdev, phy);
return 0;
+
+err_pm_disable:
+ pm_runtime_disable(dev);
+ return ret;
}
static void msm_hdmi_phy_remove(struct platform_device *pdev)
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 276/877] smb: client: cancel reconnect work in clean_demultiplex_info()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (274 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 275/877] drm/msm/hdmi_phy: fix runtime PM cleanup on probe failure Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 277/877] smb: client: fix rlist race and missing initialization Greg Kroah-Hartman
` (608 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+5003556314abc915a71f,
Namjae Jeon, Paulo Alcantara, David Howells, Shyam Prasad N,
Ronnie Sahlberg, Tom Talpey, Bharath SM
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.org>
commit c65eae6f61d1778ff7a82e4aae4080e26f486af1 upstream.
clean_demultiplex_info() cancels server->echo delayed work but not
server->reconnect, which can cause a use-after-free when the
demultiplex thread exits while a reconnect work is still queued:
cifs_demultiplex_thread()
cifs_readv_from_socket()
cifs_reconnect()
__cifs_reconnect()
cifs_queue_server_reconn()
mod_delayed_work(cifsiod_wq, &server->reconnect, 0)
clean_demultiplex_info()
cancel_delayed_work_sync(&server->echo) // echo canceled
// reconnect NOT canceled
kfree_sensitive(server) // server freed
...later, on cifsiod_wq:
smb2_reconnect_server()
server->srv_count // UAF read of freed server
Fix this by canceling server->reconnect delayed work in
clean_demultiplex_info() before the server is freed, the same way
cifs_put_tcp_session() already does.
Reported-by: syzbot+5003556314abc915a71f@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/r/6aa4a12d.f81106d8.2ab401.0023.GAE@google.com
Fixes: 53e0e11efe92 ("CIFS: Fix a possible memory corruption during reconnect")
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/connect.c | 1 +
1 file changed, 1 insertion(+)
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -982,6 +982,7 @@ clean_demultiplex_info(struct TCP_Server
spin_unlock(&server->srv_lock);
cancel_delayed_work_sync(&server->echo);
+ cancel_delayed_work_sync(&server->reconnect);
spin_lock(&server->srv_lock);
server->tcpStatus = CifsExiting;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 277/877] smb: client: fix rlist race and missing initialization
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (275 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 276/877] smb: client: cancel reconnect work in clean_demultiplex_info() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 278/877] smb: client: reject short Next offsets in parse_server_interfaces() Greg Kroah-Hartman
` (607 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Paulo Alcantara,
David Howells, Shyam Prasad N, Ronnie Sahlberg, Tom Talpey,
Bharath SM
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.org>
commit 5f270f091256da1338c3631083e15d7f83cc05e1 upstream.
TCP_Server_Info.rlist is allocated via kzalloc which zeros both ->next
and ->prev to NULL instead of pointing to itself, making list_empty()
always return false and list_add() dereference a NULL ->prev pointer.
Also, cifs_signal_cifsd_for_reconnect() can be called concurrently
from multiple cifsd threads, allowing the same server's rlist node to
be added twice into the local list, corrupting it.
Closes: https://sashiko.dev/#/patchset/20260911204446.1719356-1-pc%40manguebit.org
Fixes: df0e03a4fb94 ("smb: client: fix potential deadlock when reconnecting channels")
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/connect.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -187,6 +187,8 @@ cifs_signal_cifsd_for_reconnect(struct T
nserver = ses->chans[i].server;
if (!nserver)
continue;
+ if (!list_empty(&nserver->rlist))
+ continue;
nserver->srv_count++;
list_add(&nserver->rlist, &reco);
}
@@ -195,11 +197,15 @@ cifs_signal_cifsd_for_reconnect(struct T
}
}
+ spin_lock(&cifs_tcp_ses_lock);
list_for_each_entry_safe(server, nserver, &reco, rlist) {
list_del_init(&server->rlist);
set_need_reco(server);
+ spin_unlock(&cifs_tcp_ses_lock);
cifs_put_tcp_session(server, 0);
+ spin_lock(&cifs_tcp_ses_lock);
}
+ spin_unlock(&cifs_tcp_ses_lock);
}
/*
@@ -1768,6 +1774,7 @@ cifs_get_tcp_session(struct smb3_fs_cont
spin_lock_init(&tcp_ses->mid_lock);
INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
+ INIT_LIST_HEAD(&tcp_ses->rlist);
INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);
INIT_DELAYED_WORK(&tcp_ses->reconnect, smb2_reconnect_server);
mutex_init(&tcp_ses->reconnect_mutex);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 278/877] smb: client: reject short Next offsets in parse_server_interfaces()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (276 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 277/877] smb: client: fix rlist race and missing initialization Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 279/877] smb: client: fix smbd_connection leak on cifs_get_tcp_session() error Greg Kroah-Hartman
` (606 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Frank Sorenson, David Howells,
Paulo Alcantara
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Sorenson <sorenson@redhat.com>
commit 1b3221bb121079ad79a1f3c3aa360ba649832e7a upstream.
In parse_server_interfaces(), the server-supplied Next offset is
validated against bytes_left, but not against the size of the interface
structure itself.
A small, non-zero Next value can pass the bounds check but advance the
pointer by less than sizeof(*p). This causes the next iteration of the
loop to read misaligned, overlapping structure fields.
Fix this by ensuring the Next offset is at least sizeof(*p).
Fixes: 7d34ec36abb8 ("smb3: fix for slab out of bounds on mount to ksmbd")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/smb2ops.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -786,9 +786,9 @@ next_iface:
break;
}
/* Validate that Next doesn't point beyond the buffer */
- if (next > bytes_left) {
- cifs_dbg(VFS, "%s: invalid Next pointer %zu > %zd\n",
- __func__, next, bytes_left);
+ if (next < sizeof(*p) || next > bytes_left) {
+ cifs_dbg(VFS, "%s: invalid Next pointer %zu out of range [%zu, %zd]\n",
+ __func__, next, sizeof(*p), bytes_left);
rc = -EINVAL;
goto out;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 279/877] smb: client: fix smbd_connection leak on cifs_get_tcp_session() error
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (277 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 278/877] smb: client: reject short Next offsets in parse_server_interfaces() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 280/877] smb: client: fix unaligned access in WSL reparse point parser Greg Kroah-Hartman
` (605 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Paulo Alcantara,
Tom Talpey, Stefan Metzmacher, Shyam Prasad N, Ronnie Sahlberg,
Bharath SM
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.org>
commit e75c96157d45e498970158c8f7373d90102e33b9 upstream.
When an RDMA connection is successfully established via
smbd_get_connection() but cifs_get_tcp_session() later fails (e.g.
kthread_create() returns an error), the error path frees tcp_ses
without first destroying the smbd_connection.
Fix this by calling smbd_destroy() in the out_err cleanup path before
kfree(tcp_ses). smbd_destroy() safely handles the case where
smbd_conn is NULL, so it can be called unconditionally.
Closes: https://sashiko.dev/#/patchset/20260912165503.521597-1-pc%40manguebit.org
Fixes: 2f8946464b11 ("CIFS: SMBD: Upper layer connects to SMBDirect session")
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: Tom Talpey <tom@talpey.com>
Cc: Stefan Metzmacher <metze@samba.org>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/connect.c | 1 +
1 file changed, 1 insertion(+)
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -1885,6 +1885,7 @@ out_err:
kfree(tcp_ses->leaf_fullpath);
if (tcp_ses->ssocket)
sock_release(tcp_ses->ssocket);
+ smbd_destroy(tcp_ses);
kfree(tcp_ses);
}
return ERR_PTR(rc);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 280/877] smb: client: fix unaligned access in WSL reparse point parser
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (278 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 279/877] smb: client: fix smbd_connection leak on cifs_get_tcp_session() error Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 281/877] smb: client: fix next_buffer UAF and NextCommand bounds in compound PDUs Greg Kroah-Hartman
` (604 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Paulo Alcantara,
David Howells, Tom Talpey, Shyam Prasad N, Ronnie Sahlberg,
Bharath SM
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.org>
commit e1aeaf79dea51e6065da56924bc07e22d59012ac upstream.
When wsl_to_fattr() parses WSL extended attributes, it computes a
payload pointer from ea->ea_data + ea_name_length + 1. Since the
smb2_file_full_ea_info struct is __packed and all WSL xattr names are
6 bytes long, the value pointer always lands at an odd byte offset,
never satisfying __le32 or __le64 alignment requirements.
The code then casts this pointer to __le32 * or __le64 * and
dereferences it directly, which may cause alignment faults on some
architectures.
Replace all such casts with get_unaligned_le32() and
get_unaligned_le64() in reparse_mkdev(), wsl_make_kuid(),
wsl_make_kgid() and wsl_to_fattr().
Closes: https://sashiko.dev/#/patchset/20260906200517.725015-1-pc%40manguebit.org
Fixes: 78e26bec4d6d ("smb: client: parse uid, gid, mode and dev from WSL reparse points")
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/reparse.c | 4 ++--
fs/smb/client/reparse.h | 7 ++++---
2 files changed, 6 insertions(+), 5 deletions(-)
--- a/fs/smb/client/reparse.c
+++ b/fs/smb/client/reparse.c
@@ -726,9 +726,9 @@ static bool wsl_to_fattr(struct cifs_ope
fattr->cf_gid = wsl_make_kgid(cifs_sb, v);
else if (!strncmp(name, SMB2_WSL_XATTR_MODE, nlen)) {
/* File type in reparse point tag and in xattr mode must match. */
- if (S_DT(fattr->cf_mode) != S_DT(le32_to_cpu(*(__le32 *)v)))
+ if (S_DT(fattr->cf_mode) != S_DT(get_unaligned_le32(v)))
return false;
- fattr->cf_mode = (umode_t)le32_to_cpu(*(__le32 *)v);
+ fattr->cf_mode = (umode_t)get_unaligned_le32(v);
} else if (!strncmp(name, SMB2_WSL_XATTR_DEV, nlen)) {
fattr->cf_rdev = reparse_mkdev(v);
have_xattr_dev = true;
--- a/fs/smb/client/reparse.h
+++ b/fs/smb/client/reparse.h
@@ -9,6 +9,7 @@
#include <linux/fs.h>
#include <linux/stat.h>
#include <linux/uidgid.h>
+#include <linux/unaligned.h>
#include "fs_context.h"
#include "cifsglob.h"
@@ -22,7 +23,7 @@
static inline dev_t reparse_mkdev(void *ptr)
{
- u64 v = le64_to_cpu(*(__le64 *)ptr);
+ u64 v = get_unaligned_le64(ptr);
return MKDEV(v & 0xffffffff, v >> 32);
}
@@ -30,7 +31,7 @@ static inline dev_t reparse_mkdev(void *
static inline kuid_t wsl_make_kuid(struct cifs_sb_info *cifs_sb,
void *ptr)
{
- u32 uid = le32_to_cpu(*(__le32 *)ptr);
+ u32 uid = get_unaligned_le32(ptr);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
return cifs_sb->ctx->linux_uid;
@@ -40,7 +41,7 @@ static inline kuid_t wsl_make_kuid(struc
static inline kgid_t wsl_make_kgid(struct cifs_sb_info *cifs_sb,
void *ptr)
{
- u32 gid = le32_to_cpu(*(__le32 *)ptr);
+ u32 gid = get_unaligned_le32(ptr);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
return cifs_sb->ctx->linux_gid;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 281/877] smb: client: fix next_buffer UAF and NextCommand bounds in compound PDUs
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (279 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 280/877] smb: client: fix unaligned access in WSL reparse point parser Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 282/877] smb: client: fix potential OOB read in smb3_enum_snapshots() Greg Kroah-Hartman
` (603 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Frank Sorenson, David Howells,
Paulo Alcantara
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Sorenson <sorenson@redhat.com>
commit 05762c5bc1cfdcac36747994fde2c04387a457f1 upstream.
Fix several related bounds checking and pointer lifecycle issues in
receive_encrypted_standard()'s handling of compound encrypted frames:
- Clear next_buffer after assigning it to server->bigbuf. A stale
next_buffer pointer can lead to a use-after-free on subsequent
error paths.
- Update pdu_length to the decrypted plaintext size (buf_size). Using
the pre-decryption length allows NextCommand to point into stale
ciphertext residue.
- Reject next_cmd values smaller than MID_HEADER_SIZE(server).
- Fix an integer overflow in the upper bound check by verifying
pdu_length - next_cmd < MID_HEADER_SIZE(server), ensuring the
trailing slice is large enough for a header.
Fixes: b24df3e30cbf ("cifs: update receive_encrypted_standard to handle compounded responses")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/smb2ops.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -5237,6 +5237,7 @@ receive_encrypted_standard(struct TCP_Se
length = decrypt_raw_data(server, buf, buf_size, NULL, false);
if (length)
return length;
+ pdu_length = buf_size;
next_is_large = server->large_buf;
one_more:
@@ -5249,8 +5250,15 @@ one_more:
}
if (next_cmd) {
- if (WARN_ON_ONCE(next_cmd > pdu_length))
+ if (next_cmd < MID_HEADER_SIZE(server) ||
+ next_cmd > pdu_length ||
+ pdu_length - next_cmd < MID_HEADER_SIZE(server)) {
+ unsigned int max_next = pdu_length > (unsigned int)MID_HEADER_SIZE(server) ?
+ pdu_length - (unsigned int)MID_HEADER_SIZE(server) : 0;
+ cifs_server_dbg(VFS, "invalid NextCommand offset %u out of range [%zu, %u]\n",
+ next_cmd, MID_HEADER_SIZE(server), max_next);
return -1;
+ }
if (next_is_large)
next_buffer = (char *)cifs_buf_get();
else
@@ -5286,6 +5294,7 @@ one_more:
server->bigbuf = buf = next_buffer;
else
server->smallbuf = buf = next_buffer;
+ next_buffer = NULL;
goto one_more;
} else if (ret != 0) {
/*
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 282/877] smb: client: fix potential OOB read in smb3_enum_snapshots()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (280 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 281/877] smb: client: fix next_buffer UAF and NextCommand bounds in compound PDUs Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 283/877] smb: client: fix server->total_read for compound encrypted PDUs Greg Kroah-Hartman
` (602 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Frank Sorenson, David Howells,
Paulo Alcantara
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Sorenson <sorenson@redhat.com>
commit 4775c3b7a597907e0b97556c7986fda238a377ae upstream.
If snapshot_array_size is smaller than GMT_TOKEN_SIZE,
smb3_enum_snapshots() sets ret_data_len to
sizeof(struct smb_snapshot_array) without verifying the actual length
of the server's reply.
Because SMB2_ioctl() places no lower bound on the server-supplied
OutputCount and allocates retbuf to exactly that length, a short reply
results in ret_data_len exceeding the size of retbuf. The subsequent
copy_to_user() then reads past the end of retbuf, leaking adjacent slab
memory to userspace. The subsequent clamp check is ineffective as it
only reduces ret_data_len.
Fix this by rejecting replies shorter than
sizeof(struct smb_snapshot_array) with -EIO. Note that the bound is set
to the 12-byte struct size rather than the 16-byte
MIN_SNAPSHOT_ARRAY_SIZE defined in MS-SMB2 3.3.5.15.1, because 12 bytes
is exactly what copy_to_user() attempts to read.
Fixes: e02789a53d71 ("smb3: enumerating snapshots was leaving part of the data off end")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/smb2ops.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -2422,8 +2422,14 @@ smb3_enum_snapshots(const unsigned int x
* and retry the ioctl again with larger array size sufficient
* to hold all of the snapshot GMT tokens on the second try.
*/
- if (snapshot_in.snapshot_array_size < GMT_TOKEN_SIZE)
+ if (snapshot_in.snapshot_array_size < GMT_TOKEN_SIZE) {
+ if (ret_data_len < sizeof(struct smb_snapshot_array)) {
+ rc = -EIO;
+ kfree(retbuf);
+ return rc;
+ }
ret_data_len = sizeof(struct smb_snapshot_array);
+ }
/*
* We return struct SRV_SNAPSHOT_ARRAY, followed by
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 283/877] smb: client: fix server->total_read for compound encrypted PDUs
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (281 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 282/877] smb: client: fix potential OOB read in smb3_enum_snapshots() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 284/877] smb: client: fix missing lower-bound check on DFS referral string offsets Greg Kroah-Hartman
` (601 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Frank Sorenson, David Howells,
Paulo Alcantara
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Sorenson <sorenson@redhat.com>
commit f73726b83e4756fdaa099e1bc1143293bd57ad79 upstream.
In receive_encrypted_standard(), server->total_read is left at the
full decrypted frame size when walking sub-PDUs of a compound encrypted
frame. As a result, cifs_handle_standard() passes this full size
to smb2_check_message(), causing the PDU length guards to incorrectly
validate the entire compound frame instead of the current sub-PDU.
This allows truncated non-last sub-PDUs to bypass length validation,
leading to out-of-bounds reads in smb2_get_data_area_len().
Fix this by setting server->total_read to the true length of the
current sub-PDU: next_cmd for non-last sub-PDUs, and the remaining
pdu_length for the last one.
Fixes: b24df3e30cbf ("cifs: update receive_encrypted_standard to handle compounded responses")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/smb2ops.c | 1 +
1 file changed, 1 insertion(+)
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -5249,6 +5249,7 @@ receive_encrypted_standard(struct TCP_Se
one_more:
shdr = (struct smb2_hdr *)buf;
next_cmd = le32_to_cpu(shdr->NextCommand);
+ server->total_read = next_cmd ? next_cmd : pdu_length;
if (*num_mids >= MAX_COMPOUND) {
cifs_server_dbg(VFS, "too many PDUs in compound\n");
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 284/877] smb: client: fix missing lower-bound check on DFS referral string offsets
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (282 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 283/877] smb: client: fix server->total_read for compound encrypted PDUs Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 285/877] smb: client: fix missing iov bounds check in parse_posix_sids() Greg Kroah-Hartman
` (600 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Frank Sorenson, David Howells,
Paulo Alcantara
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Sorenson <sorenson@redhat.com>
commit e83330c55edc0c3ac08aa6c95e49e4694c65523b upstream.
parse_dfs_referrals() checks that DfsPathOffset and NetworkAddressOffset
do not exceed the buffer end, but fails to check that they don't point
inside the referral header itself.
If a server provides an offset smaller than
sizeof(struct dfs_referral_level_3), the derived string pointer overlaps
with the struct fields, causing cifs_strndup_from_utf16() to interpret
header data as UTF-16 strings.
Fix this by enforcing that string offsets are at least sizeof(*ref).
Fixes: 4ecce920e13a ("CIFS: move DFS response parsing out of SMB1 code")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/misc.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
--- a/fs/smb/client/misc.c
+++ b/fs/smb/client/misc.c
@@ -1046,7 +1046,11 @@ parse_dfs_referrals(struct get_dfs_refer
node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
/* copy DfsPath */
- if (le16_to_cpu(ref->DfsPathOffset) > data_end - (char *)ref) {
+ if (le16_to_cpu(ref->DfsPathOffset) < sizeof(*ref) ||
+ le16_to_cpu(ref->DfsPathOffset) > data_end - (char *)ref) {
+ cifs_dbg(VFS, "%s: DfsPathOffset %u out of range [%zu, %td]\n",
+ __func__, le16_to_cpu(ref->DfsPathOffset),
+ sizeof(*ref), data_end - (char *)ref);
rc = -EINVAL;
goto parse_DFS_referrals_exit;
}
@@ -1060,7 +1064,11 @@ parse_dfs_referrals(struct get_dfs_refer
}
/* copy link target UNC */
- if (le16_to_cpu(ref->NetworkAddressOffset) > data_end - (char *)ref) {
+ if (le16_to_cpu(ref->NetworkAddressOffset) < sizeof(*ref) ||
+ le16_to_cpu(ref->NetworkAddressOffset) > data_end - (char *)ref) {
+ cifs_dbg(VFS, "%s: NetworkAddressOffset %u out of range [%zu, %td]\n",
+ __func__, le16_to_cpu(ref->NetworkAddressOffset),
+ sizeof(*ref), data_end - (char *)ref);
rc = -EINVAL;
goto parse_DFS_referrals_exit;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 285/877] smb: client: fix missing iov bounds check in parse_posix_sids()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (283 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 284/877] smb: client: fix missing lower-bound check on DFS referral string offsets Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 286/877] HID: asus: fortify keyboard handshake Greg Kroah-Hartman
` (599 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Frank Sorenson, David Howells,
Paulo Alcantara
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Sorenson <sorenson@redhat.com>
commit b09d092eb24ad0110f16a9b7c1ed5d2a0c1733dc upstream.
In parse_posix_sids(), sidsbuf_end is calculated using the server-supplied
out_len without being validated against the actual length of the received
iov (iov_len).
If a server provides an inflated out_len, sidsbuf_end will point past the
end of the iov. This defeats the bounds guards in posix_info_sid_size(),
allowing out-of-bounds reads into adjacent kernel memory.
Fix this by rejecting responses where the calculated sidsbuf_end would
exceed the received iov boundaries or cause pointer wraparound.
Fixes: a90f37e3d7ac ("smb: client: parse owner/group when creating reparse points")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/smb2inode.c | 11 +++++++++++
1 file changed, 11 insertions(+)
--- a/fs/smb/client/smb2inode.c
+++ b/fs/smb/client/smb2inode.c
@@ -71,6 +71,17 @@ static int parse_posix_sids(struct cifs_
sidsbuf = (u8 *)qi + le16_to_cpu(qi->OutputBufferOffset) + qi_len;
sidsbuf_end = sidsbuf + out_len - qi_len;
+ if (sidsbuf_end < sidsbuf) {
+ cifs_dbg(VFS, "%s: server-supplied out_len %u caused pointer wraparound\n",
+ __func__, out_len);
+ return -EINVAL;
+ }
+ if (sidsbuf_end > (u8 *)rsp_iov->iov_base + rsp_iov->iov_len) {
+ cifs_dbg(VFS, "%s: server-supplied out_len %u overruns iov by %td bytes\n",
+ __func__, out_len,
+ sidsbuf_end - ((u8 *)rsp_iov->iov_base + rsp_iov->iov_len));
+ return -EINVAL;
+ }
owner_len = posix_info_sid_size(sidsbuf, sidsbuf_end);
if (owner_len == -1)
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 286/877] HID: asus: fortify keyboard handshake
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (284 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 285/877] smb: client: fix missing iov bounds check in parse_posix_sids() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 287/877] ksmbd: fix partial normalized name responses Greg Kroah-Hartman
` (598 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Benjamin Tissoires, Denis Benato,
Antheas Kapenekakis, Ilpo Järvinen, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antheas Kapenekakis <lkml@antheas.dev>
[ Upstream commit e82ae34af29e910c96d33c8b3a90c60e27f1625e ]
Handshaking with an Asus device involves sending it a feature report
with the string "ASUS Tech.Inc." and then reading it back to verify the
handshake was successful, under the feature ID the interaction will
take place.
Currently, the driver only does the first part. Add the readback to
verify the handshake was successful. As this could cause breakages,
allow the verification to fail with a dmesg error until we verify
all devices work with it (they seem to).
Since the response is more than 16 bytes, increase the buffer size
to 64 as well to avoid overflow errors. In addition, add the report
ID to prints, to help identify failed handshakes.
Reviewed-by: Benjamin Tissoires <bentiss@kernel.org>
Reviewed-by: Denis Benato <benato.denis96@gmail.com>
Acked-by: Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
Link: https://patch.msgid.link/20260122075044.5070-5-lkml@antheas.dev
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/hid-asus.c | 34 ++++++++++++++++++++++++++++++----
1 file changed, 30 insertions(+), 4 deletions(-)
diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index 28426337a2f11..1708396a04502 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -48,7 +48,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
#define FEATURE_REPORT_ID 0x0d
#define INPUT_REPORT_ID 0x5d
#define FEATURE_KBD_REPORT_ID 0x5a
-#define FEATURE_KBD_REPORT_SIZE 16
+#define FEATURE_KBD_REPORT_SIZE 64
#define FEATURE_KBD_LED_REPORT_ID1 0x5d
#define FEATURE_KBD_LED_REPORT_ID2 0x5e
@@ -393,15 +393,41 @@ static int asus_kbd_set_report(struct hid_device *hdev, const u8 *buf, size_t bu
static int asus_kbd_init(struct hid_device *hdev, u8 report_id)
{
+ /*
+ * The handshake is first sent as a set_report, then retrieved
+ * from a get_report. They should be equal.
+ */
const u8 buf[] = { report_id, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54,
0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 };
int ret;
ret = asus_kbd_set_report(hdev, buf, sizeof(buf));
- if (ret < 0)
- hid_err(hdev, "Asus failed to send init command: %d\n", ret);
+ if (ret < 0) {
+ hid_err(hdev, "Asus handshake %02x failed to send: %d\n",
+ report_id, ret);
+ return ret;
+ }
- return ret;
+ u8 *readbuf __free(kfree) = kzalloc(FEATURE_KBD_REPORT_SIZE, GFP_KERNEL);
+ if (!readbuf)
+ return -ENOMEM;
+
+ ret = hid_hw_raw_request(hdev, report_id, readbuf,
+ FEATURE_KBD_REPORT_SIZE, HID_FEATURE_REPORT,
+ HID_REQ_GET_REPORT);
+ if (ret < 0) {
+ hid_warn(hdev, "Asus handshake %02x failed to receive ack: %d\n",
+ report_id, ret);
+ } else if (memcmp(readbuf, buf, sizeof(buf)) != 0) {
+ hid_warn(hdev, "Asus handshake %02x returned invalid response: %*ph\n",
+ report_id, FEATURE_KBD_REPORT_SIZE, readbuf);
+ }
+
+ /*
+ * Do not return error if handshake is wrong until this is
+ * verified to work for all devices.
+ */
+ return 0;
}
static int asus_kbd_get_functions(struct hid_device *hdev,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 287/877] ksmbd: fix partial normalized name responses
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (285 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 286/877] HID: asus: fortify keyboard handshake Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 288/877] spi: spi-zynqmp-gqspi: stop the controller on shutdown Greg Kroah-Hartman
` (597 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mobin Aydinfar, ChenXiaoSong,
Namjae Jeon
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <linkinjeon@kernel.org>
commit f4fafaf02174c32bce2f9bb4196fadf13f1fd96e upstream.
Windows may request FILE_NORMALIZED_NAME_INFORMATION with an output
buffer that only fits the fixed portion of the variable-length response.
Treat the fixed portion as FILE_NORMALIZED_NAME_INFORMATION_SIZE so ksmbd
returns STATUS_BUFFER_OVERFLOW instead of STATUS_INFO_LENGTH_MISMATCH.
This avoids rejecting valid partial normalized-name responses.
Fixes: 6b8b79226bc3 ("ksmbd: fix partial file information responses")
Reported-by: Mobin Aydinfar <mobin@mobintestserver.ir>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/server/smb2pdu.c | 3 +++
fs/smb/server/smb2pdu.h | 1 +
2 files changed, 4 insertions(+)
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -5530,6 +5530,9 @@ static int smb2_get_info_file(struct ksm
case FILE_ALTERNATE_NAME_INFORMATION:
fixed_len = FILE_ALTERNATE_NAME_INFORMATION_SIZE;
break;
+ case FILE_NORMALIZED_NAME_INFORMATION:
+ fixed_len = FILE_NORMALIZED_NAME_INFORMATION_SIZE;
+ break;
case FILE_STREAM_INFORMATION:
fixed_len = FILE_STREAM_INFORMATION_SIZE;
break;
--- a/fs/smb/server/smb2pdu.h
+++ b/fs/smb/server/smb2pdu.h
@@ -219,6 +219,7 @@ struct file_sparse {
#define FILE_ALLOCATION_INFORMATION_SIZE 19
#define FILE_END_OF_FILE_INFORMATION_SIZE 20
#define FILE_ALTERNATE_NAME_INFORMATION_SIZE 8
+#define FILE_NORMALIZED_NAME_INFORMATION_SIZE 8
#define FILE_STREAM_INFORMATION_SIZE 32
#define FILE_PIPE_INFORMATION_SIZE 23
#define FILE_PIPE_LOCAL_INFORMATION_SIZE 24
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 288/877] spi: spi-zynqmp-gqspi: stop the controller on shutdown
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (286 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 287/877] ksmbd: fix partial normalized name responses Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 289/877] smb: client: fix busy dentry warning on unmount after DIO Greg Kroah-Hartman
` (596 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Itai Handler, Mark Brown,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Itai Handler <itai.handler@gmail.com>
commit e922bad8b2d5028c51a096d083fea41cd0987154 upstream.
The driver has no ->shutdown, and platform_drv_shutdown() has no
fallback of its own. Unlike pci_device_shutdown(), which clears bus
mastering when kexec_in_progress, nothing on the platform bus disarms a
device that can still write to memory. The normal kexec path never
calls ->suspend either, so the quiesce in zynqmp_qspi_suspend() is not
reached.
A controller that is still executing a DMA read may therefore keep
writing to memory across a kexec. QSPIDMA_DST_ADDR still points at
memory owned by the kernel that called kexec, DST_SIZE is non-zero and
the flash is still clocked, so data can keep landing in RAM while the
new kernel is being relocated, and after it has started executing.
That destination is a physical address which means nothing to the new
kernel, so the writes can corrupt whatever now occupies it: kernel text
or data, page tables, or the initrd. Nothing reports an error and the
resulting behaviour is undefined.
This can be observed by reading GQSPI_EN (offset 0x114) and
QSPIDMA_DST_ADDR/SIZE/STS/CTRL (offsets 0x800 to 0x80c) early in the new
kernel, before the driver probes: without this patch GQSPI_EN reads 1
and QSPIDMA_DST_ADDR still points into the previous kernel's memory.
Add a ->shutdown that stops the controller the way zynqmp_qspi_suspend()
already does. spi_controller_suspend() stops the queue, waits for a
message that is already executing and makes any later transfer fail with
-ESHUTDOWN, so nothing can be cut short by the register write that
follows. It may sleep, which is fine here: device_shutdown() runs in
process context. Unlike ->suspend this cannot abort on error, because a
controller left mastering the bus is worse than a truncated transfer, so
a failure to drain is only logged.
GQSPI_EN_OFST is then cleared, as zynqmp_qspi_remove() and
zynqmp_qspi_suspend() already do. Skip that write only when
pm_runtime_get_if_in_use() returns 0, i.e. runtime suspended: the clocks
are gated, so the registers are unreachable and the controller cannot be
mastering the bus. A negative return is not the same thing - it is what
the CONFIG_PM=n stub always returns, and there probe() has enabled pclk
and refclk for good, so the controller is running and must be stopped.
Fixes: dfe11a11d523 ("spi: Add support for Zynq Ultrascale+ MPSoC GQSPI controller")
Cc: stable@vger.kernel.org
Signed-off-by: Itai Handler <itai.handler@gmail.com>
Link: https://patch.msgid.link/20260910174832.873352-1-itai.handler@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
[ itai: context only - the platform_driver callback is still spelled
.remove_new in this tree, renamed back to .remove upstream by commit
494c3dc46776 ("spi: Switch back to struct platform_driver::remove()") ]
Signed-off-by: Itai Handler <itai.handler@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/spi-zynqmp-gqspi.c | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/drivers/spi/spi-zynqmp-gqspi.c b/drivers/spi/spi-zynqmp-gqspi.c
index 143c572b263e2..4fa68b11709b3 100644
--- a/drivers/spi/spi-zynqmp-gqspi.c
+++ b/drivers/spi/spi-zynqmp-gqspi.c
@@ -1385,11 +1385,45 @@ static void zynqmp_qspi_remove(struct platform_device *pdev)
clk_disable_unprepare(xqspi->pclk);
}
+static void zynqmp_qspi_shutdown(struct platform_device *pdev)
+{
+ struct zynqmp_qspi *xqspi = platform_get_drvdata(pdev);
+ int ret;
+
+ /*
+ * Stop the queue and reject any later transfer first, so the write
+ * below cannot cut into a message that is still being executed.
+ * Unlike ->suspend this cannot abort on error: a controller left
+ * mastering the bus is worse than a truncated transfer.
+ */
+ ret = spi_controller_suspend(xqspi->ctlr);
+ if (ret)
+ dev_warn(&pdev->dev, "could not stop the queue: %d\n", ret);
+
+ /*
+ * Only a runtime suspended controller can be left alone: its clocks
+ * are gated, so it cannot be mastering the bus, and its registers
+ * must not be accessed either. Any other answer means it may be
+ * running and has to be stopped. In particular, on a kernel built
+ * without runtime PM this returns -EINVAL, and there the clocks
+ * enabled in probe() are never gated at all.
+ */
+ ret = pm_runtime_get_if_in_use(&pdev->dev);
+ if (!ret)
+ return;
+
+ zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, 0x0);
+
+ if (ret > 0)
+ pm_runtime_put_noidle(&pdev->dev);
+}
+
MODULE_DEVICE_TABLE(of, zynqmp_qspi_of_match);
static struct platform_driver zynqmp_qspi_driver = {
.probe = zynqmp_qspi_probe,
.remove_new = zynqmp_qspi_remove,
+ .shutdown = zynqmp_qspi_shutdown,
.driver = {
.name = "zynqmp-qspi",
.of_match_table = zynqmp_qspi_of_match,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 289/877] smb: client: fix busy dentry warning on unmount after DIO
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (287 preceding siblings ...)
2026-09-30 15:19 ` [PATCH 6.12 288/877] spi: spi-zynqmp-gqspi: stop the controller on shutdown Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 290/877] xfs: dont stash removename operations with unknown ftype Greg Kroah-Hartman
` (595 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Zizhi Wo, Steve French, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zizhi Wo <wozizhi@huawei.com>
[ Upstream commit 75f5c412fa867efa0bf9b646bffe0d912109e84a ]
Commit c68337442f03 ("cifs: Fix busy dentry used after unmounting") fixed
the issue in cifs where deferred close of a file led to a dentry reference
count not being released in umount, by flushing deferredclose_wq in
cifs_kill_sb() to solve it.
However, the cifs DIO path suffers from the same busy-dentry problem caused
by a delayed dentry reference-count release:
[dio] [cifsd] [close + umount]
netfs_unbuffered_write_iter_locked
...
cifs_demultiplex_thread
netfs_unbuffered_write
cifs_issue_write
netfs_wait_for_in_progress_stream [1]
...
netfs_write_subrequest_terminated
netfs_subreq_clear_in_progress
netfs_wake_collector // wake [1]
netfs_put_subrequest
netfs_put_request
queue_work(system_dfl_wq, xxx) [2]
// dio write return cifs_close
_cifsFileInfo_put
// cfile->count 2->1
--cfile->count [3]
// umount
cifs_kill_sb
kill_anon_super
// warning triggered!
shrink_dcache_for_umount [4]
[system_dfl_wq] [5]
netfs_free_request
...
_cifsFileInfo_put
// cfile->count 1->0
--cfile->count
queue_work(fileinfo_put_wq, xxx)
[fileinfo_put_wq] [6]
cifsFileInfo_put_work
cifsFileInfo_put_final
dput
If the umount path is triggered before [5], it results warning:
BUG: Dentry 00000000eab1f070{i=9a917b66ae404fec,n=test} still in use (1)
[unmount of cifs cifs]
The existing per-inode ictx->io_count wait in cifs_evict_inode() does not
help: it lives in the inode eviction path, which runs after
shrink_dcache_for_umount() has already warned about the busy dentries.
Fix it by adding a per-superblock outstanding-rreq counter that is
incremented in cifs_init_request() and decremented in cifs_free_request().
In cifs_kill_sb(), before kill_anon_super(), wait for this counter to reach
0 - which guarantees that all cleanup_work for this sb have run and thus
all relevant cfile puts are queued on fileinfo_put_wq or serverclose_wq.
Then drain the workqueue so the dentry refs are dropped.
This is a targeted wait, not a flush of the system-wide system_dfl_wq.
Fixes: 340cea84f691c ("cifs: open files should not hold ref on superblock")
Signed-off-by: Zizhi Wo <wozizhi@huawei.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/cifs_fs_sb.h | 1 +
fs/smb/client/cifsfs.c | 12 ++++++++++++
fs/smb/client/connect.c | 1 +
fs/smb/client/file.c | 5 +++++
4 files changed, 19 insertions(+)
diff --git a/fs/smb/client/cifs_fs_sb.h b/fs/smb/client/cifs_fs_sb.h
index 6517591922801..2b4850566f15b 100644
--- a/fs/smb/client/cifs_fs_sb.h
+++ b/fs/smb/client/cifs_fs_sb.h
@@ -55,6 +55,7 @@ struct cifs_sb_info {
struct smb3_fs_context *ctx;
atomic_t active;
unsigned int mnt_cifs_flags;
+ atomic_t outstanding_rreq; /* nr of rreqs not yet fully deinitialized */
struct delayed_work prune_tlinks;
struct rcu_head rcu;
diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
index a14f24f8d4a51..f22c79179a23a 100644
--- a/fs/smb/client/cifsfs.c
+++ b/fs/smb/client/cifsfs.c
@@ -302,6 +302,18 @@ static void cifs_kill_sb(struct super_block *sb)
/* Wait for all opened files to release */
flush_workqueue(deferredclose_wq);
+ /*
+ * Wait for all in-flight netfs I/O requests to finish their
+ * cleanup_work so that any cifsFileInfo final puts they queue
+ * to fileinfo_put_wq/serverclose_wq have been queued, then
+ * drain the workqueue so the cfile dentry refs are dropped to
+ * avoid the busy dentry warning.
+ */
+ wait_var_event(&cifs_sb->outstanding_rreq,
+ !atomic_read(&cifs_sb->outstanding_rreq));
+ flush_workqueue(serverclose_wq);
+ flush_workqueue(fileinfo_put_wq);
+
/* finally release root dentry */
dput(cifs_sb->root);
cifs_sb->root = NULL;
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index 026c1a30816c4..a7261fb38379f 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -3399,6 +3399,7 @@ int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb)
spin_lock_init(&cifs_sb->tlink_tree_lock);
cifs_sb->tlink_tree = RB_ROOT;
+ atomic_set(&cifs_sb->outstanding_rreq, 0);
cifs_dbg(FYI, "file mode: %04ho dir mode: %04ho\n",
ctx->file_mode, ctx->dir_mode);
diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
index 339346a82ecff..79cf5829411c2 100644
--- a/fs/smb/client/file.c
+++ b/fs/smb/client/file.c
@@ -276,6 +276,7 @@ static int cifs_init_request(struct netfs_io_request *rreq, struct file *file)
return -EIO;
}
+ atomic_inc(&cifs_sb->outstanding_rreq);
return 0;
}
@@ -297,9 +298,13 @@ static void cifs_rreq_done(struct netfs_io_request *rreq)
static void cifs_free_request(struct netfs_io_request *rreq)
{
struct cifs_io_request *req = container_of(rreq, struct cifs_io_request, rreq);
+ struct cifs_sb_info *cifs_sb = CIFS_SB(rreq->inode->i_sb);
if (req->cfile)
cifsFileInfo_put(req->cfile);
+
+ if (atomic_dec_and_test(&cifs_sb->outstanding_rreq))
+ wake_up_var(&cifs_sb->outstanding_rreq);
}
static void cifs_free_subrequest(struct netfs_io_subrequest *subreq)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 290/877] xfs: dont stash removename operations with unknown ftype
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (288 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 289/877] smb: client: fix busy dentry warning on unmount after DIO Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 291/877] erofs: fix large folio race in erofs_fscache_req_complete Greg Kroah-Hartman
` (594 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
[ Upstream commit 865b751e75039fc07838b3200f9740256653da9a ]
LOLLM notices that the behavior of xrep_dir_replay_update changes based
on the ftype recorded in the stashed removename information. It also
notices that the unlink iops sometimes set that ftype to FT_UNKNOWN
because the regular directory tree update code paths don't need to know
the ftype of the child.
Unfortunately, this results in incorrect link counts, which eventually
trips link count errors in later phases of xfs_scrub, or in xfs_repair.
Fix this by creating a second xfs_name with the type set correctly.
Cc: stable@vger.kernel.org # v6.10
Fixes: 8559b21a64d983 ("xfs: implement live updates for directory repairs")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/scrub/dir_repair.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/fs/xfs/scrub/dir_repair.c b/fs/xfs/scrub/dir_repair.c
index 53272c2540200..bea08dcae5b3d 100644
--- a/fs/xfs/scrub/dir_repair.c
+++ b/fs/xfs/scrub/dir_repair.c
@@ -1379,9 +1379,24 @@ xrep_dir_live_update(
if (p->delta > 0)
error = xrep_dir_stash_createname(rd, p->name,
p->ip->i_ino);
- else
- error = xrep_dir_stash_removename(rd, p->name,
+ else {
+ /*
+ * xfs_dentry_to_name in unlink or rename-exchange can
+ * pass us names with ftype FT_UNKNOWN, but we really
+ * must know the ftype of the child that is being
+ * removed so that we can do nlink updates correctly
+ * without holding inode references.
+ */
+ struct xfs_name name = {
+ .name = p->name->name,
+ .len = p->name->len,
+ .type = xfs_mode_to_ftype(
+ VFS_IC(p->ip)->i_mode),
+ };
+
+ error = xrep_dir_stash_removename(rd, &name,
p->ip->i_ino);
+ }
mutex_unlock(&rd->pscan.lock);
if (error)
goto out_abort;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 291/877] erofs: fix large folio race in erofs_fscache_req_complete
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (289 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 290/877] xfs: dont stash removename operations with unknown ftype Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 292/877] ALSA: hda/realtek: Limit Star Labs internal mic boost Greg Kroah-Hartman
` (593 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wenwu Hou, Gao Xiang, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wenwu Hou <hwenwur@gmail.com>
This patch is for stable only. Commit c37460cd9b2fc ("erofs: remove fscache
backend entirely") upstream removed this code.
xas_for_each() iteration can race with reclamation of an unlocked large
folio and splitting of its replacement shadow entry. Fix this by
advancing past the entire folio before unlocking it.
For example:
CPU A: EROFS completion Other CPUs
---------------------------------- -----------------------------------
Find F at index 0.
Mark F uptodate.
Unlock F.
Reclaim F.
Replace indices 0–3 with a
multi-index workingset shadow.
Another reader inserts a smaller
folio, e.g. order-0 at index 0.
Split the large shadow entry:
index 0: new folio
index 1: shadow
index 2: shadow
index 3: shadow
Find a shadow at index 1.
folio_mark_uptodate(folio).
This can cause a kernel panic such as:
[1030374.432778] [ C31] BUG: unable to handle page fault for address: 00001846af017b01
[1030374.432971] [ C31] #PF: supervisor write access in kernel mode
[1030374.432973] [ C31] #PF: error_code(0x0002) - not-present page
[1030374.433543] [ C31] PGD 5a44f75067 P4D 5a44f75067 PUD 0
[1030374.433546] [ C31] Oops: 0002 [#1] PREEMPT SMP NOPTI
[1030374.433549] [ C31] CPU: 31 PID: 2425624 Comm: node Kdump: loaded Tainted: G OE K 6.6.88-****
[1030374.434154] [ C31] Hardware name: Alibaba Cloud Alibaba Cloud ECS, BIOS ?-20260421_110423-CN.l65g09119.cloud.sqa.na131 04/01/2014
[1030374.434156] [ C31] RIP: 0010:erofs_fscache_req_complete+0xc1/0x1a0 [erofs]
[1030374.434764] [ C31] Code: 17 c5 c3 48 89 c7 48 85 c0 0f 84 af 00 00 00 48 81 ff 06 04 00 00 74 1b 48 81 ff 02 04 00 00 0f 84 b9 00 00 00 66 85 ed 75 04 <f0> 80 0f 08 e8 96 04 24 c3 48 8b 54 24 18 f6 c2 03 0f 95 c0 48 85
[1030374.435044] [ C31] RSP: 0000:ffffb8f2fc973cc0 EFLAGS: 00010046
[1030374.435641] [ C31]
[1030374.435642] [ C31] RAX: 00001846af017b01 RBX: 000000000000000f RCX: 0000000000000001
[1030374.436885] [ C31] RDX: 000000000000000c RSI: ffffa02ab337d468 RDI: 00001846af017b01
[1030374.437127] [ C31] RBP: 0000000000000000 R08: ffffffffffffffc0 R09: 0000000000000002
[1030374.437672] [ C31] R10: 0000000000000005 R11: 0000000000000191 R12: ffffa0060ec72300
[1030374.437673] [ C31] R13: 0000000008000000 R14: ffffffffc11b1990 R15: 0000000000007000
[1030374.437677] [ C31] FS: 00007f4928cdec80(0000) GS:ffffa07dc5f80000(0000) knlGS:0000000000000000
[1030374.437678] [ C31] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[1030374.437680] [ C31] CR2: 00001846af017b01 CR3: 00000063d5356006 CR4: 0000000000770ee0
[1030374.437681] [ C31] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[1030374.437682] [ C31] DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400
[1030374.437684] [ C31] PKRU: 55555558
[1030374.437684] [ C31] Call Trace:
[1030374.437687] [ C31] <TASK>
[1030374.437692] [ C31] erofs_fscache_req_put+0x27/0x40 [erofs]
[1030374.438900] [ C31] cachefiles_read_complete+0x48/0x110 [cachefiles]
[1030374.440448] [ C31] iomap_dio_bio_end_io+0x128/0x160
[1030374.440456] [ C31] ? __pfx_stripe_end_io+0x10/0x10 [dm_mod]
[1030374.440950] [ C31] clone_endio+0x123/0x1f0 [dm_mod]
[1030374.441550] [ C31] blk_mq_end_request_batch+0xf4/0x440
[1030374.441556] [ C31] ? nohz_balancer_kick+0x31/0x270
[1030374.441561] [ C31] ? dma_direct_unmap_sg+0x48/0x1d0
[1030374.441565] [ C31] ? dma_pool_free+0x22/0x60
[1030374.441569] [ C31] ? nvme_pci_complete_batch+0xaf/0xc0 [nvme]
[1030374.442070] [ C31] nvme_irq+0x6e/0x80 [nvme]
[1030374.442422] [ C31] ? __pfx_nvme_pci_complete_batch+0x10/0x10 [nvme]
[1030374.442428] [ C31] __handle_irq_event_percpu+0x46/0x1a0
[1030374.442431] [ C31] handle_irq_event+0x37/0x80
[1030374.442433] [ C31] handle_edge_irq+0x93/0x240
[1030374.442436] [ C31] __common_interrupt+0x3b/0xa0
[1030374.442441] [ C31] common_interrupt+0x3f/0xa0
[1030374.442446] [ C31] asm_common_interrupt+0x22/0x40
Fixes: d435d53228dd ("erofs: change to use asynchronous io for fscache readpage/readahead")
Signed-off-by: Wenwu Hou <hwenwur@gmail.com>
Reviewed-by: Gao Xiang <xiang@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/erofs/fscache.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c
index 20e2cb18ed1d4..06987f7f6a195 100644
--- a/fs/erofs/fscache.c
+++ b/fs/erofs/fscache.c
@@ -67,6 +67,8 @@ static void erofs_fscache_req_complete(struct erofs_fscache_rq *req)
continue;
if (!failed)
folio_mark_uptodate(folio);
+ /* Skip the entire folio before unlocking allows it to be split. */
+ xas_advance(&xas, folio_next_index(folio) - 1);
folio_unlock(folio);
}
rcu_read_unlock();
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 292/877] ALSA: hda/realtek: Limit Star Labs internal mic boost
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (290 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 291/877] erofs: fix large folio race in erofs_fscache_req_complete Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 293/877] ALSA: hda/realtek: Add StarFighter HDA SSID Greg Kroah-Hartman
` (592 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sean Rhodes, Takashi Iwai,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Rhodes <sean@starlabs.systems>
[ Upstream commit 186d4adbb40138e7cb7cffc87a81e95630ced123 ]
The 30 dB internal mic boost is too high for laptops, especially with fans. Limit Star Labs internal mic boost to 10 dB.
Signed-off-by: Sean Rhodes <sean@starlabs.systems>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/be87292613b24150d6321adac102b4b25d00e9e6.1785532385.git.sean@starlabs.systems
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/pci/hda/patch_realtek.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 4b0ccb3b48b2b..e9913767b0b84 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -8243,6 +8243,7 @@ enum {
ALC245_FIXUP_CLEVO_NOISY_MIC,
ALC269_FIXUP_VAIO_VJFH52_MIC_NO_PRESENCE,
ALC233_FIXUP_MEDION_MTL_SPK,
+ ALC269_FIXUP_STARLABS_LIMIT_INT_MIC_BOOST,
ALC233_FIXUP_STARLABS_STARFIGHTER,
ALC294_FIXUP_BASS_SPEAKER_15,
ALC283_FIXUP_DELL_HP_RESUME,
@@ -10652,6 +10653,10 @@ static const struct hda_fixup alc269_fixups[] = {
{ }
},
},
+ [ALC269_FIXUP_STARLABS_LIMIT_INT_MIC_BOOST] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc269_fixup_limit_int_mic_boost,
+ },
[ALC233_FIXUP_STARLABS_STARFIGHTER] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc233_fixup_starlabs_starfighter,
@@ -11770,6 +11775,7 @@ static const struct hda_quirk alc269_fixup_vendor_tbl[] = {
SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
SND_PCI_QUIRK_VENDOR(0x19e5, "Huawei Matebook", ALC255_FIXUP_MIC_MUTE_LED),
+ SND_PCI_QUIRK_VENDOR(0x2145, "Star Labs", ALC269_FIXUP_STARLABS_LIMIT_INT_MIC_BOOST),
{}
};
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 293/877] ALSA: hda/realtek: Add StarFighter HDA SSID
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (291 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 292/877] ALSA: hda/realtek: Limit Star Labs internal mic boost Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 294/877] netfilter: nf_tables: Tolerate chains with no remaining hooks Greg Kroah-Hartman
` (591 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sean Rhodes, Takashi Iwai,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Rhodes <sean@starlabs.systems>
[ Upstream commit cd401c70df472d3eddd0b6b055726a03c212181a ]
Support the new StarFighter HDA SSID while keeping the existing SSID chained to the same quirk until the new match reaches backports.
Signed-off-by: Sean Rhodes <sean@starlabs.systems>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/06865eaedf3de8dff199e9aa7e86cd135572f20f.1785532385.git.sean@starlabs.systems
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/pci/hda/patch_realtek.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index e9913767b0b84..72d540182f8d0 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -10660,6 +10660,8 @@ static const struct hda_fixup alc269_fixups[] = {
[ALC233_FIXUP_STARLABS_STARFIGHTER] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc233_fixup_starlabs_starfighter,
+ .chained = true,
+ .chain_id = ALC269_FIXUP_STARLABS_LIMIT_INT_MIC_BOOST,
},
[ALC294_FIXUP_BASS_SPEAKER_15] = {
.type = HDA_FIXUP_FUNC,
@@ -11698,6 +11700,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1f66, 0x0105, "Ayaneo Portable Game Player", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x2014, 0x800a, "Positivo ARN50", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
SND_PCI_QUIRK(0x2039, 0x0001, "Inspur S14-G1", ALC295_FIXUP_CHROME_BOOK),
+ SND_PCI_QUIRK(0x2145, 0x0001, "Star Labs StarFighter", ALC233_FIXUP_STARLABS_STARFIGHTER),
SND_PCI_QUIRK(0x2782, 0x0214, "VAIO VJFE-CL", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
SND_PCI_QUIRK(0x2782, 0x0228, "Infinix ZERO BOOK 13", ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13),
SND_PCI_QUIRK(0x2782, 0x0232, "CHUWI CoreBook XPro", ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO),
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 294/877] netfilter: nf_tables: Tolerate chains with no remaining hooks
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (292 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 293/877] ALSA: hda/realtek: Add StarFighter HDA SSID Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 295/877] netfilter: nf_tables: Simplify chain netdev notifier Greg Kroah-Hartman
` (590 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Phil Sutter, Pablo Neira Ayuso,
Yu Junzhe, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Phil Sutter <phil@nwl.cc>
commit fc0133428e7ad65aa6b7c8e65ccfe86e469e4512 upstream.
Do not drop a netdev-family chain if the last interface it is registered
for vanishes. Users dumping and storing the ruleset upon shutdown to
restore it upon next boot may otherwise lose the chain and all contained
rules. They will still lose the list of devices, a later patch will fix
that. For now, this aligns the event handler's behaviour with that for
flowtables.
The controversal situation at netns exit should be no problem here:
event handler will unregister the hooks, core nftables cleanup code will
drop the chain itself.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Yu Junzhe <junzheyu1@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/netfilter/nf_tables.h | 2 --
net/netfilter/nf_tables_api.c | 41 -------------------------------
net/netfilter/nft_chain_filter.c | 29 ++++++----------------
3 files changed, 7 insertions(+), 65 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index f4b59915a49c5..923b2c0d6e844 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -1238,8 +1238,6 @@ static inline bool nft_is_base_chain(const struct nft_chain *chain)
return chain->flags & NFT_CHAIN_BASE;
}
-int __nft_release_basechain(struct nft_ctx *ctx);
-
unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv);
static inline bool nft_use_inc(u32 *use)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 2613ebfdc854e..af9df95ddf055 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -11362,47 +11362,6 @@ int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
}
EXPORT_SYMBOL_GPL(nft_data_dump);
-static void __nft_release_basechain_now(struct nft_ctx *ctx)
-{
- struct nft_rule *rule, *nr;
-
- list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
- list_del(&rule->list);
- nf_tables_rule_release(ctx, rule);
- }
- nf_tables_chain_destroy(ctx->chain);
-}
-
-int __nft_release_basechain(struct nft_ctx *ctx)
-{
- struct nft_rule *rule;
-
- if (WARN_ON_ONCE(!nft_is_base_chain(ctx->chain)))
- return 0;
-
- nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain);
- list_for_each_entry(rule, &ctx->chain->rules, list)
- nft_use_dec(&ctx->chain->use);
-
- nft_chain_del(ctx->chain);
- nft_use_dec(&ctx->table->use);
-
- if (!maybe_get_net(ctx->net)) {
- __nft_release_basechain_now(ctx);
- return 0;
- }
-
- /* wait for ruleset dumps to complete. Owning chain is no longer in
- * lists, so new dumps can't find any of these rules anymore.
- */
- synchronize_rcu();
-
- __nft_release_basechain_now(ctx);
- put_net(ctx->net);
- return 0;
-}
-EXPORT_SYMBOL_GPL(__nft_release_basechain);
-
static void __nft_release_hook(struct net *net, struct nft_table *table)
{
struct nft_flowtable *flowtable;
diff --git a/net/netfilter/nft_chain_filter.c b/net/netfilter/nft_chain_filter.c
index 7010541fcca66..543f258b7c6ba 100644
--- a/net/netfilter/nft_chain_filter.c
+++ b/net/netfilter/nft_chain_filter.c
@@ -322,34 +322,19 @@ static void nft_netdev_event(unsigned long event, struct net_device *dev,
struct nft_ctx *ctx)
{
struct nft_base_chain *basechain = nft_base_chain(ctx->chain);
- struct nft_hook *hook, *found = NULL;
- int n = 0;
+ struct nft_hook *hook;
list_for_each_entry(hook, &basechain->hook_list, list) {
- if (hook->ops.dev == dev)
- found = hook;
-
- n++;
- }
- if (!found)
- return;
+ if (hook->ops.dev != dev)
+ continue;
- if (n > 1) {
if (!(ctx->chain->table->flags & NFT_TABLE_F_DORMANT))
- nf_unregister_net_hook(ctx->net, &found->ops);
+ nf_unregister_net_hook(ctx->net, &hook->ops);
- list_del_rcu(&found->list);
- kfree_rcu(found, rcu);
- return;
+ list_del_rcu(&hook->list);
+ kfree_rcu(hook, rcu);
+ break;
}
-
- /* UNREGISTER events are also happening on netns exit.
- *
- * Although nf_tables core releases all tables/chains, only this event
- * handler provides guarantee that hook->ops.dev is still accessible,
- * so we cannot skip exiting net namespaces.
- */
- __nft_release_basechain(ctx);
}
static int nf_tables_netdev_event(struct notifier_block *this,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 295/877] netfilter: nf_tables: Simplify chain netdev notifier
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (293 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 294/877] netfilter: nf_tables: Tolerate chains with no remaining hooks Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 296/877] xfrm: Refactor xfrm_input lock to reduce contention with RSS Greg Kroah-Hartman
` (589 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Phil Sutter, Pablo Neira Ayuso,
Yu Junzhe, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Phil Sutter <phil@nwl.cc>
commit 375f222800bc001bb9cbd2baa1daec006430aeba upstream.
With conditional chain deletion gone, callback code simplifies: Instead
of filling an nft_ctx object, just pass basechain to the per-chain
function. Also plain list_for_each_entry() is safe now.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Yu Junzhe <junzheyu1@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/nft_chain_filter.c | 21 +++++++--------------
1 file changed, 7 insertions(+), 14 deletions(-)
diff --git a/net/netfilter/nft_chain_filter.c b/net/netfilter/nft_chain_filter.c
index 543f258b7c6ba..19a553550c769 100644
--- a/net/netfilter/nft_chain_filter.c
+++ b/net/netfilter/nft_chain_filter.c
@@ -319,17 +319,16 @@ static const struct nft_chain_type nft_chain_filter_netdev = {
};
static void nft_netdev_event(unsigned long event, struct net_device *dev,
- struct nft_ctx *ctx)
+ struct nft_base_chain *basechain)
{
- struct nft_base_chain *basechain = nft_base_chain(ctx->chain);
struct nft_hook *hook;
list_for_each_entry(hook, &basechain->hook_list, list) {
if (hook->ops.dev != dev)
continue;
- if (!(ctx->chain->table->flags & NFT_TABLE_F_DORMANT))
- nf_unregister_net_hook(ctx->net, &hook->ops);
+ if (!(basechain->chain.table->flags & NFT_TABLE_F_DORMANT))
+ nf_unregister_net_hook(dev_net(dev), &hook->ops);
list_del_rcu(&hook->list);
kfree_rcu(hook, rcu);
@@ -343,25 +342,20 @@ static int nf_tables_netdev_event(struct notifier_block *this,
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
struct nft_base_chain *basechain;
struct nftables_pernet *nft_net;
- struct nft_chain *chain, *nr;
+ struct nft_chain *chain;
struct nft_table *table;
- struct nft_ctx ctx = {
- .net = dev_net(dev),
- };
if (event != NETDEV_UNREGISTER)
return NOTIFY_DONE;
- nft_net = nft_pernet(ctx.net);
+ nft_net = nft_pernet(dev_net(dev));
mutex_lock(&nft_net->commit_mutex);
list_for_each_entry(table, &nft_net->tables, list) {
if (table->family != NFPROTO_NETDEV &&
table->family != NFPROTO_INET)
continue;
- ctx.family = table->family;
- ctx.table = table;
- list_for_each_entry_safe(chain, nr, &table->chains, list) {
+ list_for_each_entry(chain, &table->chains, list) {
if (!nft_is_base_chain(chain))
continue;
@@ -370,8 +364,7 @@ static int nf_tables_netdev_event(struct notifier_block *this,
basechain->ops.hooknum != NF_INET_INGRESS)
continue;
- ctx.chain = chain;
- nft_netdev_event(event, dev, &ctx);
+ nft_netdev_event(event, dev, basechain);
}
}
mutex_unlock(&nft_net->commit_mutex);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 296/877] xfrm: Refactor xfrm_input lock to reduce contention with RSS
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (294 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 295/877] netfilter: nf_tables: Simplify chain netdev notifier Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 297/877] xfrm: Fix dev use-after-free in xfrm async resumption Greg Kroah-Hartman
` (588 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jianbo Liu, Cosmin Ratiu,
Steffen Klassert, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jianbo Liu <jianbol@nvidia.com>
[ Upstream commit 10a11861943902fda74f37f456b45183b2bca270 ]
With newer NICs like mlx5 supporting RSS for IPsec crypto offload,
packets for a single Security Association (SA) are scattered across
multiple CPU cores for parallel processing. The xfrm_state spinlock
(x->lock) is held for each packet during xfrm processing.
When multiple connections or flows share the same SA, this parallelism
causes high lock contention on x->lock, creating a performance
bottleneck and limiting scalability.
The original xfrm_input() function exacerbated this issue by releasing
and immediately re-acquiring x->lock. For hardware crypto offload
paths, this unlock/relock sequence is unnecessary and introduces
significant overhead. This patch refactors the function to relocate
the type_offload->input_tail call for the offload path, performing all
necessary work while continuously holding the lock. This reordering is
safe, since packets which don't pass the checks below will still fail
them with the new code.
Performance testing with iperf using multiple parallel streams over a
single IPsec SA shows significant improvement in throughput as the
number of queues (and thus CPU cores) increases:
+-----------+---------------+--------------+-----------------+
| RX queues | Before (Gbps) | After (Gbps) | Improvement (%) |
+-----------+---------------+--------------+-----------------+
| 2 | 32.3 | 34.4 | 6.5 |
| 4 | 34.4 | 40.0 | 16.3 |
| 6 | 24.5 | 38.3 | 56.3 |
| 8 | 23.1 | 38.3 | 65.8 |
| 12 | 18.1 | 29.9 | 65.2 |
| 16 | 16.0 | 25.2 | 57.5 |
+-----------+---------------+--------------+-----------------+
Signed-off-by: Jianbo Liu <jianbol@nvidia.com>
Reviewed-by: Cosmin Ratiu <cratiu@nvidia.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Stable-dep-of: 3cf5cdecd99c ("xfrm: save input state data before secpath resets")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/xfrm/xfrm_input.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 1be187b980461..444334feece7b 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -493,6 +493,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
if (encap_type == -1) {
async = 1;
seq = XFRM_SKB_CB(skb)->seq.input.low;
+ spin_lock(&x->lock);
goto resume;
}
/* GRO call */
@@ -529,6 +530,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
goto drop;
}
+
+ nexthdr = x->type_offload->input_tail(x, skb);
}
goto lock;
@@ -626,11 +629,9 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
goto drop_unlock;
}
- spin_unlock(&x->lock);
-
if (xfrm_tunnel_check(skb, x, family)) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMODEERROR);
- goto drop;
+ goto drop_unlock;
}
seq_hi = htonl(xfrm_replay_seqhi(x, seq));
@@ -638,9 +639,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
XFRM_SKB_CB(skb)->seq.input.low = seq;
XFRM_SKB_CB(skb)->seq.input.hi = seq_hi;
- if (crypto_done) {
- nexthdr = x->type_offload->input_tail(x, skb);
- } else {
+ if (!crypto_done) {
+ spin_unlock(&x->lock);
dev_hold(skb->dev);
nexthdr = x->type->input(x, skb);
@@ -651,9 +651,9 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
}
dev_put(skb->dev);
+ spin_lock(&x->lock);
}
resume:
- spin_lock(&x->lock);
if (nexthdr < 0) {
if (nexthdr == -EBADMSG) {
xfrm_audit_state_icvfail(x, skb,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 297/877] xfrm: Fix dev use-after-free in xfrm async resumption
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (295 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 296/877] xfrm: Refactor xfrm_input lock to reduce contention with RSS Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 298/877] xfrm: save input state data before secpath resets Greg Kroah-Hartman
` (587 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xu Chunxiao, Dong Chenchen,
Steffen Klassert, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dong Chenchen <dongchenchen2@huawei.com>
[ Upstream commit 8045c0df98d4f14c54e5cb875f1c9c0ce89fe4ff ]
xfrm async resumption hold skb->dev refcnt until after transport_finish.
However, xfrm_rcv_cb may modify skb->dev to tunnel dev without taking
device reference, such as vti_rcv_cb. The subsequent async resumption
will decrement the tunnel device's reference count, which lead to uaf
of tunnel dev and refcnt leak of orig dev as below:
unregister_netdevice: waiting for vti1 to become free. Usage count = -2
Stash the original skb->dev to fix refcnt imbalance. The new skb->dev set
by xfrm_rcv_cb can race with device teardown. Extend rcu protection over
xfrm_rcv_cb and transport_finish to prevent races.
Fixes: 1c428b038400 ("xfrm: hold dev ref until after transport_finish NF_HOOK")
Reported-by: Xu Chunxiao <xuchunxiao3@huawei.com>
Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Backport to 6.12: retain the synchronous xfrm_inner_mode_input()
error handling. This tree lacks the mode_cbs infrastructure that
introduced the -EINPROGRESS branch, so omit the dev_put() conversion
for that absent branch. Keep the original-device reference handling
and extended RCU protection for the existing receive paths.
This supplies the receive, transport-finish and drop-path context for
3cf5cdecd99c ("xfrm: save input state data before secpath resets"),
which applies without further changes.
Stable-dep-of: 3cf5cdecd99c ("xfrm: save input state data before secpath resets")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/xfrm4_input.c | 2 --
net/ipv6/xfrm6_input.c | 2 --
net/xfrm/xfrm_input.c | 27 +++++++++++++++------------
3 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index adf21d6b6076c..9deee1558e3d6 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -76,8 +76,6 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async)
NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING,
dev_net(dev), NULL, skb, dev, NULL,
xfrm4_rcv_encap_finish);
- if (async)
- dev_put(dev);
return 0;
}
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index c9e208c57a6b5..07edef2589844 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -71,8 +71,6 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async)
NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING,
dev_net(dev), NULL, skb, dev, NULL,
xfrm6_transport_finish2);
- if (async)
- dev_put(dev);
return 0;
}
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 444334feece7b..ba512e9293201 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -457,6 +457,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
{
const struct xfrm_state_afinfo *afinfo;
struct net *net = dev_net(skb->dev);
+ struct net_device *dev = skb->dev;
int err;
__be32 seq;
__be32 seq_hi;
@@ -483,7 +484,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
LINUX_MIB_XFRMINSTATEINVALID);
if (encap_type == -1)
- dev_put(skb->dev);
+ dev_put(dev);
goto drop;
}
@@ -641,16 +642,16 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
if (!crypto_done) {
spin_unlock(&x->lock);
- dev_hold(skb->dev);
+ dev_hold(dev);
nexthdr = x->type->input(x, skb);
if (nexthdr == -EINPROGRESS) {
if (async)
- dev_put(skb->dev);
+ dev_put(dev);
return 0;
}
- dev_put(skb->dev);
+ dev_put(dev);
spin_lock(&x->lock);
}
resume:
@@ -707,9 +708,12 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
crypto_done = false;
} while (!err);
+ rcu_read_lock();
err = xfrm_rcv_cb(skb, family, x->type->proto, 0);
- if (err)
+ if (err) {
+ rcu_read_unlock();
goto drop;
+ }
nf_reset_ct(skb);
@@ -720,8 +724,9 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
if (skb_valid_dst(skb))
skb_dst_drop(skb);
if (async)
- dev_put(skb->dev);
+ dev_put(dev);
gro_cells_receive(&gro_cells, skb);
+ rcu_read_unlock();
return 0;
} else {
xo = xfrm_offload(skb);
@@ -729,23 +734,21 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
xfrm_gro = xo->flags & XFRM_GRO;
err = -EAFNOSUPPORT;
- rcu_read_lock();
afinfo = xfrm_state_afinfo_get_rcu(x->props.family);
if (likely(afinfo))
err = afinfo->transport_finish(skb, xfrm_gro || async);
- rcu_read_unlock();
if (xfrm_gro) {
sp = skb_sec_path(skb);
if (sp)
sp->olen = 0;
if (skb_valid_dst(skb))
skb_dst_drop(skb);
- if (async)
- dev_put(skb->dev);
gro_cells_receive(&gro_cells, skb);
- return err;
}
+ if (async)
+ dev_put(dev);
+ rcu_read_unlock();
return err;
}
@@ -753,7 +756,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
spin_unlock(&x->lock);
drop:
if (async)
- dev_put(skb->dev);
+ dev_put(dev);
xfrm_rcv_cb(skb, family, x && x->type ? x->type->proto : nexthdr, -1);
kfree_skb(skb);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 298/877] xfrm: save input state data before secpath resets
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (296 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 297/877] xfrm: Fix dev use-after-free in xfrm async resumption Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 299/877] remoteproc: qcom_q6v5_adsp: Fix iommu_unmap() usage Greg Kroah-Hartman
` (586 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Zhiling Zou, Steffen Klassert,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhiling Zou <zhilinz@nebusec.ai>
[ Upstream commit 3cf5cdecd99c9c186a5ea518d93bbf3045b6e3aa ]
xfrm_input() stores the current xfrm_state in the skb secpath while it
continues receive-side processing. Some input paths can reset that secpath
before xfrm_input() has finished dereferencing the state.
Receive callback users such as VTI and XFRM interfaces can reset the
secpath. The VTI receive path does so before checking whether the packet
crosses network namespaces, while the XFRM interface path does so only for
cross-network-namespace packets. The XFRM_MAX_DEPTH error path can also
reset the secpath before the final drop callback reports the current
state's protocol.
If secpath_reset() drops the last state reference while the state is
concurrently deleted, xfrm_input() can still dereference the freed state
when selecting transport_finish() or reporting the drop callback protocol.
Save the state protocol on the stack while the state is still valid,
and use the already saved address family for transport_finish(). A larval
XFRM_STATE_ACQ state has no type, so retain nexthdr as its protocol. This
preserves the existing drop-path fallback while avoiding the post-reset
state dereferences without adding an extra state reference to every
received packet.
Fixes: df3893c176e9 ("vti: Update the ipv4 side to use it's own receive hook.")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/xfrm/xfrm_input.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index ba512e9293201..63d1504b50a92 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -464,6 +464,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
struct xfrm_state *x = NULL;
xfrm_address_t *daddr;
u32 mark = skb->mark;
+ u8 xfrm_proto = nexthdr;
unsigned int family = AF_UNSPEC;
int decaps = 0;
int async = 0;
@@ -475,6 +476,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
if (encap_type < 0 || (xo && (xo->flags & XFRM_GRO || encap_type == 0 ||
encap_type == UDP_ENCAP_ESPINUDP))) {
x = xfrm_input_state(skb);
+ xfrm_proto = x->type ? x->type->proto : nexthdr;
if (unlikely(x->km.state != XFRM_STATE_VALID)) {
if (x->km.state == XFRM_STATE_ACQ)
@@ -578,11 +580,13 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
x = xfrm_input_state_lookup(net, mark, daddr, spi, nexthdr, family);
if (x == NULL) {
+ xfrm_proto = nexthdr;
secpath_reset(skb);
XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES);
xfrm_audit_state_notfound(skb, family, spi, seq);
goto drop;
}
+ xfrm_proto = x->type ? x->type->proto : nexthdr;
if (unlikely(x->dir && x->dir != XFRM_SA_DIR_IN)) {
secpath_reset(skb);
@@ -590,6 +594,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
xfrm_audit_state_notfound(skb, family, spi, seq);
xfrm_state_put(x);
x = NULL;
+ xfrm_proto = nexthdr;
goto drop;
}
@@ -709,7 +714,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
} while (!err);
rcu_read_lock();
- err = xfrm_rcv_cb(skb, family, x->type->proto, 0);
+ err = xfrm_rcv_cb(skb, family, xfrm_proto, 0);
if (err) {
rcu_read_unlock();
goto drop;
@@ -734,7 +739,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
xfrm_gro = xo->flags & XFRM_GRO;
err = -EAFNOSUPPORT;
- afinfo = xfrm_state_afinfo_get_rcu(x->props.family);
+ afinfo = xfrm_state_afinfo_get_rcu(family);
if (likely(afinfo))
err = afinfo->transport_finish(skb, xfrm_gro || async);
if (xfrm_gro) {
@@ -757,7 +762,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
drop:
if (async)
dev_put(dev);
- xfrm_rcv_cb(skb, family, x && x->type ? x->type->proto : nexthdr, -1);
+ xfrm_rcv_cb(skb, family, xfrm_proto, -1);
kfree_skb(skb);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 299/877] remoteproc: qcom_q6v5_adsp: Fix iommu_unmap() usage
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (297 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 298/877] xfrm: save input state data before secpath resets Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 300/877] KVM: s390: Fix IRQ injection with SIGP Stop and Store Status Greg Kroah-Hartman
` (585 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mostafa Saleh, Bjorn Andersson,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mostafa Saleh <smostafa@google.com>
[ Upstream commit 0d8e2195bce6f08c1c53c5ef4d7347fe46418101 ]
During adsp_map_carveout, the IOVA is computed by combining the
physical address and the SID:
iova = adsp->mem_phys | (sid << 32);
However, adsp_unmap_carveout() uses the physical address and not
the IOVA in iommu_unmap(), causing the unmap to fail or leak
mappings because the address doesn't match the original IOVA.
Cache the constructed IOVA within the qcom_adsp device struct
during mapping and use it during unmapping.
Fixes: f22eedff28af ("remoteproc: qcom: Add support for memory sandbox")
Signed-off-by: Mostafa Saleh <smostafa@google.com>
Link: https://lore.kernel.org/r/20260827203055.640116-1-smostafa@google.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/remoteproc/qcom_q6v5_adsp.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/remoteproc/qcom_q6v5_adsp.c b/drivers/remoteproc/qcom_q6v5_adsp.c
index 80ac739621bed..0345940268126 100644
--- a/drivers/remoteproc/qcom_q6v5_adsp.c
+++ b/drivers/remoteproc/qcom_q6v5_adsp.c
@@ -104,6 +104,7 @@ struct qcom_adsp {
struct completion stop_done;
phys_addr_t mem_phys;
+ unsigned long iova;
phys_addr_t mem_reloc;
void *mem_region;
size_t mem_size;
@@ -333,7 +334,7 @@ static void adsp_unmap_carveout(struct rproc *rproc)
struct qcom_adsp *adsp = rproc->priv;
if (adsp->has_iommu)
- iommu_unmap(rproc->domain, adsp->mem_phys, adsp->mem_size);
+ iommu_unmap(rproc->domain, adsp->iova, adsp->mem_size);
}
static int adsp_map_carveout(struct rproc *rproc)
@@ -341,7 +342,6 @@ static int adsp_map_carveout(struct rproc *rproc)
struct qcom_adsp *adsp = rproc->priv;
struct of_phandle_args args;
long long sid;
- unsigned long iova;
int ret;
if (!adsp->has_iommu)
@@ -358,9 +358,9 @@ static int adsp_map_carveout(struct rproc *rproc)
of_node_put(args.np);
/* Add SID configuration for ADSP Firmware to SMMU */
- iova = adsp->mem_phys | (sid << 32);
+ adsp->iova = adsp->mem_phys | (sid << 32);
- ret = iommu_map(rproc->domain, iova, adsp->mem_phys,
+ ret = iommu_map(rproc->domain, adsp->iova, adsp->mem_phys,
adsp->mem_size, IOMMU_READ | IOMMU_WRITE,
GFP_KERNEL);
if (ret) {
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 300/877] KVM: s390: Fix IRQ injection with SIGP Stop and Store Status
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (298 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 299/877] remoteproc: qcom_q6v5_adsp: Fix iommu_unmap() usage Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 301/877] bpf: Fix bpf_skb_change_tail wrt csum partial skbs Greg Kroah-Hartman
` (584 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Claudio Imbrenda, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudio Imbrenda <imbrenda@linux.ibm.com>
[ Upstream commit d343407b728a80b74be3c24b59f15e60289ea527 ]
When __inject_sigp_stop() is called for a Stop and Store Status
operation, if the vCPU is running, the interrupt is marked as pending
and the status is stored by the thread performing the KVM_RUN IOCTL.
If the vCPU is already stopped, the status is stored immediately.
Storing the status means writing into userspace, which might fault, and
__inject_sigp_stop() is called from do_inject_vcpu() which in turn is
always called holding a spinlock, which is obviously an issue.
Fix this by returning -EWOULDBLOCK from __inject_sigp_stop(), and
adding a bool flag to indicate whether a store status is needed. The
callers of do_inject_vcpu() are modified to pass the pointer to the
bool flag; whenever a Store Status operation is needed, the callers can
now perform it outside the spinlock.
Opportunistically refactor kvm_s390_set_irq_state() to use
scoped_guard() and __free().
Fixes: 6cddd432e3da ("KVM: s390: handle stop irqs without action_bits")
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
[ Added Fixes tag while picking -- Claudio ]
Message-ID: <20260812104436.109741-7-imbrenda@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/kvm/interrupt.c | 70 +++++++++++++++++++++------------------
1 file changed, 38 insertions(+), 32 deletions(-)
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 3fc07da7fd7a5..0f3ad8c80381f 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -1586,23 +1586,21 @@ static int __inject_set_prefix(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
}
#define KVM_S390_STOP_SUPP_FLAGS (KVM_S390_STOP_FLAG_STORE_STATUS)
-static int __inject_sigp_stop(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
+static int __inject_sigp_stop(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq, bool *storestatus)
{
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
struct kvm_s390_stop_info *stop = &li->irq.stop;
- int rc = 0;
vcpu->stat.inject_stop_signal++;
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_SIGP_STOP, 0, 0);
if (irq->u.stop.flags & ~KVM_S390_STOP_SUPP_FLAGS)
return -EINVAL;
-
if (is_vcpu_stopped(vcpu)) {
- if (irq->u.stop.flags & KVM_S390_STOP_FLAG_STORE_STATUS)
- rc = kvm_s390_store_status_unloaded(vcpu,
- KVM_S390_STORE_STATUS_NOADDR);
- return rc;
+ if (!(irq->u.stop.flags & KVM_S390_STOP_FLAG_STORE_STATUS))
+ return 0;
+ *storestatus = true;
+ return -EWOULDBLOCK;
}
if (test_and_set_bit(IRQ_PEND_SIGP_STOP, &li->pending_irqs))
@@ -2142,7 +2140,7 @@ void kvm_s390_clear_stop_irq(struct kvm_vcpu *vcpu)
spin_unlock(&li->lock);
}
-static int do_inject_vcpu(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
+static int do_inject_vcpu(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq, bool *storestatus)
{
int rc;
@@ -2154,7 +2152,7 @@ static int do_inject_vcpu(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
rc = __inject_set_prefix(vcpu, irq);
break;
case KVM_S390_SIGP_STOP:
- rc = __inject_sigp_stop(vcpu, irq);
+ rc = __inject_sigp_stop(vcpu, irq, storestatus);
break;
case KVM_S390_RESTART:
rc = __inject_sigp_restart(vcpu);
@@ -2190,11 +2188,16 @@ static int do_inject_vcpu(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
{
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
+ bool storestatus = false;
int rc;
spin_lock(&li->lock);
- rc = do_inject_vcpu(vcpu, irq);
+ rc = do_inject_vcpu(vcpu, irq, &storestatus);
spin_unlock(&li->lock);
+
+ if (rc == -EWOULDBLOCK && storestatus)
+ rc = kvm_s390_store_status_unloaded(vcpu, KVM_S390_STORE_STATUS_NOADDR);
+
if (!rc)
kvm_s390_vcpu_wakeup(vcpu);
return rc;
@@ -2930,7 +2933,8 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, struct kvm *kvm,
int kvm_s390_set_irq_state(struct kvm_vcpu *vcpu, void __user *irqstate, int len)
{
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
- struct kvm_s390_irq *buf;
+ struct kvm_s390_irq *buf __free(kvfree) = NULL;
+ bool tmp, storestatus = false;
int r = 0;
int n;
@@ -2938,31 +2942,33 @@ int kvm_s390_set_irq_state(struct kvm_vcpu *vcpu, void __user *irqstate, int len
if (!buf)
return -ENOMEM;
- if (copy_from_user((void *) buf, irqstate, len)) {
- r = -EFAULT;
- goto out_free;
- }
+ if (copy_from_user((void *)buf, irqstate, len))
+ return -EFAULT;
- /*
- * Don't allow setting the interrupt state
- * when there are already interrupts pending
- */
- spin_lock(&li->lock);
- if (li->pending_irqs) {
- r = -EBUSY;
- goto out_unlock;
- }
+ scoped_guard(spinlock, &li->lock) {
+ /*
+ * Don't allow setting the interrupt state
+ * when there are already interrupts pending
+ */
+ if (li->pending_irqs)
+ return -EBUSY;
- for (n = 0; n < len / sizeof(*buf); n++) {
- r = do_inject_vcpu(vcpu, &buf[n]);
- if (r)
- break;
+ for (n = 0; n < len / sizeof(*buf); n++) {
+ tmp = false;
+ r = do_inject_vcpu(vcpu, &buf[n], &tmp);
+ if (r == -EWOULDBLOCK && tmp) {
+ storestatus = true;
+ r = 0;
+ }
+ if (r)
+ break;
+ }
}
-out_unlock:
- spin_unlock(&li->lock);
-out_free:
- vfree(buf);
+ if (storestatus) {
+ n = kvm_s390_store_status_unloaded(vcpu, KVM_S390_STORE_STATUS_NOADDR);
+ return r ? r : n;
+ }
return r;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 301/877] bpf: Fix bpf_skb_change_tail wrt csum partial skbs
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (299 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 300/877] KVM: s390: Fix IRQ injection with SIGP Stop and Store Status Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 302/877] bpf: Disallow bpf_skb_pull_data() for LWT_SEG6LOCAL Greg Kroah-Hartman
` (583 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tom Hadlaw, Yusuke Suzuki,
Daniel Borkmann, Alexei Starovoitov, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Borkmann <daniel@iogearbox.net>
[ Upstream commit 3b55f350c68a0aceff108f47f9d31f47ebffaf7b ]
Cilium generates ICMP "frag needed" replies from BPF when a LB DSR
packet exceeds the egress MTU. The reply is built by first trimming the
packet down to target size via bpf_skb_change_tail(), and then pushing
the ICMP error headers in front of it.
The trim is rejected for skbs which carry a checksum offload, e.g. TCP
packets aggregated by GRO on ingress where tcp_gro_complete() leaves
the skb as CHECKSUM_PARTIAL. __bpf_skb_min_len() raises the minimum
length to the end of the L4 checksum field, so a trim to 42 bytes bails
out with -EINVAL given a min_len of 52 in this case, and due to that
the ICMP generator fails. This is not the case if GRO is turned off.
Fix this bpf_skb_change_tail() restriction and drop the checksum offload
when the new length no longer covers the checksum field. The BPF program
rewrites the skb into an ICMP error and computes the checksum itself
anyway.
Fixes: 5293efe62df8 ("bpf: add bpf_skb_change_tail helper")
Reported-by: Tom Hadlaw <tom.hadlaw@isovalent.com>
Reported-by: Yusuke Suzuki <yusuke.suzuki@isovalent.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/r/20260907121025.1923656-1-daniel@iogearbox.net
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/filter.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/net/core/filter.c b/net/core/filter.c
index e0f757ffcfc5b..9a6106ae7bb55 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -3833,12 +3833,6 @@ static u32 __bpf_skb_min_len(const struct sk_buff *skb)
if (offset > 0)
min_len = offset;
}
- if (skb->ip_summed == CHECKSUM_PARTIAL) {
- offset = skb_checksum_start_offset(skb) +
- skb->csum_offset + sizeof(__sum16);
- if (offset > 0)
- min_len = offset;
- }
return min_len;
}
@@ -3855,6 +3849,11 @@ static int bpf_skb_grow_rcsum(struct sk_buff *skb, unsigned int new_len)
static int bpf_skb_trim_rcsum(struct sk_buff *skb, unsigned int new_len)
{
+ if (skb->ip_summed == CHECKSUM_PARTIAL &&
+ new_len < skb_checksum_start_offset(skb) + skb->csum_offset +
+ sizeof(__sum16))
+ skb->ip_summed = CHECKSUM_NONE;
+
return __skb_trim_rcsum(skb, new_len);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 302/877] bpf: Disallow bpf_skb_pull_data() for LWT_SEG6LOCAL
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (300 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 301/877] bpf: Fix bpf_skb_change_tail wrt csum partial skbs Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 303/877] selftests/ftrace: Fix unique symbol check in kprobe_non_uniq_symbol.tc Greg Kroah-Hartman
` (582 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, co+adfca3e91be95776,
Alexei Starovoitov, Weiming Shi, Daniel Borkmann, Emil Tsalapatis,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <bestswngs@gmail.com>
[ Upstream commit e4a62833adff6ef0fe7c0b90393204fe3c26b5c5 ]
An LWT_SEG6LOCAL program can invalidate its cached SRH with
bpf_lwt_seg6_adjust_srh() and then call bpf_skb_pull_data(). The latter
may reallocate skb->head, leaving the per-CPU SRH pointer dangling.
Post-program SRH validation then writes through that pointer.
Disallow bpf_skb_pull_data() for LWT_SEG6LOCAL programs so the verifier
rejects this unsafe helper combination. Other LWT program types continue
to expose the helper through lwt_out_func_proto().
Fixes: 004d4b274e2a ("ipv6: sr: Add seg6local action End.BPF")
Reported-by: co+adfca3e91be95776@bugs.sh
Suggested-by: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Closes: https://lore.kernel.org/all/GCy0KRM2IcQGoJQTjJEU9D0maBxXzEDHuQpq@bugs.sh/
Link: https://lore.kernel.org/bpf/DL9COXZQXX4V.1FN45QO2Q77ZH@gmail.com/
Link: https://lore.kernel.org/bpf/20260909040807.3885815-2-bestswngs@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/filter.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/core/filter.c b/net/core/filter.c
index 9a6106ae7bb55..e1d0a9bdde87e 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -8666,6 +8666,8 @@ static const struct bpf_func_proto *
lwt_seg6local_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
switch (func_id) {
+ case BPF_FUNC_skb_pull_data:
+ return NULL;
#if IS_ENABLED(CONFIG_IPV6_SEG6_BPF)
case BPF_FUNC_lwt_seg6_store_bytes:
return &bpf_lwt_seg6_store_bytes_proto;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 303/877] selftests/ftrace: Fix unique symbol check in kprobe_non_uniq_symbol.tc
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (301 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 302/877] bpf: Disallow bpf_skb_pull_data() for LWT_SEG6LOCAL Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 304/877] bpf: Fix divide-by-zero in btf_struct_walk() Greg Kroah-Hartman
` (581 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sven Schnelle, Steven Rostedt,
Masami Hiramatsu (Google), Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Schnelle <svens@linux.ibm.com>
[ Upstream commit d22c3e0088e85be8131f7a9283f759cdbb20726d ]
The current regex also matches symbols in modules, which makes the
test fail on s390 where name_show is present only once in the kernel,
but also multiple times in modules:
000001b1401cdc20 t name_show
000001b0c05e6c40 t name_show [mdev]
000001b0c0495f30 t name_show [i2c_core]
Fix this by changing the regular expression to only match the function
name.
Link: https://lore.kernel.org/all/20260909092954.2200558-1-svens@linux.ibm.com/
Fixes: 03b80ff8023a ("selftests/ftrace: Add new test case which checks non unique symbol")
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc
index bc9514428dbaf..07b1177c16344 100644
--- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc
@@ -6,7 +6,7 @@
SYMBOL='name_show'
# We skip this test on kernel where SYMBOL is unique or does not exist.
-if [ "$(grep -c -E "[[:alnum:]]+ t ${SYMBOL}" /proc/kallsyms)" -le '1' ]; then
+if [ "$(grep -c -E "[[:alnum:]]+ t ${SYMBOL}$" /proc/kallsyms)" -le '1' ]; then
exit_unsupported
fi
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 304/877] bpf: Fix divide-by-zero in btf_struct_walk()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (302 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 303/877] selftests/ftrace: Fix unique symbol check in kprobe_non_uniq_symbol.tc Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 305/877] bpf: Fix out-of-bounds read of sk_protocol in bpf_sock_destroy() Greg Kroah-Hartman
` (580 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jiayuan Chen, Eduard Zingerman,
Alexei Starovoitov, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <jiayuan.chen@linux.dev>
[ Upstream commit b0b3dc66529676228cb938cbcad66920f735c223 ]
When an access goes past the struct and the last member is a flexible
array, btf_struct_walk() folds the offset back into a single element with
(off - moff) % t->size, but never checks that the element type has a size.
BTF takes an empty struct, so this in program BTF
/* event could be empty */
struct event {
#ifdef HAVE_TIMESTAMP
__u64 ts;
#endif
};
struct batch {
int nr;
struct event events[];
};
divides by zero at prog load time. Getting there needs a PTR_TO_BTF_ID that
is not MEM_ALLOC, e.g. a plain read of a local kptr stashed in a map from a
sleepable program.
Oops: divide error: 0000 [#1] SMP KASAN PTI
RIP: 0010:btf_struct_walk+0x53f/0x1570
Call Trace:
<TASK>
btf_struct_access+0x42a/0xcd0
check_ptr_to_btf_access+0x4dc/0x1160
check_mem_access+0x3a45/0x8740
check_load_mem+0x36a/0xd10
do_check_common+0x3ef0/0xb210
bpf_check+0x6d3b/0x8580
bpf_prog_load+0xf7c/0x2720
__sys_bpf+0xa83/0x3690
__x64_sys_bpf+0xc7/0x150
x64_sys_call+0x1f3f/0x27e0
do_syscall_64+0xe5/0x610
entry_SYSCALL_64_after_hwframe+0x76/0x7e
</TASK>
Reject a zero-sized element type. The fixed array path in the same function
already bails out on the same thing:
btf_struct_walk()
...
/* skip empty array */
if (moff == mtrue_end)
continue;
msize /= total_nelems;
Fixes: 9c5f8a1008a1 ("bpf: Support variable length array in tracing programs")
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260910122316.186384-1-jiayuan.chen@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/btf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index f219a03ceefff..0c040c2e8c4f5 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -6851,7 +6851,7 @@ static int btf_struct_walk(struct bpf_verifier_log *log, const struct btf *btf,
if (btf_type_is_int(t))
return WALK_SCALAR;
- if (!btf_type_is_struct(t))
+ if (!btf_type_is_struct(t) || !t->size)
goto error;
off = (off - moff) % t->size;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 305/877] bpf: Fix out-of-bounds read of sk_protocol in bpf_sock_destroy()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (303 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 304/877] bpf: Fix divide-by-zero in btf_struct_walk() Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 306/877] tcp: Skip cond_resched() in inet_csk_listen_stop() under BPF context Greg Kroah-Hartman
` (579 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xiang Mei (Microsoft), Jiayuan Chen,
Kuniyuki Iwashima, Alexei Starovoitov, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <jiayuan.chen@linux.dev>
[ Upstream commit 01b245ba016d44861690594e10f67e026ce8552f ]
sk_protocol lives in struct sock, not in struct sock_common. A timewait
or request sock handed to bpf_sock_destroy() by the tcp iterator is
neither, so reading sk->sk_protocol runs past the object:
==================================================================
BUG: KASAN: slab-out-of-bounds in bpf_sock_destroy+0xc7/0xe0
Read of size 2 at addr ffff8881047d11b4 by task test_progs/428
Tainted: [W]=WARN
Call Trace:
<TASK>
dump_stack_lvl+0x91/0xf0
print_report+0xd1/0x630
kasan_report+0xf3/0x130
__asan_report_load2_noabort+0x14/0x30
bpf_sock_destroy+0xc7/0xe0
bpf_prog_c3dd61f9d9cd9f37_iter_tcp6_timewait+0x9f/0xb7
bpf_iter_run_prog+0x538/0xde0
bpf_iter_tcp_seq_show+0x26b/0x4b0
bpf_seq_read+0x424/0x1210
vfs_read+0x197/0xe40
ksys_read+0x119/0x240
__x64_sys_read+0x72/0xc0
x64_sys_call+0x647/0x27e0
do_syscall_64+0xe5/0x610
entry_SYSCALL_64_after_hwframe+0x76/0x7e
Only check sk_protocol on full socks. tcp_abort() already knows how to
deal with TIME_WAIT and NEW_SYN_RECV socks. Also fix the comment, it
never matched the code.
Fixes: 4ddbcb886268 ("bpf: Add bpf_sock_destroy kfunc")
Reported-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
Closes: https://lore.kernel.org/bpf/20260702224519.800135-1-xmei5@asu.edu/
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://lore.kernel.org/r/20260910112634.152195-1-jiayuan.chen@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/filter.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/net/core/filter.c b/net/core/filter.c
index e1d0a9bdde87e..25777837af690 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -12262,8 +12262,9 @@ __bpf_kfunc_start_defs();
* @sock: Pointer to socket to be destroyed
*
* Return:
- * On error, may return EPROTONOSUPPORT, EINVAL.
- * EPROTONOSUPPORT if protocol specific destroy handler is not supported.
+ * On error, may return EOPNOTSUPP, or whatever the protocol specific
+ * destroy handler returns.
+ * EOPNOTSUPP if protocol specific destroy handler is not supported.
* 0 otherwise
*/
__bpf_kfunc int bpf_sock_destroy(struct sock_common *sock)
@@ -12275,8 +12276,12 @@ __bpf_kfunc int bpf_sock_destroy(struct sock_common *sock)
* Supporting protocols will need to acquire sock lock in the BPF context
* prior to invoking this kfunc.
*/
- if (!sk->sk_prot->diag_destroy || (sk->sk_protocol != IPPROTO_TCP &&
- sk->sk_protocol != IPPROTO_UDP))
+ if (!sk->sk_prot->diag_destroy)
+ return -EOPNOTSUPP;
+
+ if (sk_fullsock(sk) &&
+ sk->sk_protocol != IPPROTO_TCP &&
+ sk->sk_protocol != IPPROTO_UDP)
return -EOPNOTSUPP;
return sk->sk_prot->diag_destroy(sk, ECONNABORTED);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 306/877] tcp: Skip cond_resched() in inet_csk_listen_stop() under BPF context
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (304 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 305/877] bpf: Fix out-of-bounds read of sk_protocol in bpf_sock_destroy() Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 307/877] HID: elecom: fix bus type for M-XGL20DLBK Greg Kroah-Hartman
` (578 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jiayuan Chen, Alexei Starovoitov,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <jiayuan.chen@linux.dev>
[ Upstream commit eaab8cab451b9502ce224cd202550375b894a467 ]
bpf_sock_destroy() runs from the tcp iterator, under rcu_read_lock(). If
the sock is a listener that still has children in its accept queue,
tcp_abort() ends up in inet_csk_listen_stop() and the cond_resched()
there trips the debug check:
BUG: sleeping function called from invalid context at net/ipv4/inet_connection_sock.c:1523
in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 628, name: test_progs
preempt_count: 0, expected: 0
RCU nest depth: 1, expected: 0
locks held by test_progs/628: 3, last CPU#3:
#0: ffff8881158cee18 (&p->lock){+.+.}-{4:4}, at: bpf_seq_read+0x56/0x1210
#1: ffff8881106bb858 (sk_lock-AF_INET6){+.+.}-{0:0}, at: bpf_iter_tcp_seq_show+0x32b/0x4b0
#2: ffffffffb435af20 (rcu_read_lock){....}-{1:3}, at: bpf_iter_run_prog+0x46b/0xde0
CPU: 3 UID: 0 PID: 628 Comm: test_progs Tainted: G W 7.2.0+ #65 PREEMPT
Tainted: [W]=WARN
Call Trace:
<TASK>
dump_stack_lvl+0xc1/0xf0
dump_stack+0x10/0x20
__might_resched+0x3d2/0x610
inet_csk_listen_stop+0x7b/0xbf0
tcp_abort+0x23b/0x3b0
bpf_sock_destroy+0xfc/0x140
bpf_prog_448133d24601754f_iter_tcp6_server+0x81/0x8a
bpf_iter_run_prog+0x538/0xde0
bpf_iter_tcp_seq_show+0x26b/0x4b0
bpf_seq_read+0x424/0x1210
vfs_read+0x197/0xe40
ksys_read+0x119/0x240
__x64_sys_read+0x72/0xc0
x64_sys_call+0x647/0x27e0
do_syscall_64+0xe5/0x610
entry_SYSCALL_64_after_hwframe+0x76/0x7e
RIP: 0033:0x7fad39b28aca
RSP: 002b:00007ffc381c61c0 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
RAX: ffffffffffffffda RBX: 00007ffc381c6a88 RCX: 00007fad39b28aca
RDX: 0000000000000032 RSI: 00007ffc381c6250 RDI: 0000000000000014
RBP: 00007ffc381c61e0 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000003
R13: 0000000000000000 R14: 000055f077c1bbb0 R15: 00007fad3a0f3000
</TASK>
The commit that added the kfunc already guards lock_sock() in tcp_abort()
and udp_abort() with has_current_bpf_ctx(), but missed the listener path.
Do the same for the cond_resched(). The loop runs inside the iterator's
rcu_read_lock(), it must not reschedule or report a quiescent state there.
Fixes: 4ddbcb886268 ("bpf: Add bpf_sock_destroy kfunc")
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Link: https://lore.kernel.org/r/20260910112736.153710-1-jiayuan.chen@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/inet_connection_sock.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 117a424d1fee3..632434743683e 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -1541,7 +1541,8 @@ void inet_csk_listen_stop(struct sock *sk)
local_bh_enable();
sock_put(child);
- cond_resched();
+ if (!has_current_bpf_ctx())
+ cond_resched();
}
if (queue->fastopenq.rskq_rst_head) {
/* Free all the reqs queued in rskq_rst_head. */
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 307/877] HID: elecom: fix bus type for M-XGL20DLBK
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (305 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 306/877] tcp: Skip cond_resched() in inet_csk_listen_stop() under BPF context Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 308/877] KVM: x86/pmu: Move Intel PMU global MSRs to intel_is_valid_msr() Greg Kroah-Hartman
` (577 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Oscar Priego Verdugo, Jiri Kosina,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oscar Priego Verdugo <oscar.priegov@gmail.com>
[ Upstream commit 8e2a4b458ad25e13422bb059758c30a6562aa9cf ]
The M-XGL20DLBK is matched as a USB device by hid-elecom, but
its entry in hid_have_special_driver[] uses HID_BLUETOOTH_DEVICE.
This prevents the special-driver quirk entry from matching the USB
device handled by hid-elecom. Use HID_USB_DEVICE there as well.
Fixes: 55633e681afb ("HID: elecom: add support for EX-G M-XGL20DLBK wireless mouse")
Signed-off-by: Oscar Priego Verdugo <oscar.priegov@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/hid-quirks.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
index 39d81777cb7e2..2f086ac897605 100644
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -416,7 +416,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
#endif
#if IS_ENABLED(CONFIG_HID_ELECOM)
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XGL20DLBK) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XGL20DLBK) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1MRBK_01AC) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_018F) },
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 308/877] KVM: x86/pmu: Move Intel PMU global MSRs to intel_is_valid_msr()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (306 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 307/877] HID: elecom: fix bus type for M-XGL20DLBK Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 309/877] bpf: Avoid soft lockup in __htab_map_lookup_and_delete_batch() Greg Kroah-Hartman
` (576 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jim Mattson, Like Xu, Sandipan Das,
Sean Christopherson, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jim Mattson <jmattson@google.com>
[ Upstream commit 79a71cc2568f4b5d42284da2aa26f3b4f47ce01b ]
Commit c85cdc1cc1ea ("KVM: x86/pmu: Move handling PERF_GLOBAL_CTRL and
friends to common x86") moved the existence check for the following Intel
PMU MSRs to kvm_pmu_is_valid_msr():
- MSR_CORE_PERF_GLOBAL_STATUS
- MSR_CORE_PERF_GLOBAL_CTRL
- MSR_CORE_PERF_GLOBAL_OVF_CTRL
That commit deemed these MSRs valid whenever pmu->version > 1. It intended
to share the check with AMD PerfMonV2 because both vendor implementations
require version 2 or greater for global PMU controls. However, as noted in
the commit message, AMD uses different MSR indices for its global PMU
registers.
Commit 4a2771895ca6 ("KVM: x86/svm/pmu: Add AMD PerfMonV2 support")
subsequently added AMD PerfMonV2 support and set pmu->version = 2. Because
kvm_pmu_is_valid_msr() validated the Intel MSRs whenever pmu->version > 1,
KVM incorrectly permitted AMD guests with PerfMonV2 to access these Intel
MSRs without a #GP.
Move the validation of these Intel MSRs to intel_is_valid_msr() and remove
the common switch statement from kvm_pmu_is_valid_msr(). AMD already
validates its own global PMU MSRs in amd_is_valid_msr().
Fixes: 4a2771895ca6 ("KVM: x86/svm/pmu: Add AMD PerfMonV2 support")
Signed-off-by: Jim Mattson <jmattson@google.com>
Reviewed-by: Like Xu <likexu@tencent.com>
Reviewed-by: Sandipan Das <sandipan.das@amd.com>
Link: https://patch.msgid.link/20260902184711.138538-1-jmattson@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kvm/pmu.c | 8 --------
arch/x86/kvm/vmx/pmu_intel.c | 3 +++
2 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index a26e8f5ad7901..a0efe59aa0794 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -614,14 +614,6 @@ void kvm_pmu_deliver_pmi(struct kvm_vcpu *vcpu)
bool kvm_pmu_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr)
{
- switch (msr) {
- case MSR_CORE_PERF_GLOBAL_STATUS:
- case MSR_CORE_PERF_GLOBAL_CTRL:
- case MSR_CORE_PERF_GLOBAL_OVF_CTRL:
- return kvm_pmu_has_perf_global_ctrl(vcpu_to_pmu(vcpu));
- default:
- break;
- }
return kvm_pmu_call(msr_idx_to_pmc)(vcpu, msr) ||
kvm_pmu_call(is_valid_msr)(vcpu, msr);
}
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index a5edc623166ac..4f6fa564028f8 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -154,6 +154,9 @@ static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr)
int ret;
switch (msr) {
+ case MSR_CORE_PERF_GLOBAL_STATUS:
+ case MSR_CORE_PERF_GLOBAL_CTRL:
+ case MSR_CORE_PERF_GLOBAL_OVF_CTRL:
case MSR_CORE_PERF_FIXED_CTR_CTRL:
return kvm_pmu_has_perf_global_ctrl(pmu);
case MSR_IA32_PEBS_ENABLE:
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 309/877] bpf: Avoid soft lockup in __htab_map_lookup_and_delete_batch()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (307 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 308/877] KVM: x86/pmu: Move Intel PMU global MSRs to intel_is_valid_msr() Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 310/877] bpf: Fix out-of-bounds read of rtt_min in sock_ops Greg Kroah-Hartman
` (575 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Paul E. McKenney, Rik van Riel,
Jose Fernandez (Anthropic), Josef Bacik, Alexei Starovoitov,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jose Fernandez (Anthropic) <jose.fernandez@linux.dev>
[ Upstream commit 85136bf22404474a815fc0ed26ec0d1cbc1bc3f9 ]
__htab_map_lookup_and_delete_batch() has no rescheduling point. The
batch count bounds how many entries are copied out, not how many
buckets are visited, so one BPF_MAP_LOOKUP_BATCH call can walk the
map end to end. The empty-bucket fast path is worse: it stays inside
a single rcu_read_lock() / bpf_disable_instrumentation() section for
any run of consecutive empty buckets.
That holds up on small maps, but it falls apart at scale. On a
144-CPU arm64 host running a CONFIG_PREEMPT_NONE kernel, periodic
BPF_MAP_LOOKUP_BATCH calls against an LRU hash map with 16,777,216
buckets held a CPU inside the batch op for 77+ seconds and triggered
the soft lockup watchdog.
Commit 75134f16e7dd ("bpf: Add schedule points in batch ops") fixed this
same problem in the generic batch ops, but not in this htab-native path,
which every htab-based hash map variant uses for its lookup[_and_delete]
batch ops.
Complete that fix here. Leave the critical section after 64 consecutive
empty buckets, call cond_resched_tasks_rcu_qs(), and resume at the saved
bucket cursor. No locks are held at that point, and resuming from the
cursor is already the function's behavior for non-empty buckets. Add the
same call to the per-bucket loop after copy_to_user(), where every lock
has been dropped. cond_resched_rcu() is not enough here: sleeping with
bpf_prog_active elevated makes tracing programs on that CPU silently
skip their invocations.
Plain cond_resched() is not enough either. It is a no-op under PREEMPT
and PREEMPT_LAZY, the only models arm64 and x86 have offered since
commit 7dadeaa6e851 ("sched: Further restrict the preemption modes").
It is also never a Tasks RCU quiescent state, in any model: the
reschedule counts as a preemption. The walking task stays a holdout and
stalls every synchronize_rcu_tasks() caller, ftrace and BPF trampoline
teardown included, until the syscall returns [1].
cond_resched_tasks_rcu_qs() is the usual tool for that [2]. It reports
the quiescent state at each yield and still reschedules as
cond_resched() does on PREEMPT_NONE and PREEMPT_VOLUNTARY kernels.
Fixes: 057996380a42 ("bpf: Add batch ops to all htab bpf map")
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Rik van Riel <riel@surriel.com>
Link: https://lore.kernel.org/bpf/20260715215314.44423f47@fangorn/ [1]
Link: https://lore.kernel.org/bpf/9d444098-7c03-4163-af12-bd0a79a51443@paulmck-laptop/ [2]
Assisted-by: LLM
Signed-off-by: Jose Fernandez (Anthropic) <jose.fernandez@linux.dev>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Rik van Riel <riel@surriel.com>
Link: https://lore.kernel.org/r/20260909-b4-htab-batch-resched-v2-1-0cb529d8f95a@toxicpanda.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/hashtab.c | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index 66eaf95f9dbea..49db2d0e32157 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -1706,6 +1706,12 @@ static int htab_lru_percpu_map_lookup_and_delete_elem(struct bpf_map *map,
flags);
}
+/*
+ * Max consecutive empty buckets to walk in one RCU +
+ * instrumentation-disabled section before rescheduling.
+ */
+#define HTAB_BATCH_EMPTY_RESCHED 64
+
static int
__htab_map_lookup_and_delete_batch(struct bpf_map *map,
const union bpf_attr *attr,
@@ -1727,6 +1733,7 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map,
unsigned long flags = 0;
bool locked = false;
struct htab_elem *l;
+ u32 empty_cnt = 0;
struct bucket *b;
int ret = 0;
@@ -1896,12 +1903,21 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map,
}
next_batch:
- /* If we are not copying data, we can go to next bucket and avoid
- * unlocking the rcu.
+ /*
+ * If we are not copying data, we can go to next bucket and avoid
+ * unlocking the rcu. Bound the walk though: after
+ * HTAB_BATCH_EMPTY_RESCHED consecutive empty buckets, fully exit
+ * the critical section (no locks are held here) and reschedule.
*/
if (!bucket_cnt && (batch + 1 < htab->n_buckets)) {
batch++;
- goto again_nocopy;
+ if (++empty_cnt < HTAB_BATCH_EMPTY_RESCHED)
+ goto again_nocopy;
+ empty_cnt = 0;
+ rcu_read_unlock();
+ bpf_enable_instrumentation();
+ cond_resched_tasks_rcu_qs();
+ goto again;
}
rcu_read_unlock();
@@ -1915,11 +1931,13 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map,
}
total += bucket_cnt;
+ empty_cnt = 0;
batch++;
if (batch >= htab->n_buckets) {
ret = -ENOENT;
goto after_loop;
}
+ cond_resched_tasks_rcu_qs();
goto again;
after_loop:
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 310/877] bpf: Fix out-of-bounds read of rtt_min in sock_ops
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (308 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 309/877] bpf: Avoid soft lockup in __htab_map_lookup_and_delete_batch() Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 311/877] bpf: Remove migrate_{disable|enable} in ->map_for_each_callback Greg Kroah-Hartman
` (574 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, VEGA, Jiayuan Chen, Emil Tsalapatis,
Alexei Starovoitov, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <jiayuan.chen@linux.dev>
[ Upstream commit 75f8cf22463d82bb1fb0239a3d485fc8f4c8ef03 ]
A sockops prog reading skops->rtt_min never checks the sk type: on the
tcp_conn_request() path sock_ops->sk is a request_sock (non-full), and the
ctx rewrite casts it to a tcp_sock (full) and reads rtt_min past the end of
the request_sock, returning dirty adjacent memory.
SEC("sockops")
int prog(struct bpf_sock_ops *skops)
{
switch (skops->op) {
case BPF_SOCK_OPS_RWND_INIT:
leak = skops->rtt_min; /* reads the request_sock OOB */
...
}
}
For instance one such read returned rtt_min=0xffff8881, the high half of a
leaked kernel pointer.
Guarding that cast is exactly what SOCK_OPS_GET_FIELD() does -- it checks
is_locked_tcp_sock and returns 0 when sock_ops->sk is not a locked full
socket. Every other tcp_sock field in sock_ops goes through it; rtt_min is
the only one open-coded, so it skips the check.
Read rtt_min through SOCK_OPS_GET_FIELD() too. rtt_min is a bit special:
it is a struct minmax and we only want the current min, so pass
rtt_min.s[0].v. That is equivalent to the old hand-computed offset
offsetof(struct tcp_sock, rtt_min) + sizeof_field(struct minmax_sample, t)
(s[0] sits at rtt_min + 0 and .v at + sizeof(.t), i.e. what minmax_get()
returns), so the loaded field is unchanged and only the full-sock guard is
added. The two BUILD_BUG_ON()s that protected the hand-computed offset
are no longer needed.
Before patch:
0: r1 = *(u64 *)(r1 +0) ; r1 = skops->sk
1: r1 = *(u32 *)(r1 +2324) ; ((tcp_sock *)sk)->rtt_min.s[0].v
After patch:
0: *(u64 *)(r1 +56) = r9
1: r9 = *(u8 *)(r1 +50) ; is_locked_tcp_sock
2: if r9 == 0 goto pc+4 ; not a locked full sock -> 0
3: r9 = *(u64 *)(r1 +56)
4: r1 = *(u64 *)(r1 +0) ; r1 = skops->sk
5: r1 = *(u32 *)(r1 +2324) ; rtt_min.s[0].v
6: goto pc+2
7: r9 = *(u64 *)(r1 +56)
8: r1 = 0
Fixes: 44f0e43037d3 ("bpf: Add support for reading sk_state and more")
Reported-by: VEGA <vega@nebusec.ai>
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Link: https://lore.kernel.org/r/20260903100921.113374-1-jiayuan.chen@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/filter.c | 13 +------------
1 file changed, 1 insertion(+), 12 deletions(-)
diff --git a/net/core/filter.c b/net/core/filter.c
index 25777837af690..7114a64e1898e 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -10731,18 +10731,7 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
break;
case offsetof(struct bpf_sock_ops, rtt_min):
- BUILD_BUG_ON(sizeof_field(struct tcp_sock, rtt_min) !=
- sizeof(struct minmax));
- BUILD_BUG_ON(sizeof(struct minmax) <
- sizeof(struct minmax_sample));
-
- *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
- struct bpf_sock_ops_kern, sk),
- si->dst_reg, si->src_reg,
- offsetof(struct bpf_sock_ops_kern, sk));
- *insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->dst_reg,
- offsetof(struct tcp_sock, rtt_min) +
- sizeof_field(struct minmax_sample, t));
+ SOCK_OPS_GET_FIELD(rtt_min, rtt_min.s[0].v, struct tcp_sock);
break;
case offsetof(struct bpf_sock_ops, bpf_sock_ops_cb_flags):
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 311/877] bpf: Remove migrate_{disable|enable} in ->map_for_each_callback
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (309 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 310/877] bpf: Fix out-of-bounds read of rtt_min in sock_ops Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 312/877] bpf: Bail out early in __htab_map_lookup_and_delete_elem() Greg Kroah-Hartman
` (573 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hou Tao, Alexei Starovoitov,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hou Tao <houtao1@huawei.com>
[ Upstream commit ea5b229630a631ee6a72e1f58bc40029efc1daf8 ]
BPF program may call bpf_for_each_map_elem(), and it will call
the ->map_for_each_callback callback of related bpf map. Considering the
running context of bpf program has already disabled migration, remove
the unnecessary migrate_{disable|enable} pair in the implementations of
->map_for_each_callback. To ensure the guarantee will not be voilated
later, also add cant_migrate() check in the implementations.
Signed-off-by: Hou Tao <houtao1@huawei.com>
Link: https://lore.kernel.org/r/20250108010728.207536-3-houtao@huaweicloud.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Stable-dep-of: 1c21452d02ee ("bpf: Fix UAF due to concurrent consumption of ttrace lists in alloc_bulk")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/arraymap.c | 6 ++----
kernel/bpf/hashtab.c | 11 +++++------
2 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
index 7ec69545fe056..fcc0ca7ee8831 100644
--- a/kernel/bpf/arraymap.c
+++ b/kernel/bpf/arraymap.c
@@ -735,13 +735,13 @@ static long bpf_for_each_array_elem(struct bpf_map *map, bpf_callback_t callback
u64 ret = 0;
void *val;
+ cant_migrate();
+
if (flags != 0)
return -EINVAL;
is_percpu = map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY;
array = container_of(map, struct bpf_array, map);
- if (is_percpu)
- migrate_disable();
for (i = 0; i < map->max_entries; i++) {
if (is_percpu)
val = this_cpu_ptr(array->pptrs[i]);
@@ -756,8 +756,6 @@ static long bpf_for_each_array_elem(struct bpf_map *map, bpf_callback_t callback
break;
}
- if (is_percpu)
- migrate_enable();
return num_elems;
}
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index 49db2d0e32157..6df745abb88a7 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -2225,17 +2225,18 @@ static long bpf_for_each_hash_elem(struct bpf_map *map, bpf_callback_t callback_
bool is_percpu;
u64 ret = 0;
+ cant_migrate();
+
if (flags != 0)
return -EINVAL;
is_percpu = htab_is_percpu(htab);
roundup_key_size = round_up(map->key_size, 8);
- /* disable migration so percpu value prepared here will be the
- * same as the one seen by the bpf program with bpf_map_lookup_elem().
+ /* migration has been disabled, so percpu value prepared here will be
+ * the same as the one seen by the bpf program with
+ * bpf_map_lookup_elem().
*/
- if (is_percpu)
- migrate_disable();
for (i = 0; i < htab->n_buckets; i++) {
b = &htab->buckets[i];
rcu_read_lock();
@@ -2261,8 +2262,6 @@ static long bpf_for_each_hash_elem(struct bpf_map *map, bpf_callback_t callback_
rcu_read_unlock();
}
out:
- if (is_percpu)
- migrate_enable();
return num_elems;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 312/877] bpf: Bail out early in __htab_map_lookup_and_delete_elem()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (310 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 311/877] bpf: Remove migrate_{disable|enable} in ->map_for_each_callback Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 313/877] bpf: Factor out htab_elem_value helper() Greg Kroah-Hartman
` (572 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hou Tao,
Toke Høiland-Jørgensen, Alexei Starovoitov, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hou Tao <houtao1@huawei.com>
[ Upstream commit 588c6ead325aecc9894c9925cf1f771b77437bee ]
Use goto statement to bail out early when the target element is not
found, instead of using a large else branch to handle the more likely
case. This change doesn't affect functionality and simply make the code
cleaner.
Signed-off-by: Hou Tao <houtao1@huawei.com>
Reviewed-by: Toke Høiland-Jørgensen <toke@kernel.org>
Link: https://lore.kernel.org/r/20250117101816.2101857-3-houtao@huaweicloud.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Stable-dep-of: 1c21452d02ee ("bpf: Fix UAF due to concurrent consumption of ttrace lists in alloc_bulk")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/hashtab.c | 51 ++++++++++++++++++++++----------------------
1 file changed, 26 insertions(+), 25 deletions(-)
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index 6df745abb88a7..22cc255519ce8 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -1637,37 +1637,38 @@ static int __htab_map_lookup_and_delete_elem(struct bpf_map *map, void *key,
l = lookup_elem_raw(head, hash, key, key_size);
if (!l) {
ret = -ENOENT;
- } else {
- if (is_percpu) {
- u32 roundup_value_size = round_up(map->value_size, 8);
- void __percpu *pptr;
- int off = 0, cpu;
+ goto out_unlock;
+ }
- pptr = htab_elem_get_ptr(l, key_size);
- for_each_possible_cpu(cpu) {
- copy_map_value_long(&htab->map, value + off, per_cpu_ptr(pptr, cpu));
- check_and_init_map_value(&htab->map, value + off);
- off += roundup_value_size;
- }
- } else {
- u32 roundup_key_size = round_up(map->key_size, 8);
+ if (is_percpu) {
+ u32 roundup_value_size = round_up(map->value_size, 8);
+ void __percpu *pptr;
+ int off = 0, cpu;
- if (flags & BPF_F_LOCK)
- copy_map_value_locked(map, value, l->key +
- roundup_key_size,
- true);
- else
- copy_map_value(map, value, l->key +
- roundup_key_size);
- /* Zeroing special fields in the temp buffer */
- check_and_init_map_value(map, value);
+ pptr = htab_elem_get_ptr(l, key_size);
+ for_each_possible_cpu(cpu) {
+ copy_map_value_long(&htab->map, value + off, per_cpu_ptr(pptr, cpu));
+ check_and_init_map_value(&htab->map, value + off);
+ off += roundup_value_size;
}
+ } else {
+ u32 roundup_key_size = round_up(map->key_size, 8);
- hlist_nulls_del_rcu(&l->hash_node);
- if (!is_lru_map)
- free_htab_elem(htab, l);
+ if (flags & BPF_F_LOCK)
+ copy_map_value_locked(map, value, l->key +
+ roundup_key_size,
+ true);
+ else
+ copy_map_value(map, value, l->key +
+ roundup_key_size);
+ /* Zeroing special fields in the temp buffer */
+ check_and_init_map_value(map, value);
}
+ hlist_nulls_del_rcu(&l->hash_node);
+ if (!is_lru_map)
+ free_htab_elem(htab, l);
+out_unlock:
htab_unlock_bucket(htab, b, hash, bflags);
if (is_lru_map && l)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 313/877] bpf: Factor out htab_elem_value helper()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (311 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 312/877] bpf: Bail out early in __htab_map_lookup_and_delete_elem() Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 314/877] bpf: Register dtor for freeing special fields Greg Kroah-Hartman
` (571 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andrii Nakryiko, Hou Tao,
Alexei Starovoitov, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hou Tao <houtao1@huawei.com>
[ Upstream commit ba2b31b0f39fca12abbd21c53a92838bbc026023 ]
All hash maps store map key and map value together. The relative offset
of the map value compared to the map key is round_up(key_size, 8).
Therefore, factor out a common helper htab_elem_value() to calculate the
address of the map value instead of duplicating the logic.
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Hou Tao <houtao1@huawei.com>
Link: https://lore.kernel.org/r/20250401062250.543403-2-houtao@huaweicloud.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Stable-dep-of: 1c21452d02ee ("bpf: Fix UAF due to concurrent consumption of ttrace lists in alloc_bulk")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/hashtab.c | 64 +++++++++++++++++++++-----------------------
1 file changed, 30 insertions(+), 34 deletions(-)
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index 22cc255519ce8..0d1aeafe5eb14 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -195,20 +195,25 @@ static bool htab_is_percpu(const struct bpf_htab *htab)
htab->map.map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH;
}
+static inline void *htab_elem_value(struct htab_elem *l, u32 key_size)
+{
+ return l->key + round_up(key_size, 8);
+}
+
static inline void htab_elem_set_ptr(struct htab_elem *l, u32 key_size,
void __percpu *pptr)
{
- *(void __percpu **)(l->key + roundup(key_size, 8)) = pptr;
+ *(void __percpu **)htab_elem_value(l, key_size) = pptr;
}
static inline void __percpu *htab_elem_get_ptr(struct htab_elem *l, u32 key_size)
{
- return *(void __percpu **)(l->key + roundup(key_size, 8));
+ return *(void __percpu **)htab_elem_value(l, key_size);
}
static void *fd_htab_map_get_ptr(const struct bpf_map *map, struct htab_elem *l)
{
- return *(void **)(l->key + roundup(map->key_size, 8));
+ return *(void **)htab_elem_value(l, map->key_size);
}
static struct htab_elem *get_htab_elem(struct bpf_htab *htab, int i)
@@ -235,10 +240,10 @@ static void htab_free_prealloced_timers_and_wq(struct bpf_htab *htab)
elem = get_htab_elem(htab, i);
if (btf_record_has_field(htab->map.record, BPF_TIMER))
bpf_obj_free_timer(htab->map.record,
- elem->key + round_up(htab->map.key_size, 8));
+ htab_elem_value(elem, htab->map.key_size));
if (btf_record_has_field(htab->map.record, BPF_WORKQUEUE))
bpf_obj_free_workqueue(htab->map.record,
- elem->key + round_up(htab->map.key_size, 8));
+ htab_elem_value(elem, htab->map.key_size));
cond_resched();
}
}
@@ -265,7 +270,8 @@ static void htab_free_prealloced_fields(struct bpf_htab *htab)
cond_resched();
}
} else {
- bpf_obj_free_fields(htab->map.record, elem->key + round_up(htab->map.key_size, 8));
+ bpf_obj_free_fields(htab->map.record,
+ htab_elem_value(elem, htab->map.key_size));
cond_resched();
}
cond_resched();
@@ -703,7 +709,7 @@ static void *htab_map_lookup_elem(struct bpf_map *map, void *key)
struct htab_elem *l = __htab_map_lookup_elem(map, key);
if (l)
- return l->key + round_up(map->key_size, 8);
+ return htab_elem_value(l, map->key_size);
return NULL;
}
@@ -742,7 +748,7 @@ static __always_inline void *__htab_lru_map_lookup_elem(struct bpf_map *map,
if (l) {
if (mark)
bpf_lru_node_set_ref(&l->lru_node);
- return l->key + round_up(map->key_size, 8);
+ return htab_elem_value(l, map->key_size);
}
return NULL;
@@ -793,7 +799,7 @@ static void check_and_free_fields(struct bpf_htab *htab,
for_each_possible_cpu(cpu)
bpf_obj_free_fields(htab->map.record, per_cpu_ptr(pptr, cpu));
} else {
- void *map_value = elem->key + round_up(htab->map.key_size, 8);
+ void *map_value = htab_elem_value(elem, htab->map.key_size);
bpf_obj_free_fields(htab->map.record, map_value);
}
@@ -1076,11 +1082,9 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key,
htab_elem_set_ptr(l_new, key_size, pptr);
} else if (fd_htab_map_needs_adjust(htab)) {
size = round_up(size, 8);
- memcpy(l_new->key + round_up(key_size, 8), value, size);
+ memcpy(htab_elem_value(l_new, key_size), value, size);
} else {
- copy_map_value(&htab->map,
- l_new->key + round_up(key_size, 8),
- value);
+ copy_map_value(&htab->map, htab_elem_value(l_new, key_size), value);
}
l_new->hash = hash;
@@ -1142,7 +1146,7 @@ static long htab_map_update_elem(struct bpf_map *map, void *key, void *value,
if (l_old) {
/* grab the element lock and update value in place */
copy_map_value_locked(map,
- l_old->key + round_up(key_size, 8),
+ htab_elem_value(l_old, key_size),
value, false);
return 0;
}
@@ -1170,7 +1174,7 @@ static long htab_map_update_elem(struct bpf_map *map, void *key, void *value,
* and update element in place
*/
copy_map_value_locked(map,
- l_old->key + round_up(key_size, 8),
+ htab_elem_value(l_old, key_size),
value, false);
ret = 0;
goto err;
@@ -1255,8 +1259,7 @@ static long htab_lru_map_update_elem(struct bpf_map *map, void *key, void *value
l_new = prealloc_lru_pop(htab, key, hash);
if (!l_new)
return -ENOMEM;
- copy_map_value(&htab->map,
- l_new->key + round_up(map->key_size, 8), value);
+ copy_map_value(&htab->map, htab_elem_value(l_new, map->key_size), value);
ret = htab_lock_bucket(htab, b, hash, &flags);
if (ret)
@@ -1533,10 +1536,10 @@ static void htab_free_malloced_timers_and_wq(struct bpf_htab *htab)
/* We only free timer on uref dropping to zero */
if (btf_record_has_field(htab->map.record, BPF_TIMER))
bpf_obj_free_timer(htab->map.record,
- l->key + round_up(htab->map.key_size, 8));
+ htab_elem_value(l, htab->map.key_size));
if (btf_record_has_field(htab->map.record, BPF_WORKQUEUE))
bpf_obj_free_workqueue(htab->map.record,
- l->key + round_up(htab->map.key_size, 8));
+ htab_elem_value(l, htab->map.key_size));
}
cond_resched_rcu();
}
@@ -1652,15 +1655,12 @@ static int __htab_map_lookup_and_delete_elem(struct bpf_map *map, void *key,
off += roundup_value_size;
}
} else {
- u32 roundup_key_size = round_up(map->key_size, 8);
+ void *src = htab_elem_value(l, map->key_size);
if (flags & BPF_F_LOCK)
- copy_map_value_locked(map, value, l->key +
- roundup_key_size,
- true);
+ copy_map_value_locked(map, value, src, true);
else
- copy_map_value(map, value, l->key +
- roundup_key_size);
+ copy_map_value(map, value, src);
/* Zeroing special fields in the temp buffer */
check_and_init_map_value(map, value);
}
@@ -1721,12 +1721,12 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map,
bool is_percpu)
{
struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
- u32 bucket_cnt, total, key_size, value_size, roundup_key_size;
void *keys = NULL, *values = NULL, *value, *dst_key, *dst_val;
void __user *uvalues = u64_to_user_ptr(attr->batch.values);
void __user *ukeys = u64_to_user_ptr(attr->batch.keys);
void __user *ubatch = u64_to_user_ptr(attr->batch.in_batch);
u32 batch, max_count, size, bucket_size, map_id;
+ u32 bucket_cnt, total, key_size, value_size;
struct htab_elem *node_to_free = NULL;
u64 elem_map_flags, map_flags;
struct hlist_nulls_head *head;
@@ -1762,7 +1762,6 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map,
return -ENOENT;
key_size = htab->map.key_size;
- roundup_key_size = round_up(htab->map.key_size, 8);
value_size = htab->map.value_size;
size = round_up(value_size, 8);
if (is_percpu)
@@ -1854,7 +1853,7 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map,
off += size;
}
} else {
- value = l->key + roundup_key_size;
+ value = htab_elem_value(l, key_size);
if (map->map_type == BPF_MAP_TYPE_HASH_OF_MAPS) {
struct bpf_map **inner_map = value;
@@ -2116,11 +2115,11 @@ static void *bpf_hash_map_seq_next(struct seq_file *seq, void *v, loff_t *pos)
static int __bpf_hash_map_seq_show(struct seq_file *seq, struct htab_elem *elem)
{
struct bpf_iter_seq_hash_map_info *info = seq->private;
- u32 roundup_key_size, roundup_value_size;
struct bpf_iter__bpf_map_elem ctx = {};
struct bpf_map *map = info->map;
struct bpf_iter_meta meta;
int ret = 0, off = 0, cpu;
+ u32 roundup_value_size;
struct bpf_prog *prog;
void __percpu *pptr;
@@ -2130,10 +2129,9 @@ static int __bpf_hash_map_seq_show(struct seq_file *seq, struct htab_elem *elem)
ctx.meta = &meta;
ctx.map = info->map;
if (elem) {
- roundup_key_size = round_up(map->key_size, 8);
ctx.key = elem->key;
if (!info->percpu_value_buf) {
- ctx.value = elem->key + roundup_key_size;
+ ctx.value = htab_elem_value(elem, map->key_size);
} else {
roundup_value_size = round_up(map->value_size, 8);
pptr = htab_elem_get_ptr(elem, map->key_size);
@@ -2218,7 +2216,6 @@ static long bpf_for_each_hash_elem(struct bpf_map *map, bpf_callback_t callback_
struct hlist_nulls_head *head;
struct hlist_nulls_node *n;
struct htab_elem *elem;
- u32 roundup_key_size;
int i, num_elems = 0;
void __percpu *pptr;
struct bucket *b;
@@ -2233,7 +2230,6 @@ static long bpf_for_each_hash_elem(struct bpf_map *map, bpf_callback_t callback_
is_percpu = htab_is_percpu(htab);
- roundup_key_size = round_up(map->key_size, 8);
/* migration has been disabled, so percpu value prepared here will be
* the same as the one seen by the bpf program with
* bpf_map_lookup_elem().
@@ -2249,7 +2245,7 @@ static long bpf_for_each_hash_elem(struct bpf_map *map, bpf_callback_t callback_
pptr = htab_elem_get_ptr(elem, map->key_size);
val = this_cpu_ptr(pptr);
} else {
- val = elem->key + roundup_key_size;
+ val = htab_elem_value(elem, map->key_size);
}
num_elems++;
ret = callback_fn((u64)(long)map, (u64)(long)key,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 314/877] bpf: Register dtor for freeing special fields
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (312 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 313/877] bpf: Factor out htab_elem_value helper() Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 315/877] bpf: Fix UAF due to concurrent consumption of ttrace lists in alloc_bulk Greg Kroah-Hartman
` (570 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alexei Starovoitov, syzbot,
Kumar Kartikeya Dwivedi, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
[ Upstream commit 1df97a7453eec80c1912c2d0360290a3970a7671 ]
There is a race window where BPF hash map elements can leak special
fields if the program with access to the map value recreates these
special fields between the check_and_free_fields done on the map value
and its eventual return to the memory allocator.
Several ways were explored prior to this patch, most notably [0] tried
to use a poison value to reject attempts to recreate special fields for
map values that have been logically deleted but still accessible to BPF
programs (either while sitting in the free list or when reused). While
this approach works well for task work, timers, wq, etc., it is harder
to apply the idea to kptrs, which have a similar race and failure mode.
Instead, we change bpf_mem_alloc to allow registering destructor for
allocated elements, such that when they are returned to the allocator,
any special fields created while they were accessible to programs in the
mean time will be freed. If these values get reused, we do not free the
fields again before handing the element back. The special fields thus
may remain initialized while the map value sits in a free list.
When bpf_mem_alloc is retired in the future, a similar concept can be
introduced to kmalloc_nolock-backed kmem_cache, paired with the existing
idea of a constructor.
Note that the destructor registration happens in map_check_btf, after
the BTF record is populated and (at that point) avaiable for inspection
and duplication. Duplication is necessary since the freeing of embedded
bpf_mem_alloc can be decoupled from actual map lifetime due to logic
introduced to reduce the cost of rcu_barrier()s in mem alloc free path in
9f2c6e96c65e ("bpf: Optimize rcu_barrier usage between hash map and bpf_mem_alloc.").
As such, once all callbacks are done, we must also free the duplicated
record. To remove dependency on the bpf_map itself, also stash the key
size of the map to obtain value from htab_elem long after the map is
gone.
[0]: https://lore.kernel.org/bpf/20260216131341.1285427-1-mykyta.yatsenko5@gmail.com
Fixes: 14a324f6a67e ("bpf: Wire up freeing of referenced kptr")
Fixes: 1bfbc267ec91 ("bpf: Enable bpf_timer and bpf_wq in any context")
Reported-by: Alexei Starovoitov <ast@kernel.org>
Tested-by: syzbot@syzkaller.appspotmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260227224806.646888-2-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Stable-dep-of: 1c21452d02ee ("bpf: Fix UAF due to concurrent consumption of ttrace lists in alloc_bulk")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/bpf_mem_alloc.h | 6 +++
kernel/bpf/hashtab.c | 87 +++++++++++++++++++++++++++++++++++
kernel/bpf/memalloc.c | 58 ++++++++++++++++++-----
3 files changed, 140 insertions(+), 11 deletions(-)
diff --git a/include/linux/bpf_mem_alloc.h b/include/linux/bpf_mem_alloc.h
index e45162ef59bb1..4ce0d27f8ea26 100644
--- a/include/linux/bpf_mem_alloc.h
+++ b/include/linux/bpf_mem_alloc.h
@@ -14,6 +14,8 @@ struct bpf_mem_alloc {
struct obj_cgroup *objcg;
bool percpu;
struct work_struct work;
+ void (*dtor_ctx_free)(void *ctx);
+ void *dtor_ctx;
};
/* 'size != 0' is for bpf_mem_alloc which manages fixed-size objects.
@@ -32,6 +34,10 @@ int bpf_mem_alloc_percpu_init(struct bpf_mem_alloc *ma, struct obj_cgroup *objcg
/* The percpu allocation with a specific unit size. */
int bpf_mem_alloc_percpu_unit_init(struct bpf_mem_alloc *ma, int size);
void bpf_mem_alloc_destroy(struct bpf_mem_alloc *ma);
+void bpf_mem_alloc_set_dtor(struct bpf_mem_alloc *ma,
+ void (*dtor)(void *obj, void *ctx),
+ void (*dtor_ctx_free)(void *ctx),
+ void *ctx);
/* Check the allocation size for kmalloc equivalent allocator */
int bpf_mem_alloc_check_size(bool percpu, size_t size);
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index 0d1aeafe5eb14..ab41c24c68388 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -129,6 +129,11 @@ struct htab_elem {
char key[] __aligned(8);
};
+struct htab_btf_record {
+ struct btf_record *record;
+ u32 key_size;
+};
+
static inline bool htab_is_prealloc(const struct bpf_htab *htab)
{
return !(htab->map.map_flags & BPF_F_NO_PREALLOC);
@@ -475,6 +480,84 @@ static int htab_map_alloc_check(union bpf_attr *attr)
return 0;
}
+static void htab_mem_dtor(void *obj, void *ctx)
+{
+ struct htab_btf_record *hrec = ctx;
+ struct htab_elem *elem = obj;
+ void *map_value;
+
+ if (IS_ERR_OR_NULL(hrec->record))
+ return;
+
+ map_value = htab_elem_value(elem, hrec->key_size);
+ bpf_obj_free_fields(hrec->record, map_value);
+}
+
+static void htab_pcpu_mem_dtor(void *obj, void *ctx)
+{
+ void __percpu *pptr = *(void __percpu **)obj;
+ struct htab_btf_record *hrec = ctx;
+ int cpu;
+
+ if (IS_ERR_OR_NULL(hrec->record))
+ return;
+
+ for_each_possible_cpu(cpu)
+ bpf_obj_free_fields(hrec->record, per_cpu_ptr(pptr, cpu));
+}
+
+static void htab_dtor_ctx_free(void *ctx)
+{
+ struct htab_btf_record *hrec = ctx;
+
+ btf_record_free(hrec->record);
+ kfree(ctx);
+}
+
+static int htab_set_dtor(const struct bpf_htab *htab, void (*dtor)(void *, void *))
+{
+ u32 key_size = htab->map.key_size;
+ const struct bpf_mem_alloc *ma;
+ struct htab_btf_record *hrec;
+ int err;
+
+ /* No need for dtors. */
+ if (IS_ERR_OR_NULL(htab->map.record))
+ return 0;
+
+ hrec = kzalloc(sizeof(*hrec), GFP_KERNEL);
+ if (!hrec)
+ return -ENOMEM;
+ hrec->key_size = key_size;
+ hrec->record = btf_record_dup(htab->map.record);
+ if (IS_ERR(hrec->record)) {
+ err = PTR_ERR(hrec->record);
+ kfree(hrec);
+ return err;
+ }
+ ma = htab_is_percpu(htab) ? &htab->pcpu_ma : &htab->ma;
+ /* Kinda sad, but cast away const-ness since we change ma->dtor. */
+ bpf_mem_alloc_set_dtor((struct bpf_mem_alloc *)ma, dtor, htab_dtor_ctx_free, hrec);
+ return 0;
+}
+
+static int htab_map_check_btf(const struct bpf_map *map, const struct btf *btf,
+ const struct btf_type *key_type, const struct btf_type *value_type)
+{
+ struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
+
+ if (htab_is_prealloc(htab))
+ return 0;
+ /*
+ * We must set the dtor using this callback, as map's BTF record is not
+ * populated in htab_map_alloc(), so it will always appear as NULL.
+ */
+ if (htab_is_percpu(htab))
+ return htab_set_dtor(htab, htab_pcpu_mem_dtor);
+ else
+ return htab_set_dtor(htab, htab_mem_dtor);
+}
+
static struct bpf_map *htab_map_alloc(union bpf_attr *attr)
{
bool percpu = (attr->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
@@ -2316,6 +2399,7 @@ const struct bpf_map_ops htab_map_ops = {
.map_seq_show_elem = htab_map_seq_show_elem,
.map_set_for_each_callback_args = map_set_for_each_callback_args,
.map_for_each_callback = bpf_for_each_hash_elem,
+ .map_check_btf = htab_map_check_btf,
.map_mem_usage = htab_map_mem_usage,
BATCH_OPS(htab),
.map_btf_id = &htab_map_btf_ids[0],
@@ -2338,6 +2422,7 @@ const struct bpf_map_ops htab_lru_map_ops = {
.map_seq_show_elem = htab_map_seq_show_elem,
.map_set_for_each_callback_args = map_set_for_each_callback_args,
.map_for_each_callback = bpf_for_each_hash_elem,
+ .map_check_btf = htab_map_check_btf,
.map_mem_usage = htab_map_mem_usage,
BATCH_OPS(htab_lru),
.map_btf_id = &htab_map_btf_ids[0],
@@ -2511,6 +2596,7 @@ const struct bpf_map_ops htab_percpu_map_ops = {
.map_seq_show_elem = htab_percpu_map_seq_show_elem,
.map_set_for_each_callback_args = map_set_for_each_callback_args,
.map_for_each_callback = bpf_for_each_hash_elem,
+ .map_check_btf = htab_map_check_btf,
.map_mem_usage = htab_map_mem_usage,
BATCH_OPS(htab_percpu),
.map_btf_id = &htab_map_btf_ids[0],
@@ -2531,6 +2617,7 @@ const struct bpf_map_ops htab_lru_percpu_map_ops = {
.map_seq_show_elem = htab_percpu_map_seq_show_elem,
.map_set_for_each_callback_args = map_set_for_each_callback_args,
.map_for_each_callback = bpf_for_each_hash_elem,
+ .map_check_btf = htab_map_check_btf,
.map_mem_usage = htab_map_mem_usage,
BATCH_OPS(htab_lru_percpu),
.map_btf_id = &htab_map_btf_ids[0],
diff --git a/kernel/bpf/memalloc.c b/kernel/bpf/memalloc.c
index 146f5b57cfb1c..e89a6f5baf5ba 100644
--- a/kernel/bpf/memalloc.c
+++ b/kernel/bpf/memalloc.c
@@ -102,6 +102,8 @@ struct bpf_mem_cache {
int percpu_size;
bool draining;
struct bpf_mem_cache *tgt;
+ void (*dtor)(void *obj, void *ctx);
+ void *dtor_ctx;
/* list of objects to be freed after RCU GP */
struct llist_head free_by_rcu;
@@ -263,12 +265,14 @@ static void free_one(void *obj, bool percpu)
kfree(obj);
}
-static int free_all(struct llist_node *llnode, bool percpu)
+static int free_all(struct bpf_mem_cache *c, struct llist_node *llnode, bool percpu)
{
struct llist_node *pos, *t;
int cnt = 0;
llist_for_each_safe(pos, t, llnode) {
+ if (c->dtor)
+ c->dtor((void *)pos + LLIST_NODE_SZ, c->dtor_ctx);
free_one(pos, percpu);
cnt++;
}
@@ -279,7 +283,7 @@ static void __free_rcu(struct rcu_head *head)
{
struct bpf_mem_cache *c = container_of(head, struct bpf_mem_cache, rcu_ttrace);
- free_all(llist_del_all(&c->waiting_for_gp_ttrace), !!c->percpu_size);
+ free_all(c, llist_del_all(&c->waiting_for_gp_ttrace), !!c->percpu_size);
atomic_set(&c->call_rcu_ttrace_in_progress, 0);
}
@@ -311,7 +315,7 @@ static void do_call_rcu_ttrace(struct bpf_mem_cache *c)
if (atomic_xchg(&c->call_rcu_ttrace_in_progress, 1)) {
if (unlikely(READ_ONCE(c->draining))) {
llnode = llist_del_all(&c->free_by_rcu_ttrace);
- free_all(llnode, !!c->percpu_size);
+ free_all(c, llnode, !!c->percpu_size);
}
return;
}
@@ -420,7 +424,7 @@ static void check_free_by_rcu(struct bpf_mem_cache *c)
dec_active(c, &flags);
if (unlikely(READ_ONCE(c->draining))) {
- free_all(llist_del_all(&c->waiting_for_gp), !!c->percpu_size);
+ free_all(c, llist_del_all(&c->waiting_for_gp), !!c->percpu_size);
atomic_set(&c->call_rcu_in_progress, 0);
} else {
call_rcu_hurry(&c->rcu, __free_by_rcu);
@@ -638,13 +642,13 @@ static void drain_mem_cache(struct bpf_mem_cache *c)
* Except for waiting_for_gp_ttrace list, there are no concurrent operations
* on these lists, so it is safe to use __llist_del_all().
*/
- free_all(llist_del_all(&c->free_by_rcu_ttrace), percpu);
- free_all(llist_del_all(&c->waiting_for_gp_ttrace), percpu);
- free_all(__llist_del_all(&c->free_llist), percpu);
- free_all(__llist_del_all(&c->free_llist_extra), percpu);
- free_all(__llist_del_all(&c->free_by_rcu), percpu);
- free_all(__llist_del_all(&c->free_llist_extra_rcu), percpu);
- free_all(llist_del_all(&c->waiting_for_gp), percpu);
+ free_all(c, llist_del_all(&c->free_by_rcu_ttrace), percpu);
+ free_all(c, llist_del_all(&c->waiting_for_gp_ttrace), percpu);
+ free_all(c, __llist_del_all(&c->free_llist), percpu);
+ free_all(c, __llist_del_all(&c->free_llist_extra), percpu);
+ free_all(c, __llist_del_all(&c->free_by_rcu), percpu);
+ free_all(c, __llist_del_all(&c->free_llist_extra_rcu), percpu);
+ free_all(c, llist_del_all(&c->waiting_for_gp), percpu);
}
static void check_mem_cache(struct bpf_mem_cache *c)
@@ -683,6 +687,9 @@ static void check_leaked_objs(struct bpf_mem_alloc *ma)
static void free_mem_alloc_no_barrier(struct bpf_mem_alloc *ma)
{
+ /* We can free dtor ctx only once all callbacks are done using it. */
+ if (ma->dtor_ctx_free)
+ ma->dtor_ctx_free(ma->dtor_ctx);
check_leaked_objs(ma);
free_percpu(ma->cache);
free_percpu(ma->caches);
@@ -1017,3 +1024,32 @@ int bpf_mem_alloc_check_size(bool percpu, size_t size)
return 0;
}
+
+void bpf_mem_alloc_set_dtor(struct bpf_mem_alloc *ma, void (*dtor)(void *obj, void *ctx),
+ void (*dtor_ctx_free)(void *ctx), void *ctx)
+{
+ struct bpf_mem_caches *cc;
+ struct bpf_mem_cache *c;
+ int cpu, i;
+
+ ma->dtor_ctx_free = dtor_ctx_free;
+ ma->dtor_ctx = ctx;
+
+ if (ma->cache) {
+ for_each_possible_cpu(cpu) {
+ c = per_cpu_ptr(ma->cache, cpu);
+ c->dtor = dtor;
+ c->dtor_ctx = ctx;
+ }
+ }
+ if (ma->caches) {
+ for_each_possible_cpu(cpu) {
+ cc = per_cpu_ptr(ma->caches, cpu);
+ for (i = 0; i < NUM_CACHES; i++) {
+ c = &cc->cache[i];
+ c->dtor = dtor;
+ c->dtor_ctx = ctx;
+ }
+ }
+ }
+}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 315/877] bpf: Fix UAF due to concurrent consumption of ttrace lists in alloc_bulk
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (313 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 314/877] bpf: Register dtor for freeing special fields Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 316/877] bpf, sockmap: Fix self-redirect copied_seq double-counting Greg Kroah-Hartman
` (569 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alexei Starovoitov, Hou Tao,
Pu Lehui, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pu Lehui <pulehui@huawei.com>
[ Upstream commit 1c21452d02eec2f008e2c5535820f85adbd7587a ]
Syzkaller repeatedly triggered UAF splats related to nodes in
waiting_for_gp_ttrace within the bpf memalloc:
BUG: KASAN: slab-use-after-free in llist_del_first+0x85/0x110 lib/llist.c:61
Read of size 8 at addr ffff8881572cd080 by task syz.4.470/5112
...
llist_del_first+0x85/0x110 lib/llist.c:61
alloc_bulk+0x193/0x460 kernel/bpf/memalloc.c:229
bpf_mem_refill+0x386/0x560 kernel/bpf/memalloc.c:436
Freed by task 14:
...
__free_rcu kernel/bpf/memalloc.c:281 [inline]
__free_rcu_tasks_trace+0x48/0xd0 kernel/bpf/memalloc.c:291
rcu_tasks_invoke_cbs+0x1ec/0x3e0 kernel/rcu/tasks.h:571
rcu_tasks_one_gp+0x13d/0x220 kernel/rcu/tasks.h:621
rcu_tasks_kthread+0xf3/0x120 kernel/rcu/tasks.h:651
The reason is that the UAF occurs after the RCU Tasks Trace GP expires:
when the __free_rcu() callback runs, there is no synchronization
protecting llist_del_all() against concurrent alloc_bulk() operating on
waiting_for_gp_ttrace, leading to the race condition below:
CPU0 CPU1
__free_rcu (RCU Tasks Trace callback)
alloc_bulk
llist_del_first(&c->waiting_for_gp_ttrace)
entry = smp_load_acquire(&head->first);
do {
if (entry == NULL)
return NULL;
free_all(llist_del_all(&c->waiting_for_gp_ttrace))
llist_for_each_safe(pos, t, llnode)
free_one(pos);
next = READ_ONCE(entry->next); <-- trigger UAF
} while (!try_cmpxchg(&head->first, &entry, next));
In addition, there is also a theoretical race condition on the
free_by_rcu_ttrace list. This race requires two preconditions: an
in-flight Tasks Trace GP keeping c->call_rcu_ttrace_in_progress == 1,
and concurrent cross-CPU frees repopulating c->free_by_rcu_ttrace with
new nodes. Under these conditions, the following scenario triggers UAF:
// CPU0
// irq work is still busy (on PREEMPT_RT)
alloc_bulk()
llist_del_first(&c->free_by_rcu_ttrace)
entry = smp_load_acquire(&head->first);
do {
if (entry == NULL)
return NULL;
// CPU1
bpf_mem_alloc_destroy()
WRITE_ONCE(c->draining, true)
// wait for CPU0
irq_work_sync()
// CPU2
do_call_rcu_ttrace(tgt(CPU0))
if (c->draining) {
llist_del_all(&c->free_by_rcu_ttrace)
free_all()
}
// CPU0 continue
next = READ_ONCE(entry->next); <-- trigger UAF
while (!try_cmpxchg(&head->first, &entry, next));
Fix this by introducing a raw spinlock to synchronize the concurrent
consumption on waiting_for_gp_ttrace and free_by_rcu_ttrace.
Fixes: 04fabf00b4d3 ("bpf: Allow reuse from waiting_for_gp_ttrace list.")
Suggested-by: Alexei Starovoitov <ast@kernel.org>
Suggested-by: Hou Tao <houtao1@huawei.com>
Signed-off-by: Pu Lehui <pulehui@huawei.com>
Acked-by: Hou Tao <houtao1@huawei.com>
Link: https://lore.kernel.org/r/20260905021139.4116529-1-pulehui@huaweicloud.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/memalloc.c | 50 ++++++++++++++++++++++++-------------------
1 file changed, 28 insertions(+), 22 deletions(-)
diff --git a/kernel/bpf/memalloc.c b/kernel/bpf/memalloc.c
index e89a6f5baf5ba..bbc08b869aae1 100644
--- a/kernel/bpf/memalloc.c
+++ b/kernel/bpf/memalloc.c
@@ -119,6 +119,7 @@ struct bpf_mem_cache {
struct llist_head waiting_for_gp_ttrace;
struct rcu_head rcu_ttrace;
atomic_t call_rcu_ttrace_in_progress;
+ raw_spinlock_t lock;
};
struct bpf_mem_caches {
@@ -214,25 +215,24 @@ static void alloc_bulk(struct bpf_mem_cache *c, int cnt, int node, bool atomic)
gfp = __GFP_NOWARN | __GFP_ACCOUNT;
gfp |= atomic ? GFP_NOWAIT : GFP_KERNEL;
- for (i = 0; i < cnt; i++) {
- /*
- * For every 'c' llist_del_first(&c->free_by_rcu_ttrace); is
- * done only by one CPU == current CPU. Other CPUs might
- * llist_add() and llist_del_all() in parallel.
- */
- obj = llist_del_first(&c->free_by_rcu_ttrace);
- if (!obj)
- break;
- add_obj_to_free_list(c, obj);
- }
- if (i >= cnt)
- return;
+ /*
+ * c->lock serializes concurrent llist_del_first() against
+ * llist_del_all() in __free_rcu() and do_call_rcu_ttrace().
+ */
+ scoped_guard(raw_spinlock_irqsave, &c->lock) {
+ for (i = 0; i < cnt; i++) {
+ obj = llist_del_first(&c->free_by_rcu_ttrace);
+ if (!obj)
+ break;
+ add_obj_to_free_list(c, obj);
+ }
- for (; i < cnt; i++) {
- obj = llist_del_first(&c->waiting_for_gp_ttrace);
- if (!obj)
- break;
- add_obj_to_free_list(c, obj);
+ for (; i < cnt; i++) {
+ obj = llist_del_first(&c->waiting_for_gp_ttrace);
+ if (!obj)
+ break;
+ add_obj_to_free_list(c, obj);
+ }
}
if (i >= cnt)
return;
@@ -282,8 +282,12 @@ static int free_all(struct bpf_mem_cache *c, struct llist_node *llnode, bool per
static void __free_rcu(struct rcu_head *head)
{
struct bpf_mem_cache *c = container_of(head, struct bpf_mem_cache, rcu_ttrace);
+ struct llist_node *llnode;
+
+ scoped_guard(raw_spinlock_irqsave, &c->lock)
+ llnode = llist_del_all(&c->waiting_for_gp_ttrace);
- free_all(c, llist_del_all(&c->waiting_for_gp_ttrace), !!c->percpu_size);
+ free_all(c, llnode, !!c->percpu_size);
atomic_set(&c->call_rcu_ttrace_in_progress, 0);
}
@@ -314,7 +318,8 @@ static void do_call_rcu_ttrace(struct bpf_mem_cache *c)
if (atomic_xchg(&c->call_rcu_ttrace_in_progress, 1)) {
if (unlikely(READ_ONCE(c->draining))) {
- llnode = llist_del_all(&c->free_by_rcu_ttrace);
+ scoped_guard(raw_spinlock_irqsave, &c->lock)
+ llnode = llist_del_all(&c->free_by_rcu_ttrace);
free_all(c, llnode, !!c->percpu_size);
}
return;
@@ -549,6 +554,7 @@ int bpf_mem_alloc_init(struct bpf_mem_alloc *ma, int size, bool percpu)
c->objcg = objcg;
c->percpu_size = percpu_size;
c->tgt = c;
+ raw_spin_lock_init(&c->lock);
init_refill_work(c);
prefill_mem_cache(c, cpu);
}
@@ -571,7 +577,7 @@ int bpf_mem_alloc_init(struct bpf_mem_alloc *ma, int size, bool percpu)
c->objcg = objcg;
c->percpu_size = percpu_size;
c->tgt = c;
-
+ raw_spin_lock_init(&c->lock);
init_refill_work(c);
prefill_mem_cache(c, cpu);
}
@@ -623,7 +629,7 @@ int bpf_mem_alloc_percpu_unit_init(struct bpf_mem_alloc *ma, int size)
c->objcg = objcg;
c->percpu_size = percpu_size;
c->tgt = c;
-
+ raw_spin_lock_init(&c->lock);
init_refill_work(c);
prefill_mem_cache(c, cpu);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 316/877] bpf, sockmap: Fix self-redirect copied_seq double-counting
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (314 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 315/877] bpf: Fix UAF due to concurrent consumption of ttrace lists in alloc_bulk Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 317/877] bpf, arm64: set up the frame pointer for the exception callback Greg Kroah-Hartman
` (568 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jakub Sitnicki, Jiayuan Chen,
Geliang Tang, Emil Tsalapatis, Alexei Starovoitov, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geliang Tang <tanggeliang@kylinos.cn>
[ Upstream commit 490a83d6386eec1d29f470c8d7331677fb46c3b7 ]
When a BPF stream_verdict program redirects an skb back to the same
socket (self-redirect with BPF_F_INGRESS), sk_psock_verdict_apply()
calls tcp_eat_skb() which advances tcp_sk->copied_seq. However, the
skb is then delivered to the socket's psock ingress queue and later
read by tcp_bpf_recvmsg_parser(), which also advances copied_seq via
the copied_from_self accounting path. This double-counting causes
copied_seq to advance by 2x the actual data length, triggering:
TCP recvmsg seq # bug 2: copied BF2E806, seq BF2E7FD, \
rcvnxt BF2E806, fl 0
WARNING: net/ipv4/tcp.c:2745 at tcp_recvmsg_locked+0x72b/0x2640
Call Trace:
tcp_recvmsg+0x10a/0x500
sock_recvmsg+0x168/0x1d0
__sys_recvfrom+0x19a/0x2a0
__x64_sys_recvfrom+0xe4/0x1f0
do_syscall_64+0xf7/0x530
entry_SYSCALL_64_after_hwframe+0x77/0x7f
cleanup rbuf bug: copied BF2E806 seq BF2E806 rcvnxt BF2E806
WARNING: net/ipv4/tcp.c:1609 at tcp_cleanup_rbuf+0xf2/0x1c0
Call Trace:
tcp_recvmsg_locked+0x8d1/0x2640
tcp_recvmsg+0x10a/0x500
sock_recvmsg+0x168/0x1d0
__sys_recvfrom+0x19a/0x2a0
__x64_sys_recvfrom+0xe4/0x1f0
do_syscall_64+0xf7/0x530
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Fix this by converting self-redirect verdict to __SK_PASS at the
beginning of sk_psock_verdict_apply(). This bypasses the
__SK_REDIRECT case entirely (which calls sk_psock_eat_skb), letting
the __SK_PASS path queue the skb to the psock ingress queue. The
data is then read via tcp_bpf_recvmsg_parser(), which advances
copied_seq exactly once through copied_from_self. Cross-socket
redirects continue through __SK_REDIRECT with sk_psock_eat_skb()
unchanged.
Fixes: e5c6de5fa025 ("bpf, sockmap: Incorrectly handling copied_seq")
Suggested-by: Jakub Sitnicki <jakub@cloudflare.com>
Suggested-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Link: https://lore.kernel.org/r/1a8e797a1b26e2f695aaac22ac644c2862f63466.1788858299.git.tanggeliang@kylinos.cn
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/skmsg.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/core/skmsg.c b/net/core/skmsg.c
index 7e68b4fdbfce0..6eca57da3cff6 100644
--- a/net/core/skmsg.c
+++ b/net/core/skmsg.c
@@ -1035,6 +1035,10 @@ static int sk_psock_verdict_apply(struct sk_psock *psock, struct sk_buff *skb,
int err = 0;
u32 len, off;
+ if (verdict == __SK_REDIRECT && skb_bpf_ingress(skb) &&
+ skb_bpf_redirect_fetch(skb) == psock->sk)
+ verdict = __SK_PASS;
+
switch (verdict) {
case __SK_PASS:
err = -EIO;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 317/877] bpf, arm64: set up the frame pointer for the exception callback
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (315 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 316/877] bpf, sockmap: Fix self-redirect copied_seq double-counting Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 318/877] pinctrl: meson: Fix typo in s4 group name Greg Kroah-Hartman
` (567 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xu Kuohai, Donggeun Yoo,
Alexei Starovoitov, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
[ Upstream commit ef1fb82f12186dd26153b14d9fbcf4ec98db81b3 ]
A program acting as exception boundary saves all callee-saved registers,
so build_prologue() takes the exception_cb path and never calls
push_callee_regs(). That is the only place find_used_callee_regs() runs,
and with it the only place ctx->fp_used is set, so the callback prologue
does not emit the
mov x25, sp
that points BPF_REG_FP at the frame the callback runs on. x25 keeps
whatever it held when bpf_throw() was called. If the throw came from a
subprogram that uses its own BPF stack, that is the subprogram's frame
pointer, and since the subprogram never returns it never restores x25
either.
Stack accesses through BPF_REG_FP are rewritten to be stack pointer
relative, so those still land in the callback's own frame. Materializing
the register does not: a callback that passes the address of a local
variable to a helper hands over an address in the dead subprogram's
frame. That address is below the callback's stack pointer by then, and
the helper's own call chain covers it, so the helper can write over its
own return address. 0x1234 below is the value the helper was asked to
store:
pc : 0x1234
lr : 0x1234
Call trace:
0x1234 (P)
bpf_test_run+0x188/0x3e0
bpf_prog_test_run_skb+0x47c/0x998
__sys_bpf+0xbdc/0xdd8
Kernel panic - not syncing: Oops: Fatal exception in interrupt
Set ctx->fp_used on the exception callback path so that the existing code
further down sets x25 from the stack pointer. The epilogue restores it
from the main program's save area along with the other callee-saved
registers, as it already does. x86 sets the frame pointer for the
callback from the argument it is passed, and powerpc computes it from
the stack pointer.
Fixes: 5d4fa9ec5643 ("bpf, arm64: Avoid blindly saving/restoring all callee-saved registers")
Acked-by: Xu Kuohai <xukuohai@huawei.com>
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Link: https://lore.kernel.org/r/20260907130624.611942-2-donggeunyoo.kernel@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/net/bpf_jit_comp.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index 27d27848db52d..9c28bb7b69ae6 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -537,6 +537,8 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
* 12 registers are on the stack
*/
emit(A64_SUB_I(1, A64_SP, A64_FP, 96), ctx);
+ /* The callback may use its own BPF stack, set up fp for it. */
+ ctx->fp_used = true;
}
if (ctx->fp_used)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 318/877] pinctrl: meson: Fix typo in s4 group name
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (316 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 317/877] bpf, arm64: set up the frame pointer for the exception callback Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 319/877] HID: amd_sfh: Validate PCI BAR size before mapping Greg Kroah-Hartman
` (566 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sean Anderson, Neil Armstrong,
Linus Walleij, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Anderson <sanderson@brivo.com>
[ Upstream commit 692f32609a30f75ca3401e25b504bfd06bd5662a ]
One of the i2c pin groups has some junk at the end. The name should be
i2c2_scl_h1, and indeed that's the name used by i2c2_pins3 in
meson-s4.dtsi.
Fixes: 775214d389c25 ("pinctrl: meson: add pinctrl driver support for Meson-S4 Soc")
Signed-off-by: Sean Anderson <sanderson@brivo.com>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/pinctrl/meson/pinctrl-meson-s4.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pinctrl/meson/pinctrl-meson-s4.c b/drivers/pinctrl/meson/pinctrl-meson-s4.c
index 872948699e9fe..365dafe457a9f 100644
--- a/drivers/pinctrl/meson/pinctrl-meson-s4.c
+++ b/drivers/pinctrl/meson/pinctrl-meson-s4.c
@@ -854,7 +854,7 @@ static const char * const i2c1_groups[] = {
static const char * const i2c2_groups[] = {
"i2c2_sda_d", "i2c2_scl_d",
"i2c2_sda_h8", "i2c2_scl_h9",
- "i2c2_sda_h0", "i2c2_scl_h1l,"
+ "i2c2_sda_h0", "i2c2_scl_h1",
};
static const char * const i2c3_groups[] = {
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 319/877] HID: amd_sfh: Validate PCI BAR size before mapping
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (317 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 318/877] pinctrl: meson: Fix typo in s4 group name Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 320/877] HID: bpf: fix __hid_bpf_hw_check_params report length Greg Kroah-Hartman
` (565 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+4eadd4dfe9e66522bae8,
Slawomir Stepien, Basavaraj Natikar, Jiri Kosina, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Slawomir Stepien <sst@poczta.fm>
[ Upstream commit 65bcc5f89704efe5b9d69d4ea2c1002d90c31382 ]
The amd_sfh driver maps PCI BAR 2 using pcim_iomap_regions() and
subsequently accesses MMIO registers at offsets up to 0x10958 (e.g.,
AMD_P2C_MSG3 at 0x1068C). However, the driver never validates that the BAR
size is large enough to cover these accesses. If the driver is bound to a
device with a smaller BAR 2, this leads to an out-of-bounds memory access
and a page fault during the probe function.
For example, a page fault can occur when reading from privdata->mmio +
AMD_P2C_MSG3 in mp2_select_ops():
BUG: unable to handle page fault for address: ffffc9000390368c
PGD 100000067 P4D 100000067 PUD 1012c1067 PMD 105b64067 PTE 0
Oops: Oops: 0000 [#1] SMP KASAN NOPTI
RIP: 0010:readl arch/x86/include/asm/io.h:59 [inline]
RIP: 0010:mp2_select_ops drivers/hid/amd-sfh-hid/amd_sfh_pcie.c:282
[inline]
RIP: 0010:amd_mp2_pci_probe+0x337/0x5f0
drivers/hid/amd-sfh-hid/amd_sfh_pcie.c:487
Call Trace:
<TASK>
local_pci_probe drivers/pci/pci-driver.c:332 [inline]
pci_call_probe drivers/pci/pci-driver.c:394 [inline]
__pci_device_probe drivers/pci/pci-driver.c:455 [inline]
pci_device_probe+0x431/0xc90 drivers/pci/pci-driver.c:489
Fix this by verifying that the length of BAR 2 is at least 128KB before
attempting to map it. Since the maximum accessed offset is 0x10958, and PCI
BAR sizes are powers of 2, any legitimate hardware will have a BAR size of
at least 128KB.
Fixes: 4f567b9f8141 ("SFH: PCIe driver to add support of AMD sensor fusion hub")
Assisted-by: Gemini:gemini-3.7-flash Gemini:gemini-3.1-pro-preview syzbot
Reported-by: syzbot+4eadd4dfe9e66522bae8@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=4eadd4dfe9e66522bae8
Link: https://syzkaller.appspot.com/ai_job?id=3bc1c45c-548f-4ab5-8243-d2c8ec321d6c
Signed-off-by: Slawomir Stepien <sst@poczta.fm>
Acked-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
Link: https://syzkaller.appspot.com/bug?extid=4eadd4dfe9e66522bae8
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/amd-sfh-hid/amd_sfh_common.h | 4 ++++
drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 10 ++++++++++
2 files changed, 14 insertions(+)
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_common.h b/drivers/hid/amd-sfh-hid/amd_sfh_common.h
index 00308d8998d4d..f05078f93b138 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_common.h
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_common.h
@@ -12,11 +12,15 @@
#include <linux/mutex.h>
#include <linux/pci.h>
+#include <linux/sizes.h>
#include "amd_sfh_hid.h"
#define PCI_DEVICE_ID_AMD_MP2 0x15E4
#define PCI_DEVICE_ID_AMD_MP2_1_1 0x164A
+/* The BAR 2 size must cover the highest register offset (0x10958) */
+#define AMD_SFH_MIN_BAR_SIZE SZ_128K
+
#define AMD_C2P_MSG(regno) (0x10500 + ((regno) * 4))
#define AMD_P2C_MSG(regno) (0x10680 + ((regno) * 4))
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
index 33ba9af1a249f..b29f8ea39c4c1 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
@@ -390,6 +390,16 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
if (rc)
return rc;
+ if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) {
+ dev_err(&pdev->dev, "BAR 2 is not IORESOURCE_MEM\n");
+ return -ENODEV;
+ }
+
+ if (pci_resource_len(pdev, 2) < AMD_SFH_MIN_BAR_SIZE) {
+ dev_err(&pdev->dev, "BAR 2 is too small\n");
+ return -EINVAL;
+ }
+
rc = pcim_iomap_regions(pdev, BIT(2), DRIVER_NAME);
if (rc)
return rc;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 320/877] HID: bpf: fix __hid_bpf_hw_check_params report length
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (318 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 319/877] HID: amd_sfh: Validate PCI BAR size before mapping Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 321/877] RISC-V: KVM: Preserve firmware counter value across stop/start Greg Kroah-Hartman
` (564 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Benjamin Tissoires, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Tissoires <bentiss@kernel.org>
[ Upstream commit c4afa4862b878d56e0cc1021298794ac1b45bc49 ]
Turns out that USB, I2C and other transport drivers (except uhid which
just passes the data) still need to have the report ID in the first
byte.
Because they expect the first byte to be the report ID or 0, when the
report ID is 0, they strip that first byte before forwarding to the
device. This means that the transport layer forwards a buffer of size
N-1 to the device, which gets rejected.
Fixes: 5599f8019661 ("HID: bpf: export hid_hw_output_report as a BPF kfunc")
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/bpf/hid_bpf_dispatch.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c
index 1de6a7e0af7b4..a421fecce9dd1 100644
--- a/drivers/hid/bpf/hid_bpf_dispatch.c
+++ b/drivers/hid/bpf/hid_bpf_dispatch.c
@@ -359,7 +359,7 @@ hid_bpf_release_context(struct hid_bpf_ctx *ctx)
static int
__hid_bpf_hw_check_params(struct hid_bpf_ctx *ctx, __u8 *buf, size_t *buf__sz,
- enum hid_report_type rtype)
+ enum hid_report_type rtype, bool hw_request)
{
struct hid_report_enum *report_enum;
struct hid_report *report;
@@ -391,6 +391,10 @@ __hid_bpf_hw_check_params(struct hid_bpf_ctx *ctx, __u8 *buf, size_t *buf__sz,
report_len = hid_report_len(report);
+ /* unnumbered reports need to have a report ID reserved in the first byte */
+ if (hw_request && report_enum->numbered == 0)
+ report_len += 1;
+
if (*buf__sz > report_len)
*buf__sz = report_len;
@@ -424,7 +428,7 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz,
return -EDEADLOCK;
/* check arguments */
- ret = __hid_bpf_hw_check_params(ctx, buf, &size, rtype);
+ ret = __hid_bpf_hw_check_params(ctx, buf, &size, rtype, true);
if (ret)
return ret;
@@ -487,7 +491,7 @@ hid_bpf_hw_output_report(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz)
return -EDEADLOCK;
/* check arguments */
- ret = __hid_bpf_hw_check_params(ctx, buf, &size, HID_OUTPUT_REPORT);
+ ret = __hid_bpf_hw_check_params(ctx, buf, &size, HID_OUTPUT_REPORT, true);
if (ret)
return ret;
@@ -515,7 +519,7 @@ __hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *b
return -EDEADLOCK;
/* check arguments */
- ret = __hid_bpf_hw_check_params(ctx, buf, &size, type);
+ ret = __hid_bpf_hw_check_params(ctx, buf, &size, type, false);
if (ret)
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 321/877] RISC-V: KVM: Preserve firmware counter value across stop/start
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (319 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 320/877] HID: bpf: fix __hid_bpf_hw_check_params report length Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 322/877] RISC-V: KVM: Report snapshot write failure to the guest Greg Kroah-Hartman
` (563 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, SeungJu Cheon, Anup Patel,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeungJu Cheon <suunj1331@gmail.com>
[ Upstream commit 8b3fd1a8b305321171602bfa7c41212441cf69e4 ]
Firmware events accumulate in kvpmu->fw_event[].value while running,
but counter stop only clears fw_event[].started without saving the
value back to pmc->counter_val. A subsequent counter start without
SBI_PMU_START_FLAG_SET_INIT_VALUE reloads the stale counter_val into
fw_event[].value, losing all events counted so far.
Save fw_event[].value into counter_val when actually stopping a
running counter, and remove the now redundant synchronization from
the snapshot path.
Fixes: badc386869e2c ("RISC-V: KVM: Support firmware events")
Signed-off-by: SeungJu Cheon <suunj1331@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260825083719.643970-2-suunj1331@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/riscv/kvm/vcpu_pmu.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c
index 9ec3280db91d9..4073adf4f91a3 100644
--- a/arch/riscv/kvm/vcpu_pmu.c
+++ b/arch/riscv/kvm/vcpu_pmu.c
@@ -590,10 +590,12 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base,
goto out;
}
- if (!kvpmu->fw_event[fevent_code].started)
+ if (!kvpmu->fw_event[fevent_code].started) {
sbiret = SBI_ERR_ALREADY_STOPPED;
-
- kvpmu->fw_event[fevent_code].started = false;
+ } else {
+ kvpmu->fw_event[fevent_code].started = false;
+ pmc->counter_val = kvpmu->fw_event[fevent_code].value;
+ }
} else if (pmc->perf_event) {
if (pmc->started) {
/* Stop counting the counter */
@@ -611,9 +613,7 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base,
}
if (snap_flag_set && !sbiret) {
- if (pmc->cinfo.type == SBI_PMU_CTR_TYPE_FW)
- pmc->counter_val = kvpmu->fw_event[fevent_code].value;
- else if (pmc->perf_event)
+ if (pmc->perf_event)
pmc->counter_val += perf_event_read_value(pmc->perf_event,
&enabled, &running);
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 322/877] RISC-V: KVM: Report snapshot write failure to the guest
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (320 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 321/877] RISC-V: KVM: Preserve firmware counter value across stop/start Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 323/877] RISC-V: KVM: Fix perf-backed counter accounting across stop and read Greg Kroah-Hartman
` (562 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, SeungJu Cheon, Anup Patel,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeungJu Cheon <suunj1331@gmail.com>
[ Upstream commit 057dd2639ceae79adced5d8fe52c32d562edcb3a ]
If kvm_vcpu_write_guest() fails while updating the PMU snapshot area
on counter stop, the guest may receive SBI_SUCCESS without the
snapshot being updated, leaving stale data in shared memory.
Return SBI_ERR_FAILURE when the snapshot write fails.
Fixes: c2f41ddbcdd7 ("RISC-V: KVM: Implement SBI PMU Snapshot feature")
Signed-off-by: SeungJu Cheon <suunj1331@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260825083719.643970-3-suunj1331@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/riscv/kvm/vcpu_pmu.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c
index 4073adf4f91a3..468e58f152153 100644
--- a/arch/riscv/kvm/vcpu_pmu.c
+++ b/arch/riscv/kvm/vcpu_pmu.c
@@ -642,9 +642,10 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base,
}
}
- if (shmem_needs_update)
- kvm_vcpu_write_guest(vcpu, kvpmu->snapshot_addr, kvpmu->sdata,
- sizeof(struct riscv_pmu_snapshot_data));
+ if (shmem_needs_update &&
+ kvm_vcpu_write_guest(vcpu, kvpmu->snapshot_addr, kvpmu->sdata,
+ sizeof(struct riscv_pmu_snapshot_data)))
+ sbiret = SBI_ERR_FAILURE;
out:
retdata->err_val = sbiret;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 323/877] RISC-V: KVM: Fix perf-backed counter accounting across stop and read
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (321 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 322/877] RISC-V: KVM: Report snapshot write failure to the guest Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 324/877] KVM: arm64: vgic-its: Free the caches when GITS_BASER changes Greg Kroah-Hartman
` (561 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, SeungJu Cheon, Anup Patel,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeungJu Cheon <suunj1331@gmail.com>
[ Upstream commit c7e2cc38c56142cdab25e6f73602a8222bf9479b ]
pmu_ctr_read() adds the event count returned by perf_event_read_value()
to counter_val, which can accumulate the same count repeatedly across
reads. kvm_riscv_vcpu_pmu_ctr_stop() also leaves counter_val stale by
not folding the current event count into it.
Make reads of perf-backed counters side-effect free, and use
perf_event_pause() when stopping a counter to fold the current event
count into counter_val while resetting it. This preserves the counter
value across stop/start and lets the snapshot path use counter_val
directly.
Fixes: 0cb74b65d2e5 ("RISC-V: KVM: Implement perf support without sampling")
Signed-off-by: SeungJu Cheon <suunj1331@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260825083719.643970-4-suunj1331@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/riscv/kvm/vcpu_pmu.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c
index 468e58f152153..147fc0d107ca9 100644
--- a/arch/riscv/kvm/vcpu_pmu.c
+++ b/arch/riscv/kvm/vcpu_pmu.c
@@ -245,12 +245,13 @@ static int pmu_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx,
if (pmc->cinfo.type == SBI_PMU_CTR_TYPE_FW) {
fevent_code = get_event_code(pmc->event_idx);
pmc->counter_val = kvpmu->fw_event[fevent_code].value;
+ *out_val = pmc->counter_val;
} else if (pmc->perf_event) {
- pmc->counter_val += perf_event_read_value(pmc->perf_event, &enabled, &running);
+ *out_val = pmc->counter_val +
+ perf_event_read_value(pmc->perf_event, &enabled, &running);
} else {
return -EINVAL;
}
- *out_val = pmc->counter_val;
return 0;
}
@@ -561,7 +562,6 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base,
{
struct kvm_pmu *kvpmu = vcpu_to_pmu(vcpu);
int i, pmc_index, sbiret = 0;
- u64 enabled, running;
struct kvm_pmc *pmc;
int fevent_code;
bool snap_flag_set = flags & SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT;
@@ -598,8 +598,11 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base,
}
} else if (pmc->perf_event) {
if (pmc->started) {
- /* Stop counting the counter */
- perf_event_disable(pmc->perf_event);
+ /*
+ * Stop the counter and fold the live count into counter_val.
+ * Reset the event value to avoid redundant accumulation.
+ */
+ pmc->counter_val += perf_event_pause(pmc->perf_event, true);
pmc->started = false;
} else {
sbiret = SBI_ERR_ALREADY_STOPPED;
@@ -613,9 +616,6 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base,
}
if (snap_flag_set && !sbiret) {
- if (pmc->perf_event)
- pmc->counter_val += perf_event_read_value(pmc->perf_event,
- &enabled, &running);
/*
* The counter and overflow indicies in the snapshot region are w.r.to
* cbase. Modify the set bit in the counter mask instead of the pmc_index
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 324/877] KVM: arm64: vgic-its: Free the caches when GITS_BASER changes
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (322 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 323/877] RISC-V: KVM: Fix perf-backed counter accounting across stop and read Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 325/877] KVM: arm64: vgic-its: Add stronger type-checking to the ITS entry sizes Greg Kroah-Hartman
` (560 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Marc Zyngier, Fuad Tabba,
Oliver Upton, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fuad Tabba <fuad.tabba@linux.dev>
[ Upstream commit 8cd92f77ae4f5371a7d581f8324c24919670b304 ]
A guest that disables the ITS and re-points or shrinks GITS_BASER<n>
with VALID still set keeps the devices and collections it mapped
against the old table, as KVM frees them only when VALID is cleared.
The contents of the table are IMPLEMENTATION DEFINED, so a write that
gives GITS_BASER<n> a different address or size may lose whatever the
old value described. Free the list whenever the stored value changes,
and drop the translation cache with it.
The cache is not empty just because the ITS is disabled: its->enabled
is written under the cmd_lock, while vgic_its_resolve_lpi() tests it
under the its_lock, so an injection can still cache an entry after the
ITS was disabled. Hence the invalidation inside the its_lock section.
Test for a change rather than a write: its_restore_enable() rewrites
GITS_BASER<n> from its probe-time cache on resume, and KVM reports
GITS_TYPER.HCC as 0, so nothing re-maps the boot CPU's collection
afterwards.
Fixes: 36d6961c2b481 ("KVM: arm/arm64: vgic-its: Free caches when GITS_BASER Valid bit is cleared")
Suggested-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/all/87ecg9owwa.wl-maz@kernel.org/
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Link: https://patch.msgid.link/20260821064445.615838-2-fuad.tabba@linux.dev
Signed-off-by: Oliver Upton <oupton@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kvm/vgic/vgic-its.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
index 7282305de3471..6737db1fb922f 100644
--- a/arch/arm64/kvm/vgic/vgic-its.c
+++ b/arch/arm64/kvm/vgic/vgic-its.c
@@ -1637,7 +1637,7 @@ static void vgic_mmio_write_its_baser(struct kvm *kvm,
unsigned long val)
{
const struct vgic_its_abi *abi = vgic_its_get_abi(its);
- u64 entry_size, table_type;
+ u64 old, entry_size, table_type;
u64 reg, *regptr, clearbits = 0;
/* When GITS_CTLR.Enable is 1, we ignore write accesses. */
@@ -1660,7 +1660,9 @@ static void vgic_mmio_write_its_baser(struct kvm *kvm,
return;
}
- reg = update_64bit_reg(*regptr, addr & 7, len, val);
+ old = *regptr;
+
+ reg = update_64bit_reg(old, addr & 7, len, val);
reg &= ~GITS_BASER_RO_MASK;
reg &= ~clearbits;
@@ -1670,7 +1672,8 @@ static void vgic_mmio_write_its_baser(struct kvm *kvm,
*regptr = reg;
- if (!(reg & GITS_BASER_VALID)) {
+ /* The ITS driver rewrites an unchanged GITS_BASER<n> on resume. */
+ if (reg != old) {
/* Take the its_lock to prevent a race with a save/restore */
mutex_lock(&its->its_lock);
switch (table_type) {
@@ -1681,6 +1684,8 @@ static void vgic_mmio_write_its_baser(struct kvm *kvm,
vgic_its_free_collection_list(kvm, its);
break;
}
+ /* A concurrent injection may have cached a translation. */
+ vgic_its_invalidate_cache(its);
mutex_unlock(&its->its_lock);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 325/877] KVM: arm64: vgic-its: Add stronger type-checking to the ITS entry sizes
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (323 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 324/877] KVM: arm64: vgic-its: Free the caches when GITS_BASER changes Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 326/877] KVM: arm64: vgic-its: Skip unreachable devices instead of failing the save Greg Kroah-Hartman
` (559 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Marc Zyngier, Oliver Upton,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Zyngier <maz@kernel.org>
[ Upstream commit 3b2c81d5feb250dfdcb0ef5825319f36c29f8336 ]
The ITS ABI infrastructure allows for some pretty lax code, where
the size of the data doesn't have to match the size of the entry,
potentially leading to a collection of interesting bugs.
Commit 7fe28d7e68f9 ("KVM: arm64: vgic-its: Add a data length check
in vgic_its_save_*") added some checks, but starts by implicitly
casting all writes to a 64bit value, hiding some of the issues.
Instead, introduce macros that will check the data type actually used
for dealing with the table entries. The macros are taking a symbolic
entry type that is used to fetch the size of the entry type for the
current ABI. This immediately catches a couple of low-impact gotchas
(zero values that are implicitly 32bit), easy enough to fix.
Given that we currently only have a single ABI, hardcode a couple of
BUILD_BUG_ON()s that will fire if we use anything but a 64bit quantity,
and some (currently unreachable) fallback code that may become useful
one day.
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20241117165757.247686-5-maz@kernel.org
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
Stable-dep-of: cc5d96036e01 ("KVM: arm64: vgic-its: Skip unreachable devices instead of failing the save")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kvm/vgic/vgic-its.c | 69 ++++++++++++++++++++++++----------
arch/arm64/kvm/vgic/vgic.h | 23 ------------
2 files changed, 50 insertions(+), 42 deletions(-)
diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
index 6737db1fb922f..8842e53734a1d 100644
--- a/arch/arm64/kvm/vgic/vgic-its.c
+++ b/arch/arm64/kvm/vgic/vgic-its.c
@@ -31,6 +31,41 @@ static int vgic_its_commit_v0(struct vgic_its *its);
static int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq,
struct kvm_vcpu *filter_vcpu, bool needs_inv);
+#define vgic_its_read_entry_lock(i, g, valp, t) \
+ ({ \
+ int __sz = vgic_its_get_abi(i)->t##_esz; \
+ struct kvm *__k = (i)->dev->kvm; \
+ int __ret; \
+ \
+ BUILD_BUG_ON(NR_ITS_ABIS == 1 && \
+ sizeof(*(valp)) != ABI_0_ESZ); \
+ if (NR_ITS_ABIS > 1 && \
+ KVM_BUG_ON(__sz != sizeof(*(valp)), __k)) \
+ __ret = -EINVAL; \
+ else \
+ __ret = kvm_read_guest_lock(__k, (g), \
+ valp, __sz); \
+ __ret; \
+ })
+
+#define vgic_its_write_entry_lock(i, g, val, t) \
+ ({ \
+ int __sz = vgic_its_get_abi(i)->t##_esz; \
+ struct kvm *__k = (i)->dev->kvm; \
+ typeof(val) __v = (val); \
+ int __ret; \
+ \
+ BUILD_BUG_ON(NR_ITS_ABIS == 1 && \
+ sizeof(__v) != ABI_0_ESZ); \
+ if (NR_ITS_ABIS > 1 && \
+ KVM_BUG_ON(__sz != sizeof(__v), __k)) \
+ __ret = -EINVAL; \
+ else \
+ __ret = vgic_write_guest_lock(__k, (g), \
+ &__v, __sz); \
+ __ret; \
+ })
+
/*
* Creates a new (reference to a) struct vgic_irq for a given LPI.
* If this LPI is already mapped on another ITS, we increase its refcount
@@ -798,7 +833,7 @@ static int vgic_its_cmd_handle_discard(struct kvm *kvm, struct vgic_its *its,
its_free_ite(kvm, ite);
- return vgic_its_write_entry_lock(its, gpa, 0, ite_esz);
+ return vgic_its_write_entry_lock(its, gpa, 0ULL, ite);
}
return E_ITS_DISCARD_UNMAPPED_INTERRUPT;
@@ -1147,7 +1182,6 @@ static int vgic_its_cmd_handle_mapd(struct kvm *kvm, struct vgic_its *its,
bool valid = its_cmd_get_validbit(its_cmd);
u8 num_eventid_bits = its_cmd_get_size(its_cmd);
gpa_t itt_addr = its_cmd_get_ittaddr(its_cmd);
- int dte_esz = vgic_its_get_abi(its)->dte_esz;
struct its_device *device;
gpa_t gpa;
@@ -1172,7 +1206,7 @@ static int vgic_its_cmd_handle_mapd(struct kvm *kvm, struct vgic_its *its,
* is an error, so we are done in any case.
*/
if (!valid)
- return vgic_its_write_entry_lock(its, gpa, 0, dte_esz);
+ return vgic_its_write_entry_lock(its, gpa, 0ULL, dte);
device = vgic_its_alloc_device(its, device_id, itt_addr,
num_eventid_bits);
@@ -2099,7 +2133,7 @@ static int scan_its_table(struct vgic_its *its, gpa_t base, int size, u32 esz,
* vgic_its_save_ite - Save an interrupt translation entry at @gpa
*/
static int vgic_its_save_ite(struct vgic_its *its, struct its_device *dev,
- struct its_ite *ite, gpa_t gpa, int ite_esz)
+ struct its_ite *ite, gpa_t gpa)
{
u32 next_offset;
u64 val;
@@ -2110,7 +2144,7 @@ static int vgic_its_save_ite(struct vgic_its *its, struct its_device *dev,
ite->collection->collection_id;
val = cpu_to_le64(val);
- return vgic_its_write_entry_lock(its, gpa, val, ite_esz);
+ return vgic_its_write_entry_lock(its, gpa, val, ite);
}
/**
@@ -2210,7 +2244,7 @@ static int vgic_its_save_itt(struct vgic_its *its, struct its_device *device)
if (ite->irq->hw && !kvm_vgic_global_state.has_gicv4_1)
return -EACCES;
- ret = vgic_its_save_ite(its, device, ite, gpa, ite_esz);
+ ret = vgic_its_save_ite(its, device, ite, gpa);
if (ret)
return ret;
}
@@ -2249,10 +2283,9 @@ static int vgic_its_restore_itt(struct vgic_its *its, struct its_device *dev)
* @its: ITS handle
* @dev: ITS device
* @ptr: GPA
- * @dte_esz: device table entry size
*/
static int vgic_its_save_dte(struct vgic_its *its, struct its_device *dev,
- gpa_t ptr, int dte_esz)
+ gpa_t ptr)
{
u64 val, itt_addr_field;
u32 next_offset;
@@ -2265,7 +2298,7 @@ static int vgic_its_save_dte(struct vgic_its *its, struct its_device *dev,
(dev->num_eventid_bits - 1));
val = cpu_to_le64(val);
- return vgic_its_write_entry_lock(its, ptr, val, dte_esz);
+ return vgic_its_write_entry_lock(its, ptr, val, dte);
}
/**
@@ -2345,10 +2378,8 @@ static int vgic_its_device_cmp(void *priv, const struct list_head *a,
*/
static int vgic_its_save_device_tables(struct vgic_its *its)
{
- const struct vgic_its_abi *abi = vgic_its_get_abi(its);
u64 baser = its->baser_device_table;
struct its_device *dev;
- int dte_esz = abi->dte_esz;
if (!(baser & GITS_BASER_VALID))
return 0;
@@ -2367,7 +2398,7 @@ static int vgic_its_save_device_tables(struct vgic_its *its)
if (ret)
return ret;
- ret = vgic_its_save_dte(its, dev, eaddr, dte_esz);
+ ret = vgic_its_save_dte(its, dev, eaddr);
if (ret)
return ret;
}
@@ -2448,7 +2479,7 @@ static int vgic_its_restore_device_tables(struct vgic_its *its)
static int vgic_its_save_cte(struct vgic_its *its,
struct its_collection *collection,
- gpa_t gpa, int esz)
+ gpa_t gpa)
{
u64 val;
@@ -2457,7 +2488,7 @@ static int vgic_its_save_cte(struct vgic_its *its,
collection->collection_id);
val = cpu_to_le64(val);
- return vgic_its_write_entry_lock(its, gpa, val, esz);
+ return vgic_its_write_entry_lock(its, gpa, val, cte);
}
/*
@@ -2465,7 +2496,7 @@ static int vgic_its_save_cte(struct vgic_its *its,
* Return +1 on success, 0 if the entry was invalid (which should be
* interpreted as end-of-table), and a negative error value for generic errors.
*/
-static int vgic_its_restore_cte(struct vgic_its *its, gpa_t gpa, int esz)
+static int vgic_its_restore_cte(struct vgic_its *its, gpa_t gpa)
{
struct its_collection *collection;
struct kvm *kvm = its->dev->kvm;
@@ -2473,7 +2504,7 @@ static int vgic_its_restore_cte(struct vgic_its *its, gpa_t gpa, int esz)
u64 val;
int ret;
- ret = vgic_its_read_entry_lock(its, gpa, &val, esz);
+ ret = vgic_its_read_entry_lock(its, gpa, &val, cte);
if (ret)
return ret;
val = le64_to_cpu(val);
@@ -2520,7 +2551,7 @@ static int vgic_its_save_collection_table(struct vgic_its *its)
max_size = GITS_BASER_NR_PAGES(baser) * SZ_64K;
list_for_each_entry(collection, &its->collection_list, coll_list) {
- ret = vgic_its_save_cte(its, collection, gpa, cte_esz);
+ ret = vgic_its_save_cte(its, collection, gpa);
if (ret)
return ret;
gpa += cte_esz;
@@ -2534,7 +2565,7 @@ static int vgic_its_save_collection_table(struct vgic_its *its)
* table is not fully filled, add a last dummy element
* with valid bit unset
*/
- return vgic_its_write_entry_lock(its, gpa, 0, cte_esz);
+ return vgic_its_write_entry_lock(its, gpa, 0ULL, cte);
}
/*
@@ -2559,7 +2590,7 @@ static int vgic_its_restore_collection_table(struct vgic_its *its)
max_size = GITS_BASER_NR_PAGES(baser) * SZ_64K;
while (read < max_size) {
- ret = vgic_its_restore_cte(its, gpa, cte_esz);
+ ret = vgic_its_restore_cte(its, gpa);
if (ret <= 0)
break;
gpa += cte_esz;
diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h
index 309295f5e1b07..f2486b4d9f956 100644
--- a/arch/arm64/kvm/vgic/vgic.h
+++ b/arch/arm64/kvm/vgic/vgic.h
@@ -146,29 +146,6 @@ static inline int vgic_write_guest_lock(struct kvm *kvm, gpa_t gpa,
return ret;
}
-static inline int vgic_its_read_entry_lock(struct vgic_its *its, gpa_t eaddr,
- u64 *eval, unsigned long esize)
-{
- struct kvm *kvm = its->dev->kvm;
-
- if (KVM_BUG_ON(esize != sizeof(*eval), kvm))
- return -EINVAL;
-
- return kvm_read_guest_lock(kvm, eaddr, eval, esize);
-
-}
-
-static inline int vgic_its_write_entry_lock(struct vgic_its *its, gpa_t eaddr,
- u64 eval, unsigned long esize)
-{
- struct kvm *kvm = its->dev->kvm;
-
- if (KVM_BUG_ON(esize != sizeof(eval), kvm))
- return -EINVAL;
-
- return vgic_write_guest_lock(kvm, eaddr, &eval, esize);
-}
-
/*
* This struct provides an intermediate representation of the fields contained
* in the GICH_VMCR and ICH_VMCR registers, such that code exporting the GIC
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 326/877] KVM: arm64: vgic-its: Skip unreachable devices instead of failing the save
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (324 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 325/877] KVM: arm64: vgic-its: Add stronger type-checking to the ITS entry sizes Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 327/877] KVM: arm64: Return -EINVAL for an empty SMCCC filter range at base 0 Greg Kroah-Hartman
` (558 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Marc Zyngier, Fuad Tabba,
Oliver Upton, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fuad Tabba <fuad.tabba@linux.dev>
[ Upstream commit cc5d96036e01ac330d24b2f0c336d60f82ab4930 ]
vgic_its_save_device_tables() aborts with -EINVAL when a device's entry
falls outside the device table, which a guest can arrange on its own: an
indirect table lets it clear an L1 entry's valid bit without touching
GITS_BASER. That fails a save userspace should be able to issue
reliably.
Skip the device instead, and point the saved DTE chain past it, as
commit ad1e686e2378d ("KVM: arm64: vgic-its: Point saved ITEs at the
next valid entry") does for ITEs. compute_next_devid_offset() takes the
next device off the list whether or not it was saved, so the predecessor
would otherwise point at an entry the save never wrote. Restore follows
that offset while it stays inside the table being scanned: within an L2
block, or anywhere in a flat table. Both need userspace to remove a
memslot under the table, since dropping an L1 entry takes the whole
block with it and scan_its_table() stops at the block boundary.
Fixes: 57a9a117154c9 ("KVM: arm64: vgic-its: Device table save/restore")
Suggested-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/all/86bjaz5s6v.wl-maz@kernel.org/
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Link: https://patch.msgid.link/20260821064445.615838-4-fuad.tabba@linux.dev
Signed-off-by: Oliver Upton <oupton@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kvm/vgic/vgic-its.c | 32 +++++++++++++++++++-------------
1 file changed, 19 insertions(+), 13 deletions(-)
diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
index 8842e53734a1d..4b56de3352053 100644
--- a/arch/arm64/kvm/vgic/vgic-its.c
+++ b/arch/arm64/kvm/vgic/vgic-its.c
@@ -2038,18 +2038,22 @@ static int vgic_its_attr_regs_access(struct kvm_device *dev,
return ret;
}
-static u32 compute_next_devid_offset(struct list_head *h,
+static u32 compute_next_devid_offset(struct vgic_its *its, u64 baser,
struct its_device *dev)
{
- struct its_device *next;
- u32 next_offset;
+ struct its_device *next = dev;
- if (list_is_last(&dev->dev_list, h))
- return 0;
- next = list_next_entry(dev, dev_list);
- next_offset = next->device_id - dev->device_id;
+ /*
+ * Point at the next device vgic_its_save_device_tables() saves. It
+ * sorts device_list first, so the subtraction cannot underflow.
+ */
+ list_for_each_entry_continue(next, &its->device_list, dev_list) {
+ if (vgic_its_check_id(its, baser, next->device_id, NULL))
+ return min_t(u32, next->device_id - dev->device_id,
+ VITS_DTE_MAX_DEVID_OFFSET);
+ }
- return min_t(u32, next_offset, VITS_DTE_MAX_DEVID_OFFSET);
+ return 0;
}
static u32 compute_next_eventid_offset(struct list_head *h, struct its_ite *ite)
@@ -2281,17 +2285,18 @@ static int vgic_its_restore_itt(struct vgic_its *its, struct its_device *dev)
* vgic_its_save_dte - Save a device table entry at a given GPA
*
* @its: ITS handle
+ * @baser: GITS_BASER<dev> the caller is saving against
* @dev: ITS device
* @ptr: GPA
*/
-static int vgic_its_save_dte(struct vgic_its *its, struct its_device *dev,
- gpa_t ptr)
+static int vgic_its_save_dte(struct vgic_its *its, u64 baser,
+ struct its_device *dev, gpa_t ptr)
{
u64 val, itt_addr_field;
u32 next_offset;
itt_addr_field = dev->itt_addr >> 8;
- next_offset = compute_next_devid_offset(&its->device_list, dev);
+ next_offset = compute_next_devid_offset(its, baser, dev);
val = (1ULL << KVM_ITS_DTE_VALID_SHIFT |
((u64)next_offset << KVM_ITS_DTE_NEXT_SHIFT) |
(itt_addr_field << KVM_ITS_DTE_ITTADDR_SHIFT) |
@@ -2390,15 +2395,16 @@ static int vgic_its_save_device_tables(struct vgic_its *its)
int ret;
gpa_t eaddr;
+ /* Don't fail a save that userspace must be able to issue. */
if (!vgic_its_check_id(its, baser,
dev->device_id, &eaddr))
- return -EINVAL;
+ continue;
ret = vgic_its_save_itt(its, dev);
if (ret)
return ret;
- ret = vgic_its_save_dte(its, dev, eaddr);
+ ret = vgic_its_save_dte(its, baser, dev, eaddr);
if (ret)
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 327/877] KVM: arm64: Return -EINVAL for an empty SMCCC filter range at base 0
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (325 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 326/877] KVM: arm64: vgic-its: Skip unreachable devices instead of failing the save Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 328/877] KVM: arm64: Fix FGT mapping for HFGITR_EL2.nGCSEPP Greg Kroah-Hartman
` (557 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Steffen Eiden,
Fuad Tabba, Oliver Upton, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
[ Upstream commit 64dc6f1db7e620f2e9337bb181f305fb0561da79 ]
kvm_smccc_set_filter() only rejects a range if its inclusive end,
base + nr_functions - 1, is below base. That catches an empty range
(nr_functions == 0) at every nonzero base, but at base 0 the end wraps
to U32_MAX and KVM tries to insert [0, U32_MAX], which overlaps the
reserved Arm Architecture Calls ranges. KVM_ARM_VM_SMCCC_FILTER then
returns -EEXIST instead of the -EINVAL that the smccc_filter selftest
expects for an empty range.
Reject a zero function count explicitly.
Tested with a userspace reproducer on an arm64 VHE host under QEMU TCG:
EEXIST before, EINVAL after.
Fixes: 821d935c87bc ("KVM: arm64: Introduce support for userspace SMCCC filtering")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Fuad Tabba <fuad.tabba@linux.dev>
Tested-by: Fuad Tabba <fuad.tabba@linux.dev>
Link: https://patch.msgid.link/20260829054856.70549-2-kmehltretter@gmail.com
Signed-off-by: Oliver Upton <oupton@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kvm/hypercalls.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index ee6573befb813..82af201d60285 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -183,7 +183,8 @@ static int kvm_smccc_set_filter(struct kvm *kvm, struct kvm_smccc_filter __user
start = filter.base;
end = start + filter.nr_functions - 1;
- if (end < start || filter.action >= NR_SMCCC_FILTER_ACTIONS)
+ if (!filter.nr_functions || end < start ||
+ filter.action >= NR_SMCCC_FILTER_ACTIONS)
return -EINVAL;
mutex_lock(&kvm->arch.config_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 328/877] KVM: arm64: Fix FGT mapping for HFGITR_EL2.nGCSEPP
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (326 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 327/877] KVM: arm64: Return -EINVAL for an empty SMCCC filter range at base 0 Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 329/877] squashfs: Add dictionary size range check to prevent shift-out-of-bounds Greg Kroah-Hartman
` (556 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Leonardo Bras, Mark Brown,
Lorenzo Stoakes (ARM), Oliver Upton, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Brown <broonie@kernel.org>
[ Upstream commit 089e4f3c4862ba3f29dff2361caa8084879194fd ]
The encoding to trap mapping currently maps a FGT on OP_GCSPOPX to
HFGITR_EL2.nGCSEPP but as per DDI0601 2026-06 this FGT controls trapping
of GCSPUSHX and GCSPOPCX, and not the separate GCSPOPX instruction.
Update the mapping to reflect the architecture.
Fixes: 863ac38984a82 ("KVM: arm64: Add missing HFGITR_EL2 FGT entries to nested virt")
Reviewed-by: Leonardo Bras <leo.bras@arm.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Link: https://patch.msgid.link/20260901-arm64-gcs-v20-2-f31750bdfadb@kernel.org
Signed-off-by: Oliver Upton <oupton@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kvm/emulate-nested.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 05b6435d02a97..364beb6f27a1d 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -1287,7 +1287,7 @@ static const struct encoding_to_trap_config encoding_to_fgt[] __initconst = {
SR_FGT(OP_AT_S1E1A, HFGITR, ATS1E1A, 1),
SR_FGT(OP_COSP_RCTX, HFGITR, COSPRCTX, 1),
SR_FGT(OP_GCSPUSHX, HFGITR, nGCSEPP, 0),
- SR_FGT(OP_GCSPOPX, HFGITR, nGCSEPP, 0),
+ SR_FGT(OP_GCSPOPCX, HFGITR, nGCSEPP, 0),
SR_FGT(OP_GCSPUSHM, HFGITR, nGCSPUSHM_EL1, 0),
SR_FGT(OP_BRB_IALL, HFGITR, nBRBIALL, 0),
SR_FGT(OP_BRB_INJ, HFGITR, nBRBINJ, 0),
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 329/877] squashfs: Add dictionary size range check to prevent shift-out-of-bounds
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (327 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 328/877] KVM: arm64: Fix FGT mapping for HFGITR_EL2.nGCSEPP Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 330/877] scsi: sd_zbc: Reject disks with too many zones Greg Kroah-Hartman
` (555 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ran Hongyun, Phillip Lougher,
Zhihao Cheng, Christian Brauner (Amutable), Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ran Hongyun <ranhongyun1@huawei.com>
[ Upstream commit 1f7745fb3580152ca902ef181b605f33cabfb1d0 ]
When an abnormal SquashFS image (COMP_OPTS flag is 1 but dictionary size
is 0) is mounted, and performs shift operations using dictionarysize, the
shift exponent is -1, causing a shift-out-of-bounds.
Detail as below:
squashfs_comp_opts(msblk, buffer, length)
squashfs_xz_comp_opts()
if (comp_opts)
n = ffs(opts->dict_size) - 1;<----opts->dict_size=0, n=-1
if (opts->dict_size != (1 << n) && opts->dict_size !=
(1 << n) + (1 << (n + 1))) <----shift-out-of-bounds
Fix it by adding a dictionary size range check before the shift operation.
Fixes: ff750311d30a ("Squashfs: add compression options support to xz decompressor")
Signed-off-by: Ran Hongyun <ranhongyun1@huawei.com>
Link: https://patch.msgid.link/20260713115525.2661734-1-ranhongyun1@huawei.com
Reviewed-by: Phillip Lougher <phillip@squashfs.org.uk>
Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/squashfs/xz_wrapper.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/fs/squashfs/xz_wrapper.c b/fs/squashfs/xz_wrapper.c
index 6c49481a2f8c4..7d54cd524d6d9 100644
--- a/fs/squashfs/xz_wrapper.c
+++ b/fs/squashfs/xz_wrapper.c
@@ -57,10 +57,10 @@ static void *squashfs_xz_comp_opts(struct squashfs_sb_info *msblk,
opts->dict_size = le32_to_cpu(comp_opts->dictionary_size);
- /* the dictionary size should be 2^n or 2^n+2^(n+1) */
+ /* the dictionary size should be positive and 2^n or 2^n+2^(n+1) */
n = ffs(opts->dict_size) - 1;
- if (opts->dict_size != (1 << n) && opts->dict_size != (1 << n) +
- (1 << (n + 1))) {
+ if (opts->dict_size <= 0 || (opts->dict_size != (1 << n) &&
+ opts->dict_size != (1 << n) + (1 << (n + 1)))) {
err = -EIO;
goto out;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 330/877] scsi: sd_zbc: Reject disks with too many zones
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (328 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 329/877] squashfs: Add dictionary size range check to prevent shift-out-of-bounds Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 331/877] Bluetooth: SMP: reject Security Request over BR/EDR Greg Kroah-Hartman
` (554 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, ZHOU Jiaxiang, Damien Le Moal,
Martin K. Petersen (Oracle), Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: ZHOU Jiaxiang <me@fxti.xyz>
[ Upstream commit b6ec0f79745967c751c85df373062c8d15e45fc4 ]
sd_zbc_read_zones() computes the number of zones with 64-bit arithmetic and
stores the result in the unsigned int nr_zones field of struct
zoned_disk_info, silently truncating counts that exceed 32 bits. The
truncated count is later used to size per-zone resources, while the device
may still report more zones than fit.
Moreover, sd_zbc_report_zones() counts the reported zones with a signed int
zone_idx, which overflows past INT_MAX. Reject devices reporting more than
INT_MAX zones at scan time; such a device is not realistic for any medium
that exists today, and accepting it produces inconsistent zone bookkeeping.
Fixes: 89d947561077 ("sd: Implement support for ZBC devices")
Signed-off-by: ZHOU Jiaxiang <me@fxti.xyz>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Link: https://patch.msgid.link/C41798AB5AA6BF2B+20260916135822.32584-3-me@fxti.xyz
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/sd_zbc.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c
index b8d42098f0b68..b96b49763322a 100644
--- a/drivers/scsi/sd_zbc.c
+++ b/drivers/scsi/sd_zbc.c
@@ -595,7 +595,7 @@ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp)
int sd_zbc_read_zones(struct scsi_disk *sdkp, struct queue_limits *lim,
u8 buf[SD_BUF_SIZE])
{
- unsigned int nr_zones;
+ u64 nr_zones;
u32 zone_blocks = 0;
int ret;
@@ -627,6 +627,12 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, struct queue_limits *lim,
goto err;
nr_zones = round_up(sdkp->capacity, zone_blocks) >> ilog2(zone_blocks);
+ if (nr_zones > INT_MAX) {
+ sd_printk(KERN_ERR, sdkp, "Too many zones (%llu)\n",
+ nr_zones);
+ ret = -EINVAL;
+ goto err;
+ }
sdkp->early_zone_info.nr_zones = nr_zones;
sdkp->early_zone_info.zone_blocks = zone_blocks;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 331/877] Bluetooth: SMP: reject Security Request over BR/EDR
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (329 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 330/877] scsi: sd_zbc: Reject disks with too many zones Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 332/877] Bluetooth: mgmt: Dequeue pending mesh_send_sync entries on cancel Greg Kroah-Hartman
` (553 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christiano Amora,
Luiz Augusto von Dentz, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christiano Amora <christiano.amora@gmail.com>
[ Upstream commit f033482d76a9f18080c7a40c5f9c678bd7adc8f3 ]
Bose QC Ultra Headphones (dual-mode, same public address on both
transports) occasionally send an SMP Security Request on the BR/EDR
SMP fixed channel right after the ACL link is encrypted. The kernel
handles it as if it were an LE link: smp_cmd_security_req() has no
transport check, smp_ltk_encrypt() looks up an LTK with the ACL
connection's dst_type, and hci_find_ltk() matches the peer's LE LTK
because the LE public address type is stored as ADDR_LE_DEV_PUBLIC (0),
the same value as BDADDR_BREDR. HCI_OP_LE_START_ENC is then issued on
the ACL handle, the controller rejects it with Invalid HCI Command
Parameters, and hci_cs_le_start_enc() disconnects the link with
HCI_ERROR_AUTH_FAILURE. The headphones drop within a second of
connecting, before any profile is up; a manual reconnect works.
btmon (MediaTek MT7922, kernel 7.0.12):
> HCI Event: Encryption Change (0x08) plen 4
Status: Success (0x00)
Handle: 50 Address: BC:87:FA:47:73:5E (Bose Corporation)
Encryption: Enabled with AES-CCM (0x02)
> ACL Data RX: Handle 50 flags 0x02 dlen 6
BR/EDR SMP: Security Request (0x0b) len 1
Authentication requirement: No bonding, No MITM, SC (0x08)
< HCI Command: LE Start Encryption (0x08|0x0019) plen 28
Handle: 50 Address: BC:87:FA:47:73:5E (Bose Corporation)
> HCI Event: Command Status (0x0f) plen 4
LE Start Encryption (0x08|0x0019) ncmd 1
Status: Invalid HCI Command Parameters (0x12)
< HCI Command: Disconnect (0x01|0x0006) plen 3
Handle: 50 Address: BC:87:FA:47:73:5E (Bose Corporation)
Reason: Authentication Failure (0x05)
SMP over BR/EDR is limited to cross-transport key derivation; the
Security Request procedure (Core Specification Vol 3, Part H, Section
2.4.6, PDU in Section 3.6.7) has no BR/EDR counterpart. Reply with
Pairing Failed / Command Not Supported on a non-LE link, before the PDU
is parsed, and keep the connection. The reply is sent directly rather
than through smp_failure(): rejecting a command on the wrong transport
is not an authentication failure, and MGMT_EV_AUTH_FAILED would make
bluetoothd disconnect the device.
Tested on the affected host (kernel 7.0.12, MediaTek MT7922, Bose QC
Ultra) with the patched module built out of tree: 7 days and 49
reconnects without a drop, against 2 drops in the 3 days before the
patch. Every disconnect in that week had a userspace or remote reason.
Fixes: b5ae344d4c0f ("Bluetooth: Add full SMP BR/EDR support")
Assisted-by: LLM
Signed-off-by: Christiano Amora <christiano.amora@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/smp.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 9e9e9e2933096..078d5a19a846e 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -2301,6 +2301,23 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
bt_dev_dbg(hdev, "conn %p", conn);
+ /* SMP over BR/EDR only covers cross-transport key derivation; the
+ * Security Request procedure has no BR/EDR counterpart. Reject it
+ * here, otherwise smp_ltk_encrypt() finds the peer's LE LTK
+ * (ADDR_LE_DEV_PUBLIC and BDADDR_BREDR are both 0) and issues
+ * HCI_OP_LE_START_ENC on the ACL handle, which the controller
+ * rejects and hci_cs_le_start_enc() turns into a disconnect. Reply
+ * without smp_failure(): this is not an authentication failure, and
+ * MGMT_EV_AUTH_FAILED would make bluetoothd drop the device.
+ */
+ if (hcon->type != LE_LINK) {
+ u8 reason = SMP_CMD_NOTSUPP;
+
+ smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
+ &reason);
+ return 0;
+ }
+
if (skb->len < sizeof(*rp))
return SMP_INVALID_PARAMS;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 332/877] Bluetooth: mgmt: Dequeue pending mesh_send_sync entries on cancel
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (330 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 331/877] Bluetooth: SMP: reject Security Request over BR/EDR Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 333/877] cgroup: selftests: Move memcontrol specific helpers out of common cgroup_util.c Greg Kroah-Hartman
` (552 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lee Jones, Luiz Augusto von Dentz,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lee Jones <lee@kernel.org>
[ Upstream commit 71af682ba4692c2ed9ace4c3d4ca462ae368c029 ]
In send_cancel(), pending mesh_tx objects are removed from the
hdev->mesh_pending list and freed via mesh_send_complete(). However, if
a mesh transmission was already queued onto hdev->cmd_sync_work_list via
mesh_next(), the queued entry retains a raw pointer to mesh_tx.
When hci_cmd_sync_work later processes the entry, it attempts to execute
mesh_send_sync and its destroy callback mesh_send_start_complete using
the already freed mesh_tx pointer, leading to a use-after-free.
Fix this by invoking hci_cmd_sync_dequeue() for mesh_send_sync on the
target mesh_tx before completing it. If the entry is found and dequeued,
its destroy callback will complete and free the object; otherwise,
mesh_send_complete() is called directly.
Additionally, ensure the transmission queue advances after cancellation
or errors. In mesh_send_start_complete(), call mesh_next() on error
unless err is -ECANCELED, because hci_cmd_sync_dequeue() holds
hdev->cmd_sync_work_lock and calling mesh_next() synchronously would
deadlock. Instead, advance the queue in send_cancel() once the lock is
released and if no transmission is in progress.
Fixes: b338d91703fa ("Bluetooth: Implement support for Mesh")
Signed-off-by: Lee Jones <lee@kernel.org>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/mgmt.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index cdb2425a16a2c..1dc94c1518131 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2290,6 +2290,8 @@ static void mesh_send_start_complete(struct hci_dev *hdev, void *data, int err)
hci_dev_clear_flag(hdev, HCI_MESH_SENDING);
/* Send Complete Error Code for handle */
mesh_send_complete(hdev, mesh_tx, false);
+ if (err != -ECANCELED)
+ mesh_next(hdev, NULL, 0);
return;
}
@@ -2399,19 +2401,28 @@ static int send_cancel(struct hci_dev *hdev, void *data)
do {
mesh_tx = mgmt_mesh_next(hdev, cmd->sk);
- if (mesh_tx)
- mesh_send_complete(hdev, mesh_tx, false);
+ if (mesh_tx) {
+ if (!hci_cmd_sync_dequeue(hdev, mesh_send_sync,
+ mesh_tx, NULL))
+ mesh_send_complete(hdev, mesh_tx, false);
+ }
} while (mesh_tx);
} else {
mesh_tx = mgmt_mesh_find(hdev, cancel->handle);
- if (mesh_tx && mesh_tx->sk == cmd->sk)
- mesh_send_complete(hdev, mesh_tx, false);
+ if (mesh_tx && mesh_tx->sk == cmd->sk) {
+ if (!hci_cmd_sync_dequeue(hdev, mesh_send_sync,
+ mesh_tx, NULL))
+ mesh_send_complete(hdev, mesh_tx, false);
+ }
}
mgmt_cmd_complete(cmd->sk, hdev->id, MGMT_OP_MESH_SEND_CANCEL,
0, NULL, 0);
+ if (!hci_dev_test_flag(hdev, HCI_MESH_SENDING))
+ mesh_next(hdev, NULL, 0);
+
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 333/877] cgroup: selftests: Move memcontrol specific helpers out of common cgroup_util.c
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (331 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 332/877] Bluetooth: mgmt: Dequeue pending mesh_send_sync entries on cancel Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 334/877] selftests: cgroup: give the O_TMPFILE open in get_temp_fd() a mode Greg Kroah-Hartman
` (551 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, James Houghton, Michal Koutný,
Sean Christopherson, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <seanjc@google.com>
[ Upstream commit 3a7f9e518c6a83d54c84c101e23ffc8aa12df139 ]
Move a handful of helpers out of cgroup_util.c and into test_memcontrol.c
that have nothing to with cgroups in general, in anticipation of making
cgroup_util.c a generic library that can be used by other selftests.
Make read_text() and write_text() non-static so test_memcontrol.c can
use them.
Signed-off-by: James Houghton <jthoughton@google.com>
Acked-by: Michal Koutný <mkoutny@suse.com>
Link: https://lore.kernel.org/r/20250508184649.2576210-4-jthoughton@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
Stable-dep-of: c774ec8f0a5d ("selftests: cgroup: give the O_TMPFILE open in get_temp_fd() a mode")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/cgroup/cgroup_util.c | 82 +------------------
tools/testing/selftests/cgroup/cgroup_util.h | 8 +-
.../selftests/cgroup/test_memcontrol.c | 78 ++++++++++++++++++
3 files changed, 83 insertions(+), 85 deletions(-)
diff --git a/tools/testing/selftests/cgroup/cgroup_util.c b/tools/testing/selftests/cgroup/cgroup_util.c
index 1e2d46636a0ca..0ef3b8b8d7f74 100644
--- a/tools/testing/selftests/cgroup/cgroup_util.c
+++ b/tools/testing/selftests/cgroup/cgroup_util.c
@@ -20,7 +20,7 @@
#include "../clone3/clone3_selftests.h"
/* Returns read len on success, or -errno on failure. */
-static ssize_t read_text(const char *path, char *buf, size_t max_len)
+ssize_t read_text(const char *path, char *buf, size_t max_len)
{
ssize_t len;
int fd;
@@ -39,7 +39,7 @@ static ssize_t read_text(const char *path, char *buf, size_t max_len)
}
/* Returns written len on success, or -errno on failure. */
-static ssize_t write_text(const char *path, char *buf, ssize_t len)
+ssize_t write_text(const char *path, char *buf, ssize_t len)
{
int fd;
@@ -488,84 +488,6 @@ int cg_run_nowait(const char *cgroup,
return pid;
}
-int get_temp_fd(void)
-{
- return open(".", O_TMPFILE | O_RDWR | O_EXCL);
-}
-
-int alloc_pagecache(int fd, size_t size)
-{
- char buf[PAGE_SIZE];
- struct stat st;
- int i;
-
- if (fstat(fd, &st))
- goto cleanup;
-
- size += st.st_size;
-
- if (ftruncate(fd, size))
- goto cleanup;
-
- for (i = 0; i < size; i += sizeof(buf))
- read(fd, buf, sizeof(buf));
-
- return 0;
-
-cleanup:
- return -1;
-}
-
-int alloc_anon(const char *cgroup, void *arg)
-{
- size_t size = (unsigned long)arg;
- char *buf, *ptr;
-
- buf = malloc(size);
- for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
- *ptr = 0;
-
- free(buf);
- return 0;
-}
-
-int is_swap_enabled(void)
-{
- char buf[PAGE_SIZE];
- const char delim[] = "\n";
- int cnt = 0;
- char *line;
-
- if (read_text("/proc/swaps", buf, sizeof(buf)) <= 0)
- return -1;
-
- for (line = strtok(buf, delim); line; line = strtok(NULL, delim))
- cnt++;
-
- return cnt > 1;
-}
-
-int set_oom_adj_score(int pid, int score)
-{
- char path[PATH_MAX];
- int fd, len;
-
- sprintf(path, "/proc/%d/oom_score_adj", pid);
-
- fd = open(path, O_WRONLY | O_APPEND);
- if (fd < 0)
- return fd;
-
- len = dprintf(fd, "%d", score);
- if (len < 0) {
- close(fd);
- return len;
- }
-
- close(fd);
- return 0;
-}
-
int proc_mount_contains(const char *option)
{
char buf[4 * PAGE_SIZE];
diff --git a/tools/testing/selftests/cgroup/cgroup_util.h b/tools/testing/selftests/cgroup/cgroup_util.h
index 19b131ee77072..139c870ecc285 100644
--- a/tools/testing/selftests/cgroup/cgroup_util.h
+++ b/tools/testing/selftests/cgroup/cgroup_util.h
@@ -21,6 +21,9 @@ static inline int values_close(long a, long b, int err)
return labs(a - b) <= (a + b) / 100 * err;
}
+extern ssize_t read_text(const char *path, char *buf, size_t max_len);
+extern ssize_t write_text(const char *path, char *buf, ssize_t len);
+
extern int cg_find_unified_root(char *root, size_t len, bool *nsdelegate);
extern char *cg_name(const char *root, const char *name);
extern char *cg_name_indexed(const char *root, const char *name, int index);
@@ -49,11 +52,6 @@ extern int cg_enter_current_thread(const char *cgroup);
extern int cg_run_nowait(const char *cgroup,
int (*fn)(const char *cgroup, void *arg),
void *arg);
-extern int get_temp_fd(void);
-extern int alloc_pagecache(int fd, size_t size);
-extern int alloc_anon(const char *cgroup, void *arg);
-extern int is_swap_enabled(void);
-extern int set_oom_adj_score(int pid, int score);
extern int cg_wait_for_proc_count(const char *cgroup, int count);
extern int cg_killall(const char *cgroup);
int proc_mount_contains(const char *option);
diff --git a/tools/testing/selftests/cgroup/test_memcontrol.c b/tools/testing/selftests/cgroup/test_memcontrol.c
index 7a44d221b8c4b..44baef99fdb0e 100644
--- a/tools/testing/selftests/cgroup/test_memcontrol.c
+++ b/tools/testing/selftests/cgroup/test_memcontrol.c
@@ -24,6 +24,84 @@
static bool has_localevents;
static bool has_recursiveprot;
+int get_temp_fd(void)
+{
+ return open(".", O_TMPFILE | O_RDWR | O_EXCL);
+}
+
+int alloc_pagecache(int fd, size_t size)
+{
+ char buf[PAGE_SIZE];
+ struct stat st;
+ int i;
+
+ if (fstat(fd, &st))
+ goto cleanup;
+
+ size += st.st_size;
+
+ if (ftruncate(fd, size))
+ goto cleanup;
+
+ for (i = 0; i < size; i += sizeof(buf))
+ read(fd, buf, sizeof(buf));
+
+ return 0;
+
+cleanup:
+ return -1;
+}
+
+int alloc_anon(const char *cgroup, void *arg)
+{
+ size_t size = (unsigned long)arg;
+ char *buf, *ptr;
+
+ buf = malloc(size);
+ for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
+ *ptr = 0;
+
+ free(buf);
+ return 0;
+}
+
+int is_swap_enabled(void)
+{
+ char buf[PAGE_SIZE];
+ const char delim[] = "\n";
+ int cnt = 0;
+ char *line;
+
+ if (read_text("/proc/swaps", buf, sizeof(buf)) <= 0)
+ return -1;
+
+ for (line = strtok(buf, delim); line; line = strtok(NULL, delim))
+ cnt++;
+
+ return cnt > 1;
+}
+
+int set_oom_adj_score(int pid, int score)
+{
+ char path[PATH_MAX];
+ int fd, len;
+
+ sprintf(path, "/proc/%d/oom_score_adj", pid);
+
+ fd = open(path, O_WRONLY | O_APPEND);
+ if (fd < 0)
+ return fd;
+
+ len = dprintf(fd, "%d", score);
+ if (len < 0) {
+ close(fd);
+ return len;
+ }
+
+ close(fd);
+ return 0;
+}
+
/*
* This test creates two nested cgroups with and without enabling
* the memory controller.
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 334/877] selftests: cgroup: give the O_TMPFILE open in get_temp_fd() a mode
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (332 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 333/877] cgroup: selftests: Move memcontrol specific helpers out of common cgroup_util.c Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 335/877] scsi: megaraid_sas: Protect megasas_get_ctrl_info() in megasas_resume() Greg Kroah-Hartman
` (550 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Eva Kurchatova, Tejun Heo,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eva Kurchatova <eva.kurchatova@virtuozzo.com>
[ Upstream commit c774ec8f0a5d02a06d34c27f5a7de7e333b91265 ]
O_TMPFILE, like O_CREAT, needs the third argument. Without it glibc
refuses the call at compile time as soon as fortification is on:
In function 'open',
inlined from 'get_temp_fd' at test_memcontrol.c:33:9:
/usr/include/bits/fcntl2.h:52:11: error: call to '__open_missing_mode'
declared with attribute error: open with O_CREAT or O_TMPFILE in
second argument needs 3 arguments
The fortify checks take effect only once the compiler optimises, and
cgroup/Makefile builds with "-Wall -pthread" alone, so this goes
unnoticed in a plain build. Building the tests with the flags
distributions commonly use, -O2 -D_FORTIFY_SOURCE=3, loses
test_memcontrol entirely.
Fixes: 84092dbcf901 ("selftests: cgroup: add memory controller self-tests")
Signed-off-by: Eva Kurchatova <eva.kurchatova@virtuozzo.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/cgroup/test_memcontrol.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/cgroup/test_memcontrol.c b/tools/testing/selftests/cgroup/test_memcontrol.c
index 44baef99fdb0e..d817aec949fe4 100644
--- a/tools/testing/selftests/cgroup/test_memcontrol.c
+++ b/tools/testing/selftests/cgroup/test_memcontrol.c
@@ -26,7 +26,7 @@ static bool has_recursiveprot;
int get_temp_fd(void)
{
- return open(".", O_TMPFILE | O_RDWR | O_EXCL);
+ return open(".", O_TMPFILE | O_RDWR | O_EXCL, 0600);
}
int alloc_pagecache(int fd, size_t size)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 335/877] scsi: megaraid_sas: Protect megasas_get_ctrl_info() in megasas_resume()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (333 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 334/877] selftests: cgroup: give the O_TMPFILE open in get_temp_fd() a mode Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 336/877] docs: s390/pci: Improve and update PCI documentation Greg Kroah-Hartman
` (549 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kashyap Desai, Sumit Saxena,
Shivasharan S, Chandrakanth patil, Bart Van Assche,
Martin K. Petersen (Oracle), Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <bvanassche@acm.org>
[ Upstream commit 42d1221d321e55afc7bba9109a77aaf5a817c8a3 ]
Protect the megasas_get_ctrl_info() call in megasas_resume() with
instance->reset_mutex using scoped_guard().
megasas_get_ctrl_info() may release and reacquire instance->reset_mutex.
Hence, calling this function without holding instance->reset_mutex is not
safe.
Fixes: c3b10a55abc9 ("scsi: megaraid_sas: Update controller info during resume")
Cc: Kashyap Desai <kashyap.desai@broadcom.com>
Cc: Sumit Saxena <sumit.saxena@broadcom.com>
Cc: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
Cc: Chandrakanth patil <chandrakanth.patil@broadcom.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/f06b5ee432b21cf293f0663e15b64f75a84b9fd5.1788204406.git.bvanassche@acm.org
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/megaraid/megaraid_sas_base.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 8a44e01ebf9b6..04f892832c1d9 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -7873,7 +7873,9 @@ megasas_resume(struct device *dev)
goto fail_init_mfi;
}
- if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS)
+ scoped_guard(mutex, &instance->reset_mutex)
+ rval = megasas_get_ctrl_info(instance);
+ if (rval != DCMD_SUCCESS)
goto fail_init_mfi;
tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 336/877] docs: s390/pci: Improve and update PCI documentation
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (334 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 335/877] scsi: megaraid_sas: Protect megasas_get_ctrl_info() in megasas_resume() Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 337/877] s390/pci/docs: Fix sriov_numvfs attribute name Greg Kroah-Hartman
` (548 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Farhan Ali, Randy Dunlap,
Matthew Rosato, Niklas Schnelle, Gerd Bayer, Vasily Gorbik,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niklas Schnelle <schnelle@linux.ibm.com>
[ Upstream commit 737c4f4a241ca85c597ca2ef1a6f8446bf681ab5 ]
Update the s390 specific PCI documentation to better reflect current
behavior and terms such as the handling of Isolated VFs via commit
25f39d3dcb48 ("s390/pci: Ignore RID for isolated VFs").
Add a descriptions for /sys/firmware/clp/uid_checking which was added
in commit b043a81ce3ee ("s390/pci: Expose firmware provided UID Checking
state in sysfs") but missed documentation.
Similarly add documentation for the fidparm attribute added by commit
99ad39306a62 ("s390/pci: Expose FIDPARM attribute in sysfs") and
add a list of pft values and their names.
Finally improve formatting of the different attribute descriptions by
adding a separating colon.
Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
Acked-by: Randy Dunlap <rdunlap@infradead.org>
Tested-by: Randy Dunlap <rdunlap@infradead.org>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Reviewed-by: Gerd Bayer <gbayer@linux.ibm.com>
Link: https://lore.kernel.org/r/20260407-uid_slot-v8-1-15ae4409d2ce@linux.ibm.com
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Stable-dep-of: 4525a9110495 ("s390/pci/docs: Fix sriov_numvfs attribute name")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/arch/s390/pci.rst | 152 +++++++++++++++++++++-----------
1 file changed, 101 insertions(+), 51 deletions(-)
diff --git a/Documentation/arch/s390/pci.rst b/Documentation/arch/s390/pci.rst
index d5755484d8e75..c3476de4f0327 100644
--- a/Documentation/arch/s390/pci.rst
+++ b/Documentation/arch/s390/pci.rst
@@ -6,6 +6,7 @@ S/390 PCI
Authors:
- Pierre Morel
+ - Niklas Schnelle
Copyright, IBM Corp. 2020
@@ -27,14 +28,16 @@ Command line parameters
debugfs entries
---------------
-The S/390 debug feature (s390dbf) generates views to hold various debug results in sysfs directories of the form:
+The S/390 debug feature (s390dbf) generates views to hold various debug results
+in sysfs directories of the form:
* /sys/kernel/debug/s390dbf/pci_*/
For example:
- /sys/kernel/debug/s390dbf/pci_msg/sprintf
- Holds messages from the processing of PCI events, like machine check handling
+
+ holds messages from the processing of PCI events, like machine check handling
and setting of global functionality, like UID checking.
Change the level of logging to be more or less verbose by piping
@@ -47,87 +50,134 @@ Sysfs entries
Entries specific to zPCI functions and entries that hold zPCI information.
-* /sys/bus/pci/slots/XXXXXXXX
+* /sys/bus/pci/slots/XXXXXXXX:
- The slot entries are set up using the function identifier (FID) of the
- PCI function. The format depicted as XXXXXXXX above is 8 hexadecimal digits
- with 0 padding and lower case hexadecimal digits.
+ The slot entries are set up using the function identifier (FID) of the PCI
+ function as slot name. The format depicted as XXXXXXXX above is 8 hexadecimal
+ digits with 0 padding and lower case hexadecimal digits.
- /sys/bus/pci/slots/XXXXXXXX/power
A physical function that currently supports a virtual function cannot be
powered off until all virtual functions are removed with:
- echo 0 > /sys/bus/pci/devices/XXXX:XX:XX.X/sriov_numvf
+ echo 0 > /sys/bus/pci/devices/DDDD:BB:dd.f/sriov_numvf
-* /sys/bus/pci/devices/XXXX:XX:XX.X/
+* /sys/bus/pci/devices/DDDD:BB:dd.f/:
- - function_id
- A zPCI function identifier that uniquely identifies the function in the Z server.
+ - function_id:
+ The zPCI function identifier (FID) is a 32-bit hexadecimal value that
+ uniquely identifies the PCI function. Unless the hypervisor provides
+ a virtual FID e.g. on KVM this identifier is unique across the machine even
+ between different partitions.
- - function_handle
- Low-level identifier used for a configured PCI function.
- It might be useful for debugging.
+ - function_handle:
+ This 32-bit hexadecimal value is a low-level identifier used for a PCI
+ function. Note that the function handle may be changed and become invalid
+ on PCI events and when enabling/disabling the PCI function.
- - pchid
- Model-dependent location of the I/O adapter.
+ - pchid:
+ This 16-bit hexadecimal value encodes a model-dependent location for
+ the PCI function.
- - pfgid
- PCI function group ID, functions that share identical functionality
+ - pfgid:
+ PCI function group ID; functions that share identical functionality
use a common identifier.
A PCI group defines interrupts, IOMMU, IOTLB, and DMA specifics.
- - vfn
+ - vfn:
The virtual function number, from 1 to N for virtual functions,
0 for physical functions.
- - pft
- The PCI function type
-
- - port
- The port corresponds to the physical port the function is attached to.
- It also gives an indication of the physical function a virtual function
- is attached to.
-
- - uid
- The user identifier (UID) may be defined as part of the machine
- configuration or the z/VM or KVM guest configuration. If the accompanying
- uid_is_unique attribute is 1 the platform guarantees that the UID is unique
- within that instance and no devices with the same UID can be attached
- during the lifetime of the system.
-
- - uid_is_unique
- Indicates whether the user identifier (UID) is guaranteed to be and remain
- unique within this Linux instance.
-
- - pfip/segmentX
+ - pft:
+ The PCI function type is an s390-specific type attribute. It indicates
+ a more general, usage oriented, type than PCI Specification
+ class/vendor/device identifiers. That is PCI functions with the same pft
+ value may be backed by different hardware implementations. At the same time
+ apart from unclassified functions (pft is 0x00) the same pft value
+ generally implies a similar usage model. At the same time the same
+ PCI hardware device may appear with different pft values when in a
+ different usage model. For example NETD and NETH VFs may be implemented
+ by the same PCI hardware device but in NETD the parent Physical Function
+ is user managed while with NETH it is platform managed.
+
+ Currently the following PFT values are defined:
+
+ - 0x00 (UNC): Unclassified
+ - 0x02 (ROCE): RoCE Express
+ - 0x05 (ISM): Internal Shared Memory
+ - 0x0a (ROC2): RoCE Express 2
+ - 0x0b (NVMe): NVMe
+ - 0x0c (NETH): Network Express hybrid
+ - 0x0d (CNW): Cloud Network Adapter
+ - 0x0f (NETD): Network Express direct
+
+ - port:
+ The port is a decimal value corresponding to the physical port the function
+ is attached to. Virtual Functions (VFs) share the port with their parent
+ Physical Function (PF). A value of 0 indicates that the port attribute is
+ not applicable for that PCI function type.
+
+ - uid:
+ The user-defined identifier (UID) for a PCI function is a 32-bit
+ hexadecimal value. It is defined on a per instance basis as part of the
+ partition, KVM guest, or z/VM guest configuration. If UID Checking is
+ enabled the platform ensures that the UID is unique within that instance
+ and no two PCI functions with the same UID will be visible to the instance.
+
+ Independent of this guarantee and unlike the function ID (FID) the UID may
+ be the same in different partitions within the same machine. This allows to
+ create PCI configurations in multiple partitions to be identical in the
+ UID-namespace.
+
+ - uid_is_unique:
+ A 0 or 1 flag indicating whether the user-defined identifier (UID) is
+ guaranteed to be and remain unique within this Linux instance. This
+ platform feature is called UID Checking.
+
+ - pfip/segmentX:
The segments determine the isolation of a function.
They correspond to the physical path to the function.
The more the segments are different, the more the functions are isolated.
+ - fidparm:
+ Contains an 8-bit-per-PCI function parameter field in hexadecimal provided
+ by the platform. The meaning of this field is PCI function type specific.
+ For NETH VFs a value of 0x01 indicates that the function supports
+ promiscuous mode.
+
+* /sys/firmware/clp/uid_checking:
+
+ In addition to the per-device uid_is_unique attribute this presents a
+ global indication of whether UID Checking is enabled. This allows users
+ to check for UID Checking even when no PCI functions are configured.
+
Enumeration and hotplug
=======================
The PCI address consists of four parts: domain, bus, device and function,
-and is of this form: DDDD:BB:dd.f
+and is of this form: DDDD:BB:dd.f.
-* When not using multi-functions (norid is set, or the firmware does not
- support multi-functions):
+* For a PCI function for which the platform does not expose the RID, the
+ pci=norid kernel parameter is used, or a so-called isolated Virtual Function
+ which does have RID information but is used without its parent Physical
+ Function being part of the same PCI configuration:
- There is only one function per domain.
- - The domain is set from the zPCI function's UID as defined during the
- LPAR creation.
+ - The domain is set from the zPCI function's UID if UID Checking is on;
+ otherwise the domain ID is generated dynamically and is not stable
+ across reboots or hot plug.
-* When using multi-functions (norid parameter is not set),
- zPCI functions are addressed differently:
+* For a PCI function for which the platform exposes the RID and which
+ is not an Isolated Virtual Function:
- There is still only one bus per domain.
- - There can be up to 256 functions per bus.
+ - There can be up to 256 PCI functions per bus.
- - The domain part of the address of all functions for
- a multi-Function device is set from the zPCI function's UID as defined
- in the LPAR creation for the function zero.
+ - The domain part of the address of all functions within the same topology is
+ that of the configured PCI function with the lowest devfn within that
+ topology.
- - New functions will only be ready for use after the function zero
- (the function with devfn 0) has been enumerated.
+ - Virtual Functions generated by an SR-IOV capable Physical Function only
+ become visible once SR-IOV is enabled.
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 337/877] s390/pci/docs: Fix sriov_numvfs attribute name
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (335 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 336/877] docs: s390/pci: Improve and update PCI documentation Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 338/877] s390/cio: Fix cio_update_schib() to not cache invalid schib Greg Kroah-Hartman
` (547 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Randy Dunlap,
Heiko Carstens, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
[ Upstream commit 4525a911049543c23885a540a788d13be318a486 ]
The attribute is sriov_numvfs (drivers/pci/iov.c); the document names it
sriov_numvf, which does not exist.
Use sriov_numvfs.
Fixes: de267a7c71ba ("s390/pci: Documentation for zPCI")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/arch/s390/pci.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/arch/s390/pci.rst b/Documentation/arch/s390/pci.rst
index c3476de4f0327..8dc09634163ba 100644
--- a/Documentation/arch/s390/pci.rst
+++ b/Documentation/arch/s390/pci.rst
@@ -60,7 +60,7 @@ Entries specific to zPCI functions and entries that hold zPCI information.
A physical function that currently supports a virtual function cannot be
powered off until all virtual functions are removed with:
- echo 0 > /sys/bus/pci/devices/DDDD:BB:dd.f/sriov_numvf
+ echo 0 > /sys/bus/pci/devices/DDDD:BB:dd.f/sriov_numvfs
* /sys/bus/pci/devices/DDDD:BB:dd.f/:
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 338/877] s390/cio: Fix cio_update_schib() to not cache invalid schib
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (336 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 337/877] s390/pci/docs: Fix sriov_numvfs attribute name Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 339/877] s390/cio: Check pmcw.dnv before pmcw.ena in I/O entry points Greg Kroah-Hartman
` (546 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, William Bezenah, Vineeth Vijayan,
Peter Oberparleiter, Heiko Carstens, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vineeth Vijayan <vneethv@linux.ibm.com>
[ Upstream commit 29d9e5835d89223aa913dcf7b942cc1c148bdd25 ]
When pmcw.dnv is 0, the contents of all SCHIB fields are unpredictable.
Zero sch->schib in that case to prevent subsequent code from making
decisions based on unpredictable data.
Reported-by: William Bezenah <wbezenah@linux.ibm.com>
Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Fixes: 8c58a229688c ("s390/cio: Do not unregister the subchannel based on DNV")
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/s390/cio/cio.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index ad17ab0a93149..700d8d4ba9da8 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -453,7 +453,8 @@ EXPORT_SYMBOL_GPL(cio_commit_config);
/**
* cio_update_schib - Perform stsch and update schib if subchannel is valid.
* @sch: subchannel on which to perform stsch
- * Return zero on success, -ENODEV otherwise.
+ * Return zero on success, -ENODEV if the subchannel is not operational,
+ * -EACCES if the subchannel has no valid device.
*/
int cio_update_schib(struct subchannel *sch)
{
@@ -462,10 +463,12 @@ int cio_update_schib(struct subchannel *sch)
if (stsch(sch->schid, &schib))
return -ENODEV;
- memcpy(&sch->schib, &schib, sizeof(schib));
-
- if (!css_sch_is_valid(&schib))
+ if (!css_sch_is_valid(&schib)) {
+ memset(&sch->schib, 0, sizeof(sch->schib));
return -EACCES;
+ }
+
+ memcpy(&sch->schib, &schib, sizeof(schib));
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 339/877] s390/cio: Check pmcw.dnv before pmcw.ena in I/O entry points
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (337 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 338/877] s390/cio: Fix cio_update_schib() to not cache invalid schib Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 340/877] s390/cio: Guard PMCW field accesses with dnv check Greg Kroah-Hartman
` (545 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, William Bezenah, Vineeth Vijayan,
Peter Oberparleiter, Heiko Carstens, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vineeth Vijayan <vneethv@linux.ibm.com>
[ Upstream commit f6f2985eabdb2bfdc82ce90a1ea3ec53ba795f34 ]
The device number valid (dnv) bit in the PMCW must be checked before
acting on any other PMCW fields for IO-type subchannels. A subchannel
with dnv=0 has no valid device number associated, making it meaningless
to evaluate the enabled (ena) state or issue any I/O instruction against
it.
Reported-by: William Bezenah <wbezenah@linux.ibm.com>
Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Fixes: 8c58a229688c ("s390/cio: Do not unregister the subchannel based on DNV")
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/s390/cio/device_ops.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index acd6790dba4dd..c0289b81a0d71 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -142,6 +142,8 @@ int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)
if (!cdev || !cdev->dev.parent)
return -ENODEV;
sch = to_subchannel(cdev->dev.parent);
+ if (!sch->schib.pmcw.dnv)
+ return -ENODEV;
if (!sch->schib.pmcw.ena)
return -EINVAL;
if (cdev->private->state == DEV_STATE_NOT_OPER)
@@ -198,6 +200,8 @@ int ccw_device_start_timeout_key(struct ccw_device *cdev, struct ccw1 *cpa,
if (!cdev || !cdev->dev.parent)
return -ENODEV;
sch = to_subchannel(cdev->dev.parent);
+ if (!sch->schib.pmcw.dnv)
+ return -ENODEV;
if (!sch->schib.pmcw.ena)
return -EINVAL;
if (cdev->private->state == DEV_STATE_NOT_OPER)
@@ -379,6 +383,8 @@ int ccw_device_halt(struct ccw_device *cdev, unsigned long intparm)
if (!cdev || !cdev->dev.parent)
return -ENODEV;
sch = to_subchannel(cdev->dev.parent);
+ if (!sch->schib.pmcw.dnv)
+ return -ENODEV;
if (!sch->schib.pmcw.ena)
return -EINVAL;
if (cdev->private->state == DEV_STATE_NOT_OPER)
@@ -413,6 +419,8 @@ int ccw_device_resume(struct ccw_device *cdev)
if (!cdev || !cdev->dev.parent)
return -ENODEV;
sch = to_subchannel(cdev->dev.parent);
+ if (!sch->schib.pmcw.dnv)
+ return -ENODEV;
if (!sch->schib.pmcw.ena)
return -EINVAL;
if (cdev->private->state == DEV_STATE_NOT_OPER)
@@ -548,6 +556,8 @@ int ccw_device_tm_start_timeout_key(struct ccw_device *cdev, struct tcw *tcw,
int rc;
sch = to_subchannel(cdev->dev.parent);
+ if (!sch->schib.pmcw.dnv)
+ return -ENODEV;
if (!sch->schib.pmcw.ena)
return -EINVAL;
if (cdev->private->state == DEV_STATE_VERIFY) {
@@ -694,6 +704,8 @@ int ccw_device_tm_intrg(struct ccw_device *cdev)
{
struct subchannel *sch = to_subchannel(cdev->dev.parent);
+ if (!sch->schib.pmcw.dnv)
+ return -ENODEV;
if (!sch->schib.pmcw.ena)
return -EINVAL;
if (cdev->private->state != DEV_STATE_ONLINE)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 340/877] s390/cio: Guard PMCW field accesses with dnv check
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (338 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 339/877] s390/cio: Check pmcw.dnv before pmcw.ena in I/O entry points Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 341/877] fs: avoid repeated scans in evict_inodes() Greg Kroah-Hartman
` (544 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, William Bezenah, Vineeth Vijayan,
Peter Oberparleiter, Heiko Carstens, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vineeth Vijayan <vneethv@linux.ibm.com>
[ Upstream commit 9590f4d83880dfb5a81906e48e72779248fbe8f0 ]
When PMCW.DNV is 0, no I/O device is associated with the subchannel.
However, several code paths access PMCW fields directly from the cached
sch->schib without first invoking the update helper. Add explicit DNV
validation before accessing PMCW fields from the cached SCHIB to avoid
using invalid data.
Reported-by: William Bezenah <wbezenah@linux.ibm.com>
Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Fixes: 8c58a229688c ("s390/cio: Do not unregister the subchannel based on DNV")
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/s390/cio/chp.c | 3 +++
drivers/s390/cio/device.c | 9 +++++----
drivers/s390/cio/device_fsm.c | 3 +++
drivers/s390/cio/device_ops.c | 9 +++++++++
drivers/s390/cio/vfio_ccw_fsm.c | 2 +-
5 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c
index 0c5bda060249e..b6ef882f98607 100644
--- a/drivers/s390/cio/chp.c
+++ b/drivers/s390/cio/chp.c
@@ -78,6 +78,9 @@ u8 chp_get_sch_opm(struct subchannel *sch)
int opm;
int i;
+ if (!sch->schib.pmcw.dnv)
+ return 0;
+
opm = 0;
chp_id_init(&chpid);
for (i = 0; i < 8; i++) {
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 7e309ea2e177c..b6e2839dfeb37 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -925,7 +925,7 @@ static int ccw_device_move_to_sch(struct ccw_device *cdev,
if (!sch_is_pseudo_sch(old_sch)) {
spin_lock_irq(&old_sch->lock);
- old_enabled = old_sch->schib.pmcw.ena;
+ old_enabled = old_sch->schib.pmcw.dnv && old_sch->schib.pmcw.ena;
rc = 0;
if (old_enabled)
rc = cio_disable_subchannel(old_sch);
@@ -944,7 +944,7 @@ static int ccw_device_move_to_sch(struct ccw_device *cdev,
CIO_MSG_EVENT(0, "device_move(0.%x.%04x,0.%x.%04x)=%d\n",
cdev->private->dev_id.ssid,
cdev->private->dev_id.devno, sch->schid.ssid,
- sch->schib.pmcw.dev, rc);
+ sch->schid.sch_no, rc);
if (old_enabled) {
/* Try to re-enable the old subchannel. */
spin_lock_irq(&old_sch->lock);
@@ -1210,7 +1210,7 @@ static void io_subchannel_quiesce(struct subchannel *sch)
cdev = sch_get_cdev(sch);
if (cio_is_console(sch->schid))
goto out_unlock;
- if (!sch->schib.pmcw.ena)
+ if (!sch->schib.pmcw.dnv || !sch->schib.pmcw.ena)
goto out_unlock;
ret = cio_disable_subchannel(sch);
if (ret != -EBUSY)
@@ -1257,7 +1257,8 @@ static int recovery_check(struct device *dev, void *data)
switch (cdev->private->state) {
case DEV_STATE_ONLINE:
sch = to_subchannel(cdev->dev.parent);
- if ((sch->schib.pmcw.pam & sch->opm) == sch->vpm)
+ if (sch->schib.pmcw.dnv &&
+ (sch->schib.pmcw.pam & sch->opm) == sch->vpm)
break;
fallthrough;
case DEV_STATE_DISCONNECTED:
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 42791fa0b80e2..96bab4cde37a2 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -169,6 +169,9 @@ __recover_lost_chpids(struct subchannel *sch, int old_lpm)
int mask, i;
struct chp_id chpid;
+ if (!sch->schib.pmcw.dnv)
+ return;
+
chp_id_init(&chpid);
for (i = 0; i<8; i++) {
mask = 0x80 >> i;
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index c0289b81a0d71..8fe3ff4f0855d 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -490,6 +490,8 @@ struct channel_path_desc_fmt0 *ccw_device_get_chp_desc(struct ccw_device *cdev,
struct chp_id chpid;
sch = to_subchannel(cdev->dev.parent);
+ if (!sch->schib.pmcw.dnv)
+ return NULL;
chp_id_init(&chpid);
chpid.id = sch->schib.pmcw.chpid[chp_idx];
return chp_get_chp_desc(chpid);
@@ -510,6 +512,8 @@ u8 *ccw_device_get_util_str(struct ccw_device *cdev, int chp_idx)
struct chp_id chpid;
u8 *util_str;
+ if (!sch->schib.pmcw.dnv)
+ return NULL;
chp_id_init(&chpid);
chpid.id = sch->schib.pmcw.chpid[chp_idx];
chp = chpid_to_chp(chpid);
@@ -662,6 +666,9 @@ int ccw_device_get_mdc(struct ccw_device *cdev, u8 mask)
struct chp_id chpid;
int mdc = 0, i;
+ if (!sch->schib.pmcw.dnv)
+ return 0;
+
/* Adjust requested path mask to excluded varied off paths. */
if (mask)
mask &= sch->lpm;
@@ -798,6 +805,8 @@ int ccw_device_get_chpid(struct ccw_device *cdev, int chp_idx, u8 *chpid)
if ((chp_idx < 0) || (chp_idx > 7))
return -EINVAL;
+ if (!sch->schib.pmcw.dnv)
+ return -ENODEV;
mask = 0x80 >> chp_idx;
if (!(sch->schib.pmcw.pim & mask))
return -ENODEV;
diff --git a/drivers/s390/cio/vfio_ccw_fsm.c b/drivers/s390/cio/vfio_ccw_fsm.c
index 5fd94e9d5c618..9a000b0231d60 100644
--- a/drivers/s390/cio/vfio_ccw_fsm.c
+++ b/drivers/s390/cio/vfio_ccw_fsm.c
@@ -399,7 +399,7 @@ static void fsm_close(struct vfio_ccw_private *private,
spin_lock_irq(&sch->lock);
- if (!sch->schib.pmcw.ena)
+ if (!sch->schib.pmcw.dnv || !sch->schib.pmcw.ena)
goto err_unlock;
ret = cio_disable_subchannel(sch);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 341/877] fs: avoid repeated scans in evict_inodes()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (339 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 340/877] s390/cio: Guard PMCW field accesses with dnv check Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-10-01 19:58 ` Harshit Mogalapalli
2026-09-30 15:20 ` [PATCH 6.12 342/877] xsk: Use a 32-bit compare in xsk_map_gen_lookup Greg Kroah-Hartman
` (543 subsequent siblings)
884 siblings, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Julian Sun, Jan Kara,
Christian Brauner (Amutable), Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Julian Sun <sunjunchao@bytedance.com>
[ Upstream commit 7459c021874246c196f397686e100702f059b9e7 ]
We observed hung tasks when users attempted to unmount a filesystem
after its disk had been removed while still in use. During device
removal, fs_bdev_mark_dead() calls evict_inodes() while holding s_umount.
Each time evict_inodes() drops s_inode_list_lock to reschedule, it
restarts the walk from the head of s_inodes. With many referenced inodes
at the head of the list, these restarts repeatedly scan the same inodes
without reclaiming them. This can keep s_umount held for a long time,
blocking concurrent umount attempts and triggering hung-task reports.
Keep the current inode, already marked I_FREEING, out of the disposal
batch until s_inode_list_lock is reacquired. Resume the walk from this
inode and dispose of it in a later batch or at the end of the walk.
The zero-refcount and state checks under i_lock allow this walker to
claim the inode by setting I_FREEING and removing it from the LRU.
Other reclaimers skip the inode, leaving this walker responsible for
eviction. Only evict() removes it from s_inodes, so keeping it out of
the disposal batch ensures that it remains on the list while the lock
is dropped. After reacquiring the lock, reading its current next pointer
accounts for concurrent removal of following inodes.
The existing inode lifetime rules prohibit acquiring a reference to an
inode marked I_FREEING or I_WILL_FREE. __iget() requires its caller to
hold i_lock and establish that taking a reference is valid. Inode lookup
and igrab() check these flags under i_lock when acquiring a reference
from zero. ihold() requires an existing reference, which would keep
i_count nonzero and prevent this walker from claiming the inode. These
rules already allow iput_final() and the inode shrinker to release
i_lock after setting I_FREEING and before eviction completes.
A temporary __iget() reference would also keep the inode on the list,
but its release must preserve last-reference handling. Another user can
acquire a reference, update lazy timestamps and drop its reference while
the pin is held. If the pin becomes the last reference, dropping it with
atomic_dec_and_test() and evicting directly bypasses iput()'s lazytime
handling and can lose those timestamp updates.
Releasing the pin with iput() preserves that handling, but does not
guarantee eviction. fs_bdev_mark_dead() runs with SB_ACTIVE set, so iput()
may retain the inode in cache, whereas evict_inodes() must evict eligible
zero-reference inodes. The inode may also have been freed when iput()
returns, so the walker cannot then use it to force eviction. Using
I_FREEING preserves the existing eviction behavior without introducing
an additional last-reference transition.
The xfstests auto group passed on ext4 and XFS with known unrelated
failures excluded. No new issues were observed, and the previously
reproducible hung task no longer occurs with this patch.
Fixes: ac05fbb40062 ("inode: don't softlockup when evicting inodes")
Signed-off-by: Julian Sun <sunjunchao@bytedance.com>
Link: https://patch.msgid.link/20260915044912.3183440-1-sunjunchao@bytedance.com
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/inode.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/fs/inode.c b/fs/inode.c
index 8dabb224f941c..8592fd1a18526 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -790,7 +790,6 @@ void evict_inodes(struct super_block *sb)
struct inode *inode, *next;
LIST_HEAD(dispose);
-again:
spin_lock(&sb->s_inode_list_lock);
list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) {
if (atomic_read(&inode->i_count))
@@ -809,19 +808,19 @@ void evict_inodes(struct super_block *sb)
inode->i_state |= I_FREEING;
inode_lru_list_del(inode);
spin_unlock(&inode->i_lock);
- list_add(&inode->i_lru, &dispose);
/*
- * We can have a ton of inodes to evict at unmount time given
- * enough memory, check to see if we need to go to sleep for a
- * bit so we don't livelock.
+ * Keep this inode out of dispose so it stays on s_inodes while
+ * the list lock is dropped. I_FREEING prevents new references
+ * and leaves eviction to us, so we can resume the walk from it.
*/
if (need_resched()) {
spin_unlock(&sb->s_inode_list_lock);
cond_resched();
dispose_list(&dispose);
- goto again;
+ spin_lock(&sb->s_inode_list_lock);
}
+ list_add(&inode->i_lru, &dispose);
}
spin_unlock(&sb->s_inode_list_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 341/877] fs: avoid repeated scans in evict_inodes()
2026-09-30 15:20 ` [PATCH 6.12 341/877] fs: avoid repeated scans in evict_inodes() Greg Kroah-Hartman
@ 2026-10-01 19:58 ` Harshit Mogalapalli
2026-10-02 12:09 ` Greg Kroah-Hartman
0 siblings, 1 reply; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-01 19:58 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, Julian Sun, Jan Kara, Christian Brauner (Amutable),
Sasha Levin
On 30/09/26 8:50 pm, Greg Kroah-Hartman wrote:
> 6.12-stable review patch. If anyone has any objections, please let me know.
>
> ------------------
>
> From: Julian Sun <sunjunchao@bytedance.com>
>
> [ Upstream commit 7459c021874246c196f397686e100702f059b9e7 ]
>
> We observed hung tasks when users attempted to unmount a filesystem
> after its disk had been removed while still in use. During device
> removal, fs_bdev_mark_dead() calls evict_inodes() while holding s_umount.
>
> Each time evict_inodes() drops s_inode_list_lock to reschedule, it
> restarts the walk from the head of s_inodes. With many referenced inodes
> at the head of the list, these restarts repeatedly scan the same inodes
> without reclaiming them. This can keep s_umount held for a long time,
> blocking concurrent umount attempts and triggering hung-task reports.
>
> Keep the current inode, already marked I_FREEING, out of the disposal
> batch until s_inode_list_lock is reacquired. Resume the walk from this
> inode and dispose of it in a later batch or at the end of the walk.
>
> The zero-refcount and state checks under i_lock allow this walker to
> claim the inode by setting I_FREEING and removing it from the LRU.
> Other reclaimers skip the inode, leaving this walker responsible for
> eviction. Only evict() removes it from s_inodes, so keeping it out of
> the disposal batch ensures that it remains on the list while the lock
> is dropped. After reacquiring the lock, reading its current next pointer
> accounts for concurrent removal of following inodes.
>
> The existing inode lifetime rules prohibit acquiring a reference to an
> inode marked I_FREEING or I_WILL_FREE. __iget() requires its caller to
> hold i_lock and establish that taking a reference is valid. Inode lookup
> and igrab() check these flags under i_lock when acquiring a reference
> from zero. ihold() requires an existing reference, which would keep
> i_count nonzero and prevent this walker from claiming the inode. These
> rules already allow iput_final() and the inode shrinker to release
> i_lock after setting I_FREEING and before eviction completes.
>
> A temporary __iget() reference would also keep the inode on the list,
> but its release must preserve last-reference handling. Another user can
> acquire a reference, update lazy timestamps and drop its reference while
> the pin is held. If the pin becomes the last reference, dropping it with
> atomic_dec_and_test() and evicting directly bypasses iput()'s lazytime
> handling and can lose those timestamp updates.
>
> Releasing the pin with iput() preserves that handling, but does not
> guarantee eviction. fs_bdev_mark_dead() runs with SB_ACTIVE set, so iput()
> may retain the inode in cache, whereas evict_inodes() must evict eligible
> zero-reference inodes. The inode may also have been freed when iput()
> returns, so the walker cannot then use it to force eviction. Using
> I_FREEING preserves the existing eviction behavior without introducing
> an additional last-reference transition.
>
> The xfstests auto group passed on ext4 and XFS with known unrelated
> failures excluded. No new issues were observed, and the previously
> reproducible hung task no longer occurs with this patch.
>
> Fixes: ac05fbb40062 ("inode: don't softlockup when evicting inodes")
> Signed-off-by: Julian Sun <sunjunchao@bytedance.com>
> Link: https://patch.msgid.link/20260915044912.3183440-1-sunjunchao@bytedance.com
> Reviewed-by: Jan Kara <jack@suse.cz>
> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
> Signed-off-by: Sasha Levin <sashal@kernel.org>
Hi Greg/Sasha,
An AI assisted backport review flagged this, and I checked the upstream
code against the 6.12.y tip f4ffa8dc360b.
Upstream 7459c0218742 uses the current inode's successor after
relocking:
struct inode *inode;
LIST_HEAD(dispose);
spin_lock(&sb->s_inode_list_lock);
list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
/* ... intervening source omitted ... */
if (need_resched()) {
spin_unlock(&sb->s_inode_list_lock);
cond_resched();
dispose_list(&dispose);
spin_lock(&sb->s_inode_list_lock);
}
list_add(&inode->i_lru, &dispose);
6.12.y retains the cached-successor iterator:
struct inode *inode, *next;
LIST_HEAD(dispose);
spin_lock(&sb->s_inode_list_lock);
list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) {
/* ... intervening source omitted ... */
if (need_resched()) {
spin_unlock(&sb->s_inode_list_lock);
cond_resched();
dispose_list(&dispose);
spin_lock(&sb->s_inode_list_lock);
}
list_add(&inode->i_lru, &dispose);
I_FREEING protects inode, but the safe iterator's cached next can be
detached or freed while the lock is dropped. The 6.12's
invalidate_inodes() differs from upstream's disk-removal trigger.
I think 6.12.y needs the two-line iterator change from
3bc4e4410830d556b0f40dfa6671bfcaeacc1599 ("vfs: Remove unnecessary
list_for_each_entry_safe() from evict_inodes()") before this backport,
thoughts?
thanks,
Harshit
> ---
> fs/inode.c | 11 +++++------
> 1 file changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/fs/inode.c b/fs/inode.c
> index 8dabb224f941c..8592fd1a18526 100644
> --- a/fs/inode.c
> +++ b/fs/inode.c
> @@ -790,7 +790,6 @@ void evict_inodes(struct super_block *sb)
> struct inode *inode, *next;
> LIST_HEAD(dispose);
>
> -again:
> spin_lock(&sb->s_inode_list_lock);
> list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) {
> if (atomic_read(&inode->i_count))
> @@ -809,19 +808,19 @@ void evict_inodes(struct super_block *sb)
> inode->i_state |= I_FREEING;
> inode_lru_list_del(inode);
> spin_unlock(&inode->i_lock);
> - list_add(&inode->i_lru, &dispose);
>
> /*
> - * We can have a ton of inodes to evict at unmount time given
> - * enough memory, check to see if we need to go to sleep for a
> - * bit so we don't livelock.
> + * Keep this inode out of dispose so it stays on s_inodes while
> + * the list lock is dropped. I_FREEING prevents new references
> + * and leaves eviction to us, so we can resume the walk from it.
> */
> if (need_resched()) {
> spin_unlock(&sb->s_inode_list_lock);
> cond_resched();
> dispose_list(&dispose);
> - goto again;
> + spin_lock(&sb->s_inode_list_lock);
> }
> + list_add(&inode->i_lru, &dispose);
> }
> spin_unlock(&sb->s_inode_list_lock);
>
^ permalink raw reply [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 341/877] fs: avoid repeated scans in evict_inodes()
2026-10-01 19:58 ` Harshit Mogalapalli
@ 2026-10-02 12:09 ` Greg Kroah-Hartman
2026-10-02 20:47 ` Harshit Mogalapalli
0 siblings, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-02 12:09 UTC (permalink / raw)
To: Harshit Mogalapalli
Cc: stable, patches, Julian Sun, Jan Kara,
Christian Brauner (Amutable), Sasha Levin
On Fri, Oct 02, 2026 at 01:28:39AM +0530, Harshit Mogalapalli wrote:
>
>
> On 30/09/26 8:50 pm, Greg Kroah-Hartman wrote:
> > 6.12-stable review patch. If anyone has any objections, please let me know.
> >
> > ------------------
> >
> > From: Julian Sun <sunjunchao@bytedance.com>
> >
> > [ Upstream commit 7459c021874246c196f397686e100702f059b9e7 ]
> >
> > We observed hung tasks when users attempted to unmount a filesystem
> > after its disk had been removed while still in use. During device
> > removal, fs_bdev_mark_dead() calls evict_inodes() while holding s_umount.
> >
> > Each time evict_inodes() drops s_inode_list_lock to reschedule, it
> > restarts the walk from the head of s_inodes. With many referenced inodes
> > at the head of the list, these restarts repeatedly scan the same inodes
> > without reclaiming them. This can keep s_umount held for a long time,
> > blocking concurrent umount attempts and triggering hung-task reports.
> >
> > Keep the current inode, already marked I_FREEING, out of the disposal
> > batch until s_inode_list_lock is reacquired. Resume the walk from this
> > inode and dispose of it in a later batch or at the end of the walk.
> >
> > The zero-refcount and state checks under i_lock allow this walker to
> > claim the inode by setting I_FREEING and removing it from the LRU.
> > Other reclaimers skip the inode, leaving this walker responsible for
> > eviction. Only evict() removes it from s_inodes, so keeping it out of
> > the disposal batch ensures that it remains on the list while the lock
> > is dropped. After reacquiring the lock, reading its current next pointer
> > accounts for concurrent removal of following inodes.
> >
> > The existing inode lifetime rules prohibit acquiring a reference to an
> > inode marked I_FREEING or I_WILL_FREE. __iget() requires its caller to
> > hold i_lock and establish that taking a reference is valid. Inode lookup
> > and igrab() check these flags under i_lock when acquiring a reference
> > from zero. ihold() requires an existing reference, which would keep
> > i_count nonzero and prevent this walker from claiming the inode. These
> > rules already allow iput_final() and the inode shrinker to release
> > i_lock after setting I_FREEING and before eviction completes.
> >
> > A temporary __iget() reference would also keep the inode on the list,
> > but its release must preserve last-reference handling. Another user can
> > acquire a reference, update lazy timestamps and drop its reference while
> > the pin is held. If the pin becomes the last reference, dropping it with
> > atomic_dec_and_test() and evicting directly bypasses iput()'s lazytime
> > handling and can lose those timestamp updates.
> >
> > Releasing the pin with iput() preserves that handling, but does not
> > guarantee eviction. fs_bdev_mark_dead() runs with SB_ACTIVE set, so iput()
> > may retain the inode in cache, whereas evict_inodes() must evict eligible
> > zero-reference inodes. The inode may also have been freed when iput()
> > returns, so the walker cannot then use it to force eviction. Using
> > I_FREEING preserves the existing eviction behavior without introducing
> > an additional last-reference transition.
> >
> > The xfstests auto group passed on ext4 and XFS with known unrelated
> > failures excluded. No new issues were observed, and the previously
> > reproducible hung task no longer occurs with this patch.
> >
> > Fixes: ac05fbb40062 ("inode: don't softlockup when evicting inodes")
> > Signed-off-by: Julian Sun <sunjunchao@bytedance.com>
> > Link: https://patch.msgid.link/20260915044912.3183440-1-sunjunchao@bytedance.com
> > Reviewed-by: Jan Kara <jack@suse.cz>
> > Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
> > Signed-off-by: Sasha Levin <sashal@kernel.org>
>
> Hi Greg/Sasha,
>
> An AI assisted backport review flagged this, and I checked the upstream
> code against the 6.12.y tip f4ffa8dc360b.
>
> Upstream 7459c0218742 uses the current inode's successor after
> relocking:
>
> struct inode *inode;
> LIST_HEAD(dispose);
>
> spin_lock(&sb->s_inode_list_lock);
> list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
> /* ... intervening source omitted ... */
> if (need_resched()) {
> spin_unlock(&sb->s_inode_list_lock);
> cond_resched();
> dispose_list(&dispose);
> spin_lock(&sb->s_inode_list_lock);
> }
> list_add(&inode->i_lru, &dispose);
>
> 6.12.y retains the cached-successor iterator:
>
> struct inode *inode, *next;
> LIST_HEAD(dispose);
>
> spin_lock(&sb->s_inode_list_lock);
> list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) {
> /* ... intervening source omitted ... */
> if (need_resched()) {
> spin_unlock(&sb->s_inode_list_lock);
> cond_resched();
> dispose_list(&dispose);
> spin_lock(&sb->s_inode_list_lock);
> }
> list_add(&inode->i_lru, &dispose);
>
> I_FREEING protects inode, but the safe iterator's cached next can be
> detached or freed while the lock is dropped. The 6.12's invalidate_inodes()
> differs from upstream's disk-removal trigger.
>
> I think 6.12.y needs the two-line iterator change from
> 3bc4e4410830d556b0f40dfa6671bfcaeacc1599 ("vfs: Remove unnecessary
> list_for_each_entry_safe() from evict_inodes()") before this backport,
> thoughts?
If it's needed, it needs to be backported here and to older stable
kernels, and it needs a manual backport as it doesn't apply cleanly.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 341/877] fs: avoid repeated scans in evict_inodes()
2026-10-02 12:09 ` Greg Kroah-Hartman
@ 2026-10-02 20:47 ` Harshit Mogalapalli
2026-10-03 1:30 ` Sasha Levin
0 siblings, 1 reply; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-02 20:47 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: stable, patches, Julian Sun, Jan Kara,
Christian Brauner (Amutable), Sasha Levin
Hi Greg,
>>
>> Hi Greg/Sasha,
>>
>> An AI assisted backport review flagged this, and I checked the upstream
>> code against the 6.12.y tip f4ffa8dc360b.
>>
>> Upstream 7459c0218742 uses the current inode's successor after
>> relocking:
>>
>> struct inode *inode;
>> LIST_HEAD(dispose);
>>
>> spin_lock(&sb->s_inode_list_lock);
>> list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
>> /* ... intervening source omitted ... */
>> if (need_resched()) {
>> spin_unlock(&sb->s_inode_list_lock);
>> cond_resched();
>> dispose_list(&dispose);
>> spin_lock(&sb->s_inode_list_lock);
>> }
>> list_add(&inode->i_lru, &dispose);
>>
>> 6.12.y retains the cached-successor iterator:
>>
>> struct inode *inode, *next;
>> LIST_HEAD(dispose);
>>
>> spin_lock(&sb->s_inode_list_lock);
>> list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) {
>> /* ... intervening source omitted ... */
>> if (need_resched()) {
>> spin_unlock(&sb->s_inode_list_lock);
>> cond_resched();
>> dispose_list(&dispose);
>> spin_lock(&sb->s_inode_list_lock);
>> }
>> list_add(&inode->i_lru, &dispose);
>>
>> I_FREEING protects inode, but the safe iterator's cached next can be
>> detached or freed while the lock is dropped. The 6.12's invalidate_inodes()
>> differs from upstream's disk-removal trigger.
>>
>> I think 6.12.y needs the two-line iterator change from
>> 3bc4e4410830d556b0f40dfa6671bfcaeacc1599 ("vfs: Remove unnecessary
>> list_for_each_entry_safe() from evict_inodes()") before this backport,
>> thoughts?
>
> If it's needed, it needs to be backported here and to older stable
> kernels, and it needs a manual backport as it doesn't apply cleanly.
>
Please drop this stable backport.
They retain:
list_for_each_entry_safe(inode, next, &sb->s_inodes,
i_sb_list) {
...
spin_unlock(&sb->s_inode_list_lock);
dispose_list(&dispose);
spin_lock(&sb->s_inode_list_lock);
}
The safe iterator cached next before the unlock. A concurrent final
iput() can remove and free next while the lock is dropped. The loop
then dereferences that freed inode:
inode = next;
next = list_next_entry(next, i_sb_list);
I_FREEING protects only inode, not next. This creates a use-after-free
risk that can cause a crash or memory corruption.
3bc4e4410830 changes the walk to:
list_for_each_entry(inode, &sb->s_inodes, i_sb_list)
This reads inode's updated successor after relocking. So until we take
both the backport and its prereq together I think we better drop this.
thanks,
Harshit
> thanks,
>
> greg k-h
>
^ permalink raw reply [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 341/877] fs: avoid repeated scans in evict_inodes()
2026-10-02 20:47 ` Harshit Mogalapalli
@ 2026-10-03 1:30 ` Sasha Levin
0 siblings, 0 replies; 922+ messages in thread
From: Sasha Levin @ 2026-10-03 1:30 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Sasha Levin, stable, patches, Julian Sun, Jan Kara,
Christian Brauner (Amutable), Harshit Mogalapalli
> Please drop this stable backport.
Dropped from the 6.12, 6.6, 6.1, 5.15 and 5.10 queues, thanks.
It stays in 7.2 and 6.18: their bases already have 3bc4e4410830
("vfs: Remove unnecessary list_for_each_entry_safe() from
evict_inodes()"), so evict_inodes() there already walks the list with
list_for_each_entry().
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 922+ messages in thread
* [PATCH 6.12 342/877] xsk: Use a 32-bit compare in xsk_map_gen_lookup
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (340 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 341/877] fs: avoid repeated scans in evict_inodes() Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 343/877] bpf: Skip unsettled links in link iterator Greg Kroah-Hartman
` (542 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Zhiling Zou,
Alexei Starovoitov, Emil Tsalapatis, Eduard Zingerman,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhiling Zou <zhilinz@nebusec.ai>
[ Upstream commit 70504de0bb627848667207bec7ccfd647deb8814 ]
xsk_map_gen_lookup() loads a u32 key and compares it with max_entries
using BPF_JMP_IMM. BPF immediates are sign-extended to 64 bits, so a
max_entries value of 0x80000000 or higher becomes a threshold larger
than every zero-extended 32-bit key. An out-of-range index then skips
the bounds check and the generated lookup reads past xsk_map[].
Compare with BPF_JMP32_IMM so the check stays in 32-bit unsigned range.
Fixes: e65650f291ee ("bpf: Implement map_gen_lookup() callback for XSKMAP")
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Link: https://patch.msgid.link/7d2cb8e8dfaa9eb8fdff85156987a60960787dc3.1789056660.git.zhilinz@nebusec.ai
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/xdp/xskmap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/xdp/xskmap.c b/net/xdp/xskmap.c
index afa457506274c..607f8b7e16d96 100644
--- a/net/xdp/xskmap.c
+++ b/net/xdp/xskmap.c
@@ -124,7 +124,7 @@ static int xsk_map_gen_lookup(struct bpf_map *map, struct bpf_insn *insn_buf)
struct bpf_insn *insn = insn_buf;
*insn++ = BPF_LDX_MEM(BPF_W, ret, index, 0);
- *insn++ = BPF_JMP_IMM(BPF_JGE, ret, map->max_entries, 5);
+ *insn++ = BPF_JMP32_IMM(BPF_JGE, ret, map->max_entries, 5);
*insn++ = BPF_ALU64_IMM(BPF_LSH, ret, ilog2(sizeof(struct xsk_sock *)));
*insn++ = BPF_ALU64_IMM(BPF_ADD, mp, offsetof(struct xsk_map, xsk_map));
*insn++ = BPF_ALU64_REG(BPF_ADD, ret, mp);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 343/877] bpf: Skip unsettled links in link iterator
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (341 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 342/877] xsk: Use a 32-bit compare in xsk_map_gen_lookup Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 344/877] net/sched: cls_u32: fix manual hash table handle IDR aliasing Greg Kroah-Hartman
` (541 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xiang Mei, Weiming Shi,
Andrii Nakryiko, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <bestswngs@gmail.com>
[ Upstream commit 50e80e2bb5e2be8515205b9c496b9640ddefa434 ]
bpf_link_prime() inserts a link into link_idr before anon_inode_getfile()
succeeds and before bpf_link_settle() publishes the ID in link->id.
bpf_link_by_id() treats such an ID-zero link as unsettled, but the link
iterator takes a reference without this check.
If anon_inode_getfile() then fails, the creator removes the ID and frees
its still-private link directly. The iterator is left with a dangling
reference and its next bpf_link_put() accesses freed memory.
Treat ID-zero entries as transient in bpf_link_get_curr_or_next(), just as
bpf_link_by_id() does.
BUG: KASAN: slab-use-after-free in bpf_link_put
Write of size 8 by task exp/384
Call Trace:
bpf_link_put kernel/bpf/syscall.c:3372
bpf_link_seq_next kernel/bpf/link_iter.c:33
bpf_seq_read kernel/bpf/bpf_iter.c:158
vfs_read fs/read_write.c:572
ksys_read fs/read_write.c:716
do_syscall_64 arch/x86/entry/syscall_64.c:84
entry_SYSCALL_64_after_hwframe arch/x86/entry/entry_64.S:121
Kernel panic - not syncing: KASAN: panic_on_warn set ...
Fixes: 9f8836127308 ("bpf: Add bpf_link iterator")
Reported-by: Xiang Mei <xmei5@asu.edu>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20260914170206.170723-2-bestswngs@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/syscall.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 954b299f241b6..857285a48d433 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -5472,7 +5472,10 @@ struct bpf_link *bpf_link_get_curr_or_next(u32 *id)
again:
link = idr_get_next(&link_idr, id);
if (link) {
- link = bpf_link_inc_not_zero(link);
+ if (link->id)
+ link = bpf_link_inc_not_zero(link);
+ else
+ link = ERR_PTR(-EAGAIN);
if (IS_ERR(link)) {
(*id)++;
goto again;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 344/877] net/sched: cls_u32: fix manual hash table handle IDR aliasing
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (342 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 343/877] bpf: Skip unsettled links in link iterator Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 345/877] net/mlx5: devcom, Base component size on linked devices Greg Kroah-Hartman
` (540 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko (gemini + nipa),
Victor Nogueira, hybris, Jamal Hadi Salim, Simon Horman,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
[ Upstream commit 0a5f5d9e94dead312d32c366b917c64e552b72f7 ]
A u32 hash table created with an explicit handle ('tc filter add ...
handle 801: u32 divisor N') keys its IDR entry on the raw handle, while
the destroy paths free it under handle2id(handle). The two key domains
disagree for handles in the 0x800..0xFFF htid range:
handle2id() folds them back into the auto-allocated id space (1..0x7FF).
A manual table therefore leaves its raw-keyed IDR entry unreachable on
delete (a permanent leak), and its delete can drop the idr entry of an
unrelated live auto table. A later auto allocation can then hand out a
handle that aliases the live manual table; u32_lookup_ht() first-match
routes lookups and TCA_U32_LINK for that htid to the wrong table.
Key the divisor-path alloc on handle2id(handle) so allocation and
removal share one key domain. A manual handle that maps onto an id
already in use is rejected with -ENOSPC, and auto allocation skips ids
held by live manual tables.
Conditions to recreate:
ip link add test0 type dummy
tc qdisc add dev test0 clsact
tc filter add dev test0 ingress protocol ip pref 1 \
handle 801: u32 divisor 16
tc filter add dev test0 ingress protocol ip pref 2 u32 divisor 16
tc -d filter show dev test0 ingress | grep 'fh 801:'
# unpatched: two live tables with handle 0x80100000 (the pref 2 root
# hnode is auto-allocated id 1); patched: the auto hnode takes id 2.
Also tested with a poc with a live u32 table on the block, add/delete a manual
table 'handle 901: u32 divisor 1' twice; unpatched, the re-add fails with
-ENOSPC because the raw key leaked on the first delete.
Fixes: 73af53d82076 ("net: sched: cls_u32: Fix u32's systematic failure to free IDR entries for hnodes.")
Reported-by: Sashiko (gemini + nipa) <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260822222049.114526-1-jhs@mojatatu.com
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Tested-by: hybris <hybris@mojatatu.ai>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/QDISC-LQFE.v1.20260911041746.1@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/cls_u32.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 83a60698cc009..e5e5533f866dc 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -1000,8 +1000,16 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
return -ENOMEM;
}
} else {
- err = idr_alloc_u32(&tp_c->handle_idr, ht, &handle,
- handle, GFP_KERNEL);
+ /* The IDR is keyed on the mapped id, and that is
+ * what the destroy paths remove. Ask for it here,
+ * so a manual handle colliding with the
+ * auto-allocated id space is rejected (-ENOSPC)
+ * instead of aliasing a future auto id.
+ */
+ u32 id = handle2id(handle);
+
+ err = idr_alloc_u32(&tp_c->handle_idr, ht, &id, id,
+ GFP_KERNEL);
if (err) {
kfree(ht);
return err;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 345/877] net/mlx5: devcom, Base component size on linked devices
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (343 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 344/877] net/sched: cls_u32: fix manual hash table handle IDR aliasing Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 346/877] bpf: Restrict CO-RE poisoning to relocatable instructions Greg Kroah-Hartman
` (539 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shay Drory, Akiva Goldberger,
Tariq Toukan, Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shay Drory <shayd@nvidia.com>
[ Upstream commit d09e8f64653c93da5793c16be19330968f2a32e6 ]
mlx5_devcom_comp_get_size() returns the component's kref count. That
kref is bumped in mlx5_devcom_register_component() under comp_list_lock,
before the comp_dev is linked onto comp_dev_list_head under comp->sem.
The event broadcast (mlx5_devcom_locked_send_event()) walks that list.
Hence, a caller can read the expected size, but send_event won't be sent
to all peers. In the SD group registration path, this lets a member
broadcast its role-election event over an incomplete list, electing a
primary that never completes the group, is never marked ready, and
leaves the group with a stale primary.
Track the number of linked comp_devs in a dedicated counter, maintained
under comp->sem together with the list add/remove, and return it from
mlx5_devcom_comp_get_size().
Fixes: 9bb1ac80738a ("net/mlx5: devcom, Add component size getter")
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260915113459.3934760-2-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c
index 7b0766c89f4cf..cd8ce2abcf189 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c
@@ -29,6 +29,7 @@ struct mlx5_devcom_comp {
struct list_head comp_dev_list_head;
mlx5_devcom_event_handler_t handler;
struct kref ref;
+ int nr_devs;
bool ready;
struct rw_semaphore sem;
struct lock_class_key lock_key;
@@ -158,6 +159,7 @@ devcom_alloc_comp_dev(struct mlx5_devcom_dev *devc,
down_write(&comp->sem);
list_add_tail(&devcom->list, &comp->comp_dev_list_head);
+ WRITE_ONCE(comp->nr_devs, comp->nr_devs + 1);
up_write(&comp->sem);
return devcom;
@@ -170,6 +172,7 @@ devcom_free_comp_dev(struct mlx5_devcom_comp_dev *devcom)
down_write(&comp->sem);
list_del(&devcom->list);
+ WRITE_ONCE(comp->nr_devs, comp->nr_devs - 1);
up_write(&comp->sem);
kref_put(&devcom->devc->ref, mlx5_devcom_dev_release);
@@ -260,7 +263,7 @@ int mlx5_devcom_comp_get_size(struct mlx5_devcom_comp_dev *devcom)
{
struct mlx5_devcom_comp *comp = devcom->comp;
- return kref_read(&comp->ref);
+ return READ_ONCE(comp->nr_devs);
}
int mlx5_devcom_send_event(struct mlx5_devcom_comp_dev *devcom,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 346/877] bpf: Restrict CO-RE poisoning to relocatable instructions
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (344 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 345/877] net/mlx5: devcom, Base component size on linked devices Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 347/877] libbpf: Reject truncated ldimm64 CO-RE relocations Greg Kroah-Hartman
` (538 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini,
Kumar Kartikeya Dwivedi, Eduard Zingerman, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
[ Upstream commit 394ae398337c5f87e567f6cd63b937fc2b2f6ddc ]
CO-RE relocation records can name any instruction offset. When a
relocation cannot be resolved, bpf_core_patch_insn() currently poisons its
target before checking whether that instruction is a valid relocation
target. Malformed metadata can therefore replace jumps, calls, exits,
register-source arithmetic, or non-immediate loads instead of failing at
the relocation step.
Handle poisoning only after the instruction has passed the same class and
operand-form checks used for a resolved relocation. Route invalid forms
through the existing diagnostic and return a hard error. Keep poisoning
supported instructions, including both halves of a plain ldimm64, so an
unresolved relocation in dead code remains valid.
Extend bpf_core_poison_insn() to poison both halves of ldimm64, and return
its status directly from each validated instruction case. This avoids
routing the success path through a common label and leaves the helper free
to report errors.
The shared relocation code applies this restriction to both libbpf and
in-kernel CO-RE.
Fixes: d7a252708dbc ("libbpf: Improve handling of failed CO-RE relocations")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://patch.msgid.link/20260917233222.2542500-7-memxor@gmail.com
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/lib/bpf/relo_core.c | 58 +++++++++++++++++++++------------------
1 file changed, 31 insertions(+), 27 deletions(-)
diff --git a/tools/lib/bpf/relo_core.c b/tools/lib/bpf/relo_core.c
index 04c8febfc0aa7..4367378d272b3 100644
--- a/tools/lib/bpf/relo_core.c
+++ b/tools/lib/bpf/relo_core.c
@@ -965,23 +965,30 @@ static int bpf_core_calc_relo(const char *prog_name,
}
/*
- * Turn instruction for which CO_RE relocation failed into invalid one with
+ * Turn instruction for which CO-RE relocation failed into invalid one with
* distinct signature.
*/
-static void bpf_core_poison_insn(const char *prog_name, int relo_idx,
- int insn_idx, struct bpf_insn *insn)
+static int bpf_core_poison_insn(const char *prog_name, int relo_idx,
+ struct bpf_insn *insn, int insn_idx)
{
- pr_debug("prog '%s': relo #%d: substituting insn #%d w/ invalid insn\n",
- prog_name, relo_idx, insn_idx);
- insn->code = BPF_JMP | BPF_CALL;
- insn->dst_reg = 0;
- insn->src_reg = 0;
- insn->off = 0;
- /* if this instruction is reachable (not a dead code),
- * verifier will complain with the following message:
- * invalid func unknown#195896080
- */
- insn->imm = 195896080; /* => 0xbad2310 => "bad relo" */
+ int insn_cnt = is_ldimm64_insn(insn) ? 2 : 1;
+ int i;
+
+ for (i = 0; i < insn_cnt; i++) {
+ pr_debug("prog '%s': relo #%d: substituting insn #%d w/ invalid insn\n",
+ prog_name, relo_idx, insn_idx + i);
+ insn[i].code = BPF_JMP | BPF_CALL;
+ insn[i].dst_reg = 0;
+ insn[i].src_reg = 0;
+ insn[i].off = 0;
+ /*
+ * If this instruction is reachable (not dead code), the verifier
+ * will complain with "invalid func unknown#195896080".
+ */
+ insn[i].imm = 195896080; /* => 0xbad2310 => "bad relo" */
+ }
+
+ return 0;
}
static int insn_bpf_size_to_bytes(struct bpf_insn *insn)
@@ -1032,17 +1039,6 @@ int bpf_core_patch_insn(const char *prog_name, struct bpf_insn *insn,
class = BPF_CLASS(insn->code);
- if (res->poison) {
-poison:
- /* poison second part of ldimm64 to avoid confusing error from
- * verifier about "unknown opcode 00"
- */
- if (is_ldimm64_insn(insn))
- bpf_core_poison_insn(prog_name, relo_idx, insn_idx + 1, insn + 1);
- bpf_core_poison_insn(prog_name, relo_idx, insn_idx, insn);
- return 0;
- }
-
orig_val = res->orig_val;
new_val = res->new_val;
@@ -1050,7 +1046,9 @@ int bpf_core_patch_insn(const char *prog_name, struct bpf_insn *insn,
case BPF_ALU:
case BPF_ALU64:
if (BPF_SRC(insn->code) != BPF_K)
- return -EINVAL;
+ goto bad_insn;
+ if (res->poison)
+ return bpf_core_poison_insn(prog_name, relo_idx, insn, insn_idx);
if (res->validate && insn->imm != orig_val) {
pr_warn("prog '%s': relo #%d: unexpected insn #%d (ALU/ALU64) value: got %u, exp %llu -> %llu\n",
prog_name, relo_idx,
@@ -1067,6 +1065,8 @@ int bpf_core_patch_insn(const char *prog_name, struct bpf_insn *insn,
case BPF_LDX:
case BPF_ST:
case BPF_STX:
+ if (res->poison)
+ return bpf_core_poison_insn(prog_name, relo_idx, insn, insn_idx);
if (res->validate && insn->off != orig_val) {
pr_warn("prog '%s': relo #%d: unexpected insn #%d (LDX/ST/STX) value: got %u, exp %llu -> %llu\n",
prog_name, relo_idx, insn_idx, insn->off, (unsigned long long)orig_val,
@@ -1082,7 +1082,7 @@ int bpf_core_patch_insn(const char *prog_name, struct bpf_insn *insn,
pr_warn("prog '%s': relo #%d: insn #%d (LDX/ST/STX) accesses field incorrectly. "
"Make sure you are accessing pointers, unsigned integers, or fields of matching type and size.\n",
prog_name, relo_idx, insn_idx);
- goto poison;
+ return bpf_core_poison_insn(prog_name, relo_idx, insn, insn_idx);
}
orig_val = insn->off;
@@ -1125,6 +1125,9 @@ int bpf_core_patch_insn(const char *prog_name, struct bpf_insn *insn,
return -EINVAL;
}
+ if (res->poison)
+ return bpf_core_poison_insn(prog_name, relo_idx, insn, insn_idx);
+
imm = (__u32)insn[0].imm | ((__u64)insn[1].imm << 32);
if (res->validate && imm != orig_val) {
pr_warn("prog '%s': relo #%d: unexpected insn #%d (LDIMM64) value: got %llu, exp %llu -> %llu\n",
@@ -1142,6 +1145,7 @@ int bpf_core_patch_insn(const char *prog_name, struct bpf_insn *insn,
break;
}
default:
+bad_insn:
pr_warn("prog '%s': relo #%d: trying to relocate unrecognized insn #%d, code:0x%x, src:0x%x, dst:0x%x, off:0x%x, imm:0x%x\n",
prog_name, relo_idx, insn_idx, insn->code,
insn->src_reg, insn->dst_reg, insn->off, insn->imm);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 347/877] libbpf: Reject truncated ldimm64 CO-RE relocations
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (345 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 346/877] bpf: Restrict CO-RE poisoning to relocatable instructions Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 348/877] netfilter: flowtable: publish HW_DEAD after worker is done Greg Kroah-Hartman
` (537 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Kumar Kartikeya Dwivedi,
Eduard Zingerman, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
[ Upstream commit b4e875d397da451fb4e9c573ff4b86db53caba05 ]
CO-RE relocation of an ldimm64 instruction operates on two instruction
slots. A malformed BPF ELF can end a function after the first slot and
attach a CO-RE relocation to it. libbpf allocates the instruction array
according to the function symbol size, so the shared relocation code would
then access beyond the allocation.
Reject a terminal ldimm64 in libbpf's relocation loop, where the program
length is available, before resolving or applying the relocation. Both
resolved and unresolved relocations validate the absent second slot, and
unresolved relocation poisoning would additionally write past the array.
The in-kernel caller is protected by the verifier's early instruction-stream
check before it applies CO-RE relocations.
Fixes: eacaaed784e2 ("libbpf: Implement enum value-based CO-RE relocations")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/20260914140852.03DA21F0089B@smtp.kernel.org
Link: https://patch.msgid.link/20260917233222.2542500-11-memxor@gmail.com
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/lib/bpf/libbpf.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index ffb0d1f7e9a08..214f8b48c1ea3 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -5983,6 +5983,13 @@ bpf_object__relocate_core(struct bpf_object *obj, const char *targ_btf_path)
return -EINVAL;
insn = &prog->insns[insn_idx];
+ if (is_ldimm64_insn(insn) && (size_t)insn_idx + 1 >= prog->insns_cnt) {
+ pr_warn("prog '%s': relo #%d: insn #%d (LDIMM64) is truncated\n",
+ prog->name, i, insn_idx);
+ err = -EINVAL;
+ goto out;
+ }
+
err = record_relo_core(prog, rec, insn_idx);
if (err) {
pr_warn("prog '%s': relo #%d: failed to record relocation: %d\n",
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 348/877] netfilter: flowtable: publish HW_DEAD after worker is done
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (346 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 347/877] libbpf: Reject truncated ldimm64 CO-RE relocations Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 349/877] netfilter: nfnetlink_queue: hold nfnl mutex in event notifier Greg Kroah-Hartman
` (536 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jérémy Jean,
Pablo Neira Ayuso, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
[ Upstream commit d644b23afe1ef509c9961a6d84a093c2587edf02 ]
flow_offload_work_del() sets NF_FLOW_HW_DEAD before the work handler
clears NF_FLOW_HW_PENDING. Once a flow is both HW_DYING and HW_DEAD, a
concurrent garbage collection pass can remove it and schedule it for RCU
freeing.
The offload worker holds neither an RCU read lock nor a reference to the
flow. If it is preempted after publishing HW_DEAD, the RCU callback can
free the flow before the worker resumes and clears HW_PENDING, resulting
in a use-after-free.
Move HW_DEAD publication to the common worker epilogue after the pending
bit is cleared, making it the final flow access by destroy work. Order all
preceding flow accesses before publishing the bit that allows garbage
collection to free the object.
Fixes: 2c8897953f3b ("netfilter: flowtable: Add pending bit for offload work")
Assisted-by: Codex:gpt-5
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/nf_flow_table_offload.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
index 4f346f51d7d74..8e3edc7c37b38 100644
--- a/net/netfilter/nf_flow_table_offload.c
+++ b/net/netfilter/nf_flow_table_offload.c
@@ -993,7 +993,6 @@ static void flow_offload_work_del(struct flow_offload_work *offload)
flow_offload_tuple_del(offload, FLOW_OFFLOAD_DIR_ORIGINAL);
if (test_bit(NF_FLOW_HW_BIDIRECTIONAL, &offload->flow->flags))
flow_offload_tuple_del(offload, FLOW_OFFLOAD_DIR_REPLY);
- set_bit(NF_FLOW_HW_DEAD, &offload->flow->flags);
}
static void flow_offload_tuple_stats(struct flow_offload_work *offload,
@@ -1057,6 +1056,12 @@ static void flow_offload_work_handler(struct work_struct *work)
}
clear_bit(NF_FLOW_HW_PENDING, &offload->flow->flags);
+ if (offload->cmd == FLOW_CLS_DESTROY) {
+ /* Publish after the worker's last flow access. */
+ smp_mb__before_atomic();
+ set_bit(NF_FLOW_HW_DEAD, &offload->flow->flags);
+ }
+
kfree(offload);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 349/877] netfilter: nfnetlink_queue: hold nfnl mutex in event notifier
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (347 preceding siblings ...)
2026-09-30 15:20 ` [PATCH 6.12 348/877] netfilter: flowtable: publish HW_DEAD after worker is done Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 350/877] netfilter: nft_synproxy: use the family-aware checksum helper Greg Kroah-Hartman
` (535 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Florian Westphal, Pablo Neira Ayuso,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <fw@strlen.de>
[ Upstream commit 9461613afc59acef44a0071b0dd5075f6e993ffe ]
We must serialize the release notifier and the config netlink function.
A concurrent thread can issue close() which can call the release function
while unrelated socket processes UNBIND request for same portid:
Oops: general protection fault, [..]
RIP: 0010:__instance_destroy+0x60/0x210 [nfnetlink_queue]
Call Trace:
nfqnl_recv_config+0x9b0/0xdc0 [nfnetlink_queue]
nfnetlink_rcv_msg+0x7c2/0xeb0
? __pfx_nfnetlink_rcv_msg+0x10/0x10
After this, parallel UNBIND and URELEASE events are impossible.
This change isn't nice, but its the shortest fix given instances
are not refcounted and the nfnetlink config callback drops the
rcu read lock early due to need for sleeping allocations.
Fixes: 7af4cc3fa158 ("[NETFILTER]: Add "nfnetlink_queue" netfilter queue handler over nfnetlink")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/nfnetlink_queue.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 2e00a07eb545d..797c99c626d23 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -1338,6 +1338,7 @@ nfqnl_rcv_nl_event(struct notifier_block *this,
if (event == NETLINK_URELEASE && n->protocol == NETLINK_NETFILTER) {
int i;
+ nfnl_lock(NFNL_SUBSYS_QUEUE);
/* destroy all instances for this portid */
spin_lock(&q->instances_lock);
for (i = 0; i < INSTANCE_BUCKETS; i++) {
@@ -1351,6 +1352,7 @@ nfqnl_rcv_nl_event(struct notifier_block *this,
}
}
spin_unlock(&q->instances_lock);
+ nfnl_unlock(NFNL_SUBSYS_QUEUE);
}
return NOTIFY_DONE;
}
@@ -1672,9 +1674,9 @@ static int nfqnl_recv_config(struct sk_buff *skb, const struct nfnl_info *info,
/* Lookup queue under RCU. After peer_portid check (or for new queue
* in BIND case), the queue is owned by the socket sending this message.
- * A socket cannot simultaneously send a message and close, so while
- * processing this CONFIG message, nfqnl_rcv_nl_event() (triggered by
- * socket close) cannot destroy this queue. Safe to use without RCU.
+ * nfqnl_rcv_nl_event() will block on the nfnl subsys mutex that is
+ * held by the caller, so the queue cannot be destroyed in parallel,
+ * even after we drop the RCU read lock.
*/
rcu_read_lock();
queue = instance_lookup(q, queue_num);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 350/877] netfilter: nft_synproxy: use the family-aware checksum helper
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (348 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 349/877] netfilter: nfnetlink_queue: hold nfnl mutex in event notifier Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 351/877] ipvs: revalidate ihl before icmp_send Greg Kroah-Hartman
` (534 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Pablo Neira Ayuso,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
[ Upstream commit a311a898172743558b82f6035ef2aa8c310a4223 ]
nft_synproxy_do_eval() verifies the TCP checksum before it switches on
skb->protocol. It uses nf_ip_checksum(), which constructs an IPv4
pseudo header and relies on the IPv4 header checksum when folding the
whole skb. Neither operation is valid for an IPv6 packet.
A correctly checksummed IPv6 segment can therefore fail verification
when it reaches the hook as CHECKSUM_NONE or, at NF_INET_LOCAL_IN,
CHECKSUM_COMPLETE. nft_synproxy_do_eval() returns NF_DROP before
nft_synproxy_eval_v6() can send a SYN-ACK.
nft_synproxy_validate() deliberately admits NFPROTO_IPV6 and
NFPROTO_INET, and the xtables counterpart ip6t_SYNPROXY.c already calls
nf_ip6_checksum().
Use nf_checksum() with nft_pf() so the checksum helper dispatches to the
packet family's implementation.
Fixes: ad49d86e07a4 ("netfilter: nf_tables: Add synproxy support")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/nft_synproxy.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/netfilter/nft_synproxy.c b/net/netfilter/nft_synproxy.c
index a80bdce38546f..a6253595a1676 100644
--- a/net/netfilter/nft_synproxy.c
+++ b/net/netfilter/nft_synproxy.c
@@ -117,7 +117,8 @@ static void nft_synproxy_do_eval(const struct nft_synproxy *priv,
return;
}
- if (nf_ip_checksum(skb, nft_hook(pkt), thoff, IPPROTO_TCP)) {
+ if (nf_checksum(skb, nft_hook(pkt), thoff, IPPROTO_TCP,
+ nft_pf(pkt))) {
regs->verdict.code = NF_DROP;
return;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 351/877] ipvs: revalidate ihl before icmp_send
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (349 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 350/877] netfilter: nft_synproxy: use the family-aware checksum helper Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 352/877] netfilter: ctnetlink: fix suspicious RCU usage in expect_iter_name Greg Kroah-Hartman
` (533 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Julian Anastasov, Pablo Neira Ayuso,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Julian Anastasov <ja@ssi.bg>
[ Upstream commit e290145564886d6a3038810c621f738c1fe9fa51 ]
While the outer IP header is already pulled into the skb head, we must
be careful and revalidate the embedded headers after reading them from
the skb frags to prevent possible out-of-bounds access.
One such place reported by Sashiko is ip_vs_in_icmp() where local
process can change the ihl field and after pskb_may_pull() we can see
larger value. Even if icmp_send() has checks to prevent out-of-bounds
access, play safe and add check to drop the packet if the ihl field is
changed. As the outer headers are pulled, make sure the transport
header is updated too, it was used before commit 7fcc2fe39fed ("net:
icmp: avoid invalid transport header access in icmp_send tracepoint")
Fixes: f2edb9f7706d ("ipvs: implement passive PMTUD for IPIP packets")
Link: https://sashiko.dev/#/patchset/20260806105211.34622-1-ja%40ssi.bg
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/ipvs/ip_vs_core.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 1f62ca2f73309..4e30a903f4bdc 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -1776,6 +1776,12 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related,
/* Ensure the IP header is present in headroom */
if (!pskb_may_pull(skb, hlen_orig))
goto ignore_tunnel;
+ skb_set_transport_header(skb, hlen_orig);
+ /* Before now we may used ihl from skb frag, revalidate it after
+ * copying it into skb head to prevent out-of-bounds access
+ */
+ if (ip_hdr(skb)->ihl * 4 != hlen_orig)
+ goto ignore_tunnel;
IP_VS_DBG(12, "Sending ICMP for %pI4->%pI4: t=%u, c=%u, i=%u\n",
&ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr,
type, code, ntohl(info));
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 352/877] netfilter: ctnetlink: fix suspicious RCU usage in expect_iter_name
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (350 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 351/877] ipvs: revalidate ihl before icmp_send Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 353/877] arm64: io: Reject non-user protection in ioremap_prot() Greg Kroah-Hartman
` (532 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+4bd730aede2791e40bdf,
Naman Gulati, Pablo Neira Ayuso, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naman Gulati <namangulati@google.com>
[ Upstream commit 207d591c353201f3bd3e0c89bb7d44a849c8fd59 ]
expect_iter_name() is invoked by nf_ct_expect_iterate_net() under
spin_lock_bh(&nf_conntrack_expect_lock). It does not hold
rcu_read_lock().
When accessing exp->helper with rcu_dereference() in syzbot's report,
lockdep warns:
=============================
WARNING: suspicious RCU usage
syzkaller #0 Not tainted
-----------------------------
net/netfilter/nf_conntrack_netlink.c:3393 suspicious rcu_dereference_check() usage!
locks held by syz-executor381/5628: 2, last CPU#1:
#0: ffffffff9aee42a0 (nfnl_subsys_ctnetlink_exp){+.+.}-{4:4},
at: nfnetlink_rcv_msg+0xa69/0x12b0
#1: ffffffff8ea74d58 (nf_conntrack_expect_lock){+...}-{3:3},
at: nf_ct_expect_iterate_net+0x38/0x180
Call Trace:
<TASK>
dump_stack_lvl+0xe8/0x150
lockdep_rcu_suspicious+0x140/0x1d0
expect_iter_name+0xfb/0x100
nf_ct_expect_iterate_net+0xf2/0x180
ctnetlink_del_expect+0x45d/0x640
nfnetlink_rcv_msg+0xcc2/0x12b0
netlink_rcv_skb+0x226/0x4a0
nfnetlink_rcv+0x2b9/0x28c0
netlink_unicast+0x7bd/0x940
netlink_sendmsg+0x813/0xb40
____sys_sendmsg+0x54e/0x850
___sys_sendmsg+0x2a5/0x360
__sys_sendmsg+0x2a5/0x360
do_syscall_64+0x166/0x520
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Use rcu_dereference_protected() with lockdep_is_held() on
nf_conntrack_expect_lock instead, similar to expect_iter_me() in
nf_conntrack_helper.c.
Fixes: f01794106042 ("netfilter: nf_conntrack_expect: use expect->helper")
Reported-by: syzbot+4bd730aede2791e40bdf@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/6aa4a377.f81106d8.2ab401.0024.GAE@google.com/T/#u
Signed-off-by: Naman Gulati <namangulati@google.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/nf_conntrack_netlink.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index a081d38702f5d..8bb32965edb83 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -3390,7 +3390,8 @@ static bool expect_iter_name(struct nf_conntrack_expect *exp, void *data)
struct nf_conntrack_helper *helper;
const char *name = data;
- helper = rcu_dereference(exp->helper);
+ helper = rcu_dereference_protected(exp->helper,
+ lockdep_is_held(&nf_conntrack_expect_lock));
if (!helper)
return false;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 353/877] arm64: io: Reject non-user protection in ioremap_prot()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (351 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 352/877] netfilter: ctnetlink: fix suspicious RCU usage in expect_iter_name Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 354/877] ocfs2: make ocfs2_calc_xattr_init() return void Greg Kroah-Hartman
` (531 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zeng Heng, Catalin Marinas,
Will Deacon, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zeng Heng <zengheng4@huawei.com>
[ Upstream commit bb756b11ad63832ebee58caf9e8f9381eaecff9f ]
Mapping a stack-top page via /dev/mem with PROT_NONE and then
reading that process's /proc/<pid>/cmdline triggers a spurious WARN
in ioremap_prot() through generic_access_phys():
WARNING: ./arch/arm64/include/asm/io.h:275 at generic_access_phys
Call trace:
generic_access_phys+0x1c8/0x228 (P)
__access_remote_vm+0x2b4/0x398
access_remote_vm+0x14/0x30
get_mm_cmdline+0xf8/0x2a0
proc_pid_cmdline_read+0x68/0x120
generic_access_phys() passes the protection derived from the user PTE
to ioremap_prot(). On arm64, a PROT_NONE mapping is represented by a
present-invalid PTE, so pte_present() still returns true and the
protection reaches ioremap_prot().
A PROT_NONE mapping does not have PTE_USER, causing the existing
WARN_ON_ONCE() in ioremap_prot() to fire even though this is a valid
user mapping. Execute-only mappings have the same issue and must not
be readable through this path either.
ioremap_prot() should therefore reject protection values without
PTE_USER without warning. This makes the access fail cleanly for
PROT_NONE and execute-only mappings while retaining the existing
user-protection contract.
Fixes: 8f098037139b ("arm64: io: Extract user memory type in ioremap_prot()")
Signed-off-by: Zeng Heng <zengheng4@huawei.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/include/asm/io.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 46bd37707e080..16a423101bdcd 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -282,7 +282,8 @@ static inline void __iomem *ioremap_prot(phys_addr_t phys, size_t size,
pgprot_t prot;
pteval_t user_prot_val = pgprot_val(__pgprot(user_prot));
- if (WARN_ON_ONCE(!(user_prot_val & PTE_USER)))
+ /* Reject PROT_NONE and exec-only */
+ if (!(user_prot_val & PTE_USER))
return NULL;
prot = __pgprot_modify(PAGE_KERNEL, PTE_ATTRINDX_MASK,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 354/877] ocfs2: make ocfs2_calc_xattr_init() return void
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (352 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 353/877] arm64: io: Reject non-user protection in ioremap_prot() Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 355/877] drm/nouveau/clk: fix list cursor use after loop in nvkm_clk_ustate_update Greg Kroah-Hartman
` (530 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joseph Qi, Andrew Morton,
kernel test robot, Mark Fasheh, Joel Becker, Junxiao Bi,
Changwei Ge, Jun Piao, Heming Zhao, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joseph Qi <joseph.qi@linux.alibaba.com>
[ Upstream commit 525c0edc032b3297d0c1056cf1fa20cf1f9e6184 ]
ocfs2_calc_xattr_init() used to read the default ACL off the parent inode
itself, so it could return an error from ocfs2_xattr_get_nolock(). Commit
bd7c05fb4a47 ("ocfs2: fix circular locking dependency in
ocfs2_init_acl()") moved that lookup before the transaction starts and
deleted the error path, but left the now vestigial 'int ret = 0'
declaration and both 'return ret' statements behind, along with an
unreachable error branch in ocfs2_mknod().
Drop the leftover variable and convert the return type to void, so the
callee states that it always succeeds and the caller no longer carries a
check that can never trigger.
No functional change.
Link: https://lore.kernel.org/20260904023751.3703334-1-joseph.qi@linux.alibaba.com
Fixes: bd7c05fb4a47 ("ocfs2: fix circular locking dependency in ocfs2_init_acl()")
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202609040247.8B3lmoqX-lkp@intel.com/
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Jun Piao <piaojun@huawei.com>
Cc: Heming Zhao <heming.zhao@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ocfs2/namei.c | 9 ++-------
fs/ocfs2/xattr.c | 13 +++++--------
fs/ocfs2/xattr.h | 8 ++++----
3 files changed, 11 insertions(+), 19 deletions(-)
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 1dcd420878dcb..5ce71207bc9dd 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -332,13 +332,8 @@ static int ocfs2_mknod(struct mnt_idmap *idmap,
goto leave;
/* calculate meta data/clusters for setting security and acl xattr */
- status = ocfs2_calc_xattr_init(dir, mode, &si, &want_clusters,
- &xattr_credits, &want_meta,
- &acl_state);
- if (status < 0) {
- mlog_errno(status);
- goto leave;
- }
+ ocfs2_calc_xattr_init(dir, mode, &si, &want_clusters, &xattr_credits,
+ &want_meta, &acl_state);
/* Reserve a cluster if creating an extent based directory. */
if (S_ISDIR(mode) && !ocfs2_supports_inline_data(osb)) {
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 52156e8495432..3cc679e5f1a1a 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -607,12 +607,11 @@ int ocfs2_calc_security_init(struct inode *dir,
return ret;
}
-int ocfs2_calc_xattr_init(struct inode *dir, umode_t mode,
- struct ocfs2_security_xattr_info *si,
- int *want_clusters, int *xattr_credits,
- int *want_meta, struct ocfs2_acl_state *acl_state)
+void ocfs2_calc_xattr_init(struct inode *dir, umode_t mode,
+ struct ocfs2_security_xattr_info *si,
+ int *want_clusters, int *xattr_credits,
+ int *want_meta, struct ocfs2_acl_state *acl_state)
{
- int ret = 0;
struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
int s_size = 0, a_size = 0, acl_len = 0, new_clusters;
@@ -634,7 +633,7 @@ int ocfs2_calc_xattr_init(struct inode *dir, umode_t mode,
}
if (!(s_size + a_size))
- return ret;
+ return;
/*
* The max space of security xattr taken inline is
@@ -700,8 +699,6 @@ int ocfs2_calc_xattr_init(struct inode *dir, umode_t mode,
}
}
}
-
- return ret;
}
static int ocfs2_xattr_extend_allocation(struct inode *inode,
diff --git a/fs/ocfs2/xattr.h b/fs/ocfs2/xattr.h
index 5cdd6c6b40064..aeba323e14b3c 100644
--- a/fs/ocfs2/xattr.h
+++ b/fs/ocfs2/xattr.h
@@ -57,10 +57,10 @@ int ocfs2_calc_security_init(struct inode *,
int *, int *, struct ocfs2_alloc_context **);
struct ocfs2_acl_state;
-int ocfs2_calc_xattr_init(struct inode *dir, umode_t mode,
- struct ocfs2_security_xattr_info *si,
- int *want_clusters, int *xattr_credits,
- int *want_meta, struct ocfs2_acl_state *acl_state);
+void ocfs2_calc_xattr_init(struct inode *dir, umode_t mode,
+ struct ocfs2_security_xattr_info *si,
+ int *want_clusters, int *xattr_credits,
+ int *want_meta, struct ocfs2_acl_state *acl_state);
/*
* xattrs can live inside an inode, as part of an external xattr block,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 355/877] drm/nouveau/clk: fix list cursor use after loop in nvkm_clk_ustate_update
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (353 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 354/877] ocfs2: make ocfs2_calc_xattr_init() return void Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 356/877] drm/nouveau/clk: dont clobber reclock status when restoring volt/fan Greg Kroah-Hartman
` (529 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dan Carpenter, Francesco Magazzu,
Lyude Paul, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <dan.carpenter@oracle.com>
[ Upstream commit aff09d9e37e02dc60bde79035ac15b136d602259 ]
If list_for_each_entry() exits without hitting a break then "pstate" is
not a valid pstate pointer. Introduce a "found" variable instead.
The check is reachable from userspace: nvkm_clk_ustate_update() takes the
pstate id straight from the 'pstate' debugfs file, so requesting an id
that is not in clk->states - or any id at all when the perf tables are
broken and the list is empty - makes the pstate->pstate != req test
dereference the list head cast to a struct nvkm_pstate, which is an
out-of-bounds read.
Fixes: 7c8565220697 ("drm/nouveau/clk: implement power state and engine clock control in core")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
[Francesco: rebased on drm-misc-next, expanded the commit message]
Signed-off-by: Francesco Magazzu <postadelmaga@gmail.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/20260918131620.405133-2-postadelmaga@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
index 178dc56909c27..5f4cd122415fa 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
@@ -473,6 +473,7 @@ static int
nvkm_clk_ustate_update(struct nvkm_clk *clk, int req)
{
struct nvkm_pstate *pstate;
+ bool found = false;
int i = 0;
if (!clk->allow_reclock)
@@ -480,12 +481,14 @@ nvkm_clk_ustate_update(struct nvkm_clk *clk, int req)
if (req != -1 && req != -2) {
list_for_each_entry(pstate, &clk->states, head) {
- if (pstate->pstate == req)
+ if (pstate->pstate == req) {
+ found = true;
break;
+ }
i++;
}
- if (pstate->pstate != req)
+ if (!found)
return -EINVAL;
req = i;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 356/877] drm/nouveau/clk: dont clobber reclock status when restoring volt/fan
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (354 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 355/877] drm/nouveau/clk: fix list cursor use after loop in nvkm_clk_ustate_update Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 357/877] drm/nouveau/disp: dont reject HDMI config on cards without SCDC Greg Kroah-Hartman
` (528 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Francesco Magazzu, Lyude Paul,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Francesco Magazzu <postadelmaga@gmail.com>
[ Upstream commit e5cccdafc855cd5f96f4b51d38114a0360b075d7 ]
nvkm_cstate_prog() reuses 'ret' for the voltage and fan-speed restore
calls it makes after reprogramming the clocks. Those calls almost always
succeed, so the status of the reclock itself is overwritten and the
function reports success even when clk->func->calc() or clk->func->prog()
failed. The converse is also true: a successful reclock is reported as an
error if the final restore call fails, even though that failure is only
logged and otherwise ignored.
The only consumer of the return value is the error message in
nvkm_pstate_work(), so in practice a failing reclock is simply never
reported. Nothing else changes, but a function that returns success on
failure is a trap for the next caller.
Keep the calc/prog status in 'ret' and use a separate local for the
restore calls.
Fixes: 3eca809b3c05 ("drm/nouveau/clk: cosmetic changes")
Signed-off-by: Francesco Magazzu <postadelmaga@gmail.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/20260918131620.405133-5-postadelmaga@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
index 5f4cd122415fa..e6539931a7596 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
@@ -199,16 +199,18 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
}
if (volt) {
- ret = nvkm_volt_set_id(volt, cstate->voltage,
- pstate->base.voltage, clk->temp, -1);
- if (ret && ret != -ENODEV)
- nvkm_error(subdev, "failed to lower voltage: %d\n", ret);
+ int err = nvkm_volt_set_id(volt, cstate->voltage,
+ pstate->base.voltage, clk->temp, -1);
+
+ if (err && err != -ENODEV)
+ nvkm_error(subdev, "failed to lower voltage: %d\n", err);
}
if (therm) {
- ret = nvkm_therm_cstate(therm, pstate->fanspeed, -1);
- if (ret && ret != -ENODEV)
- nvkm_error(subdev, "failed to lower fan speed: %d\n", ret);
+ int err = nvkm_therm_cstate(therm, pstate->fanspeed, -1);
+
+ if (err && err != -ENODEV)
+ nvkm_error(subdev, "failed to lower fan speed: %d\n", err);
}
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 357/877] drm/nouveau/disp: dont reject HDMI config on cards without SCDC
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (355 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 356/877] drm/nouveau/clk: dont clobber reclock status when restoring volt/fan Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 358/877] net/sched: act_ct: dont WARN on benign flow_offload_alloc() failure Greg Kroah-Hartman
` (527 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Giuseppe Ranieri, Tano Dzhinski,
Lyude Paul, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Giuseppe Ranieri <giuseppe@ranieri.dev>
[ Upstream commit 1717fcc5be575d4768279148ae9465a8b13d4339 ]
nv50_hdmi_enable() passes the sink's SCDC capability from its EDID
straight through to nvif_outp_hdmi(). On pre-Maxwell-2 cards there is no
hdmi->scdc callback, so nvkm_uoutp_mthd_hdmi() rejects the whole
configuration with -EINVAL, and nv50_hdmi_enable() returns before
hdmi->ctrl() runs and before the AVI and VSI infoframes are sent.
The result on such a card driving an SCDC-capable HDMI 2.0 sink is that
HDMI audio silently stops working. Video is unaffected, and nothing is
logged, which makes the failure hard to attribute.
SCDC is optional, and the hdmi->scdc() call further down is already
guarded against a missing callback. Requesting it on a card that cannot
do it need not invalidate the rest of the HDMI configuration, so drop
that term from the condition and let the existing guard skip SCDC alone.
Fixes: 6c6abab20b99 ("drm/nouveau/disp: add output hdmi config method")
Signed-off-by: Giuseppe Ranieri <giuseppe@ranieri.dev>
Co-Authored-By: Tano Dzhinski <tano.dzhinski@gmail.com>
Signed-off-by: Tano Dzhinski <tano.dzhinski@gmail.com>
Tested-by: Tano Dzhinski <tano.dzhinski@gmail.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/20260917215114.1136715-1-tano.dzhinski@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
index 377d0e0cef848..9887b3898505b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
@@ -253,8 +253,7 @@ nvkm_uoutp_mthd_hdmi(struct nvkm_outp *outp, void *argv, u32 argc)
if (!ior->func->hdmi ||
args->v0.max_ac_packet > 0x1f ||
- args->v0.rekey > 0x7f ||
- (args->v0.scdc && !ior->func->hdmi->scdc))
+ args->v0.rekey > 0x7f)
return -EINVAL;
if (!args->v0.enable) {
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 358/877] net/sched: act_ct: dont WARN on benign flow_offload_alloc() failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (356 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 357/877] drm/nouveau/disp: dont reject HDMI config on cards without SCDC Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 359/877] net: gue: reject invalid REMCSUM offsets Greg Kroah-Hartman
` (526 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+6cc37aba98dac721c415,
Nguyen Ngoc Thang, Simon Horman, Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
[ Upstream commit 47abe7a5c4eb53269aca3506446f851572a059a3 ]
flow_offload_alloc() returns NULL when the conntrack entry is dying
(e.g. raced with a conntrack flush) or when the GFP_ATOMIC allocation
fails; both are expected under load and neither is a kernel bug. This
path runs from softirq on every committed packet, so with
panic_on_warn=1 an unprivileged user can panic the box just by racing
a conntrack flush against a `tc ... action ct commit` classifier.
Reproduced with a custom repro under QEMU: a small, fixed set of UDP
flows through `tc filter ... action ct commit` on lo, raced against
threads flooding bare ctnetlink CT_DELETE (flush) requests. Hits
WARNING: net/sched/act_ct.c:437 (tcf_ct_flow_table_add(), inlined
into tcf_ct_act() in this build) within ~15s on the unpatched kernel;
same setup is clean on the patched kernel. The fix itself is
behavior-preserving: both branches already did `goto err_alloc`
before and after, only the WARN is removed.
Fixes: 64ff70b80fd4 ("net/sched: act_ct: Offload established connections to flow table")
Reported-by: syzbot+6cc37aba98dac721c415@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=6cc37aba98dac721c415
Signed-off-by: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260915150816.36487-1-ngocthang2710.1999@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/act_ct.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
index 8aed25cad9eef..46564bfc13251 100644
--- a/net/sched/act_ct.c
+++ b/net/sched/act_ct.c
@@ -430,11 +430,10 @@ static void tcf_ct_flow_table_add(struct tcf_ct_flow_table *ct_ft,
if (test_and_set_bit(IPS_OFFLOAD_BIT, &ct->status))
return;
+ /* NULL if ct is dying (raced flush) or the atomic alloc failed. */
entry = flow_offload_alloc(ct);
- if (!entry) {
- WARN_ON_ONCE(1);
+ if (!entry)
goto err_alloc;
- }
if (tcp) {
ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 359/877] net: gue: reject invalid REMCSUM offsets
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (357 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 358/877] net/sched: act_ct: dont WARN on benign flow_offload_alloc() failure Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 360/877] net: ethernet: mtk_eth_soc: unregister net_devices in case of probe failure Greg Kroah-Hartman
` (525 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jérémy Jean,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
[ Upstream commit 2566866fc30965d915d0b52b5c3323b362619f0e ]
The REMCSUM option carries an absolute checksum start and checksum field
offset. gue_remcsum() passes them to skb_remcsum_process(), whose
partial path stores offset - start in the u16 skb->csum_offset variable.
If offset is less than start, this underflows.
A forwarded packet can retain CHECKSUM_PARTIAL and reach a NETIF_F_HW_CSUM
driver which trusts the metadata, leading skb_copy_and_csum_dev() to write
two bytes about 64 KiB beyond the destination buffer.
Reject reversed tuples in validate_gue_flags(), after the existing length
validation, so all GUE parsers enforce the ordering in one place.
Fixes: fe881ef11cf0 ("gue: Use checksum partial with remote checksum offload")
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Link: https://patch.msgid.link/20260915124806.2852293-2-Jeremy.Jean@oss.cyber.gouv.fr
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/gue.h | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/include/net/gue.h b/include/net/gue.h
index caefd6da86939..d377155fd0b31 100644
--- a/include/net/gue.h
+++ b/include/net/gue.h
@@ -84,8 +84,9 @@ static inline size_t guehdr_priv_flags_len(__be32 flags)
}
/* Validate standard and private flags. Returns non-zero (meaning invalid)
- * if there is an unknown standard or private flags, or the options length for
- * the flags exceeds the options length specific in hlen of the GUE header.
+ * if there is an unknown standard or private flags, if the options length for
+ * the flags exceeds the options length specified in hlen of the GUE header, or
+ * if a private option contains invalid data.
*/
static inline int validate_gue_flags(struct guehdr *guehdr, size_t optlen)
{
@@ -103,8 +104,8 @@ static inline int validate_gue_flags(struct guehdr *guehdr, size_t optlen)
/* Private flags are last four bytes accounted in
* guehdr_flags_len
*/
- __be32 pflags = *(__be32 *)((void *)&guehdr[1] +
- len - GUE_LEN_PRIV);
+ void *data = (void *)&guehdr[1] + len;
+ __be32 pflags = *(__be32 *)(data - GUE_LEN_PRIV);
if (pflags & ~GUE_PFLAGS_ALL)
return 1;
@@ -112,6 +113,16 @@ static inline int validate_gue_flags(struct guehdr *guehdr, size_t optlen)
len += guehdr_priv_flags_len(pflags);
if (len > optlen)
return 1;
+
+ if (pflags & GUE_PFLAG_REMCSUM) {
+ __be16 *pd = data;
+
+ /* The field offset pd[1] must not be less
+ * than the start pd[0].
+ */
+ if (ntohs(pd[1]) < ntohs(pd[0]))
+ return 1;
+ }
}
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 360/877] net: ethernet: mtk_eth_soc: unregister net_devices in case of probe failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (358 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 359/877] net: gue: reject invalid REMCSUM offsets Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 361/877] ip6_gre: Call ip6erspan_tunnel_unlink_md() in ip6erspan_changelink() Greg Kroah-Hartman
` (524 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Bianconi, Jakub Kicinski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
[ Upstream commit 310d1ac61a4d5a2ca8356a3a48d263acf54503ce ]
If register_netdev() fails for one of the MTK_MAX_DEVS devices in
mtk_probe(), the error path jumps to err_deinit_ppe, skipping
mtk_unreg_dev(). The previously registered net_devices are then freed by
mtk_free_dev() while still in NETREG_REGISTERED state, hitting the
BUG_ON(dev->reg_state != NETREG_UNREGISTERED).
Route the register_netdev() failure to err_unreg_netdev so the net_devices
registered so far are properly unregistered before being freed.
Fixes: 8a8a9e89f801 ("net: ethernet: mediatek: cleanup error path inside mtk_hw_init")
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
Link: https://patch.msgid.link/20260916-mtk_eth_soc-netdev-fix-v1-1-5dac50eb65b1@oss.qualcomm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 42a4f52ecdc2d..4c9ebbb1b4f18 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4347,6 +4347,10 @@ static int mtk_unreg_dev(struct mtk_eth *eth)
mac = netdev_priv(eth->netdev[i]);
if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
unregister_netdevice_notifier(&mac->device_notifier);
+
+ if (eth->netdev[i]->reg_state != NETREG_REGISTERED)
+ continue;
+
unregister_netdev(eth->netdev[i]);
}
@@ -5128,7 +5132,7 @@ static int mtk_probe(struct platform_device *pdev)
err = register_netdev(eth->netdev[i]);
if (err) {
dev_err(eth->dev, "error bringing up device\n");
- goto err_deinit_ppe;
+ goto err_unreg_netdev;
} else
netif_info(eth, probe, eth->netdev[i],
"mediatek frame engine at 0x%08lx, irq %d\n",
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 361/877] ip6_gre: Call ip6erspan_tunnel_unlink_md() in ip6erspan_changelink().
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (359 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 360/877] net: ethernet: mtk_eth_soc: unregister net_devices in case of probe failure Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 362/877] eth: fbnic: Handle maximum standalone channels Greg Kroah-Hartman
` (523 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Xuanqiang Luo,
Ido Schimmel, Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit dd47bcf279f1083f09bf5266890b26263361022b ]
The cited commit accidentally added ip6gre_tunnel_unlink_md()
in ip6erspan_changelink().
Let's correct it to ip6erspan_tunnel_unlink_md().
Fixes: b80d0b93b991 ("net: ip6_gre: fix tunnel metadata device sharing.")
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260916230927.378957-1-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/ip6_gre.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 4b0c166fe7e24..ce1ba9d2af405 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -2314,7 +2314,7 @@ static int ip6erspan_changelink(struct net_device *dev, struct nlattr *tb[],
return PTR_ERR(t);
ip6erspan_set_version(data, &p);
- ip6gre_tunnel_unlink_md(ign, t);
+ ip6erspan_tunnel_unlink_md(ign, t);
ip6gre_tunnel_unlink(ign, t);
ip6erspan_tnl_change(t, &p, !tb[IFLA_MTU]);
ip6erspan_tunnel_link_md(ign, t);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 362/877] eth: fbnic: Handle maximum standalone channels
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (360 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 361/877] ip6_gre: Call ip6erspan_tunnel_unlink_md() in ip6erspan_changelink() Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 363/877] eth: fbnic: Set AW_FLUSH_MODE alongside AW_FLUSH when flushing the mailbox Greg Kroah-Hartman
` (522 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Björn Töpel, Simon Horman,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Björn Töpel <bjorn@kernel.org>
[ Upstream commit 1f4c73064a50f53d596c6f1d06d2d700f43c4b32 ]
Standalone channels use one NAPI vector for each Tx and Rx queue.
fbnic's allocation path excludes FBNIC_MAX_TXQS from that layout. A
64-Tx/64-Rx configuration therefore records 128 vectors but allocates
only 64, leaving NULL entries that resource setup dereferences.
Include the maximum vector count in standalone allocation.
Fixes: bc6107771bb4 ("eth: fbnic: Allocate a netdevice and napi vectors with queues")
Signed-off-by: Björn Töpel <bjorn@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/178942020457.7700.13129750616387075931.stgit@ahduyck-xeon-server.home.arpa
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
index 16a0e30f8aaa5..38e96b003ea05 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
@@ -1162,7 +1162,7 @@ int fbnic_alloc_napi_vectors(struct fbnic_net *fbn)
int err;
/* Allocate 1 Tx queue per napi vector */
- if (num_napi < FBNIC_MAX_TXQS && num_napi == num_tx + num_rx) {
+ if (num_napi <= FBNIC_MAX_TXQS && num_napi == num_tx + num_rx) {
while (num_tx) {
err = fbnic_alloc_napi_vector(fbd, fbn,
num_napi, v_idx,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 363/877] eth: fbnic: Set AW_FLUSH_MODE alongside AW_FLUSH when flushing the mailbox
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (361 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 362/877] eth: fbnic: Handle maximum standalone channels Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 364/877] sctp: avoid livelock while updating retransmit path Greg Kroah-Hartman
` (521 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alexander Duyck, Simon Horman,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Duyck <alexanderduyck@fb.com>
[ Upstream commit 8947f13e436a4ff5eed9f8f019b2865a07af4bb2 ]
When tearing down the FW mailbox Rx ring, fbnic_mbx_reset_desc_ring()
writes AW_CFG with FLUSH set and everything else, BME included, cleared.
Clearing BME halts the device's writes to the host but leaves the staged
requests parked in the PUL write pipeline rather than draining them, so
on the write path FLUSH alone never terminates the outstanding requests
and the flush the firmware waits on never completes.
Add the FLUSH_MODE definition and set both bits so the staged writes
drain out of the pipeline on their own. BME stays cleared, so nothing
lands on the host; it is restored later in fbnic_mbx_init_desc_ring()
when the ring is rebuilt, once the outstanding writes are gone.
The read path is unaffected. AR_CFG has no equivalent mode bit and
AR_FLUSH terminates the outstanding reads by itself, so it is left as
is.
Both writes remain plain stores rather than read-modify-writes. That is
deliberate: the matching write in fbnic_mbx_init_desc_ring() restores
BME and the TLP attributes, and clears both flush bits as a side effect.
Fixes: 3b12f00ddd08 ("fbnic: Gate AXI read/write enabling on FW mailbox")
Signed-off-by: Alexander Duyck <alexanderduyck@fb.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/178942022583.7700.11050671998277309744.stgit@ahduyck-xeon-server.home.arpa
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/meta/fbnic/fbnic_csr.h | 1 +
drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 9 ++++++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_csr.h b/drivers/net/ethernet/meta/fbnic/fbnic_csr.h
index e91b4432fddd7..2da0f5f8882bc 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_csr.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_csr.h
@@ -700,6 +700,7 @@ enum {
/* PUL User Registers */
#define FBNIC_CSR_START_PUL_USER 0x31000 /* CSR section delimiter */
#define FBNIC_PUL_OB_TLP_HDR_AW_CFG 0x3103d /* 0xc40f4 */
+#define FBNIC_PUL_OB_TLP_HDR_AW_CFG_FLUSH_MODE CSR_BIT(20)
#define FBNIC_PUL_OB_TLP_HDR_AW_CFG_FLUSH CSR_BIT(19)
#define FBNIC_PUL_OB_TLP_HDR_AW_CFG_BME CSR_BIT(18)
#define FBNIC_PUL_OB_TLP_HDR_AR_CFG 0x3103e /* 0xc40f8 */
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
index 6f606bdfd2296..175ad17bd47b5 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
@@ -60,8 +60,15 @@ static void fbnic_mbx_reset_desc_ring(struct fbnic_dev *fbd, int mbx_idx)
*/
switch (mbx_idx) {
case FBNIC_IPC_MBX_RX_IDX:
+ /* Clearing BME blocks the device from writing to the host
+ * but leaves the requests parked in the write pipeline. The
+ * write path only clears outstanding requests when both FLUSH
+ * and FLUSH_MODE are set; FLUSH_MODE lets them drain without
+ * landing on the host.
+ */
wr32(fbd, FBNIC_PUL_OB_TLP_HDR_AW_CFG,
- FBNIC_PUL_OB_TLP_HDR_AW_CFG_FLUSH);
+ FBNIC_PUL_OB_TLP_HDR_AW_CFG_FLUSH |
+ FBNIC_PUL_OB_TLP_HDR_AW_CFG_FLUSH_MODE);
break;
case FBNIC_IPC_MBX_TX_IDX:
wr32(fbd, FBNIC_PUL_OB_TLP_HDR_AR_CFG,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 364/877] sctp: avoid livelock while updating retransmit path
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (362 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 363/877] eth: fbnic: Set AW_FLUSH_MODE alongside AW_FLUSH when flushing the mailbox Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 365/877] bpf: Bound ownership depth through local kptrs and graph roots Greg Kroah-Hartman
` (520 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yiqi Sun, Xin Long, Jakub Kicinski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yiqi Sun <sunyiqixm@gmail.com>
[ Upstream commit d2c31b837406395e576afeb25958c98e9938f3f6 ]
sctp_assoc_update_retran_path() can loop forever when every remaining
transport, including retran_path, is SCTP_UNCONFIRMED: the state check
runs before the wraparound test, so the loop cannot observe that it has
completed a full pass.
Fix this by considering a transport only when it is not UNCONFIRMED,
then checking whether the walk has returned to retran_path. This makes
the full-pass termination independent of the transport state while
preserving the existing fallback selection semantics.
Also restore the NULL guard around the retran_path assignment. In the
all-UNCONFIRMED case there is no eligible replacement transport, and
installing NULL would leave later retransmit-path users and the debug
print with a NULL path.
Fixes: 4c47af4d5eb2 ("net: sctp: rework multihoming retransmission path selection to rfc4960")
Signed-off-by: Yiqi Sun <sunyiqixm@gmail.com>
Acked-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/20260915095017.942213-1-sunyiqixm@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sctp/associola.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index f409b9f6b228f..0a19aea3b5246 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1303,18 +1303,19 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc)
/* Manually skip the head element. */
if (&trans->transports == &asoc->peer.transport_addr_list)
continue;
- if (trans->state == SCTP_UNCONFIRMED)
- continue;
- trans_next = sctp_trans_elect_best(trans, trans_next);
- /* Active is good enough for immediate return. */
- if (trans_next->state == SCTP_ACTIVE)
- break;
+ if (trans->state != SCTP_UNCONFIRMED) {
+ trans_next = sctp_trans_elect_best(trans, trans_next);
+ /* Active is good enough for immediate return. */
+ if (trans_next->state == SCTP_ACTIVE)
+ break;
+ }
/* We've reached the end, time to update path. */
if (trans == asoc->peer.retran_path)
break;
}
- asoc->peer.retran_path = trans_next;
+ if (trans_next)
+ asoc->peer.retran_path = trans_next;
pr_debug("%s: association:%p updated new path to addr:%pISpc\n",
__func__, asoc, &asoc->peer.retran_path->ipaddr.sa);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 365/877] bpf: Bound ownership depth through local kptrs and graph roots
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (363 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 364/877] sctp: avoid livelock while updating retransmit path Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 366/877] net: usb: catc: bound the RX packet length in catc_rx_done() Greg Kroah-Hartman
` (519 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini,
Kumar Kartikeya Dwivedi, Alexei Starovoitov, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
[ Upstream commit bfc888f04588f591851e95c974954cfca58e6c19 ]
Program-allocated objects can own other local objects through referenced
kptrs. bpf_obj_free_fields() follows those pointers through
__bpf_obj_drop_impl() synchronously, before the object storage is freed
through RCU. A self-referential local kptr type therefore permits arbitrarily
deep object chains, and dropping the head can exhaust the kernel stack.
Long acyclic type chains have the same problem.
btf_check_and_fixup_fields() still assumes referenced kptrs only point to
kernel types and checks ownership through list and rbtree roots only. Its
existing rule is sufficient for graph-only cycles: the target of each graph
edge must contain a node, so every type in a cycle has both a root and a
node. The rule rejects such a type owning another root, breaking every
cycle. It also limits graph-only chains to three types, or two if the first
type contains a node, and conservatively rejects longer acyclic chains.
The missing local-kptr edges, rather than a missed graph-only cycle, are the
bug introduced by support for bpf_kptr_xchg() into local kptrs.
Replace that restriction with one bounded ownership walk covering graph
roots and local referenced kptrs. Run it after all BTF records have been
fixed up, reject cycles and paths deeper than eight record-bearing types,
and cache each type's suffix depth while checking it against the remaining
budget. This also permits the longer acyclic graph-only layouts rejected
by the old rule; update their existing BTF tests accordingly.
Keep the bound independent of MAX_CALL_FRAMES because recursive destruction
can run below a BPF call chain. A plain local pointee without special-field
metadata adds only a final non-recursing drop. Non-owning kptrs and
kernel-BTF kptrs do not recurse through local records and remain outside the
walk. Include local percpu-kptr edges too, although allocation of percpu
objects with special fields is currently forbidden, so that relaxing that
restriction cannot bypass the ownership bound.
btf_check_and_fixup_fields() continues to initialize graph_root.value_rec,
including for separately allocated map records. The ownership relationships
belong to immutable program BTF and only need validation at BTF load time.
Fixes: b0966c724584 ("bpf: Support bpf_kptr_xchg into local kptr")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20260914132444.2564218-2-memxor@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/btf.c | 134 +++++++++++-------
.../selftests/bpf/prog_tests/linked_list.c | 4 +-
2 files changed, 88 insertions(+), 50 deletions(-)
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 0c040c2e8c4f5..5f3b1162208b5 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -4062,13 +4062,10 @@ int btf_check_and_fixup_fields(const struct btf *btf, struct btf_record *rec)
{
int i;
- /* There are three types that signify ownership of some other type:
- * kptr_ref, bpf_list_head, bpf_rb_root.
- * kptr_ref only supports storing kernel types, which can't store
- * references to program allocated local types.
- *
- * Hence we only need to ensure that bpf_{list_head,rb_root} ownership
- * does not form cycles.
+ /*
+ * Check fields which require the complete BTF and initialize runtime
+ * metadata. Ownership relationships are validated after every record has
+ * been fixed up.
*/
if (IS_ERR_OR_NULL(rec) || !(rec->field_mask & BPF_GRAPH_ROOT))
return 0;
@@ -4083,51 +4080,88 @@ int btf_check_and_fixup_fields(const struct btf *btf, struct btf_record *rec)
if (!meta)
return -EFAULT;
rec->fields[i].graph_root.value_rec = meta->record;
+ }
+ return 0;
+}
- /* We need to set value_rec for all root types, but no need
- * to check ownership cycle for a type unless it's also a
- * node type.
- */
- if (!(rec->field_mask & BPF_GRAPH_NODE))
+static int btf_owned_type_idx(const struct btf *btf, struct btf_struct_metas *tab,
+ const struct btf_field *field)
+{
+ struct btf_struct_meta *meta;
+ u32 btf_id;
+
+ if (field->type & BPF_GRAPH_ROOT) {
+ btf_id = field->graph_root.value_btf_id;
+ } else if (field->type == BPF_KPTR_REF || field->type == BPF_KPTR_PERCPU) {
+ if (btf_is_kernel(field->kptr.btf))
+ return -ENOENT;
+ btf_id = field->kptr.btf_id;
+ } else {
+ return -ENOENT;
+ }
+
+ meta = btf_find_struct_meta(btf, btf_id);
+ if (!meta)
+ return field->type & BPF_GRAPH_ROOT ? -EFAULT : -ENOENT;
+ return meta - tab->types;
+}
+
+/*
+ * Each ownership edge adds kernel frames through bpf_obj_free_fields() and
+ * __bpf_obj_drop_impl(). Keep the bound deliberately small because object
+ * destruction can itself run below a BPF call chain. A final pointee without
+ * special fields is not present in the struct metadata table and adds only a
+ * non-recursing drop.
+ */
+#define BTF_MAX_OWNERSHIP_DEPTH 8
+
+static int btf_ownership_depth(const struct btf *btf,
+ struct btf_struct_metas *tab, u8 *depth,
+ int idx, int depth_left)
+{
+ const struct btf_record *rec = tab->types[idx].record;
+ int i, ret, max_depth = 0;
+
+ if (!depth_left)
+ return -ELOOP;
+ if (depth[idx])
+ goto done;
+
+ for (i = 0; i < rec->cnt; i++) {
+ ret = btf_owned_type_idx(btf, tab, &rec->fields[i]);
+ if (ret == -ENOENT)
continue;
+ if (ret < 0)
+ return ret;
+ ret = btf_ownership_depth(btf, tab, depth, ret, depth_left - 1);
+ if (ret < 0)
+ return ret;
+ max_depth = max(max_depth, ret);
+ }
+ depth[idx] = max_depth + 1;
+done:
+ return depth[idx] > depth_left ? -ELOOP : depth[idx];
+}
- /* We need to ensure ownership acyclicity among all types. The
- * proper way to do it would be to topologically sort all BTF
- * IDs based on the ownership edges, since there can be multiple
- * bpf_{list_head,rb_node} in a type. Instead, we use the
- * following resaoning:
- *
- * - A type can only be owned by another type in user BTF if it
- * has a bpf_{list,rb}_node. Let's call these node types.
- * - A type can only _own_ another type in user BTF if it has a
- * bpf_{list_head,rb_root}. Let's call these root types.
- *
- * We ensure that if a type is both a root and node, its
- * element types cannot be root types.
- *
- * To ensure acyclicity:
- *
- * When A is an root type but not a node, its ownership
- * chain can be:
- * A -> B -> C
- * Where:
- * - A is an root, e.g. has bpf_rb_root.
- * - B is both a root and node, e.g. has bpf_rb_node and
- * bpf_list_head.
- * - C is only an root, e.g. has bpf_list_node
- *
- * When A is both a root and node, some other type already
- * owns it in the BTF domain, hence it can not own
- * another root type through any of the ownership edges.
- * A -> B
- * Where:
- * - A is both an root and node.
- * - B is only an node.
- */
- if (meta->record->field_mask & BPF_GRAPH_ROOT)
- return -ELOOP;
+static int btf_check_ownership_depth(const struct btf *btf,
+ struct btf_struct_metas *tab)
+{
+ u8 *depth;
+ int i, ret = 0;
+
+ depth = kvcalloc(tab->cnt, sizeof(*depth), GFP_KERNEL | __GFP_NOWARN);
+ if (!depth)
+ return -ENOMEM;
+
+ for (i = 0; i < tab->cnt; i++) {
+ ret = btf_ownership_depth(btf, tab, depth, i,
+ BTF_MAX_OWNERSHIP_DEPTH);
+ if (ret < 0)
+ break;
+ ret = 0;
}
- return 0;
+ kvfree(depth);
+ return ret;
}
static void __btf_struct_show(const struct btf *btf, const struct btf_type *t,
@@ -5811,6 +5845,10 @@ static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u32 uat
if (err < 0)
goto errout_meta;
}
+
+ err = btf_check_ownership_depth(btf, struct_meta_tab);
+ if (err < 0)
+ goto errout_meta;
}
err = finalize_log(&env->log, uattr, uattr_size);
diff --git a/tools/testing/selftests/bpf/prog_tests/linked_list.c b/tools/testing/selftests/bpf/prog_tests/linked_list.c
index 77d07e0a4a55c..5744909a561b2 100644
--- a/tools/testing/selftests/bpf/prog_tests/linked_list.c
+++ b/tools/testing/selftests/bpf/prog_tests/linked_list.c
@@ -711,7 +711,7 @@ static void test_btf(void)
break;
err = btf__load_into_kernel(btf);
- ASSERT_EQ(err, -ELOOP, "check btf");
+ ASSERT_EQ(err, 0, "check btf");
btf__free(btf);
break;
}
@@ -770,7 +770,7 @@ static void test_btf(void)
break;
err = btf__load_into_kernel(btf);
- ASSERT_EQ(err, -ELOOP, "check btf");
+ ASSERT_EQ(err, 0, "check btf");
btf__free(btf);
break;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 366/877] net: usb: catc: bound the RX packet length in catc_rx_done()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (364 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 365/877] bpf: Bound ownership depth through local kptrs and graph roots Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 367/877] bpf: Check params size before reading reserved fields Greg Kroah-Hartman
` (518 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aamir Ahmed, Simon Horman,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aamir Ahmed <elb12345@hotmail.co.uk>
[ Upstream commit 9d565b6b72fe3f41fd43636e143072848105189f ]
catc_rx_done() walks a multi-packet URB, reading a two-byte length from
each packet header. Its bound, pkt_len > urb->actual_length, ignores the
header offset and compares against the whole transfer rather than the
bytes left from pkt_start, so a crafted packet header makes
skb_copy_to_linear_data() read past the buffer.
A length below ETH_HLEN is also accepted, including zero, and
eth_type_trans() then reads a MAC header from the uninitialised tailroom
of a shorter skb. The is_f5u011 branch takes its length straight from
the transfer, so a zero-length URB reaches the same path.
Track the bytes remaining from the current packet, and reject a header
that does not fit, a length past what is left, and a length below an
Ethernet header.
A transfer shorter than an Ethernet header, including a zero-length one,
previously became a runt skb passed to netif_rx() and counted as
received; it is now counted in rx_length_errors and ends the walk.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Aamir Ahmed <elb12345@hotmail.co.uk>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/AS8P251MB00015FD7716F38C345619B56C8BB2@AS8P251MB0001.EURP251.PROD.OUTLOOK.COM
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/usb/catc.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
index 98346cb4ece01..dd1e29add0609 100644
--- a/drivers/net/usb/catc.c
+++ b/drivers/net/usb/catc.c
@@ -239,17 +239,26 @@ static void catc_rx_done(struct urb *urb)
}
do {
- if(!catc->is_f5u011) {
- pkt_len = le16_to_cpup((__le16*)pkt_start);
- if (pkt_len > urb->actual_length) {
+ int remaining = urb->actual_length -
+ (pkt_start - (u8 *)urb->transfer_buffer);
+
+ if (!catc->is_f5u011) {
+ if (remaining < pkt_offset) {
catc->netdev->stats.rx_length_errors++;
catc->netdev->stats.rx_errors++;
break;
}
+ pkt_len = le16_to_cpup((__le16 *)pkt_start);
} else {
pkt_len = urb->actual_length;
}
+ if (pkt_len < ETH_HLEN || pkt_len + pkt_offset > remaining) {
+ catc->netdev->stats.rx_length_errors++;
+ catc->netdev->stats.rx_errors++;
+ break;
+ }
+
if (!(skb = dev_alloc_skb(pkt_len)))
return;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 367/877] bpf: Check params size before reading reserved fields
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (365 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 366/877] net: usb: catc: bound the RX packet length in catc_rx_done() Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 368/877] net/sched: sch_hfsc: bound the classify inner-filter walk with a drift budget Greg Kroah-Hartman
` (517 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Yuqi Xu, Alexei Starovoitov,
Ren Wei, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuqi Xu <xuyuqiabc@gmail.com>
[ Upstream commit a11212910cf09b2fe8db9afa41ef60c4f81879c5 ]
bpf_crypto_ctx_create() is a kfunc whose second argument is declared
with the __sz annotation, so the verifier only guarantees that
params__sz bytes of params are valid. The function nevertheless reads
params->reserved[0] and params->reserved[1] (offsets 14 and 15) before
comparing params__sz against the size of struct bpf_crypto_params, so a
BPF program can pass a shorter buffer and have the kernel read past the
region that was validated for it.
Move the size check in front of the reserved field reads.
Fixes: 3e1c6f35409f ("bpf: make common crypto API for TC/XDP programs")
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Yuqi Xu <xuyuqiabc@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Reviewed-by: Ren Wei <weir@nebusec.ai>
Link: https://patch.msgid.link/4f3ab4b03e79017e215521743996555439bf0bb3.1789802413.git.xuyuqiabc@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/crypto.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/crypto.c b/kernel/bpf/crypto.c
index 1d024fe7248ac..3837d4dcf48d5 100644
--- a/kernel/bpf/crypto.c
+++ b/kernel/bpf/crypto.c
@@ -149,8 +149,9 @@ bpf_crypto_ctx_create(const struct bpf_crypto_params *params, u32 params__sz,
const struct bpf_crypto_type *type;
struct bpf_crypto_ctx *ctx;
- if (!params || params->reserved[0] || params->reserved[1] ||
- params__sz != sizeof(struct bpf_crypto_params)) {
+ if (!params ||
+ params__sz != sizeof(struct bpf_crypto_params) ||
+ params->reserved[0] || params->reserved[1]) {
*err = -EINVAL;
return NULL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 368/877] net/sched: sch_hfsc: bound the classify inner-filter walk with a drift budget
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (366 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 367/877] bpf: Check params size before reading reserved fields Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 369/877] drm/virtio: fix object leak when drm_gem_handle_create() fails Greg Kroah-Hartman
` (516 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko (gemini + nipa),
Victor Nogueira, hybris, Jamal Hadi Salim, Jakub Kicinski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
[ Upstream commit 8a60ade2277e1f0e0d0578d565354e52292fa46d ]
hfsc_classify() applies the "filter may only point downwards" level check
only when the filter result carries no bound class. A filter created with
a flowid gets res.class set once at bind time, so the check never runs for
it during classification. hfsc_adjust_levels() can later raise a class's
level without revalidating existing bindings, leaving two binds that were
each legal at bind time pointing at each other; the classify walk then
bounces between two interior classes forever with the qdisc lock held and
BH disabled — a soft lockup from a single packet. The stuck walk trips
the watchdog:
watchdog: BUG: soft lockup - CPU#3 stuck for 13s! [ping:444]
RIP: 0010:u32_classify+0x542/0x17f0
...
tcf_classify+0x66/0xa0
hfsc_enqueue+0x166/0xdf0
Bound the traversal with a budget of non-descending hops, the only way a
configured walk can move without descending the class tree once levels
drift after bind time. The budget is cumulative over the whole walk and
is deliberately not reset on a descending hop: a chain that alternates a
descent with a lateral hop would return the budget every lap and never
trip. Descending hops never decrement it, so legitimately deep trees are
unaffected and a terminating lateral chain still classifies normally.
Drop the packet with a rate-limited warning once the budget is exhausted,
mirroring the merged HTB fix.
This is a follow-up to commit 729c4896ab82 ("net/sched: sch_htb: limit
htb_classify inner-class filter hops"), which bounded the same classify
loop on the HTB side but left the HFSC walk unbounded.
Conditions to recreate the bug:
- CONFIG_NET_SCHED, CONFIG_NET_SCH_HFSC, CONFIG_NET_CLS_U32,
CONFIG_LOCKUP_DETECTOR.
- Build a cycle with two legal-at-bind-time flowid binds and a level
drift: class X 1:1 (child of root) with leaf child 1:10; class Y 1:2
(sibling of X) with children 1:20 and 1:200; root u32 filter flowid
1:1; filter on X flowid 1:2 (legal when Y is a leaf); after Y's level
rises to 2, filter on Y flowid 1:1 (legal then). Send one packet (ping
on the device). Unfixed kernel: classify spins with the qdisc lock
held; with softlockup_panic=1 it panics.
- Reachable from unprivileged user via unshare -Urn (CAP_NET_ADMIN).
Fixes: a2f79227138c ("net_sched: sch_hfsc: fix classification loops")
Reported-by: Sashiko (gemini + nipa) <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/netdev/QDISC-CTUU.v2.20260913192614@mojatatu.com/
Link: https://sashiko.dev/#/patchset/QDISC-CTUU.v2.20260913192614@mojatatu.com
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/QDISC-CTUU.v2.20260913192614%40mojatatu.com
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Tested-by: hybris <hybris@mojatatu.ai>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-CTUU.v3.20260916184908@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/sch_hfsc.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 601f99dd989ae..df3501dfe01a8 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -386,6 +386,15 @@ cftree_update(struct hfsc_class *cl)
#define SM_MASK ((1ULL << SM_SHIFT) - 1)
#define ISM_MASK ((1ULL << ISM_SHIFT) - 1)
+/*
+ * Cap on the non-descending hops a classify walk may take before its
+ * filter chain is treated as misconfigured. A flowid binding that was
+ * legal at bind time can become lateral once hfsc_adjust_levels()
+ * raises a class level; a few such hops are legitimate, an unbounded
+ * run means the chain cycles.
+ */
+#define HFSC_CLASSIFY_MAX_DRIFT 8
+
static inline u64
seg_x2y(u64 x, u64 sm)
{
@@ -1133,6 +1142,7 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
struct hfsc_class *head, *cl;
struct tcf_result res;
struct tcf_proto *tcf;
+ unsigned int drift;
int result;
if (TC_H_MAJ(skb->priority ^ sch->handle) == 0 &&
@@ -1142,6 +1152,7 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
head = &q->root;
+ drift = HFSC_CLASSIFY_MAX_DRIFT;
tcf = rcu_dereference_bh(q->root.filter_list);
while (tcf && (result = tcf_classify(skb, NULL, tcf, &res, false)) >= 0) {
#ifdef CONFIG_NET_CLS_ACT
@@ -1167,6 +1178,17 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
if (cl->level == 0)
return cl; /* hit leaf class */
+ /*
+ * flowid binds skip the level check above (res.class is set
+ * at bind time and levels drift after), so a walk can follow
+ * lateral hops without descending; a bounded number of them
+ * is legal, more means the chain cycles.
+ */
+ if (cl->level >= head->level && drift-- == 0) {
+ pr_warn_ratelimited("hfsc: classify hop budget exhausted, dropping packet\n");
+ return NULL;
+ }
+
/* apply inner filter chain */
tcf = rcu_dereference_bh(cl->filter_list);
head = cl;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 369/877] drm/virtio: fix object leak when drm_gem_handle_create() fails
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (367 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 368/877] net/sched: sch_hfsc: bound the classify inner-filter walk with a drift budget Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 370/877] drm/virtio: fix object leak in virtio_gpu_resource_create_ioctl() Greg Kroah-Hartman
` (515 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yuhao Jiang, Junrui Luo,
Dmitry Osipenko, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junrui Luo <moonafterrain@outlook.com>
[ Upstream commit 36570ef2244cc4d7563b1f0157bc0f032498638c ]
virtio_gpu_gem_create() owns the reference taken by
virtio_gpu_object_create(). On the drm_gem_handle_create() error path it
calls drm_gem_object_release() instead of dropping that reference.
drm_gem_object_release() is the inverse of drm_gem_object_init() and does
not touch the reference count or call obj->funcs->free(), so it is only
correct as the last step of a destructor, as in
virtio_gpu_cleanup_object(). Using it here leaves the bo at refcount 1
with no remaining reference, so virtio_gpu_free_object() never runs and
the shmem pages, sg table and virtio_gpu_object are leaked. Since
virtio_gpu_object_create() has already set bo->created,
VIRTIO_GPU_CMD_RESOURCE_UNREF is not queued either, leaking the host-side
resource and the resource id.
drm_gem_handle_create_tail() drops the handle reference on all of its
internal error paths, so the caller only has to drop its own. Use
drm_gem_object_put(), matching the success path below.
Fixes: dc5698e80cf7 ("Add virtio gpu driver.")
Reported-by: Yuhao Jiang <danisjiang@gmail.com>
Assisted-by: Claude:claude-opus-5
Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patch.msgid.link/20260915-fixes-v2-1-a0d799e4db66@outlook.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/virtio/virtgpu_gem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c
index 2e75cdeb49b3d..0233a1c3181c5 100644
--- a/drivers/gpu/drm/virtio/virtgpu_gem.c
+++ b/drivers/gpu/drm/virtio/virtgpu_gem.c
@@ -45,7 +45,7 @@ static int virtio_gpu_gem_create(struct drm_file *file,
ret = drm_gem_handle_create(file, &obj->base.base, &handle);
if (ret) {
- drm_gem_object_release(&obj->base.base);
+ drm_gem_object_put(&obj->base.base);
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 370/877] drm/virtio: fix object leak in virtio_gpu_resource_create_ioctl()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (368 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 369/877] drm/virtio: fix object leak when drm_gem_handle_create() fails Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 371/877] drm/virtio: fix object leaks in virtio_gpu_resource_create_blob_ioctl() Greg Kroah-Hartman
` (514 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Junrui Luo, Dmitry Osipenko,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junrui Luo <moonafterrain@outlook.com>
[ Upstream commit 477bc3068fc3777b9d8ffd79e265b0dfdf2d3a6b ]
virtio_gpu_resource_create_ioctl() calls drm_gem_object_release() on the
drm_gem_handle_create() error path instead of dropping the reference it
owns, so obj->funcs->free() never runs and the virtio_gpu_object, its
pages and sg table, the resource id and the host-side resource are
leaked.
Use drm_gem_object_put() instead.
Fixes: 62fb7a5e1096 ("virtio-gpu: add 3d/virgl support")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patch.msgid.link/20260915-fixes-v2-2-a0d799e4db66@outlook.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/virtio/virtgpu_ioctl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index e4f76f3155504..60e5146ddefec 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -180,7 +180,7 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
ret = drm_gem_handle_create(file, obj, &handle);
if (ret) {
- drm_gem_object_release(obj);
+ drm_gem_object_put(obj);
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 371/877] drm/virtio: fix object leaks in virtio_gpu_resource_create_blob_ioctl()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (369 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 370/877] drm/virtio: fix object leak in virtio_gpu_resource_create_ioctl() Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 372/877] drm/virtio: release the GEM object on virtio_gpu_vram_create() errors Greg Kroah-Hartman
` (513 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Junrui Luo, Dmitry Osipenko,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junrui Luo <moonafterrain@outlook.com>
[ Upstream commit 24b6d5c7641412c9ebef0d4c8b888d49a0e6b880 ]
virtio_gpu_resource_create_blob_ioctl() calls drm_gem_object_release() on
both the virtio_gpu_resource_assign_uuid() and drm_gem_handle_create()
error paths instead of dropping the reference it owns, so
obj->funcs->free() never runs and the virtio_gpu_object, the resource id
and the host-side resource are leaked.
Use drm_gem_object_put() instead.
Fixes: 897b4d1acaf5 ("drm/virtio: implement blob resources: resource create blob ioctl")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patch.msgid.link/20260915-fixes-v2-3-a0d799e4db66@outlook.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/virtio/virtgpu_ioctl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index 60e5146ddefec..d8aec5112b326 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -546,14 +546,14 @@ static int virtio_gpu_resource_create_blob_ioctl(struct drm_device *dev,
if (params.blob_flags & VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE) {
ret = virtio_gpu_resource_assign_uuid(vgdev, bo);
if (ret) {
- drm_gem_object_release(obj);
+ drm_gem_object_put(obj);
return ret;
}
}
ret = drm_gem_handle_create(file, obj, &handle);
if (ret) {
- drm_gem_object_release(obj);
+ drm_gem_object_put(obj);
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 372/877] drm/virtio: release the GEM object on virtio_gpu_vram_create() errors
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (370 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 371/877] drm/virtio: fix object leaks in virtio_gpu_resource_create_blob_ioctl() Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 373/877] drm/bridge: samsung-dsim: fix TE GPIO lifetime for host attach Greg Kroah-Hartman
` (512 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Junrui Luo, Dmitry Osipenko,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junrui Luo <moonafterrain@outlook.com>
[ Upstream commit 036d28db1818af2f9d80db771f5405da84d7732d ]
virtio_gpu_vram_create() frees the object with a bare kfree(vram) on
both error paths after drm_gem_private_object_init() has run, and on the
second one after drm_gem_create_mmap_offset() has linked obj->vma_node
into the device's VMA offset manager. The freed object stays in that
interval tree, so a later lookup or insertion walks freed memory, and
the dma_resv and gpuva lock are never destroyed.
Call drm_gem_object_release() before kfree() on both paths.
Fixes: 16845c5d5409 ("drm/virtio: implement blob resources: implement vram object")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patch.msgid.link/20260915-fixes-v2-4-a0d799e4db66@outlook.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/virtio/virtgpu_vram.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_vram.c b/drivers/gpu/drm/virtio/virtgpu_vram.c
index 25df81c027837..47a886824cd71 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vram.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vram.c
@@ -202,16 +202,12 @@ int virtio_gpu_vram_create(struct virtio_gpu_device *vgdev,
/* Create fake offset */
ret = drm_gem_create_mmap_offset(obj);
- if (ret) {
- kfree(vram);
- return ret;
- }
+ if (ret)
+ goto err_release_obj;
ret = virtio_gpu_resource_id_get(vgdev, &vram->base.hw_res_handle);
- if (ret) {
- kfree(vram);
- return ret;
- }
+ if (ret)
+ goto err_release_obj;
virtio_gpu_cmd_resource_create_blob(vgdev, &vram->base, params, NULL,
0);
@@ -225,4 +221,9 @@ int virtio_gpu_vram_create(struct virtio_gpu_device *vgdev,
*bo_ptr = &vram->base;
return 0;
+
+err_release_obj:
+ drm_gem_object_release(obj);
+ kfree(vram);
+ return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 373/877] drm/bridge: samsung-dsim: fix TE GPIO lifetime for host attach
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (371 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 372/877] drm/virtio: release the GEM object on virtio_gpu_vram_create() errors Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 374/877] Bluetooth: bnep: fix out-of-bounds reads on short RX/TX frames and control fallthrough Greg Kroah-Hartman
` (511 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Luca Ceresoli, Li Youhong,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Youhong <liyouhong@kylinos.cn>
[ Upstream commit ada667890773e033d2f40dc94176e3beb930b516 ]
When the Exynos DSI driver was generalized into samsung-dsim, the TE
GPIO acquisition was switched from gpiod_get_optional() to
devm_gpiod_get_optional() while keeping the matching gpiod_put() calls.
That combination is wrong for a managed descriptor.
However, dropping the puts and keeping the managed get is also wrong:
samsung_dsim_register_te_irq() runs from the DSI host attach callback,
and host detach/reattach can happen without destroying the device that
owns the managed action. A second attach would then request the GPIO
again without having released it.
Switch back to a non-managed gpiod_get_optional() and keep the explicit
gpiod_put() on the request_irq() error path and in
samsung_dsim_unregister_te_irq().
Fixes: e7447128ca4a ("drm: bridge: Generalize Exynos-DSI driver into a Samsung DSIM bridge")
Suggested-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Li Youhong <liyouhong@kylinos.cn>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Tested-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Link: https://patch.msgid.link/20260904014958.1572918-1-dayou5941@163.com
[Luca: remove unnecessary comment]
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/bridge/samsung-dsim.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c
index f3f836da6c2a7..b13c68cf725c8 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -1678,7 +1678,7 @@ static int samsung_dsim_register_te_irq(struct samsung_dsim *dsi, struct device
int te_gpio_irq;
int ret;
- dsi->te_gpio = devm_gpiod_get_optional(dev, "te", GPIOD_IN);
+ dsi->te_gpio = gpiod_get_optional(dev, "te", GPIOD_IN);
if (!dsi->te_gpio)
return 0;
else if (IS_ERR(dsi->te_gpio))
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 374/877] Bluetooth: bnep: fix out-of-bounds reads on short RX/TX frames and control fallthrough
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (372 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 373/877] drm/bridge: samsung-dsim: fix TE GPIO lifetime for host attach Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 375/877] Bluetooth: btintel_pcie: validate device-supplied DMA indices Greg Kroah-Hartman
` (510 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hui Peng, Luiz Augusto von Dentz,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Peng <benquike@gmail.com>
[ Upstream commit f0ca020cbb9bb7f3f4ea8ba1dfcf30a282aec91e ]
Fix multiple out-of-bounds reads in Bluetooth BNEP frame processing:
1. In bnep_rx_frame() and bnep_ctrl_frame() (net/bluetooth/bnep/core.c),
use pskb_may_pull() to verify the BNEP header, control type byte,
filter count, and extension headers exist before reading them, and
return 0 after handling BNEP_CONTROL instead of falling through to
Ethernet frame submission when no extension headers follow.
2. In bnep_net_xmit() (net/bluetooth/bnep/netdev.c), verify skb->len >=
ETH_HLEN with pskb_may_pull() before reading the 14-byte Ethernet
header to prevent an out-of-bounds heap read and infoleak on short
AF_PACKET TX frames.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Assisted-by: LLM
Signed-off-by: Hui Peng <benquike@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/bnep/core.c | 17 ++++++++++++++++-
net/bluetooth/bnep/netdev.c | 8 +++++++-
2 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index ed3ca38d8a6e1..e93c79982abcc 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -273,9 +273,14 @@ static int bnep_rx_extension(struct bnep_session *s, struct sk_buff *skb)
BT_DBG("type 0x%x len %u", h->type, h->len);
+ if (skb->len < h->len) {
+ err = -EILSEQ;
+ break;
+ }
+
switch (h->type & BNEP_TYPE_MASK) {
case BNEP_EXT_CONTROL:
- bnep_rx_control(s, skb->data, skb->len);
+ bnep_rx_control(s, skb->data, h->len);
break;
default:
@@ -376,6 +381,11 @@ static int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
goto badframe;
}
+ if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) {
+ kfree_skb(skb);
+ return 0;
+ }
+
/* Strip 802.1p header */
if (ntohs(s->eh.h_proto) == ETH_P_8021Q) {
if (!skb_pull(skb, 4))
@@ -454,6 +464,11 @@ static int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb)
goto send;
}
+ if (skb->len < ETH_HLEN) {
+ kfree_skb(skb);
+ return 0;
+ }
+
iv[il++] = (struct kvec) { &type, 1 };
len++;
diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c
index cc1cff63194f0..5d9d851db926f 100644
--- a/net/bluetooth/bnep/netdev.c
+++ b/net/bluetooth/bnep/netdev.c
@@ -169,6 +169,12 @@ static netdev_tx_t bnep_net_xmit(struct sk_buff *skb,
BT_DBG("skb %p, dev %p", skb, dev);
+ if (!pskb_may_pull(skb, ETH_HLEN)) {
+ dev->stats.tx_dropped++;
+ kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
#ifdef CONFIG_BT_BNEP_MC_FILTER
if (bnep_net_mc_filter(skb, s)) {
kfree_skb(skb);
@@ -221,7 +227,7 @@ void bnep_net_setup(struct net_device *dev)
dev->addr_len = ETH_ALEN;
ether_setup(dev);
- dev->min_mtu = 0;
+ dev->min_mtu = ETH_MIN_MTU;
dev->max_mtu = ETH_MAX_MTU;
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
dev->netdev_ops = &bnep_netdev_ops;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 375/877] Bluetooth: btintel_pcie: validate device-supplied DMA indices
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (373 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 374/877] Bluetooth: bnep: fix out-of-bounds reads on short RX/TX frames and control fallthrough Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 376/877] Bluetooth: RFCOMM: Reject short EA=0 frames in rfcomm_recv_frame() Greg Kroah-Hartman
` (509 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ravindra, Luiz Augusto von Dentz,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ravindra <ravindra@intel.com>
[ Upstream commit 37a11129345337efd6eef8e62b03b6348cd0dd8b ]
In btintel_pcie_msix_rx_handle(), the driver processes RX completion
descriptors (urbd1) written by the PCIe device into DMA-coherent memory.
urbd1->frbd_tag (a 16-bit field fully controlled by the device firmware
via DMA) is used directly as an array index into rxq->bufs[] without any
bounds check. rxq->bufs[] has only BTINTEL_PCIE_RX_DESCS_COUNT (64)
entries, while frbd_tag can be any value 0-65535. A malicious or
malfunctioning device can write an out-of-range frbd_tag, causing the
driver to dereference an out-of-bounds data_buf pointer.
Additionally, cr_hia is read from a DMA-shared index array also writable
by the device; if the device sets cr_hia >= rxq->count, the while-loop
never terminates because cr_tia is wrapped via modulo rxq->count and can
never equal an out-of-range cr_hia.
Add bounds validation for cr_hia and frbd_tag in the RX path, and cr_hia
in the TX path. Log invalid values with bt_dev_err before returning.
Fixes: c2b636b3f788 ("Bluetooth: btintel_pcie: Add support for PCIe transport")
Signed-off-by: Ravindra <ravindra@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btintel_pcie.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index bc87ebc46f4db..9facd47ff89b9 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -513,6 +513,11 @@ static void btintel_pcie_msix_tx_handle(struct btintel_pcie_data *data)
txq = &data->txq;
+ if (cr_hia >= txq->count) {
+ bt_dev_err(data->hdev, "TXQ: invalid cr_hia %u", cr_hia);
+ return;
+ }
+
while (cr_tia != cr_hia) {
data->tx_wait_done = true;
wake_up(&data->tx_wait_q);
@@ -786,6 +791,11 @@ static void btintel_pcie_msix_rx_handle(struct btintel_pcie_data *data)
rxq = &data->rxq;
+ if (cr_hia >= rxq->count) {
+ bt_dev_err(hdev, "RXQ: invalid cr_hia %u", cr_hia);
+ return;
+ }
+
/* The firmware sends multiple CD in a single MSI-X and it needs to
* process all received CDs in this interrupt.
*/
@@ -793,6 +803,12 @@ static void btintel_pcie_msix_rx_handle(struct btintel_pcie_data *data)
urbd1 = &rxq->urbd1s[cr_tia];
ipc_print_urbd1(data->hdev, urbd1, cr_tia);
+ if (urbd1->frbd_tag >= rxq->count) {
+ bt_dev_err(hdev, "RXQ: invalid frbd_tag %u",
+ urbd1->frbd_tag);
+ return;
+ }
+
buf = &rxq->bufs[urbd1->frbd_tag];
if (!buf) {
bt_dev_err(hdev, "RXQ: failed to get the DMA buffer for %d",
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 376/877] Bluetooth: RFCOMM: Reject short EA=0 frames in rfcomm_recv_frame()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (374 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 375/877] Bluetooth: btintel_pcie: validate device-supplied DMA indices Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 377/877] octeontx2-af: Fix memory scaling limitation in SR-IOV mode Greg Kroah-Hartman
` (508 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hui Peng, Luiz Augusto von Dentz,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Peng <benquike@gmail.com>
[ Upstream commit 6d91041bb38b97e2feb625123cc0529d7b83a0e1 ]
While rfcomm_recv_frame() verifies that skb->len is at least
sizeof(*hdr) + 1 (4 bytes: 3-byte header + 1-byte FCS), an RFCOMM frame
with an extended 2-byte length field (!__test_ea(hdr->len)) has a 4-byte
header plus a 1-byte FCS (5 bytes minimum, sizeof(*hdr) + 2).
When a 4-byte RFCOMM frame with EA == 0 arrives:
1. The initial skb->len < sizeof(*hdr) + 1 check passes (4 < 4 is false).
2. Trimming the FCS byte decrements skb->len to 3.
3. If __check_fcs() succeeds, skb_pull(skb, 4) fails (4 > 3) and returns
NULL without advancing skb->data.
4. Because the return value of skb_pull() is ignored, the un-pulled
3-byte struct rfcomm_hdr remains at skb->data and is either queued as
application payload via rfcomm_recv_data() or parsed as a multiplexer
control command via rfcomm_recv_mcc() on DLCI 0.
Fix this by extending the length check in rfcomm_recv_frame() to also
require skb->len >= sizeof(*hdr) + 2 when !__test_ea(hdr->len).
Fixes: b230e5bf501c ("Bluetooth: RFCOMM: validate skb length in rfcomm_recv_frame")
Assisted-by: LLM
Signed-off-by: Hui Peng <benquike@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/rfcomm/core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 5dc575833371a..6c57f5a766c17 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -1817,7 +1817,8 @@ static struct rfcomm_session *rfcomm_recv_frame(struct rfcomm_session *s,
return s;
}
- if (skb->len < sizeof(*hdr) + 1) {
+ if (skb->len < sizeof(*hdr) + 1 ||
+ (!__test_ea(hdr->len) && skb->len < sizeof(*hdr) + 2)) {
kfree_skb(skb);
return s;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 377/877] octeontx2-af: Fix memory scaling limitation in SR-IOV mode
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (375 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 376/877] Bluetooth: RFCOMM: Reject short EA=0 frames in rfcomm_recv_frame() Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 378/877] dpll: use exact lookup for reference sync pin id Greg Kroah-Hartman
` (507 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Leon Romanovsky, Ratheesh Kannoth,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ratheesh Kannoth <rkannoth@marvell.com>
[ Upstream commit d06f2ebf67ff2962fe00d687e4f0d4703eb41a12 ]
The original code used DMA_ATTR_FORCE_CONTIGUOUS, which could exhaust
the CMA pool when a large number of VFs were requested.
Fix this by switching to the DMA streaming API. This is equivalent on
Octeon platforms, which provide full I/O coherency via the SMMU.
Cc: Leon Romanovsky <leon@kernel.org>
Fixes: 73d33dbc0723 ("octeontx2-af: Use DMA_ATTR_FORCE_CONTIGUOUS attribute in DMA alloc")
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
Reviewed-by: Leon Romanovsky <leon@kernel.org>
Link: https://patch.msgid.link/20260916022111.1083017-1-rkannoth@marvell.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../ethernet/marvell/octeontx2/af/common.h | 45 ++++++++++++++++---
1 file changed, 39 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/common.h b/drivers/net/ethernet/marvell/octeontx2/af/common.h
index 2436c1ff9ba4c..680cbee17ca6f 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/common.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/common.h
@@ -7,6 +7,10 @@
#ifndef COMMON_H
#define COMMON_H
+#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
+#include <linux/mm.h>
+
#include "rvu_struct.h"
#define OTX2_ALIGN 128 /* Align to cacheline */
@@ -44,6 +48,33 @@ struct qmem {
u32 qsize;
};
+static inline void *otx2_dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle)
+{
+ dma_addr_t dma_addr;
+ void *vaddr;
+
+ vaddr = kzalloc(size, GFP_KERNEL);
+ if (!vaddr)
+ return NULL;
+
+ dma_addr = dma_map_single(dev, vaddr, size, DMA_BIDIRECTIONAL);
+ if (dma_mapping_error(dev, dma_addr)) {
+ kfree(vaddr);
+ return NULL;
+ }
+
+ *dma_handle = dma_addr;
+ return vaddr;
+}
+
+static inline void otx2_dma_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ dma_unmap_single(dev, dma_handle, size, DMA_BIDIRECTIONAL);
+ kfree(vaddr);
+}
+
static inline int qmem_alloc(struct device *dev, struct qmem **q,
int qsize, int entry_sz)
{
@@ -60,8 +91,11 @@ static inline int qmem_alloc(struct device *dev, struct qmem **q,
qmem->entry_sz = entry_sz;
qmem->alloc_sz = (qsize * entry_sz) + OTX2_ALIGN;
- qmem->base = dma_alloc_attrs(dev, qmem->alloc_sz, &qmem->iova,
- GFP_KERNEL, DMA_ATTR_FORCE_CONTIGUOUS);
+
+ if (get_order(PAGE_ALIGN(qmem->alloc_sz)) > MAX_PAGE_ORDER)
+ return -ENOMEM;
+
+ qmem->base = otx2_dma_alloc_coherent(dev, qmem->alloc_sz, &qmem->iova);
if (!qmem->base)
return -ENOMEM;
@@ -80,10 +114,9 @@ static inline void qmem_free(struct device *dev, struct qmem *qmem)
return;
if (qmem->base)
- dma_free_attrs(dev, qmem->alloc_sz,
- qmem->base - qmem->align,
- qmem->iova - qmem->align,
- DMA_ATTR_FORCE_CONTIGUOUS);
+ otx2_dma_free_coherent(dev, qmem->alloc_sz,
+ qmem->base - qmem->align,
+ qmem->iova - qmem->align);
devm_kfree(dev, qmem);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 378/877] dpll: use exact lookup for reference sync pin id
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (376 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 377/877] octeontx2-af: Fix memory scaling limitation in SR-IOV mode Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 379/877] net: usb: sr9700: include receive overhead in the length check Greg Kroah-Hartman
` (506 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ivan Vecera, Jakub Kicinski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Vecera <ivecera@redhat.com>
[ Upstream commit 7cce782d8327b7291334c4a304cf3fd909a74d9d ]
dpll_pin_ref_sync_state_set() looks up the reference sync pin in the
pin->ref_sync_pins xarray, which is keyed by the sync pin's id (see
dpll_pin_ref_sync_pair_add() using xa_insert() with ref_sync_pin->id).
The pin id to operate on is supplied by userspace via DPLL_A_PIN_ID.
The lookup however used xa_find() with a ULONG_MAX limit, which returns
the first present entry with an index greater than or equal to the
requested id, not the entry stored exactly at that id. If userspace
passes an id that is not paired as a reference sync pin, but another
pin with a higher id is present in the xarray, xa_find() silently
returns that wrong pin and the subsequent ref_sync_set() operates on
it. The request only fails when the given id is larger than every
present key.
Use xa_load() for an exact-key lookup instead, mirroring the deletion
path in dpll_pin_ref_sync_pair_del().
Fixes: 58256a26bfb3 ("dpll: add reference sync get/set")
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
Link: https://patch.msgid.link/20260917143736.526221-1-ivecera@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/dpll/dpll_netlink.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
index d6281bc46988a..270ea8f7248a4 100644
--- a/drivers/dpll/dpll_netlink.c
+++ b/drivers/dpll/dpll_netlink.c
@@ -956,8 +956,7 @@ dpll_pin_ref_sync_state_set(struct dpll_pin *pin,
unsigned long i;
int ret;
- ref_sync_pin = xa_find(&pin->ref_sync_pins, &ref_sync_pin_idx,
- ULONG_MAX, XA_PRESENT);
+ ref_sync_pin = xa_load(&pin->ref_sync_pins, ref_sync_pin_idx);
if (!ref_sync_pin) {
NL_SET_ERR_MSG(extack, "reference sync pin not found");
return -EINVAL;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 379/877] net: usb: sr9700: include receive overhead in the length check
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (377 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 378/877] dpll: use exact lookup for reference sync pin id Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 380/877] ipv6: Fix dst leak for uncached routes Greg Kroah-Hartman
` (505 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ethan Nelson-Moore, Pengpeng Hou,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <hppiscas@163.com>
[ Upstream commit c06bde80ae7a7b595732f7cabcb92cf08db9d56a ]
The receive fixup subtracts the Ethernet CRC from the reported packet
length, but compares that payload length against the whole remaining
receive buffer. The following copy starts after the three-byte header,
and the cursor advance consumes both that header and the four-byte CRC.
Require the payload to fit after SR_RX_OVERHEAD before copying it or
advancing to the next packet. The loop already ensures that the
remaining buffer is larger than the overhead, so the subtraction is
safe.
The issue was found by our static-analysis tool.
Fixes: c9b37458e956 ("USB2NET : SR9700 : One chip USB 1.1 USB2NET SR9700Device Driver Support")
Reviewed-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
Tested-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
Signed-off-by: Pengpeng Hou <hppiscas@163.com>
Link: https://patch.msgid.link/20260920034745.18468-1-hppiscas@163.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/usb/sr9700.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/usb/sr9700.c b/drivers/net/usb/sr9700.c
index e4d7bcd0d99c2..202bb55e811f4 100644
--- a/drivers/net/usb/sr9700.c
+++ b/drivers/net/usb/sr9700.c
@@ -403,7 +403,8 @@ static int sr9700_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
/* ignore the CRC length */
len = (skb->data[1] | (skb->data[2] << 8)) - 4;
- if (len > ETH_FRAME_LEN || len > skb->len || len < 0)
+ if (len > ETH_FRAME_LEN || len < 0 ||
+ len > skb->len - SR_RX_OVERHEAD)
return 0;
/* the last packet of current skb */
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 380/877] ipv6: Fix dst leak for uncached routes.
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (378 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 379/877] net: usb: sr9700: include receive overhead in the length check Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 381/877] tg3: clean up PHYLIB resources on probe failure Greg Kroah-Hartman
` (504 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Hangbin Liu,
Xuanqiang Luo, Ido Schimmel, Eric Dumazet, Jakub Kicinski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit be31fe6333f534155e6b408f1ef6d77974bb41aa ]
ip6_route_output_flags(), ip6_rt_put_flags(), and ip6_dst_check()
detect an uncached route by list_empty(&rt->dst.rt_uncached),
which replaced the static DST_NOCACHE flag check in commit
a4c2fd7f7891 ("net: remove DST_NOCACHE flag").
When a device is unregistered, rt6_uncached_list_flush_dev()
unlinks uncached routes tied to the device from rt6_uncached_list.
Previously, they were moved to another list with list_move()
(__list_del_entry() + list_add()), and since commit 98aa546af5e4
("inet: remove (struct uncached_list)->quarantine"), the routes
are just unlinked with list_del_init().
If list_del_init() runs concurrently, list_empty() evaluates to
true; ip6_route_output_flags() calls dst_hold_safe() incorrectly
and ip6_rt_put_flags() skips ip6_rt_put(), leaking dst, and thus
dev tied via rt->from as well.
The same race is partially fixed by commit 9a6f0c4d5796 ("dst:
fix races in rt6_uncached_list_del() and rt_del_uncached_list()").
Let's check rt6->dst.rt_uncached_list instead.
Note that IPv4 does not have the same issue.
Fixes: 98aa546af5e4 ("inet: remove (struct uncached_list)->quarantine")
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Reviewed-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260920191558.2990636-1-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/ip6_route.h | 4 ++--
net/ipv6/route.c | 7 ++++---
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index eaa2f6770ce77..1de182615a07a 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -94,12 +94,12 @@ static inline struct dst_entry *ip6_route_output(struct net *net,
}
/* Only conditionally release dst if flags indicates
- * !RT6_LOOKUP_F_DST_NOREF or dst is in uncached_list.
+ * !RT6_LOOKUP_F_DST_NOREF or dst is uncached.
*/
static inline void ip6_rt_put_flags(struct rt6_info *rt, int flags)
{
if (!(flags & RT6_LOOKUP_F_DST_NOREF) ||
- !list_empty(&rt->dst.rt_uncached))
+ rt->dst.rt_uncached_list)
ip6_rt_put(rt);
}
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 15f02882be040..692b44975af31 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -139,6 +139,7 @@ void rt6_uncached_list_add(struct rt6_info *rt)
{
struct uncached_list *ul = raw_cpu_ptr(&rt6_uncached_list);
+ /* Set once and never cleared: non-NULL marks an uncached route. */
rt->dst.rt_uncached_list = ul;
spin_lock_bh(&ul->lock);
@@ -2706,8 +2707,8 @@ struct dst_entry *ip6_route_output_flags(struct net *net,
rcu_read_lock();
dst = ip6_route_output_flags_noref(net, sk, fl6, flags);
rt6 = dst_rt6_info(dst);
- /* For dst cached in uncached_list, refcnt is already taken. */
- if (list_empty(&rt6->dst.rt_uncached) && !dst_hold_safe(dst)) {
+ /* For an uncached dst, refcnt is already taken. */
+ if (!rt6->dst.rt_uncached_list && !dst_hold_safe(dst)) {
dst = &net->ipv6.ip6_null_entry->dst;
dst_hold(dst);
}
@@ -2817,7 +2818,7 @@ INDIRECT_CALLABLE_SCOPE struct dst_entry *ip6_dst_check(struct dst_entry *dst,
from = rcu_dereference(rt->from);
if (from && (rt->rt6i_flags & RTF_PCPU ||
- unlikely(!list_empty(&rt->dst.rt_uncached))))
+ unlikely(rt->dst.rt_uncached_list)))
dst_ret = rt6_dst_from_check(rt, from, cookie);
else
dst_ret = rt6_check(rt, from, cookie);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 381/877] tg3: clean up PHYLIB resources on probe failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (379 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 380/877] ipv6: Fix dst leak for uncached routes Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 382/877] drm/i915/psr: Add new SU area calculation helper to apply workarounds Greg Kroah-Hartman
` (503 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ijae Kim, Myeonghun Pak, Paolo Abeni,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <mhun512@gmail.com>
[ Upstream commit a92e1a412c53dc0d9ad639e7abf8b3fc70a5b6ad ]
tg3_get_invariants() can register an MDIO bus and connect a PHY for
USE_PHYLIB devices. If tg3_init_one() later fails, its common error path
releases the mappings and netdev without undoing those PHYLIB resources.
Disconnect the PHY and unregister the MDIO bus before the remaining
teardown. Guard PHY cleanup with USE_PHYLIB to match tg3_phy_init(), and
call tg3_mdio_fini() unconditionally to match tg3_mdio_init(). The existing
IS_CONNECTED and MDIOBUS_INITED flags make both helpers safe when
initialization only completed partially.
This issue was identified during our ongoing static-analysis research while
reviewing kernel code.
Fixes: 158d7abdae85 ("tg3: Add mdio bus registration")
Assisted-by: OpenAI:GPT-5.6
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Link: https://patch.msgid.link/20260917183336.36239-1-mhun512@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/tg3.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 752f33ae98383..1df77bf9428b1 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -18031,6 +18031,10 @@ static int tg3_init_one(struct pci_dev *pdev,
return 0;
err_out_apeunmap:
+ if (tg3_flag(tp, USE_PHYLIB))
+ tg3_phy_fini(tp);
+ tg3_mdio_fini(tp);
+
if (tp->aperegs) {
iounmap(tp->aperegs);
tp->aperegs = NULL;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 382/877] drm/i915/psr: Add new SU area calculation helper to apply workarounds
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (380 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 381/877] tg3: clean up PHYLIB resources on probe failure Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 383/877] drm/i915/psr: Clear stale sel fetch enable bits on sel fetch disable Greg Kroah-Hartman
` (502 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jouni Högander, Mika Kahola,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jouni Högander <jouni.hogander@intel.com>
[ Upstream commit f3c25031bb321d8cef15ecd4df27d0f644a95193 ]
intel_psr2_sel_fetch_update is already quite long function. Now we are
about to add one more HW workaround. Let's split applying workarounds to
selective update area into a separate function.
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240926064759.1313335-2-jouni.hogander@intel.com
Stable-dep-of: 2777ec985227 ("drm/i915/psr: Clear stale sel fetch enable bits on sel fetch disable")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/i915/display/intel_psr.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 5173f5759ce88..af4548d1f724c 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -2529,11 +2529,24 @@ static bool psr2_sel_fetch_pipe_state_supported(const struct intel_crtc_state *c
return true;
}
+static void
+intel_psr_apply_su_area_workarounds(struct intel_crtc_state *crtc_state)
+{
+ struct intel_display *display = to_intel_display(crtc_state);
+ struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+
+ /* Wa_14014971492 */
+ if (!crtc_state->has_panel_replay &&
+ ((IS_DISPLAY_VER_STEP(display, IP_VER(14, 0), STEP_A0, STEP_B0) ||
+ IS_ALDERLAKE_P(i915) || IS_TIGERLAKE(i915))) &&
+ crtc_state->splitter.enable)
+ crtc_state->psr2_su_area.y1 = 0;
+}
+
int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(state);
- struct drm_i915_private *dev_priv = to_i915(state->base.dev);
struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
struct intel_plane_state *new_plane_state, *old_plane_state;
struct intel_plane *plane;
@@ -2644,12 +2657,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
if (full_update)
goto skip_sel_fetch_set_loop;
- /* Wa_14014971492 */
- if (!crtc_state->has_panel_replay &&
- ((IS_DISPLAY_VER_STEP(display, IP_VER(14, 0), STEP_A0, STEP_B0) ||
- IS_ALDERLAKE_P(dev_priv) || IS_TIGERLAKE(dev_priv))) &&
- crtc_state->splitter.enable)
- crtc_state->psr2_su_area.y1 = 0;
+ intel_psr_apply_su_area_workarounds(crtc_state);
ret = drm_atomic_add_affected_planes(&state->base, &crtc->base);
if (ret)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 383/877] drm/i915/psr: Clear stale sel fetch enable bits on sel fetch disable
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (381 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 382/877] drm/i915/psr: Add new SU area calculation helper to apply workarounds Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 384/877] s390/debug: Do not register views for failed static debug areas Greg Kroah-Hartman
` (501 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nemesa Garg, Jouni Högander,
Suraj Kandpal, Jani Nikula, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nemesa Garg <nemesa.garg@intel.com>
[ Upstream commit 2777ec9852277a06ae68fee0c4f1a32783e4a999 ]
Selective fetch is dropped while pipe CRC is active, and the planes keep
their SEL_FETCH_PLANE_CTL / SEL_FETCH_CUR_CTL enable bit set in hardware
over that. A plane disabled while selective fetch is off never gets the
bit cleared, as the disable path is guarded by enable_psr2_sel_fetch.
Once selective fetch comes back the hardware resumes fetching for a
plane that is no longer enabled and keeps its DDB range reserved.
Clear the bits as selective fetch is turned off instead. Atomic check
has both the old and the new crtc state, so record the transition there
and let the plane and cursor arm paths write the registers to 0 for that
commit.
v2: Drop the old_crtc_state->hw.active check. [Jouni]
Fixes: b1f5279b5981 ("drm/i915/psr: Move plane sel fetch configuration into plane source files")
Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/work_items/8739
Assisted-by: Copilot:Claude-Opus-5
Signed-off-by: Nemesa Garg <nemesa.garg@intel.com>
Reviewed-by: Jouni Högander <jouni.hogander@intel.com>
Signed-off-by: Suraj Kandpal <suraj.kandpal@intel.com>
Link: https://patch.msgid.link/20260909110332.3528029-3-nemesa.garg@intel.com
(cherry picked from commit a4c0e7f80429eda6990960971aebd4e4b9533cc6)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/i915/display/intel_cursor.c | 7 +++++--
.../gpu/drm/i915/display/intel_display_types.h | 2 ++
drivers/gpu/drm/i915/display/intel_psr.c | 15 +++++++++++++++
.../gpu/drm/i915/display/skl_universal_plane.c | 9 ++++-----
4 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c
index aeadb834d3328..2a70b2f7b39c8 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.c
+++ b/drivers/gpu/drm/i915/display/intel_cursor.c
@@ -536,7 +536,8 @@ static void i9xx_cursor_disable_sel_fetch_arm(struct intel_dsb *dsb,
struct intel_display *display = to_intel_display(plane->base.dev);
enum pipe pipe = plane->pipe;
- if (!crtc_state->enable_psr2_sel_fetch)
+ if (!crtc_state->enable_psr2_sel_fetch &&
+ !crtc_state->clear_psr2_sel_fetch)
return;
intel_de_write_dsb(display, dsb, SEL_FETCH_CUR_CTL(pipe), 0);
@@ -571,8 +572,10 @@ static void i9xx_cursor_update_sel_fetch_arm(struct intel_dsb *dsb,
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
enum pipe pipe = plane->pipe;
- if (!crtc_state->enable_psr2_sel_fetch)
+ if (!crtc_state->enable_psr2_sel_fetch) {
+ i9xx_cursor_disable_sel_fetch_arm(dsb, plane, crtc_state);
return;
+ }
if (drm_rect_height(&plane_state->psr2_sel_fetch_area) > 0) {
if (crtc_state->enable_psr2_su_region_et) {
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 992945b37190e..92be2cf1cf3b0 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1213,6 +1213,8 @@ struct intel_crtc_state {
bool has_sel_update;
bool enable_psr2_sel_fetch;
bool enable_psr2_su_region_et;
+ /* Drop the stale selective fetch enable bits as selective fetch is turned off */
+ bool clear_psr2_sel_fetch;
bool req_psr2_sdp_prior_scanline;
bool has_panel_replay;
bool wm_level_disabled;
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index af4548d1f724c..596b82b736b62 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -2547,6 +2547,8 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(state);
+ const struct intel_crtc_state *old_crtc_state =
+ intel_atomic_get_old_crtc_state(state, crtc);
struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
struct intel_plane_state *new_plane_state, *old_plane_state;
struct intel_plane *plane;
@@ -2559,6 +2561,19 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
bool full_update = false, su_area_changed;
int i, ret;
+ /*
+ * Selective fetch is not always usable, for instance it is dropped
+ * while pipe CRC is active. The planes keep their selective fetch
+ * enable bit set in hardware over that, and a plane disabled while
+ * selective fetch is off never gets the bit cleared. Once selective
+ * fetch comes back the hardware would resume fetching for a plane that
+ * is no longer enabled and keep its DDB range reserved, so have the
+ * plane update drop the bit for every plane of the pipe as selective
+ * fetch is turned off.
+ */
+ crtc_state->clear_psr2_sel_fetch = old_crtc_state->enable_psr2_sel_fetch &&
+ !crtc_state->enable_psr2_sel_fetch;
+
if (!crtc_state->enable_psr2_sel_fetch)
return 0;
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 7f77a76309bd5..42b3bd848162f 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -776,7 +776,8 @@ static void icl_plane_disable_sel_fetch_arm(struct intel_dsb *dsb,
struct intel_display *display = to_intel_display(plane->base.dev);
enum pipe pipe = plane->pipe;
- if (!crtc_state->enable_psr2_sel_fetch)
+ if (!crtc_state->enable_psr2_sel_fetch &&
+ !crtc_state->clear_psr2_sel_fetch)
return;
intel_de_write_dsb(display, dsb, SEL_FETCH_PLANE_CTL(pipe, plane->id), 0);
@@ -1505,10 +1506,8 @@ static void icl_plane_update_sel_fetch_arm(struct intel_dsb *dsb,
struct intel_display *display = to_intel_display(plane->base.dev);
enum pipe pipe = plane->pipe;
- if (!crtc_state->enable_psr2_sel_fetch)
- return;
-
- if (drm_rect_height(&plane_state->psr2_sel_fetch_area) > 0)
+ if (crtc_state->enable_psr2_sel_fetch &&
+ drm_rect_height(&plane_state->psr2_sel_fetch_area) > 0)
intel_de_write_dsb(display, dsb, SEL_FETCH_PLANE_CTL(pipe, plane->id),
SEL_FETCH_PLANE_CTL_ENABLE);
else
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 384/877] s390/debug: Do not register views for failed static debug areas
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (382 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 383/877] drm/i915/psr: Clear stale sel fetch enable bits on sel fetch disable Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 385/877] s390/debug: Fix NULL pointer dereference in debug_info_copy() Greg Kroah-Hartman
` (500 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mikhail Zaslonko, Heiko Carstens,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Zaslonko <zaslonko@linux.ibm.com>
[ Upstream commit 28e29992b034acffc9342df216c06097825ce610 ]
__REGISTER_STATIC_DEBUG_INFO() calls debug_register_view()
unconditionally, even when debug_register_static() has failed. In that
case _debug_register() was never reached and id->debugfs_root_entry is
still NULL, so debugfs_create_file() places the view file in the debugfs
root directory. For sclp_err this leaves a /sys/kernel/debug/hex_ascii
file with nothing to indicate which debug log it belongs to.
debug_register_static() is not exported and the macro is its only
caller, so let it return an error code and skip the view registration
when it fails. No debugfs files are created for such an area then.
Reproduce by booting with s390dbf=sclp_err::100000000. The sclp_err
registration fails, no s390dbf/sclp_err/ directory is created, and a
hex_ascii file appears in the debugfs root instead.
Fixes: d72541f94512 ("s390/debug: add early tracing support")
Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/include/asm/debug.h | 8 ++++++--
arch/s390/kernel/debug.c | 12 +++++++++---
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/arch/s390/include/asm/debug.h b/arch/s390/include/asm/debug.h
index ccd4e148b5ed4..7c3b058495d9d 100644
--- a/arch/s390/include/asm/debug.h
+++ b/arch/s390/include/asm/debug.h
@@ -451,7 +451,11 @@ static int VNAME(var, active_entries)[EARLY_AREAS] __initdata
#define __REGISTER_STATIC_DEBUG_INFO(var, name, pages, areas, view) \
static int __init VNAME(var, reg)(void) \
{ \
- debug_register_static(&var, (pages), (areas)); \
+ int rc; \
+ \
+ rc = debug_register_static(&var, (pages), (areas)); \
+ if (rc) \
+ return rc; \
debug_register_view(&var, (view)); \
return 0; \
} \
@@ -483,7 +487,7 @@ static debug_info_t __refdata var = \
__DEBUG_INFO_INIT(var, (name), (buf_size)); \
__REGISTER_STATIC_DEBUG_INFO(var, name, pages, nr_areas, view)
-void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas);
+int debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas);
#endif /* MODULE */
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index f275fa8b3873f..9becc37529447 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -702,8 +702,12 @@ EXPORT_SYMBOL(debug_register);
*
* Note: This function is called automatically via an initcall generated by
* DEFINE_STATIC_DEBUG_INFO.
+ *
+ * Return:
+ * - 0 on success
+ * - negative error code on failure
*/
-void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas)
+int debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas)
{
unsigned long flags;
debug_info_t *copy;
@@ -711,7 +715,7 @@ void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas)
if (!initialized) {
pr_err("Tried to register debug feature %s too early\n",
id->name);
- return;
+ return -EINVAL;
}
copy = debug_info_alloc("", pages_per_area, nr_areas, id->buf_size,
@@ -726,7 +730,7 @@ void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas)
id->active_entries = NULL;
spin_unlock_irqrestore(&id->lock, flags);
- return;
+ return -ENOMEM;
}
/* Replace static trace area with dynamic copy. */
@@ -744,6 +748,8 @@ void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas)
mutex_lock(&debug_mutex);
_debug_register(id);
mutex_unlock(&debug_mutex);
+
+ return 0;
}
/* Remove debugfs entries. */
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 385/877] s390/debug: Fix NULL pointer dereference in debug_info_copy()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (383 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 384/877] s390/debug: Do not register views for failed static debug areas Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 386/877] net: ethernet: ti: netcp: fix pm_runtime usage counter leak on error Greg Kroah-Hartman
` (499 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mikhail Zaslonko,
Peter Oberparleiter, Heiko Carstens, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Zaslonko <zaslonko@linux.ibm.com>
[ Upstream commit 012bfcd5a51082d5a65f096dfb9ca652b5267965 ]
When debug_register_static() fails, it clears areas, active_pages and
active_entries but leaves the area bounds unchanged. Copying such an
area, either by opening its view file or via debug_dump(), makes
debug_info_copy() dereference the NULL pointers.
Skip the copy loop when the source has no areas.
Closes: https://lore.kernel.org/r/20260903132123.12F271F00A3F@smtp.kernel.org
Fixes: d72541f94512 ("s390/debug: add early tracing support")
Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/kernel/debug.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index 9becc37529447..3aaab76f43d9b 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -344,7 +344,8 @@ static debug_info_t *debug_info_copy(debug_info_t *in, int mode)
debug_info_free(rc);
} while (1);
- if (mode == NO_AREAS)
+ /* debug_register_static() failure leaves areas NULL, bounds intact */
+ if (mode == NO_AREAS || !in->areas)
goto out;
for (i = 0; i < in->nr_areas; i++) {
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 386/877] net: ethernet: ti: netcp: fix pm_runtime usage counter leak on error
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (384 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 385/877] s390/debug: Fix NULL pointer dereference in debug_info_copy() Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 387/877] genetlink: report the real command id for dump-only ops in policy dumps Greg Kroah-Hartman
` (498 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bui duc phuc, Simon Horman,
Paolo Abeni, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: bui duc phuc <phucduc.bui@gmail.com>
[ Upstream commit ac4334522e4ba4a3b6710dd5d4cc98092824b8ca ]
pm_runtime_get_sync() leaves the runtime PM usage counter incremented even
when it fails, but the error path in netcp_probe() does not call
pm_runtime_put_noidle() to balance it, leaking a reference each time
resume fails.
Use pm_runtime_resume_and_get() instead, which automatically drops the
usage counter on failure, fixing the leak.
Fixes: 84640e27f230 ("net: netcp: Add Keystone NetCP core ethernet driver")
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260918042804.13101-1-phucduc.bui@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/ti/netcp_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c
index d07dcffc2517e..15c2a6dffb8c1 100644
--- a/drivers/net/ethernet/ti/netcp_core.c
+++ b/drivers/net/ethernet/ti/netcp_core.c
@@ -2167,7 +2167,7 @@ static int netcp_probe(struct platform_device *pdev)
return -ENOMEM;
pm_runtime_enable(&pdev->dev);
- ret = pm_runtime_get_sync(&pdev->dev);
+ ret = pm_runtime_resume_and_get(&pdev->dev);
if (ret < 0) {
dev_err(dev, "Failed to enable NETCP power-domain\n");
pm_runtime_disable(&pdev->dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 387/877] genetlink: report the real command id for dump-only ops in policy dumps
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (385 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 386/877] net: ethernet: ti: netcp: fix pm_runtime usage counter leak on error Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 388/877] net: pcs: xpcs: fix clock reference leak on xpcs_init_clks failure Greg Kroah-Hartman
` (497 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jakub Kicinski, Paolo Abeni,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <kuba@kernel.org>
[ Upstream commit 261e8a37ecbaf462cdf9c336d2b2f5056088401a ]
The op-to-policy map a CTRL_CMD_GETPOLICY dump returns is the only way
for userspace to find out which policy index belongs to which command.
ctrl_dumppolicy_put_op() tags the nest with doit->cmd, but an op which
only has a dumpit has no doit and every path which fills the split ops
in zeroes it out, so those entries all claim to be command 0. nlctrl's
own CTRL_CMD_GETPOLICY and NETDEV_CMD_QSTATS_GET are both in that group:
[{'family-id': 16, 'op-policy': {'do': 0, 'dump': 0, 'op-id': 3}},
{'family-id': 16, 'op-policy': {'dump': 1, 'op-id': 0}},
ctrl_fill_info() gets this right - it uses the iterator's cmd for
CTRL_ATTR_OP_ID - so the two introspection interfaces of the same family
contradict each other today.
Pass the command in rather than reconstructing it from
doit->cmd | dumpit->cmd inside the helper, both callers already have it.
Fixes: 26588edbef60 ("genetlink: support split policies in ctrl_dumppolicy_put_op()")
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Link: https://patch.msgid.link/20260918222949.4190284-1-kuba@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netlink/genetlink.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 3327d84518141..ecd5a0fd482a6 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -1647,7 +1647,7 @@ static void *ctrl_dumppolicy_prep(struct sk_buff *skb,
}
static int ctrl_dumppolicy_put_op(struct sk_buff *skb,
- struct netlink_callback *cb,
+ struct netlink_callback *cb, u32 cmd,
struct genl_split_ops *doit,
struct genl_split_ops *dumpit)
{
@@ -1668,7 +1668,7 @@ static int ctrl_dumppolicy_put_op(struct sk_buff *skb,
if (!nest_pol)
goto err;
- nest_op = nla_nest_start(skb, doit->cmd);
+ nest_op = nla_nest_start(skb, cmd);
if (!nest_op)
goto err;
@@ -1712,7 +1712,8 @@ static int ctrl_dumppolicy(struct sk_buff *skb, struct netlink_callback *cb)
&doit, &dumpit)))
return -ENOENT;
- if (ctrl_dumppolicy_put_op(skb, cb, &doit, &dumpit))
+ if (ctrl_dumppolicy_put_op(skb, cb, ctx->op,
+ &doit, &dumpit))
return skb->len;
/* done with the per-op policy index list */
@@ -1721,6 +1722,7 @@ static int ctrl_dumppolicy(struct sk_buff *skb, struct netlink_callback *cb)
while (ctx->dump_map) {
if (ctrl_dumppolicy_put_op(skb, cb,
+ ctx->op_iter->cmd,
&ctx->op_iter->doit,
&ctx->op_iter->dumpit))
return skb->len;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 388/877] net: pcs: xpcs: fix clock reference leak on xpcs_init_clks failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (386 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 387/877] genetlink: report the real command id for dump-only ops in policy dumps Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 389/877] thermal: gov_step_wise: Fix stale mitigation vote with non-zero lower bounds Greg Kroah-Hartman
` (496 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Coia Prant, Simon Horman,
Paolo Abeni, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Coia Prant <coiaprant@gmail.com>
[ Upstream commit 9892d71cf0ce3ff3d4fed2d9a3968fd4feb1c918 ]
xpcs_init_clks() takes references with clk_bulk_get_optional() and then
enables them with clk_bulk_prepare_enable(). If the enable step fails,
the function returns without dropping the references.
xpcs_create() handles the failure through out_free_data, which calls
xpcs_free_data() but never xpcs_clear_clks(), so the clk references are
leaked.
Add the missing clk_bulk_put() on the enable failure path. The
prepare/enable side is already rolled back by
clk_bulk_prepare_enable() itself.
Fixes: f6bb3e9d98c2 ("net: pcs: xpcs: Add Synopsys DW xPCS platform device driver")
Signed-off-by: Coia Prant <coiaprant@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260919172021.2336748-1-coiaprant@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/pcs/pcs-xpcs.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index 0152f820c1bbe..1a6576a116672 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -1393,8 +1393,10 @@ static int xpcs_init_clks(struct dw_xpcs *xpcs)
return dev_err_probe(dev, ret, "Failed to get clocks\n");
ret = clk_bulk_prepare_enable(DW_XPCS_NUM_CLKS, xpcs->clks);
- if (ret)
+ if (ret) {
+ clk_bulk_put(DW_XPCS_NUM_CLKS, xpcs->clks);
return dev_err_probe(dev, ret, "Failed to enable clocks\n");
+ }
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 389/877] thermal: gov_step_wise: Fix stale mitigation vote with non-zero lower bounds
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (387 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 388/877] net: pcs: xpcs: fix clock reference leak on xpcs_init_clks failure Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 390/877] bpf: Fix bounds check for skb-backed dynptrs Greg Kroah-Hartman
` (495 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Manaf Meethalavalappu Pallikunhi,
Rafael J. Wysocki, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
[ Upstream commit ec0d89150a9381d591344a9f6f5428655c227a7f ]
When two or more thermal zones bind to a common cooling device and one zone
uses a non-zero instance->lower value, there is a bug where the instance
holds a stale mitigation vote even after its trip is cleared.
Problem scenario:
- thermal-zone1: Trip at 50°C, cooling-map with lower=0
- thermal-zone2: Trip at 55°C, cooling-map with lower=2
- Both zones share the same cooling device (e.g., CPU)
Issue flow:
1. Both trips trigger, zone1 requests state 5, zone2 also mitigates
2. Zone2 trip clears (temp < 53°C due to hysteresis)
3. When throttle=false and trend=THERMAL_TREND_DROPPING:
- Current code checks: if (cur_state <= instance->lower)
return THERMAL_NO_TARGET
- Since cur_state (5) > instance->lower (2),
it returns instance->lower (2)
- This is the BUG where it returns instance->lower even though
trip is cleared
4. Zone2's passive polling stops (tz->passive reaches 0) - no more updates
for zone2
5. Zone2's stale vote of 2 persists indefinitely
6. Even when zone1 wants to reduce cooling to state, the cooling device
cannot go below state 2 due to zone2's stale vote
When a trip is cleared (throttle == false), always return THERMAL_NO_TARGET
instead of instance->lower. Remove the unnecessary check comparing
cur_state with instance->lower. Since passive polling is already
deactivated when the trip is cleared, the instance should always be
deactivated regardless of its current cooling state. This ensures that
instances with non-zero lower bounds do not retain stale mitigation votes
after their trips are cleared.
Fixes: 042a3d80f118 ("thermal: core: Move passive polling management to the core")
Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
Link: https://patch.msgid.link/20260922-step_wise_multi_zone_stale_vote_fix-v1-1-789f68dab229@oss.qualcomm.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/thermal/gov_step_wise.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/thermal/gov_step_wise.c b/drivers/thermal/gov_step_wise.c
index b038f042ed74e..b191e11e553b5 100644
--- a/drivers/thermal/gov_step_wise.c
+++ b/drivers/thermal/gov_step_wise.c
@@ -65,14 +65,12 @@ static unsigned long get_target_state(struct thermal_instance *instance,
min(instance->lower + 1, instance->upper),
instance->upper);
} else if (trend == THERMAL_TREND_DROPPING) {
- if (cur_state <= instance->lower)
- return THERMAL_NO_TARGET;
-
/*
- * If 'throttle' is false, no mitigation is necessary, so
- * request the lower state for this instance.
+ * If 'throttle' is false, no mitigation is necessary and
+ * passive polling is already deactivated, so clear this
+ * instance state by returning THERMAL_NO_TARGET.
*/
- return instance->lower;
+ return THERMAL_NO_TARGET;
}
return instance->target;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 390/877] bpf: Fix bounds check for skb-backed dynptrs
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (388 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 389/877] thermal: gov_step_wise: Fix stale mitigation vote with non-zero lower bounds Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 391/877] bpf: Fix bpf_sock context code generation Greg Kroah-Hartman
` (494 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini, Emil Tsalapatis,
Alexei Starovoitov, Jiayuan Chen, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emil Tsalapatis <emil@etsalapatis.com>
[ Upstream commit ed6eec97b534979dcf28b40c389cee57bd6561d4 ]
The skb_pointer_if_linear() function checks whether a
memory region of length len starting at offset off into
the skb is in the linear area, and returns a pointer to
the region if so. The check currently subtracts between
skb_headlen and offset of the check, and since skb_headlen
is unsigned the subtraction can underflow. This causes the
bounds check to spuriously pass and generate an arbitrary
pointer of the form *(skb->data + off).
The only user of this helper is currently skb-backed BPF
dynptr code. Returning the wrong pointer leads to the
dynptr erroneously being backed with invalid memory.
Ensure the subtraction cannot underflow, and fail the check if
it would. Use u64 arithmetic to also prevent overflow when
calculating (skb_headlen(skb) - off) since off is unsigned.
Fixes: 6f5a630d7c57 ("bpf, net: Introduce skb_pointer_if_linear().")
Reported-by: Nicholas Carlini <nicholas@carlini.com>
Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Link: https://patch.msgid.link/20260922172028.6269-2-emil@etsalapatis.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/skbuff.h | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 1bfdc03e0d94e..1e6b8871c432f 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -4280,7 +4280,10 @@ skb_header_pointer_careful(const struct sk_buff *skb, int offset,
static inline void * __must_check
skb_pointer_if_linear(const struct sk_buff *skb, int offset, int len)
{
- if (likely(skb_headlen(skb) - offset >= len))
+ unsigned int uoffset = (unsigned int)offset;
+
+ if (likely(uoffset <= skb_headlen(skb) &&
+ (unsigned int)len <= skb_headlen(skb) - uoffset))
return skb->data + offset;
return NULL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 391/877] bpf: Fix bpf_sock context code generation
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (389 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 390/877] bpf: Fix bounds check for skb-backed dynptrs Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 392/877] bpf, sockmap: Reject max_entries > INT_MAX in sock_map_alloc Greg Kroah-Hartman
` (493 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini, Emil Tsalapatis,
Alexei Starovoitov, Jiayuan Chen, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emil Tsalapatis <emil@etsalapatis.com>
[ Upstream commit 4a4852376e3a2727ea40e61143d6d7c22bb6dfad ]
Currently, the ctx access code reads the rx_queue_mapping
field with either a 4-byte or 2-byte load. The rest of the bits
in the register are marked known zero by the verifier. However,
the emitted ctx access code places in the register on certain
the special value (-1) using BPF_MOV_IMM64, which gets sign-extended
to turn on all the bits in the register. By shifting this value right,
the program ends up with a value at runtime above what the verifier
assumes is possible.
Fix this by ensuring the read value is as wide as the assumed size.
Use MOV32 instructions instead of MOV64 instructions to keep
the upper bits zero as assumed by the verifier. Also properly report
the size of the destination variable (the bpf_sock field, 4 bytes) instead
of the source (the socket field, 2 bytes).
Fixes: c3c16f2ea6d2 ("bpf: Add rx_queue_mapping to bpf_sock")
Reported-by: Nicholas Carlini <nicholas@carlini.com>
Suggested-by: Nicholas Carlini <nicholas@carlini.com>
Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Link: https://patch.msgid.link/20260922172028.6269-4-emil@etsalapatis.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/filter.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/net/core/filter.c b/net/core/filter.c
index 7114a64e1898e..a680cf27ad820 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -10187,11 +10187,12 @@ u32 bpf_sock_convert_ctx_access(enum bpf_access_type type,
target_size));
*insn++ = BPF_JMP_IMM(BPF_JNE, si->dst_reg, NO_QUEUE_MAPPING,
1);
- *insn++ = BPF_MOV64_IMM(si->dst_reg, -1);
+ *insn++ = BPF_MOV32_IMM(si->dst_reg, -1);
#else
- *insn++ = BPF_MOV64_IMM(si->dst_reg, -1);
- *target_size = 2;
+ *insn++ = BPF_MOV32_IMM(si->dst_reg, -1);
#endif
+ *target_size = sizeof_field(struct bpf_sock, rx_queue_mapping);
+
break;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 392/877] bpf, sockmap: Reject max_entries > INT_MAX in sock_map_alloc
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (390 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 391/877] bpf: Fix bpf_sock context code generation Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 393/877] net/mlx5: Bridge, dont fail switchdev events of sibling eswitch ports Greg Kroah-Hartman
` (492 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhao Gongyi, Alexei Starovoitov,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Gongyi <zhaogongyi@BYTEDANCE.COM>
[ Upstream commit 814a81c842bd88f6bd8a4ce550d560df071a5d03 ]
sock_map_alloc() only rejects max_entries == 0 and otherwise allows any
u32 value. sock_map_free() then walks the sks[] array with a signed int
iterator:
int i;
for (i = 0; i < stab->map.max_entries; i++)
struct sock **psk = &stab->sks[i];
When a SOCKMAP is created with max_entries = 0xffffffff (UINT_MAX), the
allocation of 32 GiB can succeed on large-memory hosts. During free the
counter reaches 0x80000000, wraps to INT_MIN, is sign-extended by movslq
and turned into a ~16 GiB negative offset from stab->sks, pointing far
below the allocation.
The faulting access is an xchg() write in sock_map_free(). Without
KASAN, the same out-of-bounds write can fault on an unmapped vmalloc page
or corrupt an unrelated allocation if that vmalloc address is populated.
On a KASAN kernel with CONFIG_KASAN_VMALLOC=y, the shadow check for that
address hits an unmapped shadow page and oopses first:
BUG: unable to handle page fault for address: fffff521b59c5a00
RIP: 0010:kasan_check_range+0x107/0x190
Call Trace:
sock_map_free+0x93/0x190
map_create+0x68d/0xb30
__sys_bpf+0x21e/0x2e70
Vmcore confirmed stab->map.max_entries == 0xffffffff, stab->sks ==
0xffffc911ace2d000, and the faulting address sks + (s64)INT_MIN * 8
exactly at 0xffffc90dace2d000. The same buggy path is reached on the
normal close()/bpf_map_free_deferred() path whenever such a map is
destroyed.
sock_map_alloc() used to bound its allocation size through
bpf_map_charge_init(), but the bound was dropped when rlimit-based memory
accounting was removed. Reject max_entries > INT_MAX at creation time so
the signed iterator in sock_map_free() never sees a value that would
overflow.
Triggered by syzkaller and reproduced on both a 6.6-based KASAN kernel
and the upstream v7.3-rc2 kernel.
Fixes: 0d2c4f964050 ("bpf: Eliminate rlimit-based memory accounting for sockmap and sockhash maps")
Signed-off-by: Zhao Gongyi <zhaogongyi@BYTEDANCE.COM>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20260917121016.48171-1-zhaogongyi@bytedance.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/sock_map.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/core/sock_map.c b/net/core/sock_map.c
index 6440ce16fc621..be4a4f8f346cb 100644
--- a/net/core/sock_map.c
+++ b/net/core/sock_map.c
@@ -41,6 +41,7 @@ static struct bpf_map *sock_map_alloc(union bpf_attr *attr)
struct bpf_stab *stab;
if (attr->max_entries == 0 ||
+ attr->max_entries > INT_MAX ||
attr->key_size != 4 ||
(attr->value_size != sizeof(u32) &&
attr->value_size != sizeof(u64)) ||
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 393/877] net/mlx5: Bridge, dont fail switchdev events of sibling eswitch ports
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (391 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 392/877] bpf, sockmap: Reject max_entries > INT_MAX in sock_map_alloc Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 394/877] net/mlx5: Bridge, dont fail unlink of untracked/unsupported peer ports Greg Kroah-Hartman
` (491 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bernardo Soares, Vlad Buslov,
Saeed Mahameed, Mark Bloch, Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernardo Soares <bsoares.it@gmail.com>
[ Upstream commit 35e6f970f553954d92ba20afa885139a8e7dd0d7 ]
mlx5 registers the bridge offload switchdev notifiers once per eswitch
instance, but the notifier chains are global, so every instance sees
every event and must filter out the ones that aren't its own. The
existing filter, mlx5_esw_bridge_dev_same_hw(), only checks that the
event netdevice sits on the same HCA - intentional for merged eswitch,
where one bridge can span representors of several eswitches on one
HCA - but same-HCA doesn't mean the instance actually has that port:
peer ports are only created reactively from NETDEV_CHANGEUPPER, so an
instance brought up after a sibling PF's port was already enslaved has
none. The port object and attribute handlers claim the event anyway
once same-HW passes, then fail the port lookup and return -EINVAL,
which gets reported to user space even though the owning instance
already handled it (e.g. "bridge vlan add ... RTNETLINK answers:
Invalid argument"). Fix by filtering on the tracked port instead.
The same gap exists in the generic recursive lower-device walk used by
attribute changes on a bridge with more than one representor enslaved
directly: mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get() is entered
with the bridge master netdevice, falls through to its generic
netdev_for_each_lower_dev() loop, and returns as soon as the recursion
into any one lower device yields a non-NULL rep - the underlying base
case, mlx5_esw_bridge_rep_vport_num_vhca_id_get(), only checks
mlx5_esw_bridge_dev_same_hw(), not ownership by the calling instance's
br_offloads. mlx5_esw_bridge_lag_rep_get(), used for the LAG-master
case, already filters on mlx5_esw_bridge_dev_same_esw() per candidate
and so cannot select a sibling's rep; it is not the source of this bug.
On a merged-eswitch HCA with a bridge spanning representors of more
than one eswitch instance directly, the walk can return a sibling's rep
instead of continuing to the one the calling instance actually owns, so
the attribute change fails the same way as above. Fix by checking
mlx5_esw_bridge_port_exists() at the point each rep is picked, same as
the previous fix did for the notifier filter.
Fixes: c358ea1741bc ("net/mlx5: Bridge, allow merged eswitch connectivity")
Signed-off-by: Bernardo Soares <bsoares.it@gmail.com>
Cc: Vlad Buslov <vladbu@nvidia.com>
Cc: Saeed Mahameed <saeedm@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Link: https://patch.msgid.link/20260918095931.29792-2-bsoares.it@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../mellanox/mlx5/core/en/rep/bridge.c | 45 +++++++++++++++----
.../ethernet/mellanox/mlx5/core/esw/bridge.c | 6 +++
.../ethernet/mellanox/mlx5/core/esw/bridge.h | 2 +
3 files changed, 44 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c
index 0f5d7ea8956f7..d8658fa517e70 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c
@@ -89,9 +89,16 @@ mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get(struct net_device *dev, struct m
struct net_device *lower_dev;
struct list_head *iter;
- if (netif_is_lag_master(dev) || mlx5e_eswitch_rep(dev))
- return mlx5_esw_bridge_rep_vport_num_vhca_id_get(dev, esw, vport_num,
- esw_owner_vhca_id);
+ if (netif_is_lag_master(dev) || mlx5e_eswitch_rep(dev)) {
+ struct net_device *rep;
+
+ rep = mlx5_esw_bridge_rep_vport_num_vhca_id_get(dev, esw, vport_num,
+ esw_owner_vhca_id);
+ if (rep && !mlx5_esw_bridge_port_exists(*vport_num, *esw_owner_vhca_id,
+ esw->br_offloads))
+ return NULL;
+ return rep;
+ }
netdev_for_each_lower_dev(dev, lower_dev, iter) {
struct net_device *rep;
@@ -108,6 +115,28 @@ mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get(struct net_device *dev, struct m
return NULL;
}
+static bool mlx5_esw_bridge_rep_port_lookup(struct net_device *dev,
+ struct mlx5_esw_bridge_offloads *br_offloads,
+ u16 *vport_num, u16 *esw_owner_vhca_id)
+{
+ if (!mlx5_esw_bridge_rep_vport_num_vhca_id_get(dev, br_offloads->esw, vport_num,
+ esw_owner_vhca_id))
+ return false;
+
+ return mlx5_esw_bridge_port_exists(*vport_num, *esw_owner_vhca_id, br_offloads);
+}
+
+static bool mlx5_esw_bridge_lower_rep_port_lookup(struct net_device *dev,
+ struct mlx5_esw_bridge_offloads *br_offloads,
+ u16 *vport_num, u16 *esw_owner_vhca_id)
+{
+ if (!mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get(dev, br_offloads->esw, vport_num,
+ esw_owner_vhca_id))
+ return false;
+
+ return mlx5_esw_bridge_port_exists(*vport_num, *esw_owner_vhca_id, br_offloads);
+}
+
static bool mlx5_esw_bridge_is_local(struct net_device *dev, struct net_device *rep,
struct mlx5_eswitch *esw)
{
@@ -222,8 +251,7 @@ mlx5_esw_bridge_port_obj_add(struct net_device *dev,
u16 vport_num, esw_owner_vhca_id;
int err;
- if (!mlx5_esw_bridge_rep_vport_num_vhca_id_get(dev, br_offloads->esw, &vport_num,
- &esw_owner_vhca_id))
+ if (!mlx5_esw_bridge_rep_port_lookup(dev, br_offloads, &vport_num, &esw_owner_vhca_id))
return 0;
port_obj_info->handled = true;
@@ -255,8 +283,7 @@ mlx5_esw_bridge_port_obj_del(struct net_device *dev,
const struct switchdev_obj_port_mdb *mdb;
u16 vport_num, esw_owner_vhca_id;
- if (!mlx5_esw_bridge_rep_vport_num_vhca_id_get(dev, br_offloads->esw, &vport_num,
- &esw_owner_vhca_id))
+ if (!mlx5_esw_bridge_rep_port_lookup(dev, br_offloads, &vport_num, &esw_owner_vhca_id))
return 0;
port_obj_info->handled = true;
@@ -287,8 +314,8 @@ mlx5_esw_bridge_port_obj_attr_set(struct net_device *dev,
u16 vport_num, esw_owner_vhca_id;
int err = 0;
- if (!mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get(dev, br_offloads->esw, &vport_num,
- &esw_owner_vhca_id))
+ if (!mlx5_esw_bridge_lower_rep_port_lookup(dev, br_offloads, &vport_num,
+ &esw_owner_vhca_id))
return 0;
port_attr_info->handled = true;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
index 282cef59e6173..6104ae8e72410 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
@@ -1683,6 +1683,12 @@ int mlx5_esw_bridge_vport_peer_unlink(struct net_device *br_netdev, u16 vport_nu
extack);
}
+bool mlx5_esw_bridge_port_exists(u16 vport_num, u16 esw_owner_vhca_id,
+ struct mlx5_esw_bridge_offloads *br_offloads)
+{
+ return mlx5_esw_bridge_port_lookup(vport_num, esw_owner_vhca_id, br_offloads);
+}
+
int mlx5_esw_bridge_port_vlan_add(u16 vport_num, u16 esw_owner_vhca_id, u16 vid, u16 flags,
struct mlx5_esw_bridge_offloads *br_offloads,
struct netlink_ext_ack *extack)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.h b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.h
index d6f5391619930..a4e59cc210894 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.h
@@ -80,6 +80,8 @@ int mlx5_esw_bridge_vlan_proto_set(u16 vport_num, u16 esw_owner_vhca_id, u16 pro
struct mlx5_esw_bridge_offloads *br_offloads);
int mlx5_esw_bridge_mcast_set(u16 vport_num, u16 esw_owner_vhca_id, bool enable,
struct mlx5_esw_bridge_offloads *br_offloads);
+bool mlx5_esw_bridge_port_exists(u16 vport_num, u16 esw_owner_vhca_id,
+ struct mlx5_esw_bridge_offloads *br_offloads);
int mlx5_esw_bridge_port_vlan_add(u16 vport_num, u16 esw_owner_vhca_id, u16 vid, u16 flags,
struct mlx5_esw_bridge_offloads *br_offloads,
struct netlink_ext_ack *extack);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 394/877] net/mlx5: Bridge, dont fail unlink of untracked/unsupported peer ports
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (392 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 393/877] net/mlx5: Bridge, dont fail switchdev events of sibling eswitch ports Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 395/877] sctp: hold asoc or transport before mod_timer() in timer handlers Greg Kroah-Hartman
` (490 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bernardo Soares, Mark Bloch,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernardo Soares <bsoares.it@gmail.com>
[ Upstream commit 2e51097c982b7b22382fda3202ba29f0ea33e8c0 ]
mlx5_esw_bridge_vport_unlink() returns -EINVAL when the port isn't
tracked by this instance's br_offloads. This is reachable on a sibling
instance that registered its notifier after the port was already
enslaved: it never saw the NETDEV_CHANGEUPPER link event, so
peer_link() never created a peer port for it, but it does see the
later unlink event and fails. Return 0 instead, and give
mlx5_esw_bridge_vport_peer_unlink() the same merged_eswitch capability
guard peer_link() already has, since without it peer_link() likewise
never creates a port to unlink.
This also matters beyond the -EINVAL itself:
mlx5_esw_bridge_switchdev_port_event() runs on the per-netns
netdev_chain, and notifier_from_errno(-EINVAL) sets NOTIFY_STOP_MASK,
which call_netdevice_notifiers_info() checks to stop calling further
listeners on that chain - so the old -EINVAL silently dropped the
event for any listener registered later on the same chain, even
though none of it was visible to user space since
__netdev_upper_dev_unlink() discards the return value.
Fixes: c358ea1741bc ("net/mlx5: Bridge, allow merged eswitch connectivity")
Signed-off-by: Bernardo Soares <bsoares.it@gmail.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Link: https://patch.msgid.link/20260918095931.29792-3-bsoares.it@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
index 6104ae8e72410..684154914cf83 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
@@ -1646,10 +1646,8 @@ int mlx5_esw_bridge_vport_unlink(struct net_device *br_netdev, u16 vport_num,
int err;
port = mlx5_esw_bridge_port_lookup(vport_num, esw_owner_vhca_id, br_offloads);
- if (!port) {
- NL_SET_ERR_MSG_MOD(extack, "Port is not attached to any bridge");
- return -EINVAL;
- }
+ if (!port)
+ return 0;
if (port->bridge->ifindex != br_netdev->ifindex) {
NL_SET_ERR_MSG_MOD(extack, "Port is attached to another bridge");
return -EINVAL;
@@ -1679,6 +1677,9 @@ int mlx5_esw_bridge_vport_peer_unlink(struct net_device *br_netdev, u16 vport_nu
struct mlx5_esw_bridge_offloads *br_offloads,
struct netlink_ext_ack *extack)
{
+ if (!MLX5_CAP_ESW(br_offloads->esw->dev, merged_eswitch))
+ return 0;
+
return mlx5_esw_bridge_vport_unlink(br_netdev, vport_num, esw_owner_vhca_id, br_offloads,
extack);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 395/877] sctp: hold asoc or transport before mod_timer() in timer handlers
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (393 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 394/877] net/mlx5: Bridge, dont fail unlink of untracked/unsupported peer ports Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 396/877] net: stmmac: selftests: Support running selftests on DSA conduits Greg Kroah-Hartman
` (489 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tangxin Xie, Xin Long,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xin Long <lucien.xin@gmail.com>
[ Upstream commit cae23ae3f7887a1cf8a75da38edcebeef695040f ]
Take the association or transport reference before rearming a timer in the
timer handlers.
The existing code calls mod_timer() before taking the reference needed by
the rearmed timer without holding the sock lock. This creates a race with
timer cleanup: if the timer is deleted after mod_timer() returns but before
the reference is taken, the cleanup path can drop the timer's reference and
destroy the transport or association. The timer handler then takes a
reference on the already freed object and eventually drops it, causing a
refcount underflow.
Hold the object before mod_timer() and drop the reference if mod_timer()
reports that the timer was already pending in timer handlers. Apply the
same ordering to the proto-unreachable path, which can rearm a transport
timer outside the timer handlers without holding the sock lock.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Tangxin Xie <xietangxin@h-partners.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/c31b5e3ee2b7274e804f5eba2f21e2412e7eef7a.1790013825.git.lucien.xin@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sctp/input.c | 7 ++++---
net/sctp/sm_sideeffect.c | 37 ++++++++++++++++++++++---------------
2 files changed, 26 insertions(+), 18 deletions(-)
diff --git a/net/sctp/input.c b/net/sctp/input.c
index df5b2187b8fad..e946c1b4abfea 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -436,9 +436,10 @@ void sctp_icmp_proto_unreachable(struct sock *sk,
if (timer_pending(&t->proto_unreach_timer))
return;
else {
- if (!mod_timer(&t->proto_unreach_timer,
- jiffies + (HZ/20)))
- sctp_transport_hold(t);
+ sctp_transport_hold(t);
+ if (mod_timer(&t->proto_unreach_timer,
+ jiffies + (HZ / 20)))
+ sctp_transport_put(t);
}
} else {
struct net *net = sock_net(sk);
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index c05f1b0736960..7d451e6c5d277 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -244,8 +244,9 @@ void sctp_generate_t3_rtx_event(struct timer_list *t)
pr_debug("%s: sock is busy\n", __func__);
/* Try again later. */
- if (!mod_timer(&transport->T3_rtx_timer, jiffies + (HZ/20)))
- sctp_transport_hold(transport);
+ sctp_transport_hold(transport);
+ if (mod_timer(&transport->T3_rtx_timer, jiffies + (HZ / 20)))
+ sctp_transport_put(transport);
goto out_unlock;
}
@@ -280,8 +281,9 @@ static void sctp_generate_timeout_event(struct sctp_association *asoc,
timeout_type);
/* Try again later. */
- if (!mod_timer(&asoc->timers[timeout_type], jiffies + (HZ/20)))
- sctp_association_hold(asoc);
+ sctp_association_hold(asoc);
+ if (mod_timer(&asoc->timers[timeout_type], jiffies + (HZ / 20)))
+ sctp_association_put(asoc);
goto out_unlock;
}
@@ -373,8 +375,9 @@ void sctp_generate_heartbeat_event(struct timer_list *t)
pr_debug("%s: sock is busy\n", __func__);
/* Try again later. */
- if (!mod_timer(&transport->hb_timer, jiffies + (HZ/20)))
- sctp_transport_hold(transport);
+ sctp_transport_hold(transport);
+ if (mod_timer(&transport->hb_timer, jiffies + (HZ / 20)))
+ sctp_transport_put(transport);
goto out_unlock;
}
@@ -383,8 +386,9 @@ void sctp_generate_heartbeat_event(struct timer_list *t)
timeout = sctp_transport_timeout(transport);
if (elapsed < timeout) {
elapsed = timeout - elapsed;
- if (!mod_timer(&transport->hb_timer, jiffies + elapsed))
- sctp_transport_hold(transport);
+ sctp_transport_hold(transport);
+ if (mod_timer(&transport->hb_timer, jiffies + elapsed))
+ sctp_transport_put(transport);
goto out_unlock;
}
@@ -417,9 +421,10 @@ void sctp_generate_proto_unreach_event(struct timer_list *t)
pr_debug("%s: sock is busy\n", __func__);
/* Try again later. */
- if (!mod_timer(&transport->proto_unreach_timer,
- jiffies + (HZ/20)))
- sctp_transport_hold(transport);
+ sctp_transport_hold(transport);
+ if (mod_timer(&transport->proto_unreach_timer,
+ jiffies + (HZ / 20)))
+ sctp_transport_put(transport);
goto out_unlock;
}
@@ -453,8 +458,9 @@ void sctp_generate_reconf_event(struct timer_list *t)
pr_debug("%s: sock is busy\n", __func__);
/* Try again later. */
- if (!mod_timer(&transport->reconf_timer, jiffies + (HZ / 20)))
- sctp_transport_hold(transport);
+ sctp_transport_hold(transport);
+ if (mod_timer(&transport->reconf_timer, jiffies + (HZ / 20)))
+ sctp_transport_put(transport);
goto out_unlock;
}
@@ -489,8 +495,9 @@ void sctp_generate_probe_event(struct timer_list *t)
pr_debug("%s: sock is busy\n", __func__);
/* Try again later. */
- if (!mod_timer(&transport->probe_timer, jiffies + (HZ / 20)))
- sctp_transport_hold(transport);
+ sctp_transport_hold(transport);
+ if (mod_timer(&transport->probe_timer, jiffies + (HZ / 20)))
+ sctp_transport_put(transport);
goto out_unlock;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 396/877] net: stmmac: selftests: Support running selftests on DSA conduits
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (394 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 395/877] sctp: hold asoc or transport before mod_timer() in timer handlers Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 397/877] net: stmmac: selftests: Check the dev->features for S-TAG offload testing Greg Kroah-Hartman
` (488 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Maxime Chevallier,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maxime Chevallier <maxime.chevallier@bootlin.com>
[ Upstream commit d68acbf93531abdb5b02b21994cd4c15a3c95b42 ]
Most stmmac selftests rely on dev_add_pack() to add custom handlers,
that validate the packets sent to ourselves through MAC loopback.
However, when the stmmac-driven interface is a DSA CPU conduit, all
frames that are received have ETH_P_XDSA as a protocol, even though they
don't actually contain any tag as they come from the loopback and not
the switch.
This will prevent any incoming packet to match our packet handlers.
Let's register a ETH_P_ALL packet handler when we detect that we're a
DSA conduit, and use a proxy packet handler to filter the h_proto.
As this allows external frames to be received through our .func(), the
packet handler is added after the dev->addr field is populated in our
selftest attributes.
Note that we may still receive incoming packets from the switch, but
these frames shouldn't interfere with the very specific frames used for
selftests, and stmmac selftests in general aren't safe against external
traffic interferences.
This was validated on a WPQ864 devkit for IPQ8064, that has the SoC
connected to a QCA8k switch.
The ARP offload's packet handler is left alone, this feature is just not
implemented in stmmac and due for removal.
Fixes: 091810dbded9 ("net: stmmac: Introduce selftests support")
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20260917215339.2022523-2-maxime.chevallier@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../stmicro/stmmac/stmmac_selftests.c | 89 +++++++++++++++----
1 file changed, 71 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
index 266211a401392..e1a5a0316d8d9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
@@ -13,6 +13,7 @@
#include <linux/ip.h>
#include <linux/phy.h>
#include <linux/udp.h>
+#include <net/dsa.h>
#include <net/pkt_cls.h>
#include <net/pkt_sched.h>
#include <net/tcp.h>
@@ -238,6 +239,9 @@ struct stmmac_test_priv {
struct stmmac_packet_attrs *packet;
struct packet_type pt;
struct completion comp;
+ __be16 packet_type;
+ int (*func)(struct sk_buff *skb, struct net_device *ndev,
+ struct packet_type *pt, struct net_device *orig_ndev);
int double_vlan;
int vlan_id;
int ok;
@@ -317,6 +321,50 @@ static int stmmac_test_loopback_validate(struct sk_buff *skb,
return 0;
}
+static int stmmac_sft_filter(struct sk_buff *skb, struct net_device *ndev,
+ struct packet_type *pt,
+ struct net_device *orig_ndev)
+{
+ struct stmmac_test_priv *tpriv = pt->af_packet_priv;
+ struct ethhdr *hdr = eth_hdr(skb);
+ int ret = 0;
+
+ if (hdr->h_proto == tpriv->packet_type) {
+ struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
+
+ if (nskb)
+ ret = tpriv->func(nskb, ndev, pt, orig_ndev);
+ }
+
+ kfree_skb(skb);
+ return ret;
+}
+
+static void stmmac_sft_add_pack(struct packet_type *pt)
+{
+ struct stmmac_test_priv *tpriv = pt->af_packet_priv;
+
+ if (netdev_uses_dsa(tpriv->pt.dev)) {
+ tpriv->packet_type = tpriv->pt.type;
+ tpriv->func = tpriv->pt.func;
+
+ /* DSA conduit will report ETH_P_XDSA, so our packet handler
+ * won't match. Let's register a ETH_P_ALL match and filter
+ * manually in stmmac_sft_filter.
+ */
+ tpriv->pt.type = htons(ETH_P_ALL);
+ tpriv->pt.func = stmmac_sft_filter;
+ tpriv->pt.ignore_outgoing = true;
+ }
+
+ dev_add_pack(pt);
+}
+
+static void stmmac_sft_remove_pack(struct packet_type *pt)
+{
+ dev_remove_pack(pt);
+}
+
static int __stmmac_test_loopback(struct stmmac_priv *priv,
struct stmmac_packet_attrs *attr)
{
@@ -338,7 +386,7 @@ static int __stmmac_test_loopback(struct stmmac_priv *priv,
tpriv->packet = attr;
if (!attr->dont_wait)
- dev_add_pack(&tpriv->pt);
+ stmmac_sft_add_pack(&tpriv->pt);
skb = stmmac_test_get_udp_skb(priv, attr);
if (!skb) {
@@ -361,7 +409,7 @@ static int __stmmac_test_loopback(struct stmmac_priv *priv,
cleanup:
if (!attr->dont_wait)
- dev_remove_pack(&tpriv->pt);
+ stmmac_sft_remove_pack(&tpriv->pt);
kfree(tpriv);
return ret;
}
@@ -775,7 +823,7 @@ static int stmmac_test_flowctrl(struct stmmac_priv *priv)
tpriv->pt.func = stmmac_test_flowctrl_validate;
tpriv->pt.dev = priv->dev;
tpriv->pt.af_packet_priv = tpriv;
- dev_add_pack(&tpriv->pt);
+ stmmac_sft_add_pack(&tpriv->pt);
/* Compute minimum number of packets to make FIFO full */
pkt_count = priv->plat->rx_fifo_size;
@@ -833,7 +881,7 @@ static int stmmac_test_flowctrl(struct stmmac_priv *priv)
cleanup:
dev_mc_del(priv->dev, paddr);
dev_set_promiscuity(priv->dev, -1);
- dev_remove_pack(&tpriv->pt);
+ stmmac_sft_remove_pack(&tpriv->pt);
kfree(tpriv);
return ret;
}
@@ -938,18 +986,20 @@ static int __stmmac_test_vlanfilt(struct stmmac_priv *priv)
* HASH values.
*/
tpriv->vlan_id = 0x123;
- dev_add_pack(&tpriv->pt);
ret = vlan_vid_add(priv->dev, htons(ETH_P_8021Q), tpriv->vlan_id);
if (ret)
goto cleanup;
+ attr.vlan = 1;
+ attr.dst = priv->dev->dev_addr;
+ attr.sport = 9;
+ attr.dport = 9;
+
+ stmmac_sft_add_pack(&tpriv->pt);
+
for (i = 0; i < 4; i++) {
- attr.vlan = 1;
attr.vlan_id_out = tpriv->vlan_id + i;
- attr.dst = priv->dev->dev_addr;
- attr.sport = 9;
- attr.dport = 9;
skb = stmmac_test_get_udp_skb(priv, &attr);
if (!skb) {
@@ -976,9 +1026,9 @@ static int __stmmac_test_vlanfilt(struct stmmac_priv *priv)
}
vlan_del:
+ stmmac_sft_remove_pack(&tpriv->pt);
vlan_vid_del(priv->dev, htons(ETH_P_8021Q), tpriv->vlan_id);
cleanup:
- dev_remove_pack(&tpriv->pt);
kfree(tpriv);
return ret;
}
@@ -1032,18 +1082,20 @@ static int __stmmac_test_dvlanfilt(struct stmmac_priv *priv)
* HASH values.
*/
tpriv->vlan_id = 0x123;
- dev_add_pack(&tpriv->pt);
ret = vlan_vid_add(priv->dev, htons(ETH_P_8021AD), tpriv->vlan_id);
if (ret)
goto cleanup;
+ attr.vlan = 2;
+ attr.dst = priv->dev->dev_addr;
+ attr.sport = 9;
+ attr.dport = 9;
+
+ stmmac_sft_add_pack(&tpriv->pt);
+
for (i = 0; i < 4; i++) {
- attr.vlan = 2;
attr.vlan_id_out = tpriv->vlan_id + i;
- attr.dst = priv->dev->dev_addr;
- attr.sport = 9;
- attr.dport = 9;
skb = stmmac_test_get_udp_skb(priv, &attr);
if (!skb) {
@@ -1070,9 +1122,9 @@ static int __stmmac_test_dvlanfilt(struct stmmac_priv *priv)
}
vlan_del:
+ stmmac_sft_remove_pack(&tpriv->pt);
vlan_vid_del(priv->dev, htons(ETH_P_8021AD), tpriv->vlan_id);
cleanup:
- dev_remove_pack(&tpriv->pt);
kfree(tpriv);
return ret;
}
@@ -1303,7 +1355,6 @@ static int stmmac_test_vlanoff_common(struct stmmac_priv *priv, bool svlan)
tpriv->pt.af_packet_priv = tpriv;
tpriv->packet = &attr;
tpriv->vlan_id = 0x123;
- dev_add_pack(&tpriv->pt);
ret = vlan_vid_add(priv->dev, htons(proto), tpriv->vlan_id);
if (ret)
@@ -1311,6 +1362,8 @@ static int stmmac_test_vlanoff_common(struct stmmac_priv *priv, bool svlan)
attr.dst = priv->dev->dev_addr;
+ stmmac_sft_add_pack(&tpriv->pt);
+
skb = stmmac_test_get_udp_skb(priv, &attr);
if (!skb) {
ret = -ENOMEM;
@@ -1328,9 +1381,9 @@ static int stmmac_test_vlanoff_common(struct stmmac_priv *priv, bool svlan)
ret = tpriv->ok ? 0 : -ETIMEDOUT;
vlan_del:
+ stmmac_sft_remove_pack(&tpriv->pt);
vlan_vid_del(priv->dev, htons(proto), tpriv->vlan_id);
cleanup:
- dev_remove_pack(&tpriv->pt);
kfree(tpriv);
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 397/877] net: stmmac: selftests: Check the dev->features for S-TAG offload testing
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (395 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 396/877] net: stmmac: selftests: Support running selftests on DSA conduits Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 398/877] net: stmmac: selftests: Capture all packets for vlan checks Greg Kroah-Hartman
` (487 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Maxime Chevallier,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maxime Chevallier <maxime.chevallier@bootlin.com>
[ Upstream commit ba804b23d76d278ee475b8427fa7c5623ce5e270 ]
The S-TAG offload insertion incorrectly checks the dvlan (double vlan)
DMA cap, which is different than S-TAG support. Use
NETIF_F_HW_VLAN_STAG_TX to check if the feature is supported instead.
Note that this flag isn't set in stmmac yet, but contrary to ARP
offload, this is a feature that has a chance to get there eventually so
let's leave the selftest here for now. It'll report -EOPNOTSUPP in the
meantime.
Fixes: 091810dbded9 ("net: stmmac: Introduce selftests support")
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20260917215339.2022523-4-maxime.chevallier@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
index e1a5a0316d8d9..6f2edff624134 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
@@ -1395,7 +1395,7 @@ static int stmmac_test_vlanoff(struct stmmac_priv *priv)
static int stmmac_test_svlanoff(struct stmmac_priv *priv)
{
- if (!priv->dma_cap.dvlan)
+ if (!(priv->dev->features & NETIF_F_HW_VLAN_STAG_TX))
return -EOPNOTSUPP;
return stmmac_test_vlanoff_common(priv, true);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 398/877] net: stmmac: selftests: Capture all packets for vlan checks
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (396 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 397/877] net: stmmac: selftests: Check the dev->features for S-TAG offload testing Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 399/877] net: stmmac: dwmac4: Use the correct bufzise when the len is exactly 8K Greg Kroah-Hartman
` (486 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Maxime Chevallier,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maxime Chevallier <maxime.chevallier@bootlin.com>
[ Upstream commit 960db6f65788c21249ea04a947d5c01e38d19294 ]
While we use vlan_vid_add to trigger the tag filtering machinery
in the driver, there's no netdev associated to the VLAN. This causes the
skb to arrive with empty skb->vlan_tci fields, as the packet is marked
OTHERHOST in __netif_receive_skb_core(), and we fail our validation.
Let's use the proxy mechanism introduced for DSA, that registers a
ETH_P_ALL packet handler that runs earlier, before the vlan netdev
lookup, then filters for the correct ethertype before passing an skb
clone to our validation function.
As we may receive external frames with the right tag from the outside,
let's move the address check in the vlan validation function earlier.
Fixes: 091810dbded9 ("net: stmmac: Introduce selftests support")
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20260917215339.2022523-5-maxime.chevallier@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../stmicro/stmmac/stmmac_selftests.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
index 6f2edff624134..e39ee3ea0efff 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
@@ -242,6 +242,7 @@ struct stmmac_test_priv {
__be16 packet_type;
int (*func)(struct sk_buff *skb, struct net_device *ndev,
struct packet_type *pt, struct net_device *orig_ndev);
+ bool capture_all;
int double_vlan;
int vlan_id;
int ok;
@@ -344,13 +345,15 @@ static void stmmac_sft_add_pack(struct packet_type *pt)
{
struct stmmac_test_priv *tpriv = pt->af_packet_priv;
- if (netdev_uses_dsa(tpriv->pt.dev)) {
+ if (netdev_uses_dsa(tpriv->pt.dev) || tpriv->capture_all) {
tpriv->packet_type = tpriv->pt.type;
tpriv->func = tpriv->pt.func;
/* DSA conduit will report ETH_P_XDSA, so our packet handler
* won't match. Let's register a ETH_P_ALL match and filter
- * manually in stmmac_sft_filter.
+ * manually in stmmac_sft_filter. This is also useful for
+ * VLAN tests, to capture packets otherwise marked as
+ * OTHERHOST.
*/
tpriv->pt.type = htons(ETH_P_ALL);
tpriv->pt.func = stmmac_sft_filter;
@@ -923,6 +926,11 @@ static int stmmac_test_vlan_validate(struct sk_buff *skb,
goto out;
if (skb_headlen(skb) < (STMMAC_TEST_PKT_SIZE - ETH_HLEN))
goto out;
+
+ ehdr = (struct ethhdr *)skb_mac_header(skb);
+ if (!ether_addr_equal_unaligned(ehdr->h_dest, tpriv->packet->dst))
+ goto out;
+
if (tpriv->vlan_id) {
if (skb->vlan_proto != htons(proto))
goto out;
@@ -934,10 +942,6 @@ static int stmmac_test_vlan_validate(struct sk_buff *skb,
}
}
- ehdr = (struct ethhdr *)skb_mac_header(skb);
- if (!ether_addr_equal_unaligned(ehdr->h_dest, tpriv->packet->dst))
- goto out;
-
ihdr = ip_hdr(skb);
if (tpriv->double_vlan)
ihdr = (struct iphdr *)(skb_network_header(skb) + 4);
@@ -979,6 +983,7 @@ static int __stmmac_test_vlanfilt(struct stmmac_priv *priv)
tpriv->pt.dev = priv->dev;
tpriv->pt.af_packet_priv = tpriv;
tpriv->packet = &attr;
+ tpriv->capture_all = true;
/*
* As we use HASH filtering, false positives may appear. This is a
@@ -1075,6 +1080,7 @@ static int __stmmac_test_dvlanfilt(struct stmmac_priv *priv)
tpriv->pt.dev = priv->dev;
tpriv->pt.af_packet_priv = tpriv;
tpriv->packet = &attr;
+ tpriv->capture_all = true;
/*
* As we use HASH filtering, false positives may appear. This is a
@@ -1355,6 +1361,7 @@ static int stmmac_test_vlanoff_common(struct stmmac_priv *priv, bool svlan)
tpriv->pt.af_packet_priv = tpriv;
tpriv->packet = &attr;
tpriv->vlan_id = 0x123;
+ tpriv->capture_all = true;
ret = vlan_vid_add(priv->dev, htons(proto), tpriv->vlan_id);
if (ret)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 399/877] net: stmmac: dwmac4: Use the correct bufzise when the len is exactly 8K
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (397 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 398/877] net: stmmac: selftests: Capture all packets for vlan checks Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 400/877] bpf: Reject dev-bound-only programs on other devices Greg Kroah-Hartman
` (485 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Maxime Chevallier, Nicolai Buchwitz,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maxime Chevallier <maxime.chevallier@bootlin.com>
[ Upstream commit b42e7012773a0e81e97a2dda6ef907f5147a6658 ]
DMA bufsize selection isn't made on the MTU but the actual frame length,
so including the L2 header. On DWMAC4, if the len is exactly BUF_SIZE_8KiB,
the next larger size is incorrectly selected.
Lets fix the comparison and while at it, rename the parameter from len
to mtu.
Fixes: c3efed5ad1b0 ("net: stmmac: Enable dwmac4 jumbo frame more than 8KiB").
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Link: https://patch.msgid.link/20260917215339.2022523-6-maxime.chevallier@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 4 ++--
drivers/net/ethernet/stmicro/stmmac/hwif.h | 2 +-
drivers/net/ethernet/stmicro/stmmac/ring_mode.c | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
index e99401bcc1f84..67c886316cbdd 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
@@ -490,11 +490,11 @@ static void dwmac4_set_sarc(struct dma_desc *p, u32 sarc_type)
p->des3 |= cpu_to_le32(sarc_type & TDES3_SA_INSERT_CTRL_MASK);
}
-static int set_16kib_bfsize(int mtu)
+static int set_16kib_bfsize(int len)
{
int ret = 0;
- if (unlikely(mtu >= BUF_SIZE_8KiB))
+ if (unlikely(len > BUF_SIZE_8KiB))
ret = BUF_SIZE_16KiB;
return ret;
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index 31d7f9375d747..4376d61db969f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -587,7 +587,7 @@ struct stmmac_mode_ops {
unsigned int (*is_jumbo_frm) (int len, int ehn_desc);
int (*jumbo_frm)(struct stmmac_tx_queue *tx_q, struct sk_buff *skb,
int csum);
- int (*set_16kib_bfsize)(int mtu);
+ int (*set_16kib_bfsize)(int len);
void (*init_desc3)(struct dma_desc *p);
void (*refill_desc3)(struct stmmac_rx_queue *rx_q, struct dma_desc *p);
void (*clean_desc3)(struct stmmac_tx_queue *tx_q, struct dma_desc *p);
diff --git a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
index 45c14c1bb0eaa..88a8d22812f5d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
+++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
@@ -128,10 +128,10 @@ static void clean_desc3(struct stmmac_tx_queue *tx_q, struct dma_desc *p)
p->des3 = 0;
}
-static int set_16kib_bfsize(int mtu)
+static int set_16kib_bfsize(int len)
{
int ret = 0;
- if (unlikely(mtu > BUF_SIZE_8KiB))
+ if (unlikely(len > BUF_SIZE_8KiB))
ret = BUF_SIZE_16KiB;
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 400/877] bpf: Reject dev-bound-only programs on other devices
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (398 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 399/877] net: stmmac: dwmac4: Use the correct bufzise when the len is exactly 8K Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-10-01 20:09 ` Harshit Mogalapalli
2026-09-30 15:21 ` [PATCH 6.12 401/877] nfc: nfcmrvl: validate helper command length before pull Greg Kroah-Hartman
` (484 subsequent siblings)
884 siblings, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, co+ac0a8c41de69121d, Weiming Shi,
Alexei Starovoitov, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <bestswngs@gmail.com>
[ Upstream commit 6db1ce73e9853f533eb7f413f14ba00f8ec6f80d ]
__bpf_offload_dev_match() falls back to comparing offdev pointers after an
exact netdev mismatch. Bound-only programs normally have NULL offdevs, so
unrelated netdevs compare equal. A bound-only program on an
offload-registered netdev can instead inherit a real offdev and match a
sibling port. With CAP_BPF and CAP_NET_ADMIN, a caller can use
bpf(BPF_LINK_CREATE) with a different target ifindex to run metadata kfuncs
specialized for the bound driver on the target driver's xdp_buff. Running a
veth-bound program on tun reads beyond tun's bare stack xdp_buff as a
veth_xdp_buff.
Oops: general protection fault, probably for non-canonical address
KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
RIP: 0010:veth_xdp_rx_timestamp (drivers/net/veth.c:1673)
Call Trace:
...
tun_build_skb (drivers/net/tun.c:1739)
tun_get_user (drivers/net/tun.c:1856)
tun_chr_write_iter (drivers/net/tun.c:2091)
vfs_write (fs/read_write.c:595 fs/read_write.c:687)
ksys_write (fs/read_write.c:739)
do_syscall_64 (arch/x86/entry/syscall_64.c:84)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
Kernel panic - not syncing: Fatal exception in interrupt
Restrict non-offloaded programs to exact netdev matches and retain the
shared-offdev fallback only for genuinely offloaded multi-port programs.
Fixes: 2b3486bc2d23 ("bpf: Introduce device-bound XDP programs")
Reported-by: <co+ac0a8c41de69121d@bugs.sh>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20260917161335.1020405-2-bestswngs@gmail.com/
Link: https://patch.msgid.link/20260920132303.4109240-3-bestswngs@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/offload.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kernel/bpf/offload.c b/kernel/bpf/offload.c
index 56115739fcfdd..1b6f9e7175666 100644
--- a/kernel/bpf/offload.c
+++ b/kernel/bpf/offload.c
@@ -703,6 +703,8 @@ static bool __bpf_offload_dev_match(struct bpf_prog *prog,
return false;
if (offload->netdev == netdev)
return true;
+ if (!bpf_prog_is_offloaded(prog->aux))
+ return false;
ondev1 = bpf_offload_find_netdev(offload->netdev);
ondev2 = bpf_offload_find_netdev(netdev);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 400/877] bpf: Reject dev-bound-only programs on other devices
2026-09-30 15:21 ` [PATCH 6.12 400/877] bpf: Reject dev-bound-only programs on other devices Greg Kroah-Hartman
@ 2026-10-01 20:09 ` Harshit Mogalapalli
2026-10-02 20:59 ` Harshit Mogalapalli
2026-10-02 21:10 ` Sasha Levin
0 siblings, 2 replies; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-01 20:09 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, co+ac0a8c41de69121d, Weiming Shi, Alexei Starovoitov,
Sasha Levin
On 30/09/26 8:51 pm, Greg Kroah-Hartman wrote:
> 6.12-stable review patch. If anyone has any objections, please let me know.
>
> ------------------
>
> From: Weiming Shi <bestswngs@gmail.com>
>
> [ Upstream commit 6db1ce73e9853f533eb7f413f14ba00f8ec6f80d ]
>
> __bpf_offload_dev_match() falls back to comparing offdev pointers after an
> exact netdev mismatch. Bound-only programs normally have NULL offdevs, so
> unrelated netdevs compare equal. A bound-only program on an
> offload-registered netdev can instead inherit a real offdev and match a
> sibling port. With CAP_BPF and CAP_NET_ADMIN, a caller can use
> bpf(BPF_LINK_CREATE) with a different target ifindex to run metadata kfuncs
> specialized for the bound driver on the target driver's xdp_buff. Running a
> veth-bound program on tun reads beyond tun's bare stack xdp_buff as a
> veth_xdp_buff.
>
> Oops: general protection fault, probably for non-canonical address
> KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
> RIP: 0010:veth_xdp_rx_timestamp (drivers/net/veth.c:1673)
> Call Trace:
> ...
> tun_build_skb (drivers/net/tun.c:1739)
> tun_get_user (drivers/net/tun.c:1856)
> tun_chr_write_iter (drivers/net/tun.c:2091)
> vfs_write (fs/read_write.c:595 fs/read_write.c:687)
> ksys_write (fs/read_write.c:739)
> do_syscall_64 (arch/x86/entry/syscall_64.c:84)
> entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
> Kernel panic - not syncing: Fatal exception in interrupt
>
> Restrict non-offloaded programs to exact netdev matches and retain the
> shared-offdev fallback only for genuinely offloaded multi-port programs.
>
> Fixes: 2b3486bc2d23 ("bpf: Introduce device-bound XDP programs")
> Reported-by: <co+ac0a8c41de69121d@bugs.sh>
> Signed-off-by: Weiming Shi <bestswngs@gmail.com>
> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
> Link: https://lore.kernel.org/bpf/20260917161335.1020405-2-bestswngs@gmail.com/
> Link: https://patch.msgid.link/20260920132303.4109240-3-bestswngs@gmail.com
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---
> kernel/bpf/offload.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/kernel/bpf/offload.c b/kernel/bpf/offload.c
> index 56115739fcfdd..1b6f9e7175666 100644
> --- a/kernel/bpf/offload.c
> +++ b/kernel/bpf/offload.c
> @@ -703,6 +703,8 @@ static bool __bpf_offload_dev_match(struct bpf_prog *prog,
> return false;
> if (offload->netdev == netdev)
> return true;
> + if (!bpf_prog_is_offloaded(prog->aux))
> + return false;
Hi Greg/Sasha,
An AI assisted backport review flagged this, and I checked the upstream
code against the 6.12.y tip f4ffa8dc360b.
Upstream 6db1ce73e985 checks device binding in dev_xdp_install():
if (bpf_prog_is_dev_bound(prog->aux) &&
!bpf_offload_dev_match(prog, dev)) {
NL_SET_ERR_MSG(extack, "Program bound to different device");
return -EINVAL;
}
6.12.y bpf_xdp_link_update() goes directly to that installer:
mode = dev_xdp_mode(xdp_link->dev, xdp_link->flags);
bpf_op = dev_xdp_bpf_op(xdp_link->dev, mode);
err = dev_xdp_install(xdp_link->dev, mode, bpf_op, NULL,
xdp_link->flags, new_prog);
if (err)
goto out_unlock;
Link update calls dev_xdp_install() directly, bypassing 6.12's binding
check in dev_xdp_attach(). Type checks and tun's callback cannot prevent
wrong-device installation, leaving metadata kfuncs with an incompatible
context. The matcher fix is correct; this bypass predates it. No
destination kernel crash was reproduced.
I think 6.12.y needs ad27ed7d2309419a129078d781504f486b1b469a ("bpf,
xdp: move offload check into dev_xdp_install()"), adapted to the 6.12
installer, alongside this fix, thoughts?
thanks,
Harshit>
> ondev1 = bpf_offload_find_netdev(offload->netdev);
> ondev2 = bpf_offload_find_netdev(netdev);
^ permalink raw reply [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 400/877] bpf: Reject dev-bound-only programs on other devices
2026-10-01 20:09 ` Harshit Mogalapalli
@ 2026-10-02 20:59 ` Harshit Mogalapalli
2026-10-03 1:30 ` Sasha Levin
2026-10-02 21:10 ` Sasha Levin
1 sibling, 1 reply; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-02 20:59 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable, Sasha Levin
Cc: patches, co+ac0a8c41de69121d, Weiming Shi, Alexei Starovoitov
Hi Greg/Sasha,
On 02/10/26 1:39 am, Harshit Mogalapalli wrote:
>
>
...
>> Signed-off-by: Sasha Levin <sashal@kernel.org>
>> ---
>> kernel/bpf/offload.c | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/kernel/bpf/offload.c b/kernel/bpf/offload.c
>> index 56115739fcfdd..1b6f9e7175666 100644
>> --- a/kernel/bpf/offload.c
>> +++ b/kernel/bpf/offload.c
>> @@ -703,6 +703,8 @@ static bool __bpf_offload_dev_match(struct
>> bpf_prog *prog,
>> return false;
>> if (offload->netdev == netdev)
>> return true;
>> + if (!bpf_prog_is_offloaded(prog->aux))
>> + return false;
>
>
> Hi Greg/Sasha,
>
> An AI assisted backport review flagged this, and I checked the upstream
> code against the 6.12.y tip f4ffa8dc360b.
>
> Upstream 6db1ce73e985 checks device binding in dev_xdp_install():
>
> if (bpf_prog_is_dev_bound(prog->aux) &&
> !bpf_offload_dev_match(prog, dev)) {
> NL_SET_ERR_MSG(extack, "Program bound to different device");
> return -EINVAL;
> }
>
> 6.12.y bpf_xdp_link_update() goes directly to that installer:
>
> mode = dev_xdp_mode(xdp_link->dev, xdp_link->flags);
> bpf_op = dev_xdp_bpf_op(xdp_link->dev, mode);
> err = dev_xdp_install(xdp_link->dev, mode, bpf_op, NULL,
> xdp_link->flags, new_prog);
> if (err)
> goto out_unlock;
>
> Link update calls dev_xdp_install() directly, bypassing 6.12's binding
> check in dev_xdp_attach(). Type checks and tun's callback cannot prevent
> wrong-device installation, leaving metadata kfuncs with an incompatible
> context. The matcher fix is correct; this bypass predates it. No
> destination kernel crash was reproduced.
>
> I think 6.12.y needs ad27ed7d2309419a129078d781504f486b1b469a ("bpf,
> xdp: move offload check into dev_xdp_install()"), adapted to the 6.12
> installer, alongside this fix, thoughts?
>
https://git.kernel.org/pub/scm/linux/kernel/git/stable/stable-queue.git/tree/queue-6.12
I still see this.
I think we need to drop this until we take the prereq as well Greg.
Sorry for the ping.
thanks,
Harshit
> thanks,
> Harshit>
>> ondev1 = bpf_offload_find_netdev(offload->netdev);
>> ondev2 = bpf_offload_find_netdev(netdev);
>
^ permalink raw reply [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 400/877] bpf: Reject dev-bound-only programs on other devices
2026-10-02 20:59 ` Harshit Mogalapalli
@ 2026-10-03 1:30 ` Sasha Levin
0 siblings, 0 replies; 922+ messages in thread
From: Sasha Levin @ 2026-10-03 1:30 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: Sasha Levin, patches, co+ac0a8c41de69121d, Weiming Shi,
Alexei Starovoitov, Harshit Mogalapalli
> I think we need to drop this until we take the prereq as well Greg.
ad27ed7d2309 ("bpf, xdp: move offload check into dev_xdp_install()")
is queued for the next 6.12 and 6.6 releases.
I'm keeping 6db1ce73e985 in this release, because it independently
closes the BPF_LINK_CREATE/netlink path. Without the prereq the
LINK_UPDATE path stays open, as it already is today, so the fix is
incomplete but not a regression. Dropping it would leave both paths
open.
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 922+ messages in thread
* Re: [PATCH 6.12 400/877] bpf: Reject dev-bound-only programs on other devices
2026-10-01 20:09 ` Harshit Mogalapalli
2026-10-02 20:59 ` Harshit Mogalapalli
@ 2026-10-02 21:10 ` Sasha Levin
1 sibling, 0 replies; 922+ messages in thread
From: Sasha Levin @ 2026-10-02 21:10 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: Sasha Levin, patches, co+ac0a8c41de69121d, Weiming Shi,
Alexei Starovoitov, Harshit Mogalapalli
> I think 6.12.y needs ad27ed7d2309419a129078d781504f486b1b469a ("bpf,
> xdp: move offload check into dev_xdp_install()"), adapted to the 6.12
> installer, alongside this fix, thoughts?
Queued for 6.12 and 6.6, thanks.
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 922+ messages in thread
* [PATCH 6.12 401/877] nfc: nfcmrvl: validate helper command length before pull
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (399 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 400/877] bpf: Reject dev-bound-only programs on other devices Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 402/877] nfc: st21nfca: validate received frame size Greg Kroah-Hartman
` (483 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pengpeng Hou, David Heidelberg,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <pengpeng@iscas.ac.cn>
[ Upstream commit 686f942332b1667f13f3b8d6a2f50bcfbf42e277 ]
The firmware download receive path removes the NCI data header and
reads the helper command before validating the remaining packet length.
A short frame can therefore reach the data access before the malformed
packet is rejected.
Validate the complete helper command length before stripping the NCI
data header.
Fixes: 3194c6870158 ("NFC: nfcmrvl: add firmware download support")
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260715084325.40276-1-pengpeng@iscas.ac.cn
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nfc/nfcmrvl/fw_dnld.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/nfc/nfcmrvl/fw_dnld.c b/drivers/nfc/nfcmrvl/fw_dnld.c
index 93094418fd247..9716caddb88e8 100644
--- a/drivers/nfc/nfcmrvl/fw_dnld.c
+++ b/drivers/nfc/nfcmrvl/fw_dnld.c
@@ -262,9 +262,14 @@ static int process_state_fw_dnld(struct nfcmrvl_private *priv,
* B8..N: payload
*/
- /* Remove NCI HDR */
- skb_pull(skb, 3);
- if (skb->data[0] != HELPER_CMD_PACKET_FORMAT || skb->len != 5) {
+ if (skb->len != NCI_DATA_HDR_SIZE + 5) {
+ nfc_err(priv->dev, "bad command");
+ return -EINVAL;
+ }
+
+ /* Remove NCI header */
+ skb_pull(skb, NCI_DATA_HDR_SIZE);
+ if (skb->data[0] != HELPER_CMD_PACKET_FORMAT) {
nfc_err(priv->dev, "bad command");
return -EINVAL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 402/877] nfc: st21nfca: validate received frame size
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (400 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 401/877] nfc: nfcmrvl: validate helper command length before pull Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 403/877] nfc: llcp: Fix list corruption / refcount desync in nfc_llcp_recv_dm() Greg Kroah-Hartman
` (482 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pengpeng Hou, David Heidelberg,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <pengpeng@iscas.ac.cn>
[ Upstream commit a653c01ce447f10c36b901646888c0330363af4f ]
st21nfca_hci_i2c_repack() trims a received frame at its EOF marker
before removing byte stuffing. It then assumes the truncated frame
contains the LLC header and two CRC bytes, and it unconditionally reads
the byte after an escape marker.
A malformed frame can place EOF immediately after the start marker or can
end its data portion with an escape marker. The former leaves too few
bytes for check_crc(), while the latter makes the unstuffing loop read past
the current skb length.
Require the minimum framing bytes both before and after unstuffing. Use
separate input and output cursors while removing byte stuffing, and reject
an escape marker without its encoded byte. This keeps malformed frames
within the received frame boundary before CRC processing.
Fixes: 3096e25a3e40 ("NFC: st21nfca: Fix incorrect byte stuffing revocation")
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260715084405.41546-1-pengpeng@iscas.ac.cn
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nfc/st21nfca/i2c.c | 29 +++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)
diff --git a/drivers/nfc/st21nfca/i2c.c b/drivers/nfc/st21nfca/i2c.c
index 02c3d11a19c43..4d95e25d3724f 100644
--- a/drivers/nfc/st21nfca/i2c.c
+++ b/drivers/nfc/st21nfca/i2c.c
@@ -290,27 +290,36 @@ static int check_crc(u8 *buf, int buflen)
*/
static int st21nfca_hci_i2c_repack(struct sk_buff *skb)
{
- int i, j, r, size;
+ int read, write, r, size;
- if (skb->len < 1 || (skb->len > 1 && skb->data[1] != 0))
+ if (skb->len < ST21NFCA_FRAME_HEADROOM ||
+ !IS_START_OF_FRAME(skb->data))
return -EBADMSG;
size = get_frame_size(skb->data, skb->len);
if (size > 0) {
+ if (size < ST21NFCA_FRAME_HEADROOM + 2)
+ return -EBADMSG;
+
skb_trim(skb, size);
/* remove ST21NFCA byte stuffing for upper layer */
- for (i = 1, j = 0; i < skb->len; i++) {
- if (skb->data[i + j] ==
+ for (read = 1, write = 1; read < skb->len;) {
+ if (skb->data[read] ==
(u8) ST21NFCA_ESCAPE_BYTE_STUFFING) {
- skb->data[i] = skb->data[i + j + 1]
- | ST21NFCA_BYTE_STUFFING_MASK;
- i++;
- j++;
+ if (read + 1 == skb->len)
+ return -EBADMSG;
+
+ skb->data[write++] = skb->data[read + 1]
+ | ST21NFCA_BYTE_STUFFING_MASK;
+ read += 2;
+ } else {
+ skb->data[write++] = skb->data[read++];
}
- skb->data[i] = skb->data[i + j];
}
/* remove byte stuffing useless byte */
- skb_trim(skb, i - j);
+ skb_trim(skb, write);
+ if (skb->len < ST21NFCA_FRAME_HEADROOM + 2)
+ return -EBADMSG;
/* remove ST21NFCA_SOF_EOF from head */
skb_pull(skb, 1);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 403/877] nfc: llcp: Fix list corruption / refcount desync in nfc_llcp_recv_dm()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (401 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 402/877] nfc: st21nfca: validate received frame size Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 404/877] selftests: nci: Correct pthread_create return value check Greg Kroah-Hartman
` (481 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aldo Ariel Panzardo,
David Heidelberg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
[ Upstream commit bf1460acdf8cf5a07c819f59785d40f20d113099 ]
nfc_llcp_recv_dm() handles DM(NOBOUND)/DM(REJ) for a socket that is still
linked on local->connecting_sockets: it looks the socket up with
nfc_llcp_connecting_sock_get(), sets sk->sk_state = LLCP_CLOSED and
returns, without taking the socket lock and without unlinking the socket
from the connecting_sockets list.
llcp_sock_release() selects the list to unlink from by sk_state: a socket
in LLCP_CONNECTING is unlinked from connecting_sockets, otherwise from the
sockets list. Because recv_dm left the socket physically on
connecting_sockets but in the LLCP_CLOSED state, release() takes the else
branch and calls nfc_llcp_sock_unlink(&local->sockets, sk). That runs
sk_del_node_init() while holding sockets.lock, i.e. it removes the socket
from the connecting_sockets hlist under the wrong lock. A concurrent
connect() linking another socket onto connecting_sockets under
connecting_sockets.lock then mutates the same hlist unserialized, which
corrupts the list and desyncs the sk_add_node()/sk_del_node_init()
sock_hold()/__sock_put() pairing. An unprivileged local process holding
LLCP sockets, with the DM supplied by the remote peer over an established
LLCP link, can drive this to leak kernel sockets without bound (the
mis-decrement goes through the non-freeing __sock_put() path, so the
object is never released), leading to memory exhaustion / DoS.
This is the same class of bug that was fixed in the sibling handler
nfc_llcp_recv_cc() by commit b493ea2765cc ("nfc: llcp: Fix use-after-free
race in nfc_llcp_recv_cc()"); recv_dm did not receive the equivalent fix.
Fix it the same way: take lock_sock(), re-check that the socket is still
hashed (release() may have won the race), and for the NOBOUND/REJ case
unlink it from connecting_sockets before moving it to LLCP_CLOSED. The
unlink drops the connecting_sockets membership reference via
sk_del_node_init(), leaving the socket unhashed, so the later
nfc_llcp_sock_unlink() in llcp_sock_release() becomes a no-op and no
double put occurs.
Fixes: a69f32af86e3 ("NFC: Socket linked list")
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Link: https://patch.msgid.link/20260716232657.203145-1-qwe.aldo@gmail.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/nfc/llcp_core.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
index 7b86faf3f4ce5..9ae9b4fde311e 100644
--- a/net/nfc/llcp_core.c
+++ b/net/nfc/llcp_core.c
@@ -1249,6 +1249,7 @@ static void nfc_llcp_recv_dm(struct nfc_llcp_local *local,
struct nfc_llcp_sock *llcp_sock;
struct sock *sk;
u8 dsap, ssap, reason;
+ bool connecting = false;
dsap = nfc_llcp_dsap(skb);
ssap = nfc_llcp_ssap(skb);
@@ -1260,6 +1261,7 @@ static void nfc_llcp_recv_dm(struct nfc_llcp_local *local,
case LLCP_DM_NOBOUND:
case LLCP_DM_REJ:
llcp_sock = nfc_llcp_connecting_sock_get(local, dsap);
+ connecting = true;
break;
default:
@@ -1274,10 +1276,33 @@ static void nfc_llcp_recv_dm(struct nfc_llcp_local *local,
sk = &llcp_sock->sk;
+ lock_sock(sk);
+
+ /* Check if socket was destroyed whilst waiting for the lock */
+ if (!sk_hashed(sk)) {
+ release_sock(sk);
+ nfc_llcp_sock_put(llcp_sock);
+ return;
+ }
+
+ /*
+ * For DM(NOBOUND)/DM(REJ) the socket is still linked on the
+ * connecting_sockets list. Unlink it here, under the socket lock,
+ * before moving it to LLCP_CLOSED: llcp_sock_release() selects the
+ * list to unlink from by sk_state, so leaving a connecting socket
+ * in the CLOSED state would make it unlink from the wrong list and
+ * corrupt the connecting_sockets list / desync the socket refcount.
+ * This mirrors nfc_llcp_recv_cc().
+ */
+ if (connecting)
+ nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
+
sk->sk_err = ENXIO;
sk->sk_state = LLCP_CLOSED;
sk->sk_state_change(sk);
+ release_sock(sk);
+
nfc_llcp_sock_put(llcp_sock);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 404/877] selftests: nci: Correct pthread_create return value check
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (402 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 403/877] nfc: llcp: Fix list corruption / refcount desync in nfc_llcp_recv_dm() Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 405/877] nfc: llcp: Fix race condition in accept_queue lifecycle Greg Kroah-Hartman
` (480 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Lei Zhu, David Heidelberg,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lei Zhu <zhulei@kylinos.cn>
[ Upstream commit 3d8afc5243ea2ee803d98e69eb4a01748167ac1b ]
The pthread_create() functions returns 0 on success and a positive value on
failure. Modify the return value check to correctly detect failure cases.
Fixes: 72696bd8a09d ("selftests: nci: Extract the start/stop discovery function")
Signed-off-by: Lei Zhu <zhulei@kylinos.cn>
Link: https://patch.msgid.link/20260729072426.303484-1-zhulei_szu@163.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/nci/nci_dev.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/nci/nci_dev.c b/tools/testing/selftests/nci/nci_dev.c
index 1562aa7d60b0f..2fae9ea352c87 100644
--- a/tools/testing/selftests/nci/nci_dev.c
+++ b/tools/testing/selftests/nci/nci_dev.c
@@ -438,7 +438,7 @@ FIXTURE_SETUP(NCI)
else
rc = pthread_create(&thread_t, NULL, virtual_dev_open,
(void *)&self->virtual_nci_fd);
- ASSERT_GT(rc, -1);
+ ASSERT_EQ(rc, 0);
rc = send_cmd_with_idx(self->sd, self->fid, self->pid,
NFC_CMD_DEV_UP, self->dev_idex);
@@ -509,7 +509,7 @@ FIXTURE_TEARDOWN(NCI)
rc = pthread_create(&thread_t, NULL, virtual_deinit,
(void *)&self->virtual_nci_fd);
- ASSERT_GT(rc, -1);
+ ASSERT_EQ(rc, 0);
rc = send_cmd_with_idx(self->sd, self->fid, self->pid,
NFC_CMD_DEV_DOWN, self->dev_idex);
EXPECT_EQ(rc, 0);
@@ -590,7 +590,7 @@ int start_polling(int dev_idx, int proto, int virtual_fd, int sd, int fid, int p
rc = pthread_create(&thread_t, NULL, virtual_poll_start,
(void *)&virtual_fd);
- if (rc < 0)
+ if (rc)
return rc;
rc = send_cmd_mt_nla(sd, fid, pid, NFC_CMD_START_POLL, 2, nla_start_poll_type,
@@ -610,7 +610,7 @@ int stop_polling(int dev_idx, int virtual_fd, int sd, int fid, int pid)
rc = pthread_create(&thread_t, NULL, virtual_poll_stop,
(void *)&virtual_fd);
- if (rc < 0)
+ if (rc)
return rc;
rc = send_cmd_with_idx(sd, fid, pid,
@@ -830,6 +830,8 @@ int disconnect_tag(int nfc_sock, int virtual_fd)
status = pthread_create(&thread_t, NULL, virtual_deactivate_proc,
(void *)&virtual_fd);
+ if (status)
+ return status;
close(nfc_sock);
pthread_join(thread_t, (void **)&status);
@@ -874,7 +876,7 @@ TEST_F(NCI, deinit)
else
rc = pthread_create(&thread_t, NULL, virtual_deinit,
(void *)&self->virtual_nci_fd);
- ASSERT_GT(rc, -1);
+ ASSERT_EQ(rc, 0);
rc = send_cmd_with_idx(self->sd, self->fid, self->pid,
NFC_CMD_DEV_DOWN, self->dev_idex);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 405/877] nfc: llcp: Fix race condition in accept_queue lifecycle
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (403 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 404/877] selftests: nci: Correct pthread_create return value check Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 406/877] selftests: nci: Fix uninitialized family ID on missing attribute Greg Kroah-Hartman
` (479 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lee Jones, David Heidelberg,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lee Jones <lee@kernel.org>
[ Upstream commit c3eef2f988a3db9690369d7cef9a3344dd9788d3 ]
In nfc_llcp_socket_release(), sockets and listener accept queues are
walked under the local sockets rwlock and bh_lock_sock(). However,
bh_lock_sock() does not synchronise against process-context lock_sock()
held by nfc_llcp_accept_dequeue() during accept(). Because
socket_release() does not check sock_owned_by_user(), both paths can
concurrently unlink and release the same child socket, resulting in
use-after-free or a NULL pointer dereference of child->parent in
nfc_llcp_accept_unlink().
Fix this synchronisation race by having nfc_llcp_socket_release() use
process-context lock_sock() instead of bh_lock_sock():
1. Pop sockets from the local sockets list under the write lock using
nfc_llcp_sock_list_pop() so lock_sock() can be acquired without
holding the rwlock.
2. Because lock_sock() can sleep, defer the final release of the
nfc_llcp_local structure to a workqueue (release_work). This avoids
a sleeping-in-atomic bug when the last local reference is dropped
from softirq context. Additionally, hold a single device reference
on local from registration until final destruction.
3. In nfc_llcp_local_get(), use kref_get_unless_zero() to prevent
resurrecting a local object whose teardown has been scheduled.
4. In llcp_sock_accept(), verify that the listener socket state is still
LLCP_LISTEN after waking from schedule_timeout() to prevent hangs if
the listener is closed concurrently.
5. When unlinking unaccepted child sockets during listener release,
unlink them from local->sockets, call sock_orphan(), and drop their
initial sk_alloc creation reference via sock_put().
6. Make nfc_llcp_accept_unlink() idempotent by guarding parent access with
a NULL check.
Fixes: 50b78b2a6500 ("NFC: Fix sleeping in atomic when releasing socket")
Signed-off-by: Lee Jones <lee@kernel.org>
Link: https://patch.msgid.link/20260902123033.1169067-1-lee@kernel.org
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/nfc/llcp.h | 1 +
net/nfc/llcp_core.c | 125 +++++++++++++++++++++++++++-----------------
net/nfc/llcp_sock.c | 49 ++++++++++++-----
3 files changed, 116 insertions(+), 59 deletions(-)
diff --git a/net/nfc/llcp.h b/net/nfc/llcp.h
index d8345ed57c954..23ae7a0112d37 100644
--- a/net/nfc/llcp.h
+++ b/net/nfc/llcp.h
@@ -91,6 +91,7 @@ struct nfc_llcp_local {
struct hlist_head pending_sdreqs;
struct timer_list sdreq_timer;
struct work_struct sdreq_timeout_work;
+ struct work_struct release_work;
u8 sdreq_next_tid;
/* sockets array */
diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
index 9ae9b4fde311e..a4d7b2eaebd43 100644
--- a/net/nfc/llcp_core.c
+++ b/net/nfc/llcp_core.c
@@ -20,6 +20,8 @@ static LIST_HEAD(llcp_devices);
/* Protects llcp_devices list */
static DEFINE_SPINLOCK(llcp_devices_lock);
+static struct workqueue_struct *llcp_wq;
+
static void nfc_llcp_rx_skb(struct nfc_llcp_local *local, struct sk_buff *skb);
void nfc_llcp_sock_link(struct llcp_sock_list *l, struct sock *sk)
@@ -63,21 +65,33 @@ static void nfc_llcp_socket_purge(struct nfc_llcp_sock *sock)
}
}
+static struct sock *nfc_llcp_sock_list_pop(struct llcp_sock_list *l)
+{
+ struct sock *sk;
+
+ write_lock(&l->lock);
+ sk = sk_head(&l->head);
+ if (sk) {
+ sock_hold(sk);
+ sk_del_node_init(sk);
+ }
+ write_unlock(&l->lock);
+
+ return sk;
+}
+
static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool device,
int err)
{
struct sock *sk;
- struct hlist_node *tmp;
struct nfc_llcp_sock *llcp_sock;
skb_queue_purge(&local->tx_queue);
- write_lock(&local->sockets.lock);
-
- sk_for_each_safe(sk, tmp, &local->sockets.head) {
+ while ((sk = nfc_llcp_sock_list_pop(&local->sockets))) {
llcp_sock = nfc_llcp_sock(sk);
- bh_lock_sock(sk);
+ lock_sock(sk);
nfc_llcp_socket_purge(llcp_sock);
@@ -91,17 +105,27 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool device,
list_for_each_entry_safe(lsk, n,
&llcp_sock->accept_queue,
accept_queue) {
- accept_sk = &lsk->sk;
- bh_lock_sock(accept_sk);
-
- nfc_llcp_accept_unlink(accept_sk);
+ bool put_creation = false;
- if (err)
- accept_sk->sk_err = err;
- accept_sk->sk_state = LLCP_CLOSED;
- accept_sk->sk_state_change(sk);
+ accept_sk = &lsk->sk;
+ lock_sock_nested(accept_sk,
+ SINGLE_DEPTH_NESTING);
+
+ if (nfc_llcp_sock(accept_sk)->parent == sk) {
+ nfc_llcp_accept_unlink(accept_sk);
+ nfc_llcp_sock_unlink(&local->sockets, accept_sk);
+
+ if (err)
+ accept_sk->sk_err = err;
+ accept_sk->sk_state = LLCP_CLOSED;
+ accept_sk->sk_state_change(accept_sk);
+ sock_orphan(accept_sk);
+ put_creation = true;
+ }
- bh_unlock_sock(accept_sk);
+ release_sock(accept_sk);
+ if (put_creation)
+ sock_put(accept_sk); /* creation ref */
}
}
@@ -110,23 +134,18 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool device,
sk->sk_state = LLCP_CLOSED;
sk->sk_state_change(sk);
- bh_unlock_sock(sk);
-
- sk_del_node_init(sk);
+ release_sock(sk);
+ sock_put(sk);
}
- write_unlock(&local->sockets.lock);
-
/* If we still have a device, we keep the RAW sockets alive */
if (device == true)
return;
- write_lock(&local->raw_sockets.lock);
-
- sk_for_each_safe(sk, tmp, &local->raw_sockets.head) {
+ while ((sk = nfc_llcp_sock_list_pop(&local->raw_sockets))) {
llcp_sock = nfc_llcp_sock(sk);
- bh_lock_sock(sk);
+ lock_sock(sk);
nfc_llcp_socket_purge(llcp_sock);
@@ -135,26 +154,20 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool device,
sk->sk_state = LLCP_CLOSED;
sk->sk_state_change(sk);
- bh_unlock_sock(sk);
-
- sk_del_node_init(sk);
+ release_sock(sk);
+ sock_put(sk);
}
-
- write_unlock(&local->raw_sockets.lock);
}
static struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
{
- /* Since using nfc_llcp_local may result in usage of nfc_dev, whenever
- * we hold a reference to local, we also need to hold a reference to
- * the device to avoid UAF.
- */
- if (!nfc_get_device(local->dev->idx))
+ if (!local)
return NULL;
- kref_get(&local->ref);
+ if (kref_get_unless_zero(&local->ref))
+ return local;
- return local;
+ return NULL;
}
static void local_cleanup(struct nfc_llcp_local *local)
@@ -172,30 +185,34 @@ static void local_cleanup(struct nfc_llcp_local *local)
nfc_llcp_free_sdp_tlv_list(&local->pending_sdreqs);
}
-static void local_release(struct kref *ref)
+static void local_release_work(struct work_struct *work)
{
struct nfc_llcp_local *local;
+ struct nfc_dev *dev;
- local = container_of(ref, struct nfc_llcp_local, ref);
+ local = container_of(work, struct nfc_llcp_local, release_work);
+ dev = local->dev;
local_cleanup(local);
kfree(local);
+ nfc_put_device(dev);
}
-int nfc_llcp_local_put(struct nfc_llcp_local *local)
+static void local_release(struct kref *ref)
{
- struct nfc_dev *dev;
- int ret;
+ struct nfc_llcp_local *local;
- if (local == NULL)
- return 0;
+ local = container_of(ref, struct nfc_llcp_local, ref);
- dev = local->dev;
+ queue_work(llcp_wq, &local->release_work);
+}
- ret = kref_put(&local->ref, local_release);
- nfc_put_device(dev);
+int nfc_llcp_local_put(struct nfc_llcp_local *local)
+{
+ if (!local)
+ return 0;
- return ret;
+ return kref_put(&local->ref, local_release);
}
static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local,
@@ -1703,6 +1720,7 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
INIT_WORK(&local->rx_work, nfc_llcp_rx_work);
INIT_WORK(&local->timeout_work, nfc_llcp_timeout_work);
+ INIT_WORK(&local->release_work, local_release_work);
rwlock_init(&local->sockets.lock);
rwlock_init(&local->connecting_sockets.lock);
@@ -1746,10 +1764,23 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev)
int __init nfc_llcp_init(void)
{
- return nfc_llcp_sock_init();
+ int ret;
+
+ llcp_wq = alloc_workqueue("nfc_llcp_wq", WQ_UNBOUND, 0);
+ if (!llcp_wq)
+ return -ENOMEM;
+
+ ret = nfc_llcp_sock_init();
+ if (ret) {
+ destroy_workqueue(llcp_wq);
+ return ret;
+ }
+
+ return 0;
}
void nfc_llcp_exit(void)
{
nfc_llcp_sock_exit();
+ destroy_workqueue(llcp_wq);
}
diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
index 507447bbceea4..f9d35711eb9a7 100644
--- a/net/nfc/llcp_sock.c
+++ b/net/nfc/llcp_sock.c
@@ -392,11 +392,12 @@ void nfc_llcp_accept_unlink(struct sock *sk)
pr_debug("state %d\n", sk->sk_state);
- list_del_init(&llcp_sock->accept_queue);
- sk_acceptq_removed(llcp_sock->parent);
- llcp_sock->parent = NULL;
-
- sock_put(sk);
+ if (llcp_sock->parent) {
+ list_del_init(&llcp_sock->accept_queue);
+ sk_acceptq_removed(llcp_sock->parent);
+ llcp_sock->parent = NULL;
+ sock_put(sk);
+ }
}
void nfc_llcp_accept_enqueue(struct sock *parent, struct sock *sk)
@@ -423,12 +424,20 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent,
list_for_each_entry_safe(lsk, n, &llcp_parent->accept_queue,
accept_queue) {
+ struct nfc_llcp_local *local;
+
sk = &lsk->sk;
- lock_sock(sk);
+ lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
if (sk->sk_state == LLCP_CLOSED) {
- release_sock(sk);
+ local = nfc_llcp_sock(sk)->local;
+
nfc_llcp_accept_unlink(sk);
+ if (local)
+ nfc_llcp_sock_unlink(&local->sockets, sk);
+ sock_orphan(sk);
+ release_sock(sk);
+ sock_put(sk);
continue;
}
@@ -464,7 +473,7 @@ static int llcp_sock_accept(struct socket *sock, struct socket *newsock,
pr_debug("parent %p\n", sk);
- lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
+ lock_sock(sk);
if (sk->sk_state != LLCP_LISTEN) {
ret = -EBADFD;
@@ -490,7 +499,12 @@ static int llcp_sock_accept(struct socket *sock, struct socket *newsock,
release_sock(sk);
timeo = schedule_timeout(timeo);
- lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
+ lock_sock(sk);
+
+ if (sk->sk_state != LLCP_LISTEN) {
+ ret = -EBADFD;
+ break;
+ }
}
__set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait);
@@ -629,13 +643,24 @@ static int llcp_sock_release(struct socket *sock)
list_for_each_entry_safe(lsk, n, &llcp_sock->accept_queue,
accept_queue) {
+ bool put_creation = false;
+
accept_sk = &lsk->sk;
- lock_sock(accept_sk);
+ lock_sock_nested(accept_sk, SINGLE_DEPTH_NESTING);
- nfc_llcp_send_disconnect(lsk);
- nfc_llcp_accept_unlink(accept_sk);
+ if (nfc_llcp_sock(accept_sk)->parent == sk) {
+ nfc_llcp_send_disconnect(lsk);
+ nfc_llcp_accept_unlink(accept_sk);
+ nfc_llcp_sock_unlink(&local->sockets, accept_sk);
+
+ accept_sk->sk_state = LLCP_CLOSED;
+ sock_orphan(accept_sk);
+ put_creation = true;
+ }
release_sock(accept_sk);
+ if (put_creation)
+ sock_put(accept_sk); /* creation ref */
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 406/877] selftests: nci: Fix uninitialized family ID on missing attribute
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (404 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 405/877] nfc: llcp: Fix race condition in accept_queue lifecycle Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 407/877] selftests/nci: Fix out-of-bounds store on thread join Greg Kroah-Hartman
` (478 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chaithanya Lagisetty, Hangbin Liu,
David Heidelberg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chaithanya Lagisetty <nagachaithanya9911@gmail.com>
[ Upstream commit eda518d2cdb6074a0bcdfa06af291616bcb5c421 ]
get_family_id() walks the generic netlink CTRL_CMD_GETFAMILY reply
looking for the CTRL_ATTR_FAMILY_ID attribute and returns the parsed
value in the local variable "id". If the reply does not carry that
attribute, the parsing loop never assigns "id" and the function returns
an indeterminate stack value, which the caller stores in self->fid and
uses for subsequent netlink requests.
Initialize "id" to 0 so a missing attribute yields a deterministic
(invalid) family ID instead of a garbage value.
Fixes: f595cf1242f3 ("selftests: Add nci suite")
Signed-off-by: Chaithanya Lagisetty <nagachaithanya9911@gmail.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Link: https://patch.msgid.link/20260901070618.3299012-1-nagachaithanya9911@gmail.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/nci/nci_dev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/nci/nci_dev.c b/tools/testing/selftests/nci/nci_dev.c
index 2fae9ea352c87..2a96ca0a9fb1b 100644
--- a/tools/testing/selftests/nci/nci_dev.c
+++ b/tools/testing/selftests/nci/nci_dev.c
@@ -182,7 +182,7 @@ static int get_family_id(int sd, __u32 pid, __u32 *event_group)
} ans;
struct nlattr *na;
int resp_len;
- __u16 id;
+ __u16 id = 0;
int len;
int rc;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 407/877] selftests/nci: Fix out-of-bounds store on thread join
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (405 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 406/877] selftests: nci: Fix uninitialized family ID on missing attribute Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 408/877] nfc: virtual_ncidev: Add missing ioctl compat handler Greg Kroah-Hartman
` (477 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Gellermann, Simon Horman,
David Heidelberg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Gellermann <christian.gellermann@codasip.com>
[ Upstream commit 6be581aeffc215bfc77939cd59902b0dbc4af23e ]
The NCI test collects the exit status of its helper threads by passing
the address of an int to pthread_join():
int status;
...
pthread_join(thread_t, (void **) &status);
pthread_join() stores a void pointer to the memory location. On 64-bit
systems, a void pointer is wider than an int, so the store overruns the
4 bytes of space allocated on the stack for the integer and corrupts the
adjacent stack. On our CHERI system, this caused a fault due to a
capability bounds violation.
Fix this by introducing a helper that joins a thread through a void
pointer and converts the result back to an integer, which is what the
helper threads return.
While here, also fix the logic in disconnect_tag() if the helper thread
creation failed. Previously, it would have joined a thread that was
never created when pthread_create() failed.
Fixes: f595cf1242f3 ("selftests: Add nci suite")
Signed-off-by: Chris Gellermann <christian.gellermann@codasip.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260904095915.3372241-1-christian.gellermann@codasip.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/nci/nci_dev.c | 31 +++++++++++++++++----------
1 file changed, 20 insertions(+), 11 deletions(-)
diff --git a/tools/testing/selftests/nci/nci_dev.c b/tools/testing/selftests/nci/nci_dev.c
index 2a96ca0a9fb1b..ab34e08c64d60 100644
--- a/tools/testing/selftests/nci/nci_dev.c
+++ b/tools/testing/selftests/nci/nci_dev.c
@@ -8,6 +8,7 @@
#include <stdlib.h>
#include <errno.h>
+#include <stdint.h>
#include <string.h>
#include <sys/ioctl.h>
#include <fcntl.h>
@@ -87,6 +88,16 @@ struct msgtemplate {
char buf[MAX_MSG_SIZE];
};
+static int join_thread_status(pthread_t thread)
+{
+ void *thread_ret = NULL;
+
+ if (pthread_join(thread, &thread_ret))
+ return -1;
+
+ return (int)(intptr_t)thread_ret;
+}
+
static int create_nl_socket(void)
{
int fd;
@@ -444,7 +455,7 @@ FIXTURE_SETUP(NCI)
NFC_CMD_DEV_UP, self->dev_idex);
EXPECT_EQ(rc, 0);
- pthread_join(thread_t, (void **)&status);
+ status = join_thread_status(thread_t);
ASSERT_EQ(status, 0);
self->open_state = true;
}
@@ -514,7 +525,7 @@ FIXTURE_TEARDOWN(NCI)
NFC_CMD_DEV_DOWN, self->dev_idex);
EXPECT_EQ(rc, 0);
- pthread_join(thread_t, (void **)&status);
+ status = join_thread_status(thread_t);
ASSERT_EQ(status, 0);
}
@@ -585,7 +596,6 @@ int start_polling(int dev_idx, int proto, int virtual_fd, int sd, int fid, int p
void *nla_start_poll_data[2] = {&dev_idx, &proto};
int nla_start_poll_len[2] = {4, 4};
pthread_t thread_t;
- int status;
int rc;
rc = pthread_create(&thread_t, NULL, virtual_poll_start,
@@ -598,14 +608,12 @@ int start_polling(int dev_idx, int proto, int virtual_fd, int sd, int fid, int p
if (rc != 0)
return rc;
- pthread_join(thread_t, (void **)&status);
- return status;
+ return join_thread_status(thread_t);
}
int stop_polling(int dev_idx, int virtual_fd, int sd, int fid, int pid)
{
pthread_t thread_t;
- int status;
int rc;
rc = pthread_create(&thread_t, NULL, virtual_poll_stop,
@@ -618,8 +626,7 @@ int stop_polling(int dev_idx, int virtual_fd, int sd, int fid, int pid)
if (rc != 0)
return rc;
- pthread_join(thread_t, (void **)&status);
- return status;
+ return join_thread_status(thread_t);
}
TEST_F(NCI, start_poll)
@@ -834,8 +841,10 @@ int disconnect_tag(int nfc_sock, int virtual_fd)
return status;
close(nfc_sock);
- pthread_join(thread_t, (void **)&status);
- return status;
+ if (status)
+ return -1;
+
+ return join_thread_status(thread_t);
}
TEST_F(NCI, t4t_tag_read)
@@ -882,7 +891,7 @@ TEST_F(NCI, deinit)
NFC_CMD_DEV_DOWN, self->dev_idex);
EXPECT_EQ(rc, 0);
- pthread_join(thread_t, (void **)&status);
+ status = join_thread_status(thread_t);
self->open_state = 0;
ASSERT_EQ(status, 0);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 408/877] nfc: virtual_ncidev: Add missing ioctl compat handler
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (406 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 407/877] selftests/nci: Fix out-of-bounds store on thread join Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 409/877] nfc: llcp: fix sdreq TLV list leak on parse/alloc/send failure Greg Kroah-Hartman
` (476 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Gellermann, Simon Horman,
David Heidelberg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Gellermann <christian.gellermann@codasip.com>
[ Upstream commit 51814683e28fc64eceb415962376956c3cfc75a7 ]
The compat handler for ioctls to the virtual nci device is missing. So,
nci-specific ioctls of a compat task return with -1 and errno set to
ENOTTY. Add a handler.
The handling of an ioctl() call of a compat task to get the index of
virtual nci device (IOCTL_GET_NCIDEV_IDX) lands in the default case of
the ioctl compat handler (see fs/ioctl.c):
COMPAT_SYSCALL_DEFINE3(ioctl, ...)
{
...
default:
error = do_vfs_ioctl(fd_file(f), fd, cmd, ...);
if (error != -ENOIOCTLCMD)
break;
if (fd_file(f)->f_op->compat_ioctl)
error = fd_file(f)->f_op->compat_ioctl(fd_file(f), cmd, arg);
if (error == -ENOIOCTLCMD)
error = -ENOTTY;
...
}
There, do_vfs_ioctl() returns -ENOIOCTLCMD and compat_ioctl is not
set for virtual_ncidev_fops, i.e. f_op->compat_ioctl == NULL. So, the
ioctl() syscall returns with -1 and errno set to ENOTTY to the compat
task.
To fix this, use the compat_ptr_ioctl helper for compat handling here.
It shall be used for ioctls that "either ignore the argument or pass a
pointer to a compatible data type". The driver's sole ioctl takes a user
void pointer and copies nfc_dev->idx to it, a 4-byte integer across all
ABIs.
This issue has been found by running the nci_dev kernel selftest as
rv64 binary on top of a CHERI kernel, where the ioctl() ends up in
the ioctl compat handler, similar to a 32-bit application on top of a
64-bit kernel.
Fixes: e624e6c3e777 ("nfc: Add a virtual nci device driver")
Signed-off-by: Chris Gellermann <christian.gellermann@codasip.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260904164252.18351-1-christian.gellermann@codasip.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nfc/virtual_ncidev.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/nfc/virtual_ncidev.c b/drivers/nfc/virtual_ncidev.c
index 590b038e449e5..db15d26692666 100644
--- a/drivers/nfc/virtual_ncidev.c
+++ b/drivers/nfc/virtual_ncidev.c
@@ -195,7 +195,8 @@ static const struct file_operations virtual_ncidev_fops = {
.write = virtual_ncidev_write,
.open = virtual_ncidev_open,
.release = virtual_ncidev_close,
- .unlocked_ioctl = virtual_ncidev_ioctl
+ .unlocked_ioctl = virtual_ncidev_ioctl,
+ .compat_ioctl = compat_ptr_ioctl,
};
static struct miscdevice miscdev = {
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 409/877] nfc: llcp: fix sdreq TLV list leak on parse/alloc/send failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (407 preceding siblings ...)
2026-09-30 15:21 ` [PATCH 6.12 408/877] nfc: virtual_ncidev: Add missing ioctl compat handler Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 410/877] nfc: st21nfca: validate ISO15693 inventory length Greg Kroah-Hartman
` (475 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cong Nguyen, Simon Horman,
David Heidelberg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Nguyen <congnt264@gmail.com>
[ Upstream commit 66f4300206b82b0b143ef0d9be90cd8d29f23a47 ]
nfc_genl_llc_sdreq() builds a list of TLV nodes while walking nested
netlink attrs, but 3 error paths (nested-attr parse failure, TLV alloc
ENOMEM, nfc_llcp_send_snl_sdreq() failure) all skip freeing what was
already queued.
Route them through a new free_list label, mirroring the SDRES path in
the same file which already does this. Harmless on the success path
too -- send_snl_sdreq() drains the list as it moves nodes, so it's
already empty by the time free_list runs.
Fixes: d9b8d8e19b07 ("NFC: llcp: Service Name Lookup netlink interface")
Assisted-by: Claude:claude-opus-4
Signed-off-by: Cong Nguyen <congnt264@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260914121129.2098606-1-congnt264@gmail.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/nfc/netlink.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index dd2ce73a24fbe..ce18dda58a832 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -1176,7 +1176,7 @@ static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info)
if (rc != 0) {
rc = -EINVAL;
- goto put_local;
+ goto free_list;
}
if (!sdp_attrs[NFC_SDP_ATTR_URI])
@@ -1195,7 +1195,7 @@ static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info)
sdreq = nfc_llcp_build_sdreq_tlv(tid, uri, uri_len);
if (sdreq == NULL) {
rc = -ENOMEM;
- goto put_local;
+ goto free_list;
}
tlvs_len += sdreq->tlv_len;
@@ -1210,6 +1210,9 @@ static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info)
rc = nfc_llcp_send_snl_sdreq(local, &sdreq_list, tlvs_len);
+free_list:
+ nfc_llcp_free_sdp_tlv_list(&sdreq_list);
+
put_local:
nfc_llcp_local_put(local);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 410/877] nfc: st21nfca: validate ISO15693 inventory length
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (408 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 409/877] nfc: llcp: fix sdreq TLV list leak on parse/alloc/send failure Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 411/877] nfc: llcp: fix -ENOMEM on connect with zero-length service name Greg Kroah-Hartman
` (474 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pengpeng Hou, David Heidelberg,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <pengpeng@iscas.ac.cn>
[ Upstream commit 7f2ea5ed588c03d481f0301e6c3d4240132383fb ]
The ISO15693 inventory helper removes a two-byte prefix without checking
that it exists, then accepts a one-byte remainder before reading data[1] as
the DSFID.
Require the prefix and at least two remaining bytes before copying the UID
data and reading the DSFID.
Fixes: 7974728094d3 ("NFC: st21nfca: Add ISO15693 Reader/Writer support")
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260830132958.6397-1-pengpeng@iscas.ac.cn
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nfc/st21nfca/core.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/nfc/st21nfca/core.c b/drivers/nfc/st21nfca/core.c
index 161caf2675cfc..7eb5e5f0686be 100644
--- a/drivers/nfc/st21nfca/core.c
+++ b/drivers/nfc/st21nfca/core.c
@@ -577,9 +577,7 @@ static int st21nfca_get_iso15693_inventory(struct nfc_hci_dev *hdev,
if (r < 0)
goto exit;
- skb_pull(inventory_skb, 2);
-
- if (inventory_skb->len == 0 ||
+ if (!skb_pull(inventory_skb, 2) || inventory_skb->len < 2 ||
inventory_skb->len > NFC_ISO15693_UID_MAXSIZE) {
r = -EPROTO;
goto exit;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 411/877] nfc: llcp: fix -ENOMEM on connect with zero-length service name
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (409 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 410/877] nfc: st21nfca: validate ISO15693 inventory length Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 412/877] nfc: llcp: fix WKS SAP hijacking via prefix match in nfc_llcp_wks_sap() Greg Kroah-Hartman
` (473 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ömer Mete Kaya,
David Heidelberg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ömer Mete Kaya <omermetekaya0@gmail.com>
[ Upstream commit c04981e42d94f39c1dba965cc462a046e946a6c5 ]
When service_name_len is 0, kmemdup() returns ZERO_SIZE_PTR which
passes the NULL check, causing nfc_llcp_send_connect() to attempt
building a zero-length service name TLV and fail with -ENOMEM.
Fix by setting service_name to NULL directly when service_name_len is 0.
Fixes: d646960f7986 ("NFC: Initial LLCP support")
Signed-off-by: Ömer Mete Kaya <omermetekaya0@gmail.com>
Link: https://patch.msgid.link/20260909122029.34081-1-omermetekaya0@gmail.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/nfc/llcp_sock.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
index f9d35711eb9a7..0601ddb4304aa 100644
--- a/net/nfc/llcp_sock.c
+++ b/net/nfc/llcp_sock.c
@@ -759,12 +759,16 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
llcp_sock->service_name_len = min_t(unsigned int,
addr->service_name_len,
NFC_LLCP_MAX_SERVICE_NAME);
- llcp_sock->service_name = kmemdup(addr->service_name,
- llcp_sock->service_name_len,
- GFP_KERNEL);
- if (!llcp_sock->service_name) {
- ret = -ENOMEM;
- goto sock_llcp_release;
+ if (llcp_sock->service_name_len == 0) {
+ llcp_sock->service_name = NULL;
+ } else {
+ llcp_sock->service_name = kmemdup(addr->service_name,
+ llcp_sock->service_name_len,
+ GFP_KERNEL);
+ if (!llcp_sock->service_name) {
+ ret = -ENOMEM;
+ goto sock_llcp_release;
+ }
}
nfc_llcp_sock_link(&local->connecting_sockets, sk);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 412/877] nfc: llcp: fix WKS SAP hijacking via prefix match in nfc_llcp_wks_sap()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (410 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 411/877] nfc: llcp: fix -ENOMEM on connect with zero-length service name Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 413/877] nfc: llcp: fix slab-out-of-bounds reads when logging service names Greg Kroah-Hartman
` (472 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ömer Mete Kaya,
David Heidelberg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ömer Mete Kaya <omermetekaya0@gmail.com>
[ Upstream commit 408cff6bd60636df201274d320edfdfde9ed41db ]
nfc_llcp_wks_sap() compares only service_name_len bytes, so a short
service_name like "u" matches longer WKS strings like "urn:nfc:sn:snep".
Fix by requiring exact length match before strncmp().
Fixes: d646960f7986 ("NFC: Initial LLCP support")
Signed-off-by: Ömer Mete Kaya <omermetekaya0@gmail.com>
Link: https://patch.msgid.link/20260909121437.33744-1-omermetekaya0@gmail.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/nfc/llcp_core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
index a4d7b2eaebd43..0b1a2755f58ac 100644
--- a/net/nfc/llcp_core.c
+++ b/net/nfc/llcp_core.c
@@ -367,7 +367,8 @@ static int nfc_llcp_wks_sap(const char *service_name, size_t service_name_len)
if (wks[sap] == NULL)
continue;
- if (strncmp(wks[sap], service_name, service_name_len) == 0)
+ if (strlen(wks[sap]) == service_name_len &&
+ !strncmp(wks[sap], service_name, service_name_len))
return sap;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 413/877] nfc: llcp: fix slab-out-of-bounds reads when logging service names
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (411 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 412/877] nfc: llcp: fix WKS SAP hijacking via prefix match in nfc_llcp_wks_sap() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 414/877] nfc: pn533: fix OOB read in pn533_acr122_is_rx_frame_valid() Greg Kroah-Hartman
` (471 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+1e3df0852e82c21ca418,
Ömer Mete Kaya, David Heidelberg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ömer Mete Kaya <omermetekaya0@gmail.com>
[ Upstream commit 7dcf371a35632f035baf77bcf2c129165f772ce4 ]
nfc_llcp_wks_sap() and nfc_llcp_build_sdreq_tlv() pass non-null-
terminated strings to pr_debug() using the %s format specifier.
The buffers are allocated via kmemdup() or come from netlink
attributes and are not guaranteed to be null-terminated, causing
__dynamic_pr_debug() to read beyond the allocated region:
KASAN: slab-out-of-bounds Read in __dynamic_pr_debug
Fix both call sites by using %.*s with the explicit length to limit
the output to the actual length of the string.
Fixes: d9b8d8e19b07 ("NFC: llcp: Service Name Lookup netlink interface")
Reported-by: syzbot+1e3df0852e82c21ca418@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=1e3df0852e82c21ca418
Signed-off-by: Ömer Mete Kaya <omermetekaya0@gmail.com>
Link: https://patch.msgid.link/20260908161952.731468-1-omermetekaya0@gmail.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/nfc/llcp_commands.c | 2 +-
net/nfc/llcp_core.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c
index a93bf0b43d504..2d9e0925b1cc7 100644
--- a/net/nfc/llcp_commands.c
+++ b/net/nfc/llcp_commands.c
@@ -135,7 +135,7 @@ struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, const char *uri,
{
struct nfc_llcp_sdp_tlv *sdreq;
- pr_debug("uri: %s, len: %zu\n", uri, uri_len);
+ pr_debug("uri: %.*s, len: %zu\n", (int)uri_len, uri, uri_len);
/* sdreq->tlv_len is u8, takes uri_len, + 3 for header, + 1 for NULL */
if (WARN_ON_ONCE(uri_len > U8_MAX - 4))
diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
index 0b1a2755f58ac..49f7793ab0312 100644
--- a/net/nfc/llcp_core.c
+++ b/net/nfc/llcp_core.c
@@ -356,7 +356,7 @@ static int nfc_llcp_wks_sap(const char *service_name, size_t service_name_len)
{
int sap, num_wks;
- pr_debug("%s\n", service_name);
+ pr_debug("%.*s\n", (int)service_name_len, service_name);
if (service_name == NULL)
return -EINVAL;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 414/877] nfc: pn533: fix OOB read in pn533_acr122_is_rx_frame_valid()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (412 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 413/877] nfc: llcp: fix slab-out-of-bounds reads when logging service names Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 415/877] net/sched: act_gate: budget the per-entry list in get_fill_size Greg Kroah-Hartman
` (470 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+1853daab1a47603d4678,
Deepanshu Kartikey, David Heidelberg, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Deepanshu Kartikey <kartikey406@gmail.com>
[ Upstream commit b61732f47316d45f27706db7812950145d3327b5 ]
frame->ccid.datalen is read directly from the USB response frame
and used, unchecked, as an index into frame->data[]. A malicious or
malfunctioning device can set this field to an arbitrary value,
causing the driver to read far outside the received buffer.
Bound ccid.datalen against the maximum possible ACR122 frame size
before using it. This replaces the existing datalen == 0 check,
since datalen < 2 already covers that case and additionally
rejects datalen == 1, which would still underflow the
"datalen - 2" offset used below.
Fixes: 9815c7cf22da ("NFC: pn533: Separate physical layer from the core implementation")
Reported-by: syzbot+1853daab1a47603d4678@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=1853daab1a47603d4678
Tested-by: syzbot+1853daab1a47603d4678@syzkaller.appspotmail.com
Assisted-by: LLM
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
Link: https://patch.msgid.link/20260923035627.6210-1-kartikey406@gmail.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nfc/pn533/usb.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c
index 0f12f86ebb023..35f3350cad324 100644
--- a/drivers/nfc/pn533/usb.c
+++ b/drivers/nfc/pn533/usb.c
@@ -319,7 +319,9 @@ static bool pn533_acr122_is_rx_frame_valid(void *_frame, struct pn533 *dev)
if (frame->ccid.type != 0x83)
return false;
- if (!frame->ccid.datalen)
+ if (frame->ccid.datalen < 2 ||
+ frame->ccid.datalen > PN533_ACR122_FRAME_MAX_PAYLOAD_LEN +
+ PN533_ACR122_RX_FRAME_TAIL_LEN)
return false;
if (frame->data[frame->ccid.datalen - 2] == 0x63)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 415/877] net/sched: act_gate: budget the per-entry list in get_fill_size
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (413 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 414/877] nfc: pn533: fix OOB read in pn533_acr122_is_rx_frame_valid() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 416/877] veth: manage XDP program pointers during channel resize Greg Kroah-Hartman
` (469 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, hybris, Jamal Hadi Salim,
Victor Nogueira, Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Nogueira <victor@mojatatu.com>
[ Upstream commit cfa165cbfbed9d0f4bbc22fef4309f595a3ab187 ]
tcf_gate_get_fill_size returns only the TCA_GATE_PARMS size, but
tcf_gate_dump also emits three 64-bit timestamps, the clock id, flags,
priority and the variable-length TCA_GATE_ENTRY_LIST nest. The per-entry
nest is unbounded: parse_gate_list places no cap on the number of
sched-entries, so a gate with many entries can push the real dump well
past the skb that tca_get_fill allocates from this size.
RTM_NEWACTION then fails the add-notify with -EINVAL while the action is
already committed to the IDR, and a subsequent RTM_GETACTION on the
installed gate also returns -EINVAL because its dump no longer fits.
Fix this by accounting for the missing fields in tcf_gate_get_fill_size
along with all elements in the entries list.
Note that sizing the reply from the action lets an oversized gate
install cleanly for the first time: with the input unbounded by
parse_gate_list, the sized skb can now grow well above
NLMSG_GOODSIZE per netlink request (a transient GFP_KERNEL allocation
reachable only with namespace-local CAP_NET_ADMIN). Overload from a
malicious netns admin is hardening material, not net, per the
discussion at
https://lore.kernel.org/netdev/20260914191108.55a1a4f1@kernel.org/;
a follow-up patch for net-next will cap the sched-entry count.
Fixes: 4e76e75d6aba ("net sched actions: calculate add/delete event message size")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260824153903.4143642-1-victor@mojatatu.com
Tested-by: hybris <hybris@mojatatu.ai>
Co-developed-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
Link: https://patch.msgid.link/QDISC-3BLH.v1.20260914203033@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/act_gate.c | 30 +++++++++++++++++++++++++++++-
1 file changed, 29 insertions(+), 1 deletion(-)
diff --git a/net/sched/act_gate.c b/net/sched/act_gate.c
index 58cae012a4391..d66c07aef95a2 100644
--- a/net/sched/act_gate.c
+++ b/net/sched/act_gate.c
@@ -686,7 +686,35 @@ static void tcf_gate_stats_update(struct tc_action *a, u64 bytes, u64 packets,
static size_t tcf_gate_get_fill_size(const struct tc_action *act)
{
- return nla_total_size(sizeof(struct tc_gate));
+ struct tcf_gate *gact = to_gate(act);
+ const struct tcf_gate_params *p;
+ struct tcfg_gate_entry *entry;
+ size_t size = nla_total_size(sizeof(struct tc_gate)) /* TCA_GATE_PARMS */
+ + 3 * nla_total_size_64bit(sizeof(u64)) /* TCA_GATE_BASE_TIME
+ * TCA_GATE_CYCLE_TIME
+ * TCA_GATE_CYCLE_TIME_EXT
+ */
+ + nla_total_size(sizeof(s32)) /* TCA_GATE_CLOCKID */
+ + nla_total_size(sizeof(u32)) /* TCA_GATE_FLAGS */
+ + nla_total_size(sizeof(s32)) /* TCA_GATE_PRIORITY */
+ + nla_total_size(0); /* TCA_GATE_ENTRY_LIST */
+ /* TCA_GATE_TM is budgeted by tcf_action_shared_attrs_size() */
+
+ rcu_read_lock();
+ p = rcu_dereference(gact->param);
+ if (p) {
+ list_for_each_entry_rcu(entry, &p->entries, list)
+ /* TCA_GATE_ONE_ENTRY nest and its attributes */
+ size += nla_total_size(0)
+ + nla_total_size(sizeof(u32)) /* TCA_GATE_ENTRY_INDEX */
+ + nla_total_size(0) /* TCA_GATE_ENTRY_GATE */
+ + nla_total_size(sizeof(u32)) /* TCA_GATE_ENTRY_INTERVAL */
+ + nla_total_size(sizeof(s32)) /* TCA_GATE_ENTRY_MAX_OCTETS */
+ + nla_total_size(sizeof(s32)); /* TCA_GATE_ENTRY_IPV */
+ }
+ rcu_read_unlock();
+
+ return size;
}
static void tcf_gate_entry_destructor(void *priv)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 416/877] veth: manage XDP program pointers during channel resize
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (414 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 415/877] net/sched: act_gate: budget the per-entry list in get_fill_size Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 417/877] net: skbuff: fix pull-bound underflow in skb_checksum_setup_ipv6() Greg Kroah-Hartman
` (468 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Weiming Shi, Stanislav Fomichev,
Jiayuan Chen, Jason Xing, Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <kuba@kernel.org>
[ Upstream commit 7104a370714346b667712913dc16abf14bbc97ed ]
veth_set_channels() tears down XDP resources for removed RX queues
without clearing rq->xdp_prog. If the program is then detached or
replaced, those queues keep the old pointer after bpf_prog_put().
A later channel increase can re-enable NAPI and run the freed program.
BUG: unable to handle page fault for address: ffffc90000256048
Oops: Oops: 0000 [#1] SMP KASAN NOPTI
RIP: veth_xdp_rcv_skb (include/linux/filter.h:779
include/net/xdp.h:696 drivers/net/veth.c:820)
Call Trace:
veth_xdp_rcv (drivers/net/veth.c:941)
veth_poll (drivers/net/veth.c:986)
__napi_poll (net/core/dev.c:7787)
net_rx_action (net/core/dev.c:7850 net/core/dev.c:8007)
handle_softirqs (kernel/softirq.c:645)
Kernel panic - not syncing: Fatal exception in interrupt
Fixes: 4752eeb3d891 ("veth: implement support for set_channel ethtool op")
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
Link: https://patch.msgid.link/20260921231856.1798630-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/veth.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 03341951a2126..f3e5f8ce9ac20 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -1053,6 +1053,7 @@ static int __veth_napi_enable_range(struct net_device *dev, int start, int end)
for (i = start; i < end; i++) {
struct veth_rq *rq = &priv->rq[i];
+ rcu_assign_pointer(rq->xdp_prog, priv->_xdp_prog);
napi_enable(&rq->xdp_napi);
rcu_assign_pointer(priv->rq[i].napi, &priv->rq[i].xdp_napi);
}
@@ -1087,6 +1088,7 @@ static void veth_napi_del_range(struct net_device *dev, int start, int end)
rcu_assign_pointer(priv->rq[i].napi, NULL);
napi_disable(&rq->xdp_napi);
+ rcu_assign_pointer(rq->xdp_prog, NULL);
__netif_napi_del(&rq->xdp_napi);
}
synchronize_net();
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 417/877] net: skbuff: fix pull-bound underflow in skb_checksum_setup_ipv6()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (415 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 416/877] veth: manage XDP program pointers during channel resize Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 418/877] vrf: Stop corrupting skb->csum when capturing CHECKSUM_COMPLETE packets Greg Kroah-Hartman
` (467 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Shihuang Liu,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shihuang Liu <shlomojune6@gmail.com>
[ Upstream commit 3b4e0b0c008a8c1b474730248cd5b873026c74bd ]
skb_maybe_pull_tail() subtracts skb_headlen(skb) from the unsigned max
argument and passes the result to __pskb_pull_tail() as a signed int. The
function does not ensure that max is at least skb_headlen(skb).
This can happen while parsing IPv6 extension headers when an skb already
has a linear area larger than MAX_IPV6_HDR_LEN. Once the parser needs data
beyond the linear area, max - skb_headlen(skb) wraps and is converted to a
negative delta. __pskb_pull_tail() then passes that negative length to
skb_copy_bits(), where it can become a very large copy length.
Pass the requested length itself as the pull bound at the three
extension-header call sites, so the delta can no longer go negative.
Fixes: 1431fb31ecba ("xen-netback: fix fragment detection in checksum setup")
Suggested-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Shihuang Liu <shlomojune6@gmail.com>
Link: https://patch.msgid.link/20260919133604.50948-1-shlomojune6@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/skbuff.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 1e4f7b8e952cc..623d9d10a208f 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -5841,7 +5841,8 @@ static int skb_checksum_setup_ipv6(struct sk_buff *skb, bool recalculate)
err = skb_maybe_pull_tail(skb,
off +
sizeof(struct ipv6_opt_hdr),
- MAX_IPV6_HDR_LEN);
+ off +
+ sizeof(struct ipv6_opt_hdr));
if (err < 0)
goto out;
@@ -5856,7 +5857,8 @@ static int skb_checksum_setup_ipv6(struct sk_buff *skb, bool recalculate)
err = skb_maybe_pull_tail(skb,
off +
sizeof(struct ip_auth_hdr),
- MAX_IPV6_HDR_LEN);
+ off +
+ sizeof(struct ip_auth_hdr));
if (err < 0)
goto out;
@@ -5871,7 +5873,8 @@ static int skb_checksum_setup_ipv6(struct sk_buff *skb, bool recalculate)
err = skb_maybe_pull_tail(skb,
off +
sizeof(struct frag_hdr),
- MAX_IPV6_HDR_LEN);
+ off +
+ sizeof(struct frag_hdr));
if (err < 0)
goto out;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 418/877] vrf: Stop corrupting skb->csum when capturing CHECKSUM_COMPLETE packets
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (416 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 417/877] net: skbuff: fix pull-bound underflow in skb_checksum_setup_ipv6() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 419/877] bpf: Fix immediate JMP JEQ/JNE on MIPS32 Greg Kroah-Hartman
` (466 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Stefano Sasso, Ido Schimmel,
David Ahern, Eric Dumazet, Andrea Mayer, Jakub Kicinski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <idosch@nvidia.com>
[ Upstream commit ab7aa05c06ae340e5c7530bb78fa8d23794e460b ]
The VRF device is an Ethernet device but it can have non-Ethernet ports
such as IP tunnels. Before the cited commit, capturing packets from such
ports on the VRF device resulted in these packets being detected as
malformed since they lack an Ethernet header.
The cited commit fixed it by pushing a dummy Ethernet header to such
packets before the capture and pulling it afterwards. In the case of
CHECKSUM_COMPLETE packets it also updated skb->csum with the checksum of
the dummy Ethernet header. This is wrong as skb->csum should not include
the checksum of the Ethernet header ("checksum of the _whole_ packet as
seen by netif_rx()").
This also means that L4 protocols receive a corrupted skb->csum and
potentially drop the packet, as is the case with UDP packets whose
checksum was completed by software.
Fix by removing the unnecessary call to skb_postpush_rcsum().
Fixes: 048939088220 ("vrf: add mac header for tunneled packets when sniffer is attached")
Reported-by: Stefano Sasso <stesasso@gmail.com>
Closes: https://lore.kernel.org/netdev/CALtE316UtL3x7LL6uxfXzx8rW6AbzYPeDOb478hqJCr_-dj=Wg@mail.gmail.com/
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Andrea Mayer <andrea.mayer@uniroma2.it>
Link: https://patch.msgid.link/20260922131239.2509494-1-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/vrf.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index e684d59291efc..c071b3ccd8cb9 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -1224,8 +1224,6 @@ static int vrf_prepare_mac_header(struct sk_buff *skb,
skb->protocol = eth->h_proto;
skb->pkt_type = PACKET_HOST;
- skb_postpush_rcsum(skb, skb->data, ETH_HLEN);
-
skb_pull_inline(skb, ETH_HLEN);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 419/877] bpf: Fix immediate JMP JEQ/JNE on MIPS32
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (417 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 418/877] vrf: Stop corrupting skb->csum when capturing CHECKSUM_COMPLETE packets Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 420/877] bpf: Fix BSWAP 32 and 16 on MIPS64 Greg Kroah-Hartman
` (465 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Johan Almbladh, Alexei Starovoitov,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Almbladh <johan.almbladh@anyfinetworks.com>
[ Upstream commit db762fd96be225bd06161c9631160c755d891693 ]
An addu instruction was emitted instead of addiu, causing the immediate
value 1 to be interpreted as register $at. This made the comparison
result invalid when the immediate operand was negative. Note that $at
is mapped to BPF_REG_AX, which is used for constant blinding.
Fix the instruction to use the immediate form.
Found with test_bpf on MIPS32r1 emulated by QEMU.
Fixes: eb63cfcd2ee8 ("mips, bpf: Add eBPF JIT for 32-bit MIPS")
Signed-off-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20260923105158.3514342-1-johan.almbladh@anyfinetworks.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/mips/net/bpf_jit_comp32.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/mips/net/bpf_jit_comp32.c b/arch/mips/net/bpf_jit_comp32.c
index 40a878b672f5d..15a2a153dc873 100644
--- a/arch/mips/net/bpf_jit_comp32.c
+++ b/arch/mips/net/bpf_jit_comp32.c
@@ -1111,7 +1111,7 @@ static void emit_jmp_i64(struct jit_context *ctx,
emit(ctx, xor, tmp, lo(dst), tmp);
}
if (imm < 0) { /* Compare sign extension */
- emit(ctx, addu, MIPS_R_T9, hi(dst), 1);
+ emit(ctx, addiu, MIPS_R_T9, hi(dst), 1);
emit(ctx, or, tmp, tmp, MIPS_R_T9);
} else { /* Compare zero extension */
emit(ctx, or, tmp, tmp, hi(dst));
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 420/877] bpf: Fix BSWAP 32 and 16 on MIPS64
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (418 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 419/877] bpf: Fix immediate JMP JEQ/JNE on MIPS32 Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 421/877] driver core: Add device probe log helper dev_warn_probe() Greg Kroah-Hartman
` (464 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Johan Almbladh, Alexei Starovoitov,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Almbladh <johan.almbladh@anyfinetworks.com>
[ Upstream commit 8110ba09777873443db286b3cbb89b0e6311c554 ]
The 16/32-bit byteswap implementations for MIPS64r1 and earlier do
not have an explicit zero extension afterwards. The input is first
sign-extended to 64 bits, and the byteswap sequence can then leave
the result sign-extended depending on the value of the low bits.
Add the missing zero-extension.
Found with test_bpf on MIPS64r1 emulated by QEMU.
Fixes: fbc802de6b10 ("mips, bpf: Add new eBPF JIT for 64-bit MIPS")
Signed-off-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20260923105158.3514342-2-johan.almbladh@anyfinetworks.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/mips/net/bpf_jit_comp64.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/mips/net/bpf_jit_comp64.c b/arch/mips/net/bpf_jit_comp64.c
index fa7e9aa37f498..6681ccac9dd9e 100644
--- a/arch/mips/net/bpf_jit_comp64.c
+++ b/arch/mips/net/bpf_jit_comp64.c
@@ -305,8 +305,7 @@ static void emit_bswap_r64(struct jit_context *ctx, u8 dst, u32 width)
case 16:
emit_sext(ctx, dst, dst);
emit_bswap_r(ctx, dst, width);
- if (cpu_has_mips64r2 || cpu_has_mips64r6)
- emit_zext(ctx, dst);
+ emit_zext(ctx, dst);
break;
}
clobber_reg(ctx, dst);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 421/877] driver core: Add device probe log helper dev_warn_probe()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (419 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 420/877] bpf: Fix BSWAP 32 and 16 on MIPS64 Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 422/877] tg3: use random MAC address when tg3_get_device_address fails Greg Kroah-Hartman
` (463 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dragan Simic,
Hélène Vulquin, Mark Brown, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dragan Simic <dsimic@manjaro.org>
[ Upstream commit 36e69b160705b65bf136c2fb6a1194447eeb8478 ]
Some drivers can still provide their functionality to a certain extent
even when some of their resource acquisitions eventually fail. In such
cases, emitting errors isn't the desired action, but warnings should be
emitted instead.
To solve this, introduce dev_warn_probe() as a new device probe log helper,
which behaves identically as the already existing dev_err_probe(), while it
produces warnings instead of errors. The intended use is with the resources
that are actually optional for a particular driver.
While there, copyedit the kerneldoc for dev_err_probe() a bit, to simplify
its wording a bit, and reuse it as the kerneldoc for dev_warn_probe(), with
the necessary wording adjustments, of course.
Signed-off-by: Dragan Simic <dsimic@manjaro.org>
Tested-by: Hélène Vulquin <oss@helene.moe>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://patch.msgid.link/2be0a28538bb2a3d1bcc91e2ca1f2d0dc09146d9.1727601608.git.dsimic@manjaro.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 4eb3f195ef08 ("tg3: use random MAC address when tg3_get_device_address fails")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/base/core.c | 129 +++++++++++++++++++++++++++++--------
include/linux/dev_printk.h | 1 +
2 files changed, 102 insertions(+), 28 deletions(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 2e1cce6265e05..a6134a5e5e110 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -5112,6 +5112,49 @@ define_dev_printk_level(_dev_info, KERN_INFO);
#endif
+static void __dev_probe_failed(const struct device *dev, int err, bool fatal,
+ const char *fmt, va_list vargsp)
+{
+ struct va_format vaf;
+ va_list vargs;
+
+ /*
+ * On x86_64 and possibly on other architectures, va_list is actually a
+ * size-1 array containing a structure. As a result, function parameter
+ * vargsp decays from T[1] to T*, and &vargsp has type T** rather than
+ * T(*)[1], which is expected by its assignment to vaf.va below.
+ *
+ * One standard way to solve this mess is by creating a copy in a local
+ * variable of type va_list and then using a pointer to that local copy
+ * instead, which is the approach employed here.
+ */
+ va_copy(vargs, vargsp);
+
+ vaf.fmt = fmt;
+ vaf.va = &vargs;
+
+ switch (err) {
+ case -EPROBE_DEFER:
+ device_set_deferred_probe_reason(dev, &vaf);
+ dev_dbg(dev, "error %pe: %pV", ERR_PTR(err), &vaf);
+ break;
+
+ case -ENOMEM:
+ /* Don't print anything on -ENOMEM, there's already enough output */
+ break;
+
+ default:
+ /* Log fatal final failures as errors, otherwise produce warnings */
+ if (fatal)
+ dev_err(dev, "error %pe: %pV", ERR_PTR(err), &vaf);
+ else
+ dev_warn(dev, "error %pe: %pV", ERR_PTR(err), &vaf);
+ break;
+ }
+
+ va_end(vargs);
+}
+
/**
* dev_err_probe - probe error check and log helper
* @dev: the pointer to the struct device
@@ -5124,7 +5167,7 @@ define_dev_printk_level(_dev_info, KERN_INFO);
* -EPROBE_DEFER and propagate error upwards.
* In case of -EPROBE_DEFER it sets also defer probe reason, which can be
* checked later by reading devices_deferred debugfs attribute.
- * It replaces code sequence::
+ * It replaces the following code sequence::
*
* if (err != -EPROBE_DEFER)
* dev_err(dev, ...);
@@ -5136,47 +5179,77 @@ define_dev_printk_level(_dev_info, KERN_INFO);
*
* return dev_err_probe(dev, err, ...);
*
- * Using this helper in your probe function is totally fine even if @err is
- * known to never be -EPROBE_DEFER.
+ * Using this helper in your probe function is totally fine even if @err
+ * is known to never be -EPROBE_DEFER.
* The benefit compared to a normal dev_err() is the standardized format
- * of the error code, it being emitted symbolically (i.e. you get "EAGAIN"
- * instead of "-35") and the fact that the error code is returned which allows
- * more compact error paths.
+ * of the error code, which is emitted symbolically (i.e. you get "EAGAIN"
+ * instead of "-35"), and having the error code returned allows more
+ * compact error paths.
*
* Returns @err.
*/
int dev_err_probe(const struct device *dev, int err, const char *fmt, ...)
{
- struct va_format vaf;
- va_list args;
+ va_list vargs;
- va_start(args, fmt);
- vaf.fmt = fmt;
- vaf.va = &args;
+ va_start(vargs, fmt);
- switch (err) {
- case -EPROBE_DEFER:
- device_set_deferred_probe_reason(dev, &vaf);
- dev_dbg(dev, "error %pe: %pV", ERR_PTR(err), &vaf);
- break;
+ /* Use dev_err() for logging when err doesn't equal -EPROBE_DEFER */
+ __dev_probe_failed(dev, err, true, fmt, vargs);
- case -ENOMEM:
- /*
- * We don't print anything on -ENOMEM, there is already enough
- * output.
- */
- break;
+ va_end(vargs);
- default:
- dev_err(dev, "error %pe: %pV", ERR_PTR(err), &vaf);
- break;
- }
+ return err;
+}
+EXPORT_SYMBOL_GPL(dev_err_probe);
- va_end(args);
+/**
+ * dev_warn_probe - probe error check and log helper
+ * @dev: the pointer to the struct device
+ * @err: error value to test
+ * @fmt: printf-style format string
+ * @...: arguments as specified in the format string
+ *
+ * This helper implements common pattern present in probe functions for error
+ * checking: print debug or warning message depending if the error value is
+ * -EPROBE_DEFER and propagate error upwards.
+ * In case of -EPROBE_DEFER it sets also defer probe reason, which can be
+ * checked later by reading devices_deferred debugfs attribute.
+ * It replaces the following code sequence::
+ *
+ * if (err != -EPROBE_DEFER)
+ * dev_warn(dev, ...);
+ * else
+ * dev_dbg(dev, ...);
+ * return err;
+ *
+ * with::
+ *
+ * return dev_warn_probe(dev, err, ...);
+ *
+ * Using this helper in your probe function is totally fine even if @err
+ * is known to never be -EPROBE_DEFER.
+ * The benefit compared to a normal dev_warn() is the standardized format
+ * of the error code, which is emitted symbolically (i.e. you get "EAGAIN"
+ * instead of "-35"), and having the error code returned allows more
+ * compact error paths.
+ *
+ * Returns @err.
+ */
+int dev_warn_probe(const struct device *dev, int err, const char *fmt, ...)
+{
+ va_list vargs;
+
+ va_start(vargs, fmt);
+
+ /* Use dev_warn() for logging when err doesn't equal -EPROBE_DEFER */
+ __dev_probe_failed(dev, err, false, fmt, vargs);
+
+ va_end(vargs);
return err;
}
-EXPORT_SYMBOL_GPL(dev_err_probe);
+EXPORT_SYMBOL_GPL(dev_warn_probe);
static inline bool fwnode_is_primary(struct fwnode_handle *fwnode)
{
diff --git a/include/linux/dev_printk.h b/include/linux/dev_printk.h
index ca32b5bb28eb5..eb2094e43050c 100644
--- a/include/linux/dev_printk.h
+++ b/include/linux/dev_printk.h
@@ -276,6 +276,7 @@ do { \
dev_driver_string(dev), dev_name(dev), ## arg)
__printf(3, 4) int dev_err_probe(const struct device *dev, int err, const char *fmt, ...);
+__printf(3, 4) int dev_warn_probe(const struct device *dev, int err, const char *fmt, ...);
/* Simple helper for dev_err_probe() when ERR_PTR() is to be returned. */
#define dev_err_ptr_probe(dev, ___err, fmt, ...) \
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 422/877] tg3: use random MAC address when tg3_get_device_address fails
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (420 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 421/877] driver core: Add device probe log helper dev_warn_probe() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 423/877] net: bcmgenet: fix 64-bit RTNL stats reading in ethtool on 32-bit systems Greg Kroah-Hartman
` (462 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jakub Kicinski, Ivan Delalande,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Delalande <colona@arista.com>
[ Upstream commit 4eb3f195ef08c5acaed87958297e41cc49588dde ]
Some of the tg3 NICs we use (BCM57762) reset the SRAM MAC address to the
placeholder address on link flaps, tg3_chip_reset, etc. We've typically
fixed it from userspace, but since e4c00ba7274b ("tg3: replace
placeholder MAC address with device property") was merged, tg3 just
fails probe as we don't have a way to get it through the generic
device_get_mac_address infrastructure as fallback on our systems.
Make the driver assign a random address in this condition instead of
being fatal for probe. Set deferred_probe_reason through dev_warn_probe
if the address isn't yet available from the provider.
Fixes: e4c00ba7274b ("tg3: replace placeholder MAC address with device property")
Suggested-by: Jakub Kicinski <kuba@kernel.org>
Link: https://lore.kernel.org/netdev/20260909191751.651aa5c4@kernel.org/
Signed-off-by: Ivan Delalande <colona@arista.com>
Link: https://patch.msgid.link/20260918224715.GA654128@visor
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/tg3.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 1df77bf9428b1..7f143e388d420 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -17899,11 +17899,14 @@ static int tg3_init_one(struct pci_dev *pdev,
err = tg3_get_device_address(tp, addr);
if (err) {
- dev_err(&pdev->dev,
- "Could not obtain valid ethernet address, aborting\n");
- goto err_out_apeunmap;
+ dev_warn_probe(&pdev->dev, err,
+ "Could not obtain a valid ethernet address\n");
+ if (err == -EPROBE_DEFER)
+ goto err_out_apeunmap;
+ eth_hw_addr_random(dev);
+ } else {
+ eth_hw_addr_set(dev, addr);
}
- eth_hw_addr_set(dev, addr);
intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW;
rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 423/877] net: bcmgenet: fix 64-bit RTNL stats reading in ethtool on 32-bit systems
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (421 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 422/877] tg3: use random MAC address when tg3_get_device_address fails Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 424/877] net: bcmgenet: initialize u64 stats seq counter for all queues Greg Kroah-Hartman
` (461 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Florian Fainelli,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Fainelli <florian.fainelli@broadcom.com>
[ Upstream commit 0e2bec77ea62895416600c90588f593516572bca ]
When bcmgenet was converted to 64-bit statistics, STAT_RTNL members were
switched to point into struct rtnl_link_stats64, whose fields are 64-bit
(__u64) regardless of architecture.
However, bcmgenet_get_ethtool_stats() retained a legacy check:
if (sizeof(unsigned long) != sizeof(u32) &&
s->stat_sizeof == sizeof(unsigned long))
On 32-bit systems, sizeof(unsigned long) == sizeof(u32), causing this
condition to evaluate to false. As a result, 64-bit RTNL stats fields were
read via *(u32 *)p. On 32-bit Big-Endian systems (such as MIPS BE), this
reads the high 32 bits and returns 0 until the counter exceeds 4GB; on
32-bit Little-Endian systems (such as 32-bit ARM), the value is truncated
to 32 bits.
Fix this by checking if s->stat_sizeof == sizeof(u64) so 64-bit fields are
always read as 64-bit values.
Fixes: 59aa6e3072aa ("net: bcmgenet: switch to use 64bit statistics")
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20260921220021.281418-2-florian.fainelli@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/genet/bcmgenet.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index eb6ef5ad8c2e1..ba33161db296f 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1289,9 +1289,8 @@ static void bcmgenet_get_ethtool_stats(struct net_device *dev,
p = (char *)&stats64;
p += s->stat_offset;
- if (sizeof(unsigned long) != sizeof(u32) &&
- s->stat_sizeof == sizeof(unsigned long))
- data[i] = *(unsigned long *)p;
+ if (s->stat_sizeof == sizeof(u64))
+ data[i] = *(u64 *)p;
else
data[i] = *(u32 *)p;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 424/877] net: bcmgenet: initialize u64 stats seq counter for all queues
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (422 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 423/877] net: bcmgenet: fix 64-bit RTNL stats reading in ethtool on 32-bit systems Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 425/877] net: bcmgenet: move bcmgenet_power_up into resume_noirq Greg Kroah-Hartman
` (460 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Florian Fainelli,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Fainelli <florian.fainelli@broadcom.com>
[ Upstream commit 3aeaa609fda19c09d5298c9fedaaa3b6229601b5 ]
bcmgenet_gstrings_stats statically defines ethtool statistics for queues
0 through GENET_MAX_MQ_CNT (4). However, bcmgenet_probe() only initialized
the u64_stats_sync seq counter up to priv->hw_params->rx_queues and
priv->hw_params->tx_queues.
Since priv->hw_params->rx_queues is 0 across all hardware versions (and
priv->hw_params->tx_queues is 0 on GENET V1), rings 1..4 have uninitialized
u64_stats_sync structures. When ethtool -S is run on 32-bit kernels,
bcmgenet_get_ethtool_stats() reads stats from rx_rings[1..4], causing
lockdep warnings due to the uninitialized sequence counters.
Initialize the sequence counters for all GENET_MAX_MQ_CNT + 1 queues.
Fixes: ffc2c8c4a714 ("net: bcmgenet: Initialize u64 stats seq counter")
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20260921220021.281418-3-florian.fainelli@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/genet/bcmgenet.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index ba33161db296f..aa565011fb808 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -4069,10 +4069,10 @@ static int bcmgenet_probe(struct platform_device *pdev)
priv->rx_rings[i].rx_max_coalesced_frames = 1;
/* Initialize u64 stats seq counter for 32bit machines */
- for (i = 0; i <= priv->hw_params->rx_queues; i++)
+ for (i = 0; i <= GENET_MAX_MQ_CNT; i++) {
u64_stats_init(&priv->rx_rings[i].stats64.syncp);
- for (i = 0; i <= priv->hw_params->tx_queues; i++)
u64_stats_init(&priv->tx_rings[i].stats64.syncp);
+ }
/* libphy will determine the link state */
netif_carrier_off(dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 425/877] net: bcmgenet: move bcmgenet_power_up into resume_noirq
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (423 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 424/877] net: bcmgenet: initialize u64 stats seq counter for all queues Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 426/877] net: bcmgenet: allow return of power up status Greg Kroah-Hartman
` (459 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Doug Berger, Florian Fainelli,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Doug Berger <opendmb@gmail.com>
[ Upstream commit ffce2bedd361177718dc0c3787f4adb4785a0151 ]
The bcmgenet_power_up() function is moved from the resume method
to the resume_noirq method for symmetry with the suspend_noirq
method. This allows the wol_active flag to be removed.
The UMAC_IRQ_WAKE_EVENT interrupts that can be unmasked by the
bcmgenet_wol_power_down_cfg() function are now re-masked by the
bcmgenet_wol_power_up_cfg() function at the resume_noirq level
as well.
Signed-off-by: Doug Berger <opendmb@gmail.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20250306192643.2383632-13-opendmb@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: cbbc1aee7776 ("net: bcmgenet: do not skip WoL power up on GENET V1")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/broadcom/genet/bcmgenet.c | 24 +++++++++----------
.../net/ethernet/broadcom/genet/bcmgenet.h | 1 -
.../ethernet/broadcom/genet/bcmgenet_wol.c | 8 +++----
3 files changed, 15 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index aa565011fb808..af7657de90591 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -4136,8 +4136,20 @@ static int bcmgenet_resume_noirq(struct device *d)
reg = bcmgenet_intrl2_0_readl(priv, INTRL2_CPU_STAT);
if (reg & UMAC_IRQ_WAKE_EVENT)
pm_wakeup_event(&priv->pdev->dev, 0);
+
+ /* From WOL-enabled suspend, switch to regular clock */
+ bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC);
}
+ /* If this is an internal GPHY, power it back on now, before UniMAC is
+ * brought out of reset as absolutely no UniMAC activity is allowed
+ */
+ if (priv->internal_phy)
+ bcmgenet_power_up(priv, GENET_POWER_PASSIVE);
+
+ /* take MAC out of reset */
+ bcmgenet_umac_reset(priv);
+
bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_WAKE_EVENT, INTRL2_CPU_CLEAR);
return 0;
@@ -4154,18 +4166,6 @@ static int bcmgenet_resume(struct device *d)
if (!netif_running(dev))
return 0;
- /* From WOL-enabled suspend, switch to regular clock */
- if (device_may_wakeup(d) && priv->wolopts)
- bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC);
-
- /* If this is an internal GPHY, power it back on now, before UniMAC is
- * brought out of reset as absolutely no UniMAC activity is allowed
- */
- if (priv->internal_phy)
- bcmgenet_power_up(priv, GENET_POWER_PASSIVE);
-
- bcmgenet_umac_reset(priv);
-
init_umac(priv);
phy_init_hw(dev->phydev);
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
index 89b071da31142..3e0878a03b43d 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
@@ -658,7 +658,6 @@ struct bcmgenet_priv {
struct clk *clk_wol;
u32 wolopts;
u8 sopass[SOPASS_MAX];
- bool wol_active;
struct bcmgenet_mib_counters mib;
};
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
index 98358b71cef5c..d67f1cb14a800 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
@@ -199,7 +199,6 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
retries);
clk_prepare_enable(priv->clk_wol);
- priv->wol_active = 1;
if (hfb_enable) {
bcmgenet_hfb_reg_writel(priv, hfb_enable,
@@ -238,13 +237,12 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
return;
}
- if (!priv->wol_active)
- return; /* failed to suspend so skip the rest */
-
- priv->wol_active = 0;
clk_disable_unprepare(priv->clk_wol);
priv->crc_fwd_en = 0;
+ bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_WAKE_EVENT,
+ INTRL2_CPU_MASK_SET);
+
/* Disable Magic Packet Detection */
if (priv->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 426/877] net: bcmgenet: allow return of power up status
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (424 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 425/877] net: bcmgenet: move bcmgenet_power_up into resume_noirq Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 427/877] net: bcmgenet: do not skip WoL power up on GENET V1 Greg Kroah-Hartman
` (458 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Doug Berger, Florian Fainelli,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Doug Berger <opendmb@gmail.com>
[ Upstream commit 2432b9817b7cb91aaae9e5032da0bb017cb3102d ]
It is possible for a WoL power up to fail due to the GENET being
reset while in the suspend state. Allow these failures to be
returned as error codes to allow different recovery behavior
when necessary.
Signed-off-by: Doug Berger <opendmb@gmail.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20250306192643.2383632-14-opendmb@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: cbbc1aee7776 ("net: bcmgenet: do not skip WoL power up on GENET V1")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/genet/bcmgenet.c | 13 ++++++++-----
drivers/net/ethernet/broadcom/genet/bcmgenet.h | 4 ++--
drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c | 12 +++++++-----
3 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index af7657de90591..fc1d4cef3ad81 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1693,13 +1693,14 @@ static int bcmgenet_power_down(struct bcmgenet_priv *priv,
return ret;
}
-static void bcmgenet_power_up(struct bcmgenet_priv *priv,
- enum bcmgenet_power_mode mode)
+static int bcmgenet_power_up(struct bcmgenet_priv *priv,
+ enum bcmgenet_power_mode mode)
{
+ int ret = 0;
u32 reg;
if (!bcmgenet_has_ext(priv))
- return;
+ return ret;
reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
@@ -1735,11 +1736,13 @@ static void bcmgenet_power_up(struct bcmgenet_priv *priv,
}
break;
case GENET_POWER_WOL_MAGIC:
- bcmgenet_wol_power_up_cfg(priv, mode);
- return;
+ ret = bcmgenet_wol_power_up_cfg(priv, mode);
+ break;
default:
break;
}
+
+ return ret;
}
static struct enet_cb *bcmgenet_get_txcb(struct bcmgenet_priv *priv,
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
index 3e0878a03b43d..532a4ea04c6e6 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
@@ -739,8 +739,8 @@ void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol);
int bcmgenet_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol);
int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
enum bcmgenet_power_mode mode);
-void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
- enum bcmgenet_power_mode mode);
+int bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
+ enum bcmgenet_power_mode mode);
void bcmgenet_eee_enable_set(struct net_device *dev, bool enable);
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
index d67f1cb14a800..945b32fe5697d 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
@@ -227,14 +227,14 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
return 0;
}
-void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
- enum bcmgenet_power_mode mode)
+int bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
+ enum bcmgenet_power_mode mode)
{
u32 reg;
if (mode != GENET_POWER_WOL_MAGIC) {
netif_err(priv, wol, priv->dev, "invalid mode: %d\n", mode);
- return;
+ return -EINVAL;
}
clk_disable_unprepare(priv->clk_wol);
@@ -247,7 +247,7 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
if (priv->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
if (!(reg & MPD_EN))
- return; /* already reset so skip the rest */
+ return -EPERM; /* already reset so skip the rest */
reg &= ~(MPD_EN | MPD_PW_EN);
bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);
}
@@ -256,7 +256,7 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
if (priv->wolopts & WAKE_FILTER) {
reg = bcmgenet_hfb_reg_readl(priv, HFB_CTRL);
if (!(reg & RBUF_ACPI_EN))
- return; /* already reset so skip the rest */
+ return -EPERM; /* already reset so skip the rest */
reg &= ~(RBUF_HFB_EN | RBUF_ACPI_EN);
bcmgenet_hfb_reg_writel(priv, reg, HFB_CTRL);
}
@@ -267,4 +267,6 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
reg &= ~CMD_CRC_FWD;
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
spin_unlock_bh(&priv->reg_lock);
+
+ return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 427/877] net: bcmgenet: do not skip WoL power up on GENET V1
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (425 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 426/877] net: bcmgenet: allow return of power up status Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 428/877] net: bcmgenet: validate Ethernet address in bcmgenet_set_mac_addr Greg Kroah-Hartman
` (457 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Florian Fainelli,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Fainelli <florian.fainelli@broadcom.com>
[ Upstream commit cbbc1aee7776c7fa1d89e6cb963a23e58c495dca ]
bcmgenet_power_up() had an early check for bcmgenet_has_ext(priv) before
dispatching by power mode. GENET V1 does not have the EXT block (unlike
GENET V2+), which causes bcmgenet_power_up() to immediately return 0.
As a consequence, when waking up from GENET_POWER_WOL_MAGIC on GENET V1,
bcmgenet_wol_power_up_cfg() is never invoked to disable the WoL clock,
clear wake event masks, and restore normal PHY and MAC operations.
Move the bcmgenet_has_ext() checks to the GENET_POWER_PASSIVE and
GENET_POWER_CABLE_SENSE cases where the EXT registers are actually
accessed, allowing GENET_POWER_WOL_MAGIC cleanup to execute on all
hardware versions.
Fixes: c3ae64ae0c08 ("net: bcmgenet: handle GENET_POWER_WOL_MAGIC")
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20260921220021.281418-4-florian.fainelli@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/genet/bcmgenet.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index fc1d4cef3ad81..dad5adfadb76d 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1699,13 +1699,12 @@ static int bcmgenet_power_up(struct bcmgenet_priv *priv,
int ret = 0;
u32 reg;
- if (!bcmgenet_has_ext(priv))
- return ret;
-
- reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
-
switch (mode) {
case GENET_POWER_PASSIVE:
+ if (!bcmgenet_has_ext(priv))
+ break;
+
+ reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
reg &= ~(EXT_PWR_DOWN_DLL | EXT_PWR_DOWN_BIAS |
EXT_ENERGY_DET_MASK);
if (GENET_IS_V5(priv) && !bcmgenet_has_ephy_16nm(priv)) {
@@ -1729,8 +1728,12 @@ static int bcmgenet_power_up(struct bcmgenet_priv *priv,
break;
case GENET_POWER_CABLE_SENSE:
+ if (!bcmgenet_has_ext(priv))
+ break;
+
/* enable APD */
if (!GENET_IS_V5(priv)) {
+ reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
reg |= EXT_PWR_DN_EN_LD;
bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 428/877] net: bcmgenet: validate Ethernet address in bcmgenet_set_mac_addr
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (426 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 427/877] net: bcmgenet: do not skip WoL power up on GENET V1 Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 429/877] net: bcmgenet: mask DMA_TIMEOUT_MASK when reading DMA_RING0_TIMEOUT Greg Kroah-Hartman
` (456 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Florian Fainelli,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Fainelli <florian.fainelli@broadcom.com>
[ Upstream commit 273941c85fc2632cd3e56ddff737b9245de7697d ]
bcmgenet_set_mac_addr() did not check whether the provided MAC address is a
valid Ethernet address before applying it. Userspace could configure an
invalid address (such as all zeroes or a multicast address) while the
interface is down.
Add a call to is_valid_ether_addr() and return -EADDRNOTAVAIL if the MAC
address is not valid.
Fixes: 1c1008c793fa ("net: bcmgenet: add main driver file")
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20260921220021.281418-5-florian.fainelli@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/genet/bcmgenet.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index dad5adfadb76d..a326ee63c1b7c 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -3562,6 +3562,9 @@ static int bcmgenet_set_mac_addr(struct net_device *dev, void *p)
if (netif_running(dev))
return -EBUSY;
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
eth_hw_addr_set(dev, addr->sa_data);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 429/877] net: bcmgenet: mask DMA_TIMEOUT_MASK when reading DMA_RING0_TIMEOUT
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (427 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 428/877] net: bcmgenet: validate Ethernet address in bcmgenet_set_mac_addr Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 430/877] ip_gre: Reject enabling collect metadata through changelink Greg Kroah-Hartman
` (455 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Florian Fainelli,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Fainelli <florian.fainelli@broadcom.com>
[ Upstream commit d64e277b955be4506931802837499b62c8f3968a ]
bcmgenet_get_coalesce() reads DMA_RING0_TIMEOUT to calculate
rx_coalesce_usecs without masking out bits outside DMA_TIMEOUT_MASK
(16 bits). If upper bits are non-zero or contain status/flags, the
computed value of rx_coalesce_usecs returned to userspace via ethtool
becomes corrupted.
Mask the register read with DMA_TIMEOUT_MASK before computing the
timeout in microseconds.
Fixes: 4a29645bfe6c ("net: bcmgenet: Implement RX coalescing control knobs")
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20260921220021.281418-6-florian.fainelli@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/genet/bcmgenet.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index a326ee63c1b7c..14e891db97ea8 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -819,7 +819,8 @@ static int bcmgenet_get_coalesce(struct net_device *dev,
ec->rx_max_coalesced_frames =
bcmgenet_rdma_ring_readl(priv, 0, DMA_MBUF_DONE_THRESH);
ec->rx_coalesce_usecs =
- bcmgenet_rdma_readl(priv, DMA_RING0_TIMEOUT) * 8192 / 1000;
+ (bcmgenet_rdma_readl(priv, DMA_RING0_TIMEOUT) &
+ DMA_TIMEOUT_MASK) * 8192 / 1000;
for (i = 0; i <= priv->hw_params->rx_queues; i++) {
ring = &priv->rx_rings[i];
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 430/877] ip_gre: Reject enabling collect metadata through changelink
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (428 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 429/877] net: bcmgenet: mask DMA_TIMEOUT_MASK when reading DMA_RING0_TIMEOUT Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 431/877] vxlan: use one headroom snapshot for neighbour replies Greg Kroah-Hartman
` (454 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xuanqiang Luo, Ido Schimmel,
Hangbin Liu, Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
[ Upstream commit a3f315be9d30eeb6938d11fa17fd4b32d52f7c42 ]
ipgre_netlink_parms() can enable collect_md on an existing GRE, GRETAP
or ERSPAN device. Unlike newlink, changelink does not enforce metadata
tunnel uniqueness. Converting a non-metadata device can therefore
replace the metadata receive entry for another device of the same type
in the same netns. Deleting either device then clears the shared entry,
breaking metadata receive lookup for the surviving device.
If parameter validation fails after collect_md is set, deleting the
modified device can also clear an entry it never owned.
Reject enabling metadata mode in both changelink callbacks before any
encapsulation or tunnel parameters are modified. Allow requests that
repeat the metadata attribute on an existing metadata device.
Fixes: 2e15ea390e6f ("ip_gre: Add support to collect tunnel metadata.")
Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Link: https://patch.msgid.link/20260921031859.9283-1-xuanqiang.luo@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/ip_gre.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index f344e9bb31fbb..5c5ea36584bf9 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -1449,6 +1449,12 @@ static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
if (!rtnl_dev_link_net_capable(dev, t->net))
return -EPERM;
+ if (data && data[IFLA_GRE_COLLECT_METADATA] && !t->collect_md) {
+ NL_SET_ERR_MSG(extack,
+ "Enabling collect_md on an existing device is not supported");
+ return -EOPNOTSUPP;
+ }
+
err = ipgre_newlink_encap_setup(dev, data);
if (err)
return err;
@@ -1481,6 +1487,12 @@ static int erspan_changelink(struct net_device *dev, struct nlattr *tb[],
if (!rtnl_dev_link_net_capable(dev, t->net))
return -EPERM;
+ if (data && data[IFLA_GRE_COLLECT_METADATA] && !t->collect_md) {
+ NL_SET_ERR_MSG(extack,
+ "Enabling collect_md on an existing device is not supported");
+ return -EOPNOTSUPP;
+ }
+
err = ipgre_newlink_encap_setup(dev, data);
if (err)
return err;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 431/877] vxlan: use one headroom snapshot for neighbour replies
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (429 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 430/877] ip_gre: Reject enabling collect metadata through changelink Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 432/877] net: xps: reject an out of range traffic class Greg Kroah-Hartman
` (453 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sanghyun Park, Jakub Kicinski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sanghyun Park <sanghyun.park.cnu@gmail.com>
[ Upstream commit 481506a756dcd828ef42391cb08f38d8d96d38fc ]
vxlan_na_create() samples LL_RESERVED_SPACE() to size the reply skb and then
samples it again to reserve headroom. A concurrent vxlan_changelink() can
update needed_headroom between the two reads, creating a TOCTOU race. The
second value can exceed the allocation and make the Ethernet header write out
of bounds.
The race is reproducible on the unpatched kernel. It occurred when
vxlan_na_create() generated a neighbour reply while vxlan_changelink() changed
the link headroom. KASAN caught a four-byte write two bytes beyond a 704-byte
skbuff_small_head allocation.
Snapshot the headroom once and use that value for both allocation and
reservation.
Fixes: 4b29dba9c085 ("vxlan: fix nonfunctional neigh_reduce()")
Signed-off-by: Sanghyun Park <sanghyun.park.cnu@gmail.com>
Link: https://patch.msgid.link/20260918032842.502409-2-sanghyun.park.cnu@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/vxlan/vxlan_core.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index b14dbc6892078..f612def46c3c4 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -1979,13 +1979,15 @@ static struct sk_buff *vxlan_na_create(struct sk_buff *request,
struct ipv6hdr *pip6;
u8 *daddr;
int na_olen = 8; /* opt hdr + ETH_ALEN for target */
+ int headroom;
int ns_olen;
int i, len;
if (dev == NULL || !pskb_may_pull(request, request->len))
return NULL;
- len = LL_RESERVED_SPACE(dev) + sizeof(struct ipv6hdr) +
+ headroom = LL_RESERVED_SPACE(dev);
+ len = headroom + sizeof(struct ipv6hdr) +
sizeof(*na) + na_olen + dev->needed_tailroom;
reply = alloc_skb(len, GFP_ATOMIC);
if (reply == NULL)
@@ -1993,7 +1995,7 @@ static struct sk_buff *vxlan_na_create(struct sk_buff *request,
reply->protocol = htons(ETH_P_IPV6);
reply->dev = dev;
- skb_reserve(reply, LL_RESERVED_SPACE(request->dev));
+ skb_reserve(reply, headroom);
skb_push(reply, sizeof(struct ethhdr));
skb_reset_mac_header(reply);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 432/877] net: xps: reject an out of range traffic class
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (430 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 431/877] vxlan: use one headroom snapshot for neighbour replies Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 433/877] drm/imagination: clamp freelist reconstruction requests Greg Kroah-Hartman
` (452 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Norbert Szetei, Jakub Kicinski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Norbert Szetei <norbert@doyensec.com>
[ Upstream commit 4da3b7b8b50f3e2fde54a4c18a82a8e3f6223910 ]
Only the entries below dev->num_tc are valid in dev->tc_to_txq[], and
dev->prio_tc_map[] may only name classes below it. netdev_set_num_tc()
lowers dev->num_tc without touching either array.
netdev_txq_to_tc() walks all TC_MAX_QUEUE slots and
netdev_get_prio_tc_map() returns the entry as it stands, so a leftover
entry is handed out as a traffic class >= dev->num_tc. Taking that
class from netdev_txq_to_tc(), __netif_set_xps_queue() rejects only a
negative one and indexes an XPS map sized for dev->num_tc classes:
tci = j * num_tc + tc;
RCU_INIT_POINTER(new_dev_maps->attr_map[tci], map);
attr_map[] holds nr_ids * num_tc entries and j runs over the ids named
in the mask, so a class that is not below num_tc pushes tci past the end
of the map for the last ids and the store overruns it.
Any caller that lowers num_tc leaves such entries behind, and
mqprio_destroy() tears down with netdev_set_num_tc(dev, 0) rather than
netdev_reset_tc(). After mqprio with 8 classes then 1, tc_to_txq[1..7]
still describe txq 1..7. The splat is from an XPS write to txq 2 on a
veth with 8 rx queues: attr_map[] has 8 * 1 entries, tci = j + 2, and
j == 6 stores one past the end of the 88-byte map:
BUG: KASAN: slab-out-of-bounds in __netif_set_xps_queue (net/core/dev.c:2954)
Write of size 8 at addr ffff88813016bc58 by task xps_oob/634
__netif_set_xps_queue (net/core/dev.c:2954)
xps_rxqs_store (net/core/net-sysfs.c:1880)
netdev_queue_attr_store (net/core/net-sysfs.c:1390)
Allocated by task 634:
__kmalloc_noprof (mm/slub.c:5439)
__netif_set_xps_queue (net/core/dev.c:2937)
The buggy address is located 0 bytes to the right of
allocated 88-byte region [ffff88813016bc00, ffff88813016bc58)
Reject a class the map has no room for.
Fixes: 184c449f91fe ("net: Add support for XPS with QoS via traffic classes")
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
Link: https://patch.msgid.link/162DD16F-54C6-444A-9E09-0B8CB3D591F2@doyensec.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/dev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index d4f0db3208483..6c63867ff76d6 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2686,7 +2686,7 @@ int __netif_set_xps_queue(struct net_device *dev, const unsigned long *mask,
dev = netdev_get_tx_queue(dev, index)->sb_dev ? : dev;
tc = netdev_txq_to_tc(dev, index);
- if (tc < 0)
+ if (tc < 0 || tc >= num_tc)
return -EINVAL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 433/877] drm/imagination: clamp freelist reconstruction requests
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (431 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 432/877] net: xps: reject an out of range traffic class Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 434/877] bonding: crypto offload enabled, non-offload slave failover, rekey failed Greg Kroah-Hartman
` (451 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pengpeng Hou, Alessio Belle,
Brajesh Gupta, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <hppiscas@163.com>
[ Upstream commit 45585c3aa285854face65293acc95eff73063d6d ]
The firmware reconstruction count controls accesses to the request's
fixed freelist ID array and the copy into the fixed response array.
Neither access currently bounds the count to those protocol arrays.
Clamp the count to the request capacity, which is shared by the response
layout, and use that count consistently for reconstruction and response
publication. Keep the firmware recovery exchange instead of dropping an
oversized request without a response, as discussed with the firmware
maintainer.
The issue was found by our static-analysis tool.
Fixes: 6eedddab733b ("drm/imagination: Implement free list and HWRT create and destroy ioctls")
Assisted-by: gpt 5
Signed-off-by: Pengpeng Hou <hppiscas@163.com>
Reviewed-by: Alessio Belle <alessio.belle@imgtec.com>
Link: https://patch.msgid.link/20260920034329.16614-1-hppiscas@163.com
Signed-off-by: Brajesh Gupta <brajesh.gupta@imgtec.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/imagination/pvr_free_list.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/imagination/pvr_free_list.c b/drivers/gpu/drm/imagination/pvr_free_list.c
index 5e51bc980751c..083ae6fa09765 100644
--- a/drivers/gpu/drm/imagination/pvr_free_list.c
+++ b/drivers/gpu/drm/imagination/pvr_free_list.c
@@ -8,6 +8,7 @@
#include "pvr_vm.h"
#include <drm/drm_gem.h>
+#include <drm/drm_print.h>
#include <linux/slab.h>
#include <linux/xarray.h>
#include <uapi/drm/pvr_drm.h>
@@ -613,13 +614,21 @@ pvr_free_list_process_reconstruct_req(struct pvr_device *pvr_dev,
};
struct rogue_fwif_freelists_reconstruction_data *resp =
&resp_cmd.cmd_data.free_lists_reconstruction_data;
+ u32 count = min_t(u32, req->freelist_count,
+ ARRAY_SIZE(req->freelist_ids));
- for (u32 i = 0; i < req->freelist_count; i++)
+ if (count != req->freelist_count) {
+ drm_warn_once(from_pvr_device(pvr_dev),
+ "Requested reconstruction of %u freelists, limiting to %u\n",
+ req->freelist_count, count);
+ }
+
+ for (u32 i = 0; i < count; i++)
pvr_free_list_reconstruct(pvr_dev, req->freelist_ids[i]);
- resp->freelist_count = req->freelist_count;
+ resp->freelist_count = count;
memcpy(resp->freelist_ids, req->freelist_ids,
- req->freelist_count * sizeof(resp->freelist_ids[0]));
+ count * sizeof(resp->freelist_ids[0]));
WARN_ON(pvr_kccb_send_cmd(pvr_dev, &resp_cmd, NULL));
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 434/877] bonding: crypto offload enabled, non-offload slave failover, rekey failed
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (432 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 433/877] drm/imagination: clamp freelist reconstruction requests Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 435/877] macsec: add some of the lower devices features when offloading Greg Kroah-Hartman
` (450 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Dai, Hangbin Liu, Paolo Abeni,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Dai <zdai@linux.ibm.com>
[ Upstream commit 00efbbd40bd5fd92c67b7cf1aab8904fa59a96f6 ]
Create a bonding device (i.e. bond0) in active-backup mode, 2 slaves.
Active slave: offload capable interface (i.e. eth1), primary interface.
Backup slave: non-offload capable interface(i.e. eth2).
Configure strongswan service swantl.conf child SA "hw_offload = crypto"
Start strongswan service
IPSec Crytpo Offload is enabled on top of bond0. i.e.
ip xfrm state |grep offload
crypto offload parameters: dev bond0 dir out mode crypto
crypto offload parameters: dev bond0 dir in mode crypto
Active slave eth1 takes adavantage of IPSec Crypto Offload capability.
If active slave eth1 is down for any reason (i.e. eth1 link down):
ip link set down dev eth1
non-offload capable interface eth2 failover to becomes active slave.
The existing SAs can continue use software IPsec after failover.
Traffic still keeps going properly.
However if eth1 link had not recovered yet, strongswan service does
new child SA rekey, or uses swanctl command to do new child SA rekey,
it will fail because active slave eth2 doesn't support crypto offload.
In bond_ipsec_add_sa routine, it returns -EINVAL now, which is
treated as fatal error by xfrm_dev_state_add routine in kernel xfrm.
To make the non-offload active slave survive the child SA rekey, need
to make bond_ipsec_add_sa routine returns -EOPNOTSUPP instead when
active slave doesn't support IPsec Crypto offload, the xfrm will
gracefully fallback to create new SA using Software IPsec.
Network traffic can keep going.
After offload capable interface eth1 link is up, becomes active slave,
next time strongswan child SA rekey will create a new SA which enables
crypto offload again.
Fixes: 18cb261afd7b ("bonding: support hardware encryption offload to slaves")
Signed-off-by: David Dai <zdai@linux.ibm.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Link: https://patch.msgid.link/20260918211155.1664493-1-zdai@linux.ibm.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/bonding/bond_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 5911dcaedf0fc..d10bbe4c35718 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -494,7 +494,7 @@ static int bond_ipsec_add_sa(struct xfrm_state *xs,
!real_dev->xfrmdev_ops->xdo_dev_state_add ||
netif_is_bond_master(real_dev)) {
NL_SET_ERR_MSG_MOD(extack, "Slave does not support ipsec offload");
- err = -EINVAL;
+ err = -EOPNOTSUPP;
goto out;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 435/877] macsec: add some of the lower devices features when offloading
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (433 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 434/877] bonding: crypto offload enabled, non-offload slave failover, rekey failed Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits " Greg Kroah-Hartman
` (449 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sabrina Dubroca, Simon Horman,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sabrina Dubroca <sd@queasysnail.net>
[ Upstream commit bd97c29f7e9e45980417973d5e8b755bd71e10a9 ]
This commit extends the set of netdevice features supported by macsec
devices when offload is enabled, which increases performance
significantly (for a single TCP stream: 17.5Gbps to 38.5Gbps on my
test machines).
Commit c850240b6c41 ("net: macsec: report real_dev features when HW
offloading is enabled") previously attempted something similar, but
had to be reverted (commit 8bcd560ae878 ("Revert "net: macsec: report
real_dev features when HW offloading is enabled"")) because the set of
features it exposed was too large.
During initialization, all features are set, and they're then removed
via ndo_fix_features (macsec_fix_features). This allows the
offloadable features to be automatically enabled if offloading is
turned on after device creation.
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/8b32c3011d269d6f149724e80c1ffe67c9534067.1730929545.git.sd@queasysnail.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: c2de369c5c5b ("macsec: initialize SecY before registering the netdevice")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/macsec.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index 66f7407a2b178..b1eb6b5dde0fe 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -2695,6 +2695,8 @@ static int macsec_update_offload(struct net_device *dev, enum macsec_offload off
macsec_set_head_tail_room(dev);
macsec->insert_tx_tag = macsec_needs_tx_tag(macsec, ops);
+ netdev_update_features(dev);
+
return ret;
}
@@ -3550,6 +3552,10 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
#define MACSEC_FEATURES \
(NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST)
+#define MACSEC_OFFLOAD_FEATURES \
+ (MACSEC_FEATURES | NETIF_F_GSO_SOFTWARE | NETIF_F_SOFT_FEATURES | \
+ NETIF_F_LRO | NETIF_F_RXHASH | NETIF_F_CSUM_MASK | NETIF_F_RXCSUM)
+
static int macsec_dev_init(struct net_device *dev)
{
struct macsec_dev *macsec = macsec_priv(dev);
@@ -3560,7 +3566,10 @@ static int macsec_dev_init(struct net_device *dev)
if (err)
return err;
- dev->features = real_dev->features & MACSEC_FEATURES;
+ dev->hw_features = real_dev->hw_features & MACSEC_OFFLOAD_FEATURES;
+ dev->hw_features |= NETIF_F_GSO_SOFTWARE;
+
+ dev->features = real_dev->features & MACSEC_OFFLOAD_FEATURES;
dev->features |= NETIF_F_GSO_SOFTWARE;
dev->lltx = true;
dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
@@ -3590,8 +3599,12 @@ static netdev_features_t macsec_fix_features(struct net_device *dev,
{
struct macsec_dev *macsec = macsec_priv(dev);
struct net_device *real_dev = macsec->real_dev;
+ netdev_features_t mask;
+
+ mask = macsec_is_offloaded(macsec) ? MACSEC_OFFLOAD_FEATURES
+ : MACSEC_FEATURES;
- features &= (real_dev->features & MACSEC_FEATURES) |
+ features &= (real_dev->features & mask) |
NETIF_F_GSO_SOFTWARE | NETIF_F_SOFT_FEATURES;
return features;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits when offloading
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (434 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 435/877] macsec: add some of the lower devices features when offloading Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-10-01 5:27 ` Karl Mehltretter
2026-10-01 20:12 ` Harshit Mogalapalli
2026-09-30 15:22 ` [PATCH 6.12 437/877] macsec: initialize SecY before registering the netdevice Greg Kroah-Hartman
` (448 subsequent siblings)
884 siblings, 2 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sabrina Dubroca, Simon Horman,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sabrina Dubroca <sd@queasysnail.net>
[ Upstream commit de187a390838c0b3dfd00ae5399aa406d0a79f13 ]
If macsec is offloaded, we need to follow the lower device's
capabilities, like VLAN devices do.
Leave the limits unchanged when the offload is disabled.
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/8240c0181e851f169d815f59658a01fb9dfc5073.1730929545.git.sd@queasysnail.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: c2de369c5c5b ("macsec: initialize SecY before registering the netdevice")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/macsec.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index b1eb6b5dde0fe..ce4a08f77724f 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -2650,6 +2650,17 @@ static void macsec_set_head_tail_room(struct net_device *dev)
dev->needed_tailroom = real_dev->needed_tailroom + needed_tailroom;
}
+static void macsec_inherit_tso_max(struct net_device *dev)
+{
+ struct macsec_dev *macsec = macsec_priv(dev);
+
+ /* if macsec is offloaded, we need to follow the lower
+ * device's capabilities. otherwise, we can ignore them.
+ */
+ if (macsec_is_offloaded(macsec))
+ netif_inherit_tso_max(dev, macsec->real_dev);
+}
+
static int macsec_update_offload(struct net_device *dev, enum macsec_offload offload)
{
enum macsec_offload prev_offload;
@@ -2695,6 +2706,8 @@ static int macsec_update_offload(struct net_device *dev, enum macsec_offload off
macsec_set_head_tail_room(dev);
macsec->insert_tx_tag = macsec_needs_tx_tag(macsec, ops);
+ macsec_inherit_tso_max(dev);
+
netdev_update_features(dev);
return ret;
@@ -3566,6 +3579,8 @@ static int macsec_dev_init(struct net_device *dev)
if (err)
return err;
+ macsec_inherit_tso_max(dev);
+
dev->hw_features = real_dev->hw_features & MACSEC_OFFLOAD_FEATURES;
dev->hw_features |= NETIF_F_GSO_SOFTWARE;
@@ -4521,6 +4536,13 @@ static int macsec_notify(struct notifier_block *this, unsigned long event,
if (dev->mtu > mtu)
dev_set_mtu(dev, mtu);
}
+ break;
+ case NETDEV_FEAT_CHANGE:
+ list_for_each_entry(m, &rxd->secys, secys) {
+ macsec_inherit_tso_max(m->secy.netdev);
+ netdev_update_features(m->secy.netdev);
+ }
+ break;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits when offloading
2026-09-30 15:22 ` [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits " Greg Kroah-Hartman
@ 2026-10-01 5:27 ` Karl Mehltretter
2026-10-01 11:31 ` Sasha Levin
2026-10-01 20:12 ` Harshit Mogalapalli
1 sibling, 1 reply; 922+ messages in thread
From: Karl Mehltretter @ 2026-10-01 5:27 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Karl Mehltretter, stable, patches, Sabrina Dubroca, Simon Horman,
Jakub Kicinski, Sasha Levin
I object to this patch as queued. The backport is missing prerequisite
f29d24a2106a ("macsec: clean up local variables in macsec_notify"), so
NETDEV_FEAT_CHANGE dereferences an uninitialized rxd.
Clang 21 reports this in an allmodconfig W=1 build:
warning: variable 'rxd' is uninitialized when used here
[-Wuninitialized]
In QEMU, the exact review tip f4ffa8dc360b hits a NULL-pointer oops at
macsec_notify+0x130/0x1e0. With f29d24a2106a applied before this patch,
the same test passes and the MACsec device inherits the changed TSO
limits. A three-device test covering feature changes, MTU changes,
down/up, and unregister also passes. The corrected file builds cleanly
with Clang W=1.
Please add the prerequisite before this patch.
An LLM agent assisted with the review and QEMU A/B testing.
Thanks,
Karl
^ permalink raw reply [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits when offloading
2026-10-01 5:27 ` Karl Mehltretter
@ 2026-10-01 11:31 ` Sasha Levin
0 siblings, 0 replies; 922+ messages in thread
From: Sasha Levin @ 2026-10-01 11:31 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Sasha Levin, Karl Mehltretter, stable, patches, Sabrina Dubroca,
Simon Horman, Jakub Kicinski
On Thu, Oct 01, 2026 at 07:27:46AM +0200, Karl Mehltretter wrote:
> I object to this patch as queued. The backport is missing prerequisite
> f29d24a2106a ("macsec: clean up local variables in macsec_notify"), so
> NETDEV_FEAT_CHANGE dereferences an uninitialized rxd.
I've dropped it and the pre-reqs for now, thanks!
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 922+ messages in thread
* Re: [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits when offloading
2026-09-30 15:22 ` [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits " Greg Kroah-Hartman
2026-10-01 5:27 ` Karl Mehltretter
@ 2026-10-01 20:12 ` Harshit Mogalapalli
2026-10-02 12:10 ` Greg Kroah-Hartman
1 sibling, 1 reply; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-01 20:12 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, Sabrina Dubroca, Simon Horman, Jakub Kicinski,
Sasha Levin
On 30/09/26 8:52 pm, Greg Kroah-Hartman wrote:
> 6.12-stable review patch. If anyone has any objections, please let me know.
>
> ------------------
>
> From: Sabrina Dubroca <sd@queasysnail.net>
>
> [ Upstream commit de187a390838c0b3dfd00ae5399aa406d0a79f13 ]
>
> If macsec is offloaded, we need to follow the lower device's
> capabilities, like VLAN devices do.
>
> Leave the limits unchanged when the offload is disabled.
>
> Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
> Reviewed-by: Simon Horman <horms@kernel.org>
> Link: https://patch.msgid.link/8240c0181e851f169d815f59658a01fb9dfc5073.1730929545.git.sd@queasysnail.net
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> Stable-dep-of: c2de369c5c5b ("macsec: initialize SecY before registering the netdevice")
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---
> drivers/net/macsec.c | 22 ++++++++++++++++++++++
> 1 file changed, 22 insertions(+)
>
> diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
> index b1eb6b5dde0fe..ce4a08f77724f 100644
> --- a/drivers/net/macsec.c
> +++ b/drivers/net/macsec.c
> @@ -2650,6 +2650,17 @@ static void macsec_set_head_tail_room(struct net_device *dev)
> dev->needed_tailroom = real_dev->needed_tailroom + needed_tailroom;
> }
>
> +static void macsec_inherit_tso_max(struct net_device *dev)
> +{
> + struct macsec_dev *macsec = macsec_priv(dev);
> +
> + /* if macsec is offloaded, we need to follow the lower
> + * device's capabilities. otherwise, we can ignore them.
> + */
> + if (macsec_is_offloaded(macsec))
> + netif_inherit_tso_max(dev, macsec->real_dev);
> +}
> +
> static int macsec_update_offload(struct net_device *dev, enum macsec_offload offload)
> {
> enum macsec_offload prev_offload;
> @@ -2695,6 +2706,8 @@ static int macsec_update_offload(struct net_device *dev, enum macsec_offload off
> macsec_set_head_tail_room(dev);
> macsec->insert_tx_tag = macsec_needs_tx_tag(macsec, ops);
>
> + macsec_inherit_tso_max(dev);
> +
> netdev_update_features(dev);
>
> return ret;
> @@ -3566,6 +3579,8 @@ static int macsec_dev_init(struct net_device *dev)
> if (err)
> return err;
>
> + macsec_inherit_tso_max(dev);
> +
> dev->hw_features = real_dev->hw_features & MACSEC_OFFLOAD_FEATURES;
> dev->hw_features |= NETIF_F_GSO_SOFTWARE;
>
> @@ -4521,6 +4536,13 @@ static int macsec_notify(struct notifier_block *this, unsigned long event,
> if (dev->mtu > mtu)
> dev_set_mtu(dev, mtu);
> }
> + break;
> + case NETDEV_FEAT_CHANGE:
> + list_for_each_entry(m, &rxd->secys, secys) {
> + macsec_inherit_tso_max(m->secy.netdev);
> + netdev_update_features(m->secy.netdev);
> + }
> + break;
Hi Greg/Sasha,
An AI assisted backport review flagged this, and I checked the upstream
code against the 6.12.y tip f4ffa8dc360b.
Upstream de187a390838 initializes rxd before macsec_notify() dispatches:
struct macsec_rxh_data *rxd;
struct macsec_dev *m, *n;
LIST_HEAD(head);
if (!is_macsec_master(real_dev))
return NOTIFY_DONE;
rxd = macsec_data_rtnl(real_dev);
switch (event) {
6.12.y inserts the new label inside the older MTU case's block:
case NETDEV_CHANGEMTU: {
struct macsec_dev *m;
struct macsec_rxh_data *rxd;
rxd = macsec_data_rtnl(real_dev);
/* ... intervening source omitted ... */
break;
case NETDEV_FEAT_CHANGE:
list_for_each_entry(m, &rxd->secys, secys) {
macsec_inherit_tso_max(m->secy.netdev);
netdev_update_features(m->secy.netdev);
}
break;
}
NETDEV_FEAT_CHANGE skips the rxd assignment and dereferences an
uninitialized pointer. Software MACsec reaches it too, before the
offload check.
I think 6.12.y needs f29d24a2106ae28a9b257503a615ee438efa3f95 ("macsec:
clean up local variables in macsec_notify") before this backport,
thoughts?
thanks,
harshit
> }
> }
>
^ permalink raw reply [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits when offloading
2026-10-01 20:12 ` Harshit Mogalapalli
@ 2026-10-02 12:10 ` Greg Kroah-Hartman
2026-10-02 20:43 ` Harshit Mogalapalli
0 siblings, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-02 12:10 UTC (permalink / raw)
To: Harshit Mogalapalli
Cc: stable, patches, Sabrina Dubroca, Simon Horman, Jakub Kicinski,
Sasha Levin
On Fri, Oct 02, 2026 at 01:42:28AM +0530, Harshit Mogalapalli wrote:
>
>
> On 30/09/26 8:52 pm, Greg Kroah-Hartman wrote:
> > 6.12-stable review patch. If anyone has any objections, please let me know.
> >
> > ------------------
> >
> > From: Sabrina Dubroca <sd@queasysnail.net>
> >
> > [ Upstream commit de187a390838c0b3dfd00ae5399aa406d0a79f13 ]
> >
> > If macsec is offloaded, we need to follow the lower device's
> > capabilities, like VLAN devices do.
> >
> > Leave the limits unchanged when the offload is disabled.
> >
> > Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
> > Reviewed-by: Simon Horman <horms@kernel.org>
> > Link: https://patch.msgid.link/8240c0181e851f169d815f59658a01fb9dfc5073.1730929545.git.sd@queasysnail.net
> > Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> > Stable-dep-of: c2de369c5c5b ("macsec: initialize SecY before registering the netdevice")
> > Signed-off-by: Sasha Levin <sashal@kernel.org>
> > ---
> > drivers/net/macsec.c | 22 ++++++++++++++++++++++
> > 1 file changed, 22 insertions(+)
> >
> > diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
> > index b1eb6b5dde0fe..ce4a08f77724f 100644
> > --- a/drivers/net/macsec.c
> > +++ b/drivers/net/macsec.c
> > @@ -2650,6 +2650,17 @@ static void macsec_set_head_tail_room(struct net_device *dev)
> > dev->needed_tailroom = real_dev->needed_tailroom + needed_tailroom;
> > }
> > +static void macsec_inherit_tso_max(struct net_device *dev)
> > +{
> > + struct macsec_dev *macsec = macsec_priv(dev);
> > +
> > + /* if macsec is offloaded, we need to follow the lower
> > + * device's capabilities. otherwise, we can ignore them.
> > + */
> > + if (macsec_is_offloaded(macsec))
> > + netif_inherit_tso_max(dev, macsec->real_dev);
> > +}
> > +
> > static int macsec_update_offload(struct net_device *dev, enum macsec_offload offload)
> > {
> > enum macsec_offload prev_offload;
> > @@ -2695,6 +2706,8 @@ static int macsec_update_offload(struct net_device *dev, enum macsec_offload off
> > macsec_set_head_tail_room(dev);
> > macsec->insert_tx_tag = macsec_needs_tx_tag(macsec, ops);
> > + macsec_inherit_tso_max(dev);
> > +
> > netdev_update_features(dev);
> > return ret;
> > @@ -3566,6 +3579,8 @@ static int macsec_dev_init(struct net_device *dev)
> > if (err)
> > return err;
> > + macsec_inherit_tso_max(dev);
> > +
> > dev->hw_features = real_dev->hw_features & MACSEC_OFFLOAD_FEATURES;
> > dev->hw_features |= NETIF_F_GSO_SOFTWARE;
> > @@ -4521,6 +4536,13 @@ static int macsec_notify(struct notifier_block *this, unsigned long event,
> > if (dev->mtu > mtu)
> > dev_set_mtu(dev, mtu);
> > }
> > + break;
> > + case NETDEV_FEAT_CHANGE:
> > + list_for_each_entry(m, &rxd->secys, secys) {
> > + macsec_inherit_tso_max(m->secy.netdev);
> > + netdev_update_features(m->secy.netdev);
> > + }
> > + break;
>
> Hi Greg/Sasha,
>
> An AI assisted backport review flagged this, and I checked the upstream
> code against the 6.12.y tip f4ffa8dc360b.
>
> Upstream de187a390838 initializes rxd before macsec_notify() dispatches:
>
> struct macsec_rxh_data *rxd;
> struct macsec_dev *m, *n;
> LIST_HEAD(head);
>
> if (!is_macsec_master(real_dev))
> return NOTIFY_DONE;
>
> rxd = macsec_data_rtnl(real_dev);
>
> switch (event) {
>
> 6.12.y inserts the new label inside the older MTU case's block:
>
> case NETDEV_CHANGEMTU: {
> struct macsec_dev *m;
> struct macsec_rxh_data *rxd;
>
> rxd = macsec_data_rtnl(real_dev);
> /* ... intervening source omitted ... */
> break;
> case NETDEV_FEAT_CHANGE:
> list_for_each_entry(m, &rxd->secys, secys) {
> macsec_inherit_tso_max(m->secy.netdev);
> netdev_update_features(m->secy.netdev);
> }
> break;
> }
>
> NETDEV_FEAT_CHANGE skips the rxd assignment and dereferences an
> uninitialized pointer. Software MACsec reaches it too, before the
> offload check.
>
> I think 6.12.y needs f29d24a2106ae28a9b257503a615ee438efa3f95 ("macsec:
> clean up local variables in macsec_notify") before this backport,
> thoughts?
This patch is now dropped, thanks.
greg k-h
^ permalink raw reply [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits when offloading
2026-10-02 12:10 ` Greg Kroah-Hartman
@ 2026-10-02 20:43 ` Harshit Mogalapalli
0 siblings, 0 replies; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-02 20:43 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: stable, patches, Sabrina Dubroca, Simon Horman, Jakub Kicinski,
Sasha Levin
Hi Greg,
>> 6.12.y inserts the new label inside the older MTU case's block:
>>
>> case NETDEV_CHANGEMTU: {
>> struct macsec_dev *m;
>> struct macsec_rxh_data *rxd;
>>
>> rxd = macsec_data_rtnl(real_dev);
>> /* ... intervening source omitted ... */
>> break;
>> case NETDEV_FEAT_CHANGE:
>> list_for_each_entry(m, &rxd->secys, secys) {
>> macsec_inherit_tso_max(m->secy.netdev);
>> netdev_update_features(m->secy.netdev);
>> }
>> break;
>> }
>>
>> NETDEV_FEAT_CHANGE skips the rxd assignment and dereferences an
>> uninitialized pointer. Software MACsec reaches it too, before the
>> offload check.
>>
>> I think 6.12.y needs f29d24a2106ae28a9b257503a615ee438efa3f95 ("macsec:
>> clean up local variables in macsec_notify") before this backport,
>> thoughts?
>
> This patch is now dropped, thanks.
>
thanks for dealing with this and other report Greg!
Harshit
> greg k-h
>
^ permalink raw reply [flat|nested] 922+ messages in thread
* [PATCH 6.12 437/877] macsec: initialize SecY before registering the netdevice
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (435 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits " Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 438/877] net: dsa: mt7530: fix NULL dereference on unbind of MT7531 and MT7621 Greg Kroah-Hartman
` (447 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+f2f6312ad1b5a0bfe316,
Sabrina Dubroca, Haseeb Malik, Paolo Abeni, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haseeb Malik <haseebulhaq55@gmail.com>
[ Upstream commit c2de369c5c5b8599ca10fd5ca8d11fcd845c1331 ]
Creating a MACsec device with MAC offload over an LRO-capable lower
device triggers a warning in rtmsg_ifinfo_build_skb() when IPv4
forwarding is enabled by default.
register_netdevice() invokes inetdev_init(), which disables LRO and emits
a NETDEV_FEAT_CHANGE notification. This reaches macsec_fill_info() before
macsec_add_dev() initializes the SecY. key_len is still zero, so
macsec_fill_info() returns -EMSGSIZE and trips the WARN_ON in
rtmsg_ifinfo_build_skb(), even though the skb has enough space.
Even without the warning, notifications during registration can report
uninitialized SecY attributes, including the SCI. This ordering has existed
since the driver was introduced.
Initialize the SecY and apply the new-link attributes before registration.
Move MAC address inheritance into macsec_newlink() so the SCI can also be
initialized before registration-time notifications report it. Move the
per-CPU statistics and metadata destination allocation into ndo_init(),
and release partial allocations on failure.
Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver")
Reported-by: syzbot+f2f6312ad1b5a0bfe316@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=f2f6312ad1b5a0bfe316
Suggested-by: Sabrina Dubroca <sd@queasysnail.net>
Link: https://lists.openwall.net/linux-kernel/2026/08/19/552
Signed-off-by: Haseeb Malik <haseebulhaq55@gmail.com>
Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
Link: https://patch.msgid.link/20260921-fix-macsec-net-v3-1-accf94f93f5e@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/macsec.c | 84 +++++++++++++++++++++++---------------------
1 file changed, 43 insertions(+), 41 deletions(-)
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index ce4a08f77724f..fd6f88cfaff61 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -3579,6 +3579,22 @@ static int macsec_dev_init(struct net_device *dev)
if (err)
return err;
+ err = -ENOMEM;
+ macsec->stats = netdev_alloc_pcpu_stats(struct pcpu_secy_stats);
+ if (!macsec->stats)
+ goto destroy_gro_cells;
+
+ macsec->secy.tx_sc.stats =
+ netdev_alloc_pcpu_stats(struct pcpu_tx_sc_stats);
+ if (!macsec->secy.tx_sc.stats)
+ goto free_secy_stats;
+
+ macsec->secy.tx_sc.md_dst = metadata_dst_alloc(0, METADATA_MACSEC,
+ GFP_KERNEL);
+ if (!macsec->secy.tx_sc.md_dst)
+ goto free_tx_sc_stats;
+ macsec->secy.tx_sc.md_dst->u.macsec_info.sci = macsec->secy.sci;
+
macsec_inherit_tso_max(dev);
dev->hw_features = real_dev->hw_features & MACSEC_OFFLOAD_FEATURES;
@@ -3591,8 +3607,6 @@ static int macsec_dev_init(struct net_device *dev)
macsec_set_head_tail_room(dev);
- if (is_zero_ether_addr(dev->dev_addr))
- eth_hw_addr_inherit(dev, real_dev);
if (is_zero_ether_addr(dev->broadcast))
memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len);
@@ -3600,6 +3614,14 @@ static int macsec_dev_init(struct net_device *dev)
netdev_hold(real_dev, &macsec->dev_tracker, GFP_KERNEL);
return 0;
+
+free_tx_sc_stats:
+ free_percpu(macsec->secy.tx_sc.stats);
+free_secy_stats:
+ free_percpu(macsec->stats);
+destroy_gro_cells:
+ gro_cells_destroy(&macsec->gro_cells);
+ return err;
}
static void macsec_dev_uninit(struct net_device *dev)
@@ -4127,26 +4149,11 @@ static sci_t dev_to_sci(struct net_device *dev, __be16 port)
return make_sci(dev->dev_addr, port);
}
-static int macsec_add_dev(struct net_device *dev, sci_t sci, u8 icv_len)
+static void macsec_init_secy(struct net_device *dev, sci_t sci, u8 icv_len)
{
struct macsec_dev *macsec = macsec_priv(dev);
struct macsec_secy *secy = &macsec->secy;
- macsec->stats = netdev_alloc_pcpu_stats(struct pcpu_secy_stats);
- if (!macsec->stats)
- return -ENOMEM;
-
- secy->tx_sc.stats = netdev_alloc_pcpu_stats(struct pcpu_tx_sc_stats);
- if (!secy->tx_sc.stats)
- return -ENOMEM;
-
- secy->tx_sc.md_dst = metadata_dst_alloc(0, METADATA_MACSEC, GFP_KERNEL);
- if (!secy->tx_sc.md_dst)
- /* macsec and secy percpu stats will be freed when unregistering
- * net_device in macsec_free_netdev()
- */
- return -ENOMEM;
-
if (sci == MACSEC_UNDEF_SCI)
sci = dev_to_sci(dev, MACSEC_PORT_ES);
@@ -4160,15 +4167,12 @@ static int macsec_add_dev(struct net_device *dev, sci_t sci, u8 icv_len)
secy->xpn = DEFAULT_XPN;
secy->sci = sci;
- secy->tx_sc.md_dst->u.macsec_info.sci = sci;
secy->tx_sc.active = true;
secy->tx_sc.encoding_sa = DEFAULT_ENCODING_SA;
secy->tx_sc.encrypt = DEFAULT_ENCRYPT;
secy->tx_sc.send_sci = DEFAULT_SEND_SCI;
secy->tx_sc.end_station = false;
secy->tx_sc.scb = false;
-
- return 0;
}
static struct lock_class_key macsec_netdev_addr_lock_key;
@@ -4228,6 +4232,24 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
if (rx_handler && rx_handler != macsec_handle_frame)
return -EBUSY;
+ if (is_zero_ether_addr(dev->dev_addr))
+ eth_hw_addr_inherit(dev, real_dev);
+
+ if (data && data[IFLA_MACSEC_SCI])
+ sci = nla_get_sci(data[IFLA_MACSEC_SCI]);
+ else if (data && data[IFLA_MACSEC_PORT])
+ sci = dev_to_sci(dev, nla_get_be16(data[IFLA_MACSEC_PORT]));
+ else
+ sci = dev_to_sci(dev, MACSEC_PORT_ES);
+
+ /* Registration can notify listeners before returning. */
+ macsec_init_secy(dev, sci, icv_len);
+ if (data) {
+ err = macsec_changelink_common(dev, data);
+ if (err)
+ return err;
+ }
+
err = register_netdevice(dev);
if (err < 0)
return err;
@@ -4240,31 +4262,11 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
if (err < 0)
goto unregister;
- /* need to be already registered so that ->init has run and
- * the MAC addr is set
- */
- if (data && data[IFLA_MACSEC_SCI])
- sci = nla_get_sci(data[IFLA_MACSEC_SCI]);
- else if (data && data[IFLA_MACSEC_PORT])
- sci = dev_to_sci(dev, nla_get_be16(data[IFLA_MACSEC_PORT]));
- else
- sci = dev_to_sci(dev, MACSEC_PORT_ES);
-
if (rx_handler && sci_exists(real_dev, sci)) {
err = -EBUSY;
goto unlink;
}
- err = macsec_add_dev(dev, sci, icv_len);
- if (err)
- goto unlink;
-
- if (data) {
- err = macsec_changelink_common(dev, data);
- if (err)
- goto del_dev;
- }
-
/* If h/w offloading is available, propagate to the device */
if (macsec_is_offloaded(macsec)) {
const struct macsec_ops *ops;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 438/877] net: dsa: mt7530: fix NULL dereference on unbind of MT7531 and MT7621
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (436 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 437/877] macsec: initialize SecY before registering the netdevice Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 439/877] tcp: fix use-after-free of retransmit_skb_hint in tcp_send_synack() Greg Kroah-Hartman
` (446 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aleksei Sviridkin, Jakub Kicinski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksei Sviridkin <f@lex.la>
[ Upstream commit c2cdef41e0b4d8ed23a5b41e6ad4e64594e055e4 ]
The core and io supplies are only requested for ID_MT7530: both the
devm_regulator_get() in probe and the regulator_enable() in
mt7530_setup() are guarded by the switch id, but mt7530_remove()
disables them unconditionally. On an MT7621 or an MT7531 both pointers
are still NULL from devm_kzalloc(), so rmmod or a sysfs unbind calls
regulator_disable() on NULL.
Fixes: ddda1ac116c8 ("net: dsa: mt7530: support the 7530 switch on the Mediatek MT7621 SoC")
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Link: https://patch.msgid.link/20260918015020.2518315-2-f@lex.la
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/dsa/mt7530-mdio.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/net/dsa/mt7530-mdio.c b/drivers/net/dsa/mt7530-mdio.c
index e19b46449ffe6..9bc142e55df23 100644
--- a/drivers/net/dsa/mt7530-mdio.c
+++ b/drivers/net/dsa/mt7530-mdio.c
@@ -230,15 +230,17 @@ mt7530_remove(struct mdio_device *mdiodev)
if (!priv)
return;
- ret = regulator_disable(priv->core_pwr);
- if (ret < 0)
- dev_err(priv->dev,
- "Failed to disable core power: %d\n", ret);
-
- ret = regulator_disable(priv->io_pwr);
- if (ret < 0)
- dev_err(priv->dev, "Failed to disable io pwr: %d\n",
- ret);
+ if (priv->id == ID_MT7530) {
+ ret = regulator_disable(priv->core_pwr);
+ if (ret < 0)
+ dev_err(priv->dev,
+ "Failed to disable core power: %d\n", ret);
+
+ ret = regulator_disable(priv->io_pwr);
+ if (ret < 0)
+ dev_err(priv->dev, "Failed to disable io pwr: %d\n",
+ ret);
+ }
mt7530_remove_common(priv);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 439/877] tcp: fix use-after-free of retransmit_skb_hint in tcp_send_synack()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (437 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 438/877] net: dsa: mt7530: fix NULL dereference on unbind of MT7531 and MT7621 Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 440/877] nfp: hold IPsec RX state under the XArray lock Greg Kroah-Hartman
` (445 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kimi Security Team, Weiming Shi,
Yilin Zhang, Eric Dumazet, Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yilin Zhang <yilinzhang@moonshot.ai>
[ Upstream commit fe99bbeee5c5dbd3abc30721a8079ced59649d97 ]
When tcp_send_synack() replaces the cloned SYN skb at the head of the
retransmit queue with a copy, it frees the original with
tcp_rtx_queue_unlink_and_free() and only repairs tp->highest_sack.
tp->retransmit_skb_hint keeps pointing at the freed
skbuff_fclone_cache object.
The dangling hint is read in tcp_verify_retransmit_hint() and used as
the root of the rbtree walk in tcp_xmit_retransmit_queue(). An
unprivileged TFO client (sendmsg(MSG_FASTOPEN)) can arm the hint with
an attacker-supplied ICMP fragmentation-needed message, after which a
simultaneous open frees the armed SYN skb:
BUG: KASAN: slab-use-after-free in tcp_mark_skb_lost (net/ipv4/tcp_input.c:1316)
Read of size 4 at addr ffff88800604d928 by task swapper/1/0
Call Trace:
tcp_mark_skb_lost (net/ipv4/tcp_input.c:1316)
tcp_simple_retransmit (net/ipv4/tcp_input.c:3158)
tcp_v4_err (net/ipv4/tcp_ipv4.c:587)
Sync the hint to the copy.
Fixes: c31b70c9968f ("tcp: Add logic to check for SYN w/ data in tcp_simple_retransmit")
Reported-by: Kimi Security Team <bug-report@moonshot.ai>
Tested-by: Weiming Shi <shiweiming@moonshot.ai>
Signed-off-by: Yilin Zhang <yilinzhang@moonshot.ai>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/8a9dff4063a2745653b7e88ceb745d75efa16e68.1790224474.git.yilinzhang@moonshot.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/tcp_output.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index a8c4801228677..aa00a9fb2506c 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -3679,6 +3679,7 @@ void tcp_send_active_reset(struct sock *sk, enum sk_rst_reason reason)
*/
int tcp_send_synack(struct sock *sk)
{
+ struct tcp_sock *tp = tcp_sk(sk);
struct sk_buff *skb;
skb = tcp_rtx_queue_head(sk);
@@ -3696,6 +3697,8 @@ int tcp_send_synack(struct sock *sk)
if (!nskb)
return -ENOMEM;
INIT_LIST_HEAD(&nskb->tcp_tsorted_anchor);
+ if (skb == tp->retransmit_skb_hint)
+ tp->retransmit_skb_hint = nskb;
tcp_highest_sack_replace(sk, skb, nskb);
tcp_rtx_queue_unlink_and_free(skb, sk);
__skb_header_release(nskb);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 440/877] nfp: hold IPsec RX state under the XArray lock
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (438 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 439/877] tcp: fix use-after-free of retransmit_skb_hint in tcp_send_synack() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 441/877] net/smc: fix UAF on lgr list traversal in smcr_port_err() Greg Kroah-Hartman
` (444 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Changyul Lee, Sang-Hoon Choi,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sang-Hoon Choi <csh0052@gmail.com>
[ Upstream commit 1a983a4e14c635c40354be110cd9a1a5c94e01e6 ]
nfp_net_ipsec_rx() drops the XArray lock before taking a reference to the
xfrm_state it found. The delete path can erase the entry and drop the last
state reference in that interval. RX can then try to increment a zero
refcount after the state has been queued for destruction.
The driver queues firmware invalidation asynchronously; the delete path
does not wait for the command to complete or drain pending RX processing.
The XFRM garbage collector waits for an RCU grace period before freeing
the state. That delays reclamation but does not make acquiring a reference
from zero valid.
Take the xfrm_state reference before releasing the XArray lock so
xa_erase() cannot run between lookup and reference acquisition.
Fixes: 57f273adbcd4 ("nfp: add framework to support ipsec offloading")
Reported-by: Changyul Lee <lcy8047@gmail.com>
Signed-off-by: Sang-Hoon Choi <csh0052@gmail.com>
Link: https://patch.msgid.link/179001455912.44752.17153022439349797877.idr-bug-92@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/netronome/nfp/crypto/ipsec.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c b/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
index 515069d5637b0..3925a00aeaf7e 100644
--- a/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
+++ b/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
@@ -637,11 +637,12 @@ int nfp_net_ipsec_rx(struct nfp_meta_parsed *meta, struct sk_buff *skb)
xa_lock(&nn->xa_ipsec);
x = xa_load(&nn->xa_ipsec, saidx);
+ if (x)
+ xfrm_state_hold(x);
xa_unlock(&nn->xa_ipsec);
if (!x)
return -EINVAL;
- xfrm_state_hold(x);
sp->xvec[sp->len++] = x;
sp->olen++;
xo = xfrm_offload(skb);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 441/877] net/smc: fix UAF on lgr list traversal in smcr_port_err()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (439 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 440/877] nfp: hold IPsec RX state under the XArray lock Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 442/877] tipc: Fix a data race on mon->peer_cnt in mon_timeout() Greg Kroah-Hartman
` (443 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mahanta Jambigi, Sidraya Jayagond,
Dust Li, Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sidraya Jayagond <sidraya@linux.ibm.com>
[ Upstream commit 61cb282fe97b3b0ba32ca09417a693162bf4ae3f ]
smcr_port_err() traverses smc_lgr_list.list without holding
smc_lgr_list.lock, allowing a concurrent smc_lgr_terminate_sched()
to free an lgr while it is still being dereferenced.
Hold smc_lgr_list.lock across the traversal. Update
smc_ib_gid_check() to call smcr_port_err() after releasing the lock.
Fixes: 541afa10c126 ("net/smc: add smcr_port_err() and smcr_link_down() processing")
Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
Signed-off-by: Sidraya Jayagond <sidraya@linux.ibm.com>
Reviewed-by: Dust Li <dust.li@linux.alibaba.com>
Link: https://patch.msgid.link/20260922073149.474762-1-sidraya@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/smc/smc_core.c | 2 ++
net/smc/smc_ib.c | 10 ++++++++--
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
index ed0027ba66c75..e0bf348bd812e 100644
--- a/net/smc/smc_core.c
+++ b/net/smc/smc_core.c
@@ -1830,6 +1830,7 @@ void smcr_port_err(struct smc_ib_device *smcibdev, u8 ibport)
struct smc_link_group *lgr, *n;
int i;
+ spin_lock_bh(&smc_lgr_list.lock);
list_for_each_entry_safe(lgr, n, &smc_lgr_list.list, list) {
if (strncmp(smcibdev->pnetid[ibport - 1], lgr->pnet_id,
SMC_MAX_PNETID_LEN))
@@ -1844,6 +1845,7 @@ void smcr_port_err(struct smc_ib_device *smcibdev, u8 ibport)
smcr_link_down_cond_sched(lnk);
}
}
+ spin_unlock_bh(&smc_lgr_list.lock);
}
static void smc_link_down_work(struct work_struct *work)
diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c
index fc07fc4ed9986..0cca7b9ca044e 100644
--- a/net/smc/smc_ib.c
+++ b/net/smc/smc_ib.c
@@ -333,6 +333,7 @@ static bool smc_ib_check_link_gid(u8 gid[SMC_GID_SIZE], bool smcrv2,
static void smc_ib_gid_check(struct smc_ib_device *smcibdev, u8 ibport)
{
struct smc_link_group *lgr;
+ bool stale_gid = false;
int i;
spin_lock_bh(&smc_lgr_list.lock);
@@ -348,11 +349,16 @@ static void smc_ib_gid_check(struct smc_ib_device *smcibdev, u8 ibport)
continue;
if (!smc_ib_check_link_gid(lgr->lnk[i].gid,
lgr->smc_version == SMC_V2,
- smcibdev, ibport))
- smcr_port_err(smcibdev, ibport);
+ smcibdev, ibport)) {
+ stale_gid = true;
+ goto out;
+ }
}
}
+out:
spin_unlock_bh(&smc_lgr_list.lock);
+ if (stale_gid)
+ smcr_port_err(smcibdev, ibport);
}
static int smc_ib_remember_port_attr(struct smc_ib_device *smcibdev, u8 ibport)
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 442/877] tipc: Fix a data race on mon->peer_cnt in mon_timeout()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (440 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 441/877] net/smc: fix UAF on lgr list traversal in smcr_port_err() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 443/877] net: ethernet: stmmac: dwmac-rk: fix bulk clock leak when the PHY clock fails Greg Kroah-Hartman
` (442 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ginger Li, Tung Nguyen,
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ginger Li <ginger.jzllee@gmail.com>
[ Upstream commit 8e1937fed6738460554ec123c64839e2445e7d53 ]
mon_timeout() evaluates dom_size(mon->peer_cnt) before it takes mon->lock,
while mon->peer_cnt is updated under that lock by tipc_mon_add_peer() and
tipc_mon_remove_peer(). The value can therefore be stale, and the decision
whether the local domain has to be recomputed can be based on an outdated
member count.
Read mon->peer_cnt inside the write_lock_bh(&mon->lock) protected region.
Fixes: 35c55c9877f8 ("tipc: add neighbor monitoring framework")
Signed-off-by: Ginger Li <ginger.jzllee@gmail.com>
Reviewed-by: Tung Nguyen <tung.quang.nguyen@est.tech>
Link: https://patch.msgid.link/20260922080909.21123-1-ginger.jzllee@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/tipc/monitor.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c
index b45c5b91bc7af..5e4585b034970 100644
--- a/net/tipc/monitor.c
+++ b/net/tipc/monitor.c
@@ -632,9 +632,10 @@ static void mon_timeout(struct timer_list *t)
{
struct tipc_monitor *mon = from_timer(mon, t, timer);
struct tipc_peer *self;
- int best_member_cnt = dom_size(mon->peer_cnt) - 1;
+ int best_member_cnt;
write_lock_bh(&mon->lock);
+ best_member_cnt = dom_size(mon->peer_cnt) - 1;
self = mon->self;
if (self && (best_member_cnt != self->applied)) {
mon_update_local_domain(mon);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 443/877] net: ethernet: stmmac: dwmac-rk: fix bulk clock leak when the PHY clock fails
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (441 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 442/877] tipc: Fix a data race on mon->peer_cnt in mon_timeout() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 444/877] llc: fix skb UAF and leaks on llc_mac_hdr_init() failure Greg Kroah-Hartman
` (441 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Maxime Chevallier, Heiko Stuebner,
Lorenzo Bianconi, Coia Prant, Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Coia Prant <coiaprant@gmail.com>
[ Upstream commit 8db67bb6a1fffa4df68fbbc22e39943aeeff9178 ]
gmac_clk_enable() enables the bulk clocks first and then the optional
PHY clock. If clk_prepare_enable() on the PHY clock fails, the function
returns without rolling back the bulk clocks, and bsp_priv->clk_enabled
stays false, so the later gmac_clk_enable(bsp_priv, false) becomes a
no-op and the bulk clock references are leaked.
Add the missing clk_bulk_disable_unprepare() on that failure path.
Fixes: ea449f7fa0bf ("net: ethernet: stmmac: dwmac-rk: rework optional clock handling")
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Acked-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
Signed-off-by: Coia Prant <coiaprant@gmail.com>
Link: https://patch.msgid.link/20260923123713.3137146-1-coiaprant@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index d152afa48d5c2..e093bf4cd56a8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -1709,8 +1709,11 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
return ret;
ret = clk_prepare_enable(bsp_priv->clk_phy);
- if (ret)
+ if (ret) {
+ clk_bulk_disable_unprepare(bsp_priv->num_clks,
+ bsp_priv->clks);
return ret;
+ }
if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
bsp_priv->ops->set_clock_selection(bsp_priv,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 444/877] llc: fix skb UAF and leaks on llc_mac_hdr_init() failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (442 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 443/877] net: ethernet: stmmac: dwmac-rk: fix bulk clock leak when the PHY clock fails Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 445/877] bridge: check llc_mac_hdr_init() return value in br_send_bpdu() Greg Kroah-Hartman
` (440 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Jakub Kicinski,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 72f9dd522f8d6c5a00be9695c7bb74631eb5069e ]
In llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(), if llc_mac_hdr_init()
fails, kfree_skb(skb) is called instead of kfree_skb(nskb). This leaks
the newly allocated nskb, reads from the freed skb via LLC_I_GET_NR(pdu),
and double-frees skb when llc_conn_state_process() drops its reference.
In llc_sap_action_send_xid_r() and llc_sap_action_send_test_r(), nskb is
leaked if llc_mac_hdr_init() returns an error.
Free nskb in all three error paths.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Closes: https://lore.kernel.org/netdev/179022851638.2160803.1808206741379444999@kernel.org/
Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260924082951.1599377-2-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/llc/llc_c_ac.c | 2 +-
net/llc/llc_s_ac.c | 4 ++++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c
index 40ca3c1e42a2e..5c8483f63ebbc 100644
--- a/net/llc/llc_c_ac.c
+++ b/net/llc/llc_c_ac.c
@@ -443,7 +443,7 @@ int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,
if (likely(!rc))
llc_conn_send_pdu(sk, nskb);
else
- kfree_skb(skb);
+ kfree_skb(nskb);
}
if (rc) {
nr = LLC_I_GET_NR(pdu);
diff --git a/net/llc/llc_s_ac.c b/net/llc/llc_s_ac.c
index 7a0cae9a81114..cc6fb29a9510a 100644
--- a/net/llc/llc_s_ac.c
+++ b/net/llc/llc_s_ac.c
@@ -127,6 +127,8 @@ int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb)
rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
if (likely(!rc))
rc = dev_queue_xmit(nskb);
+ else
+ kfree_skb(nskb);
out:
return rc;
}
@@ -176,6 +178,8 @@ int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb)
rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
if (likely(!rc))
rc = dev_queue_xmit(nskb);
+ else
+ kfree_skb(nskb);
out:
return rc;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 445/877] bridge: check llc_mac_hdr_init() return value in br_send_bpdu()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (443 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 444/877] llc: fix skb UAF and leaks on llc_mac_hdr_init() failure Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 446/877] net/sched: sch_teql: fix shadowed err in __teql_resolve() Greg Kroah-Hartman
` (439 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nikolay Aleksandrov, Ido Schimmel,
bridge, Eric Dumazet, Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit ac704ff08e511c87643799c385f55ecd69b85e03 ]
If llc_mac_hdr_init() fails (for instance if the port device type does
not support LLC or dev_hard_header() fails), br_send_bpdu() should drop
the skb instead of resetting the mac header to the LLC payload and
transmitting a malformed frame.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Closes: https://lore.kernel.org/netdev/179022851638.2160803.1808206741379444999@kernel.org/
Cc: Nikolay Aleksandrov <razor@blackwall.org>
Cc: Ido Schimmel <idosch@nvidia.com>
Cc: bridge@lists.linux.dev
Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/20260924082951.1599377-3-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bridge/br_stp_bpdu.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c
index 7895489ac6fe7..e44e448b1157b 100644
--- a/net/bridge/br_stp_bpdu.c
+++ b/net/bridge/br_stp_bpdu.c
@@ -52,7 +52,10 @@ static void br_send_bpdu(struct net_bridge_port *p,
LLC_SAP_BSPAN, LLC_PDU_CMD);
llc_pdu_init_as_ui_cmd(skb);
- llc_mac_hdr_init(skb, p->dev->dev_addr, p->br->group_addr);
+ if (llc_mac_hdr_init(skb, p->dev->dev_addr, p->br->group_addr)) {
+ kfree_skb(skb);
+ return;
+ }
skb_reset_mac_header(skb);
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 446/877] net/sched: sch_teql: fix shadowed err in __teql_resolve()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (444 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 445/877] bridge: check llc_mac_hdr_init() return value in br_send_bpdu() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 447/877] vlan: ensure sufficient headroom in vlan_dev_hard_header() Greg Kroah-Hartman
` (438 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jamal Hadi Salim, Jiri Pirko,
Eric Dumazet, Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 907b978e82cb4c1c245fc2985bb27c5d5c88c8f6 ]
__teql_resolve() declares an inner 'int err;' inside the
'if (neigh_event_send(n, skb_res) == 0)' block, shadowing the outer
'int err = 0;'. As a result, a negative return from dev_hard_header()
is written to the inner variable and __teql_resolve() still returns 0.
Remove the shadowed variable and set the outer err to -EINVAL when
dev_hard_header() returns a negative error.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Closes: https://lore.kernel.org/netdev/179022851638.2160803.1808206741379444999@kernel.org/
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Cc: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260924082951.1599377-4-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/sch_teql.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index eb424b20027e5..d3baf17ebe6ce 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -265,14 +265,11 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res,
}
if (neigh_event_send(n, skb_res) == 0) {
- int err;
char haddr[MAX_ADDR_LEN];
neigh_ha_snapshot(haddr, n, dev);
- err = dev_hard_header(skb, dev, ntohs(skb_protocol(skb, false)),
- haddr, NULL, skb->len);
-
- if (err < 0)
+ if (dev_hard_header(skb, dev, ntohs(skb_protocol(skb, false)),
+ haddr, NULL, skb->len) < 0)
err = -EINVAL;
} else {
err = (skb_res == NULL) ? -EAGAIN : 1;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 447/877] vlan: ensure sufficient headroom in vlan_dev_hard_header()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (445 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 446/877] net/sched: sch_teql: fix shadowed err in __teql_resolve() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 448/877] autofs: fix sbi->pipe file reference leak in autofs_kill_sb() Greg Kroah-Hartman
` (437 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zixuan Chai, Hangbin Liu,
Eric Dumazet, Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit cd5dd68267c4238795fadaf02b3575ca3f8a6500 ]
Callers that only reserve ETH_HLEN or less (such as llc_alloc_frame()),
or skbs allocated before dynamic device/headroom changes (e.g. toggling
VLAN_FLAG_REORDER_HDR or bonding/team switching slaves), can reach
vlan_dev_hard_header() with insufficient headroom and trigger
skb_under_panic().
Use skb_cow_head() in vlan_dev_hard_header() when VLAN_FLAG_REORDER_HDR
is not set to ensure sufficient headroom for the VLAN header(s) and the
underlying device hard header.
Use READ_ONCE() to read dev->hard_header_len and dev->needed_headroom as
they can be updated concurrently under RTNL (e.g. in
vlan_transfer_features()) while vlan_dev_hard_header() runs locklessly on
the transmit path. Also avoid LL_RESERVED_SPACE(dev) here so that the
extra HH_DATA_MOD alignment padding does not trigger unnecessary
pskb_expand_head() reallocations on inner stacked VLAN devices after the
outer VLAN header has been pushed.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Zixuan Chai <petalzu987@gmail.com>
Closes: https://lore.kernel.org/netdev/cover.1789987105.git.petalzu987@gmail.com/
Link: https://lore.kernel.org/netdev/179022851638.2160803.1808206741379444999@kernel.org/
Cc: Hangbin Liu <liuhangbin@gmail.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260924082951.1599377-5-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/8021q/vlan_dev.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index e7e5b903fa8c3..61fb68fadea33 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -54,6 +54,11 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
int rc;
if (!(vlan->flags & VLAN_FLAG_REORDER_HDR)) {
+ unsigned int hlen = READ_ONCE(dev->hard_header_len) +
+ READ_ONCE(dev->needed_headroom);
+
+ if (skb_cow_head(skb, hlen) < 0)
+ return -ENOMEM;
vhdr = skb_push(skb, VLAN_HLEN);
vlan_tci = vlan->vlan_id;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 448/877] autofs: fix sbi->pipe file reference leak in autofs_kill_sb()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (446 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 447/877] vlan: ensure sufficient headroom in vlan_dev_hard_header() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 449/877] perf/x86/intel: Ensure KVM guest PEBS path doesnt set unwanted PERF_GLOBAL_CTRL bits Greg Kroah-Hartman
` (436 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hui Peng,
Christian Brauner (Amutable), Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Peng <benquike@gmail.com>
[ Upstream commit aa5e44b29ffe4eaa08cc2237fd65bc2596bc023e ]
When autofs_fill_super() fails before clearing AUTOFS_SBI_CATATONIC (for
example, when find_get_pid() fails on an invalid pgrp mount option, or
when an fs_context is closed before mounting), deactivate_locked_super()
invokes autofs_kill_sb() -> autofs_catatonic_mode(sbi).
Because AUTOFS_SBI_CATATONIC is still set in sbi->flags,
autofs_catatonic_mode() returns early without calling fput(sbi->pipe),
permanently leaking the pipe struct file reference.
Explicitly release sbi->pipe in autofs_kill_sb() if it is still non-NULL
after autofs_catatonic_mode().
Fixes: ebc921ca9b92 ("autofs: copy autofs4 to autofs")
Signed-off-by: Hui Peng <benquike@gmail.com>
Link: https://patch.msgid.link/20260919204808.2812930-1-benquike@gmail.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/autofs/inode.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c
index ec3c1ac1c1f9d..7203dba0ebce4 100644
--- a/fs/autofs/inode.c
+++ b/fs/autofs/inode.c
@@ -51,6 +51,10 @@ void autofs_kill_sb(struct super_block *sb)
if (sbi) {
/* Free wait queues, close pipe */
autofs_catatonic_mode(sbi);
+ if (sbi->pipe) {
+ fput(sbi->pipe);
+ sbi->pipe = NULL;
+ }
put_pid(sbi->oz_pgrp);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 449/877] perf/x86/intel: Ensure KVM guest PEBS path doesnt set unwanted PERF_GLOBAL_CTRL bits
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (447 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 448/877] autofs: fix sbi->pipe file reference leak in autofs_kill_sb() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 450/877] perf/x86/intel: Dont write PEBS_ENABLED on host<=>guest xfers if CPU has PEBS isolation, to fix stuck PEBS_ENABLED Greg Kroah-Hartman
` (435 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sean Christopherson,
Peter Zijlstra (Intel), Ingo Molnar, Dapeng Mi, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <seanjc@google.com>
[ Upstream commit cec38d5c098a350dcf084d345025136ade7e6d1e ]
When reinstating PEBS counters into PERF_GLOBAL_CTRL for a KVM guest, mask
the value with perf's desired/original PERF_GLOBAL_CTRL value to ensure
KVM doesn't unintentionally set reserved bits in PERF_GLOBAL_CTRL. E.g.
if the guest's PEBS_ENABLE value had bit 63, "Enable Precise Store", set,
then using the raw guest PEBS value would propagate bit 63 to the guest's
PERF_GLOBAL_CTRL value (which thankfully would be a failed VM-Entry, not
a VMX Abort).
The only reason this bug isn't reachable is because KVM doesn't support
"Enable Precise Store" (which is probably a KVM bug?), i.e. bit 63 can't
be set in kvm_pmu->pebs_enable and thus not in arr[pebs_enable].guest. In
other words, this _should_ be a glorified NOP in the current code base.
Fixes: c59a1f106f5c ("KVM: x86/pmu: Add IA32_PEBS_ENABLE MSR emulation for extended PEBS")
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20260921191418.950933-2-seanjc@google.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/events/intel/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 27001daade100..b4c1875ef1373 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -4355,7 +4355,7 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr, void *data)
arr[pebs_enable].guest &= ~kvm_pmu->host_cross_mapped_mask;
arr[global_ctrl].guest &= ~kvm_pmu->host_cross_mapped_mask;
/* Set hw GLOBAL_CTRL bits for PEBS counter when it runs for guest */
- arr[global_ctrl].guest |= arr[pebs_enable].guest;
+ arr[global_ctrl].guest |= intel_ctrl & arr[pebs_enable].guest;
}
return arr;
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 450/877] perf/x86/intel: Dont write PEBS_ENABLED on host<=>guest xfers if CPU has PEBS isolation, to fix stuck PEBS_ENABLED
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (448 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 449/877] perf/x86/intel: Ensure KVM guest PEBS path doesnt set unwanted PERF_GLOBAL_CTRL bits Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 451/877] perf/x86/intel: Dont pointlessly context switch DS_AREA (and PEBS config) if PEBS is unused Greg Kroah-Hartman
` (434 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sean Christopherson,
Peter Zijlstra (Intel), Ingo Molnar, Dapeng Mi, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <seanjc@google.com>
[ Upstream commit 4b64dbdc5861477f148e13d1ed127e7fe7182e4f ]
When filling the list of MSRs to be loaded by KVM on VM-Enter and VM-Exit,
*never* insert an entry for PEBS_ENABLED if the CPU properly isolates PEBS
events, in which case disabling counters via PERF_GLOBAL_CTRL is sufficient
to prevent unwanted PEBS events in the guest (or host). Because perf loads
PEBS_ENABLE with the unfiltered cpu_hw_events.pebs_enabled, i.e. with both
host and guest masks, there is no need to load different values for the
guest versus host, perf+KVM can and should simply control which counters
are enabled/disabled via PERF_GLOBAL_CTRL.
Avoiding touching PEBS_ENABLED "fixes" a bug where PEBS_ENABLED can end up
with "stuck" bits if a PEBS event is throttled between generating the list
and actually entering the guest (Intel CPUs can't arbtitrarily block NMIs).
Fixes in quotes because leaving PEBS_ENABLED as-is doesn't fix the
underlying problem of perf (via PMIs) being able to modify state after the
perf<=>KVM handoff.
But not writing PEBS_ENABLED is desirable no matter what, as stating the
obvious, leaving PEBS_ENABLED as-is avoids three MSR writes on every VMX
transition: one each on entry/exit, and one more explicit WRMSR to zero
PEBS_ENABLED before VM-Entry (KVM assumes the only reason PEBS_ENABLED is
in the load list is if the CPU lacks PEBS isolation and thus needs a
quiescent period).
Opportunistically add comments to (better) explain the rules for generating
the set of PEBS counters that will be active while the guest is running,
along with a FIXME for the suspected hack-a-fix where perf disables guest
PEBS if _any_ PEBS event is configured to count in the host (commit
854250329c02 ("KVM: x86/pmu: Disable guest PEBS temporarily in two rare
situations") doesn't explain the motivation, at all).
Fixes: c59a1f106f5c ("KVM: x86/pmu: Add IA32_PEBS_ENABLE MSR emulation for extended PEBS")
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20260921191418.950933-3-seanjc@google.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/events/intel/core.c | 55 ++++++++++++++++++++++++------------
1 file changed, 37 insertions(+), 18 deletions(-)
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index b4c1875ef1373..573298a35005f 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -4288,12 +4288,15 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr, void *data)
struct kvm_pmu *kvm_pmu = (struct kvm_pmu *)data;
u64 intel_ctrl = hybrid(cpuc->pmu, intel_ctrl);
u64 pebs_mask = cpuc->pebs_enabled & x86_pmu.pebs_capable;
- int global_ctrl, pebs_enable;
+ u64 guest_pebs_mask;
+ int global_ctrl;
/*
* In addition to obeying exclude_guest/exclude_host, remove bits being
* used for PEBS when running a guest, because PEBS writes to virtual
- * addresses (not physical addresses).
+ * addresses (not physical addresses). If the guest wants to utilize
+ * PEBS, and PEBS can be safely enabled in the guest, bits for the guest's
+ * PEBS-enabled counters will be OR'd back in as appropriate.
*/
*nr = 0;
global_ctrl = (*nr)++;
@@ -4340,24 +4343,40 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr, void *data)
};
}
- pebs_enable = (*nr)++;
- arr[pebs_enable] = (struct perf_guest_switch_msr){
- .msr = MSR_IA32_PEBS_ENABLE,
- .host = cpuc->pebs_enabled & ~cpuc->intel_ctrl_guest_mask,
- .guest = pebs_mask & ~cpuc->intel_ctrl_host_mask & kvm_pmu->pebs_enable,
- };
+ /*
+ * Restrict guest PEBS events to counters that (a) perf supports, (b)
+ * the guest wants to use for PEBS, (c) are not excluded from counting
+ * in the guest, and (d) _are_ excluded from counting in the host.
+ */
+ guest_pebs_mask = pebs_mask & intel_ctrl & kvm_pmu->pebs_enable &
+ ~cpuc->intel_ctrl_host_mask &
+ cpuc->intel_ctrl_guest_mask;
- if (arr[pebs_enable].host) {
- /* Disable guest PEBS if host PEBS is enabled. */
- arr[pebs_enable].guest = 0;
- } else {
- /* Disable guest PEBS thoroughly for cross-mapped PEBS counters. */
- arr[pebs_enable].guest &= ~kvm_pmu->host_cross_mapped_mask;
- arr[global_ctrl].guest &= ~kvm_pmu->host_cross_mapped_mask;
- /* Set hw GLOBAL_CTRL bits for PEBS counter when it runs for guest */
- arr[global_ctrl].guest |= intel_ctrl & arr[pebs_enable].guest;
- }
+ /*
+ * Disable counters where the guest PMC is different than the host PMC
+ * being used on behalf of the guest, as the PEBS record includes
+ * PERF_GLOBAL_STATUS, i.e. the guest will see overflow status for the
+ * wrong counter(s).
+ */
+ guest_pebs_mask &= ~kvm_pmu->host_cross_mapped_mask;
+
+ /*
+ * FIXME: Allow guest and host usage of PEBS events to co-exist instead
+ * of disabling guest PEBS entirely if the host is using PEBS.
+ * What exactly goes wrong if guest and host are using PEBS is
+ * unknown.
+ */
+ if (pebs_mask & ~cpuc->intel_ctrl_guest_mask)
+ guest_pebs_mask = 0;
+ /*
+ * Do NOT mess with PEBS_ENABLED. As above, disabling counters via
+ * PERF_GLOBAL_CTRL is sufficient, and loading a stale PEBS_ENABLED,
+ * e.g. on VM-Exit, can put the system in a bad state. Simply enable
+ * counters in PERF_GLOBAL_CTRL, as perf load PEBS_ENABLED with the
+ * full value, i.e. perf *also* relies on PERF_GLOBAL_CTRL.
+ */
+ arr[global_ctrl].guest |= guest_pebs_mask;
return arr;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 451/877] perf/x86/intel: Dont pointlessly context switch DS_AREA (and PEBS config) if PEBS is unused
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (449 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 450/877] perf/x86/intel: Dont write PEBS_ENABLED on host<=>guest xfers if CPU has PEBS isolation, to fix stuck PEBS_ENABLED Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 452/877] perf/x86/intel: Make @data a mandatory param for intel_guest_get_msrs() Greg Kroah-Hartman
` (433 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sean Christopherson,
Peter Zijlstra (Intel), Ingo Molnar, Jim Mattson, Dapeng Mi,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <seanjc@google.com>
[ Upstream commit d06260e99eb93d2942b7af4ccd789eb8a6c829d3 ]
When filling the list of MSRs to be loaded by KVM on VM-Enter and VM-Exit,
load the guest values for DS_AREA and (conditionally) MSR_PEBS_DATA_CFG if
and only if PEBS will be active in the guest, i.e. only if a PEBS record
may be generated while running the guest. As shown by the !pebs_ept path,
it's perfectly safe to run with the host's DS_AREA, so long as PEBS-enabled
counters are disabled via PERF_GLOBAL_CTRL.
Omitting DS_AREA and MSR_PEBS_DATA_CFG when PEBS is unused saves two MSR
writes per MSR on each VMX transition, i.e. eliminates two/four pointless
MSR writes on each VMX roundtrip when PEBS isn't being used by the guest.
Fixes: c59a1f106f5c ("KVM: x86/pmu: Add IA32_PEBS_ENABLE MSR emulation for extended PEBS")
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Jim Mattson <jmattson@google.com>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20260921191418.950933-4-seanjc@google.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/events/intel/core.c | 39 +++++++++++++++++++++++-------------
1 file changed, 25 insertions(+), 14 deletions(-)
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 573298a35005f..313456a90bcbe 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -4326,23 +4326,14 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr, void *data)
return arr;
}
+ /*
+ * If the guest won't use PEBS or the CPU doesn't support PEBS in the
+ * guest, then there's nothing more to do as disabling PMCs via
+ * PERF_GLOBAL_CTRL is sufficient on CPUs with guest/host isolation.
+ */
if (!kvm_pmu || !x86_pmu.pebs_ept)
return arr;
- arr[(*nr)++] = (struct perf_guest_switch_msr){
- .msr = MSR_IA32_DS_AREA,
- .host = (unsigned long)cpuc->ds,
- .guest = kvm_pmu->ds_area,
- };
-
- if (x86_pmu.intel_cap.pebs_baseline) {
- arr[(*nr)++] = (struct perf_guest_switch_msr){
- .msr = MSR_PEBS_DATA_CFG,
- .host = cpuc->active_pebs_data_cfg,
- .guest = kvm_pmu->pebs_data_cfg,
- };
- }
-
/*
* Restrict guest PEBS events to counters that (a) perf supports, (b)
* the guest wants to use for PEBS, (c) are not excluded from counting
@@ -4369,6 +4360,26 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr, void *data)
if (pebs_mask & ~cpuc->intel_ctrl_guest_mask)
guest_pebs_mask = 0;
+ /*
+ * Context switch DS_AREA and PEBS_DATA_CFG if and only if PEBS will be
+ * active in the guest; if no records will be generated while the guest
+ * is running, then simply keep the host values resident in hardware.
+ */
+ arr[(*nr)++] = (struct perf_guest_switch_msr){
+ .msr = MSR_IA32_DS_AREA,
+ .host = (unsigned long)cpuc->ds,
+ .guest = guest_pebs_mask ? kvm_pmu->ds_area : (unsigned long)cpuc->ds,
+ };
+
+ if (x86_pmu.intel_cap.pebs_baseline) {
+ arr[(*nr)++] = (struct perf_guest_switch_msr){
+ .msr = MSR_PEBS_DATA_CFG,
+ .host = cpuc->active_pebs_data_cfg,
+ .guest = guest_pebs_mask ? kvm_pmu->pebs_data_cfg :
+ cpuc->active_pebs_data_cfg,
+ };
+ }
+
/*
* Do NOT mess with PEBS_ENABLED. As above, disabling counters via
* PERF_GLOBAL_CTRL is sufficient, and loading a stale PEBS_ENABLED,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 452/877] perf/x86/intel: Make @data a mandatory param for intel_guest_get_msrs()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (450 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 451/877] perf/x86/intel: Dont pointlessly context switch DS_AREA (and PEBS config) if PEBS is unused Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 453/877] mptcp: return sk_wait_data() errors from recvmsg() Greg Kroah-Hartman
` (432 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sean Christopherson,
Peter Zijlstra (Intel), Ingo Molnar, Jim Mattson, Dapeng Mi,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <seanjc@google.com>
[ Upstream commit a391618e1d563f099e4c2a704f45d08329ccdf7c ]
Drop "support" for passing a NULL @data/@kvm_pmu param when getting guest
MSRs. KVM, the only in-tree user, unconditionally passes a non-NULL
pointer, and carrying code that suggests @data may be NULL is confusing,
e.g. incorrectly implies that there are scenarios where KVM doesn't pass
a PMU context.
Fixes: 8183a538cd95 ("KVM: x86/pmu: Add IA32_DS_AREA MSR emulation to support guest DS")
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Jim Mattson <jmattson@google.com>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20260921191418.950933-5-seanjc@google.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/events/intel/core.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 313456a90bcbe..8298b5462d49e 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -4327,11 +4327,11 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr, void *data)
}
/*
- * If the guest won't use PEBS or the CPU doesn't support PEBS in the
- * guest, then there's nothing more to do as disabling PMCs via
- * PERF_GLOBAL_CTRL is sufficient on CPUs with guest/host isolation.
+ * If the CPU doesn't support PEBS in the guest, then there's nothing
+ * more to do as disabling PMCs via PERF_GLOBAL_CTRL is sufficient on
+ * CPUs with guest/host isolation.
*/
- if (!kvm_pmu || !x86_pmu.pebs_ept)
+ if (!x86_pmu.pebs_ept)
return arr;
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 453/877] mptcp: return sk_wait_data() errors from recvmsg()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (451 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 452/877] perf/x86/intel: Make @data a mandatory param for intel_guest_get_msrs() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 454/877] rculist: add list_splice_rcu() for private lists Greg Kroah-Hartman
` (431 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mark Amirkan, Matthieu Baerts (NGI0),
Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Amirkan <markdamirkan@gmail.com>
[ Upstream commit 60404266ef3e0a1cd8f7a164060e0c83efb72f4b ]
Commit 581302298524 ("mptcp: error out earlier on disconnect") made
mptcp_recvmsg() stop when sk_wait_data() returns an error. The error is
stored in err, but the function then jumps to a path which returns
copied. When no data was copied, recvmsg() therefore returns zero and
reports a false EOF.
Store the result in copied, which is the value returned by the function.
This also keeps the usual partial-read result when data was copied before
the error.
A recvmsg() blocked in one thread reproduces the issue when another
thread disconnects the same MPTCP socket with connect(AF_UNSPEC).
Before this change recvmsg() returns zero; afterwards it returns -EPIPE.
Fixes: 581302298524 ("mptcp: error out earlier on disconnect")
Cc: stable@vger.kernel.org
Signed-off-by: Mark Amirkan <markdamirkan@gmail.com>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260913-b4-send-mptcp-recv-error-v1-1-4eaa3684a8b8@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mptcp/protocol.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index ee160c783ff5a..4e467e7d3b362 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -2364,7 +2364,7 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
mptcp_cleanup_rbuf(msk, copied);
err = sk_wait_data(sk, &timeo, NULL);
if (err < 0) {
- err = copied ? : err;
+ copied = copied ? : err;
goto out_err;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 454/877] rculist: add list_splice_rcu() for private lists
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (452 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 453/877] mptcp: return sk_wait_data() errors from recvmsg() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 455/877] netfilter: nf_tables: join hook list via splice_list_rcu() in commit phase Greg Kroah-Hartman
` (430 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Paul E. McKenney, Pablo Neira Ayuso,
Benjamin Robin (Schneider Electric), Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <pablo@netfilter.org>
[ Upstream commit f902877b635551513729bdf9a8d1422c4aab7741 ]
This patch adds a helper function, list_splice_rcu(), to safely splice
a private (non-RCU-protected) list into an RCU-protected list.
The function ensures that only the pointer visible to RCU readers
(prev->next) is updated using rcu_assign_pointer(), while the rest of
the list manipulations are performed with regular assignments, as the
source list is private and not visible to concurrent RCU readers.
This is useful for moving elements from a private list into a global
RCU-protected list, ensuring safe publication for RCU readers.
Subsystems with some sort of batching mechanism from userspace can
benefit from this new function.
The function __list_splice_rcu() has been added for clarity and to
follow the same pattern as in the existing list_splice*() interfaces,
where there is a check to ensure that the list to splice is not
empty. Note that __list_splice_rcu() has no documentation for this
reason.
Reviewed-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Benjamin Robin (Schneider Electric) <benjamin.robin@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/rculist.h | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/include/linux/rculist.h b/include/linux/rculist.h
index 14dfa6008467e..2e4d990f07ad4 100644
--- a/include/linux/rculist.h
+++ b/include/linux/rculist.h
@@ -207,6 +207,35 @@ static inline void list_replace_rcu(struct list_head *old,
old->prev = LIST_POISON2;
}
+static inline void __list_splice_rcu(struct list_head *list,
+ struct list_head *prev,
+ struct list_head *next)
+{
+ struct list_head *first = list->next;
+ struct list_head *last = list->prev;
+
+ last->next = next;
+ first->prev = prev;
+ next->prev = last;
+ rcu_assign_pointer(list_next_rcu(prev), first);
+}
+
+/**
+ * list_splice_rcu - splice a non-RCU list into an RCU-protected list,
+ * designed for stacks.
+ * @list: the non RCU-protected list to splice
+ * @head: the place in the existing RCU-protected list to splice
+ *
+ * The list pointed to by @head can be RCU-read traversed concurrently with
+ * this function.
+ */
+static inline void list_splice_rcu(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list))
+ __list_splice_rcu(list, head, head->next);
+}
+
/**
* __list_splice_init_rcu - join an RCU-protected list into an existing list.
* @list: the RCU-protected list to splice
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 455/877] netfilter: nf_tables: join hook list via splice_list_rcu() in commit phase
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (453 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 454/877] rculist: add list_splice_rcu() for private lists Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 456/877] x86/mce: Fix hardware debug register corruption on task migration Greg Kroah-Hartman
` (429 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pablo Neira Ayuso, Sasha Levin,
Benjamin Robin (Schneider Electric)
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <pablo@netfilter.org>
[ Upstream commit a6134e62dba2ea4f760b29d5226907f447c92400 ]
Publish new hooks in the list into the basechain/flowtable using
splice_list_rcu() to ensure netlink dump list traversal via rcu is safe
while concurrent ruleset update is going on.
Fixes: 78d9f48f7f44 ("netfilter: nf_tables: add devices to existing flowtable")
Fixes: b9703ed44ffb ("netfilter: nf_tables: support for adding new devices to an existing netdev chain")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Benjamin Robin (Schneider Electric) <benjamin.robin@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/nf_tables_api.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index af9df95ddf055..0aa96283385a6 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -10360,8 +10360,8 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
nft_chain_commit_update(nft_trans_container_chain(trans));
nf_tables_chain_notify(&ctx, NFT_MSG_NEWCHAIN,
&nft_trans_chain_hooks(trans));
- list_splice(&nft_trans_chain_hooks(trans),
- &nft_trans_basechain(trans)->hook_list);
+ list_splice_rcu(&nft_trans_chain_hooks(trans),
+ &nft_trans_basechain(trans)->hook_list);
/* trans destroyed after rcu grace period */
} else {
nft_chain_commit_drop_policy(nft_trans_container_chain(trans));
@@ -10513,8 +10513,8 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
nft_trans_flowtable(trans),
&nft_trans_flowtable_hooks(trans),
NFT_MSG_NEWFLOWTABLE);
- list_splice(&nft_trans_flowtable_hooks(trans),
- &nft_trans_flowtable(trans)->hook_list);
+ list_splice_rcu(&nft_trans_flowtable_hooks(trans),
+ &nft_trans_flowtable(trans)->hook_list);
} else {
nft_clear(net, nft_trans_flowtable(trans));
nf_tables_flowtable_notify(&ctx,
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 456/877] x86/mce: Fix hardware debug register corruption on task migration
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (454 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 455/877] netfilter: nf_tables: join hook list via splice_list_rcu() in commit phase Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 457/877] x86/PCI: Disable enhanced atomics on AMD NBIO 7.7 and 7.11 Greg Kroah-Hartman
` (428 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Masami Hiramatsu (Google),
Borislav Petkov (AMD), Peter Zijlstra (Intel), stable
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
commit b8d1d5b63a8ef532038eebd9d97d406860385668 upstream.
In exc_machine_check_user(), local_db_save() and local_db_restore() are
invoked in the outer entry stubs (DEFINE_IDTENTRY_MCE_USER,
DEFINE_FREDENTRY_MCE, and DEFINE_IDTENTRY_RAW), surrounding
exc_machine_check_user().
However, exc_machine_check_user() calls irqentry_exit_to_user_mode(), which
handles pending thread work and may schedule() if TIF_NEED_RESCHED is set. If
the task migrates to another CPU during schedule(), local_db_restore() runs on
the new CPU with the dr7 state saved from the old CPU. This corrupts the new
CPU's DR7 hardware debug register and leaves the old CPU's DR7 disabled. In
short, local_db_save() and local_db_restore() pair must be run on the same
CPU.
To fix this, move local_db_save() and local_db_restore() inside
exc_machine_check_user() and exc_machine_check_kernel(). In
exc_machine_check_user(), DR7 is saved and restored strictly around
do_machine_check() to avoid schedule() during migration. In
exc_machine_check_kernel(), local_db_save() is called at the entry point to
prevent early memory accesses from triggering nested #DB exceptions, and
restored on all exits.
Fixes: cd840e424f27 ("x86/entry, mce: Disallow #DB during #MC")
Assisted-by: LLM
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: <stable@kernel.org>
Link: https://patch.msgid.link/179005109564.388919.3937970081044095776.stgit@devnote2
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/kernel/cpu/mce/core.c | 27 ++++++++++-----------------
1 file changed, 10 insertions(+), 17 deletions(-)
--- a/arch/x86/kernel/cpu/mce/core.c
+++ b/arch/x86/kernel/cpu/mce/core.c
@@ -2135,6 +2135,9 @@ bool filter_mce(struct mce *m)
static __always_inline void exc_machine_check_kernel(struct pt_regs *regs)
{
irqentry_state_t irq_state;
+ unsigned long dr7;
+
+ dr7 = local_db_save();
WARN_ON_ONCE(user_mode(regs));
@@ -2143,20 +2146,26 @@ static __always_inline void exc_machine_
* mce_check_crashing_cpu() for details.
*/
if (mca_cfg.initialized && mce_check_crashing_cpu())
- return;
+ goto out;
irq_state = irqentry_nmi_enter(regs);
do_machine_check(regs);
irqentry_nmi_exit(regs, irq_state);
+out:
+ local_db_restore(dr7);
}
static __always_inline void exc_machine_check_user(struct pt_regs *regs)
{
+ unsigned long dr7;
+
irqentry_enter_from_user_mode(regs);
+ dr7 = local_db_save();
do_machine_check(regs);
+ local_db_restore(dr7);
irqentry_exit_to_user_mode(regs);
}
@@ -2165,21 +2174,13 @@ static __always_inline void exc_machine_
/* MCE hit kernel mode */
DEFINE_IDTENTRY_MCE(exc_machine_check)
{
- unsigned long dr7;
-
- dr7 = local_db_save();
exc_machine_check_kernel(regs);
- local_db_restore(dr7);
}
/* The user mode variant. */
DEFINE_IDTENTRY_MCE_USER(exc_machine_check)
{
- unsigned long dr7;
-
- dr7 = local_db_save();
exc_machine_check_user(regs);
- local_db_restore(dr7);
}
#ifdef CONFIG_X86_FRED
@@ -2196,28 +2197,20 @@ DEFINE_IDTENTRY_MCE_USER(exc_machine_che
*/
DEFINE_FREDENTRY_MCE(exc_machine_check)
{
- unsigned long dr7;
-
- dr7 = local_db_save();
if (user_mode(regs))
exc_machine_check_user(regs);
else
exc_machine_check_kernel(regs);
- local_db_restore(dr7);
}
#endif
#else
/* 32bit unified entry point */
DEFINE_IDTENTRY_RAW(exc_machine_check)
{
- unsigned long dr7;
-
- dr7 = local_db_save();
if (user_mode(regs))
exc_machine_check_user(regs);
else
exc_machine_check_kernel(regs);
- local_db_restore(dr7);
}
#endif
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 457/877] x86/PCI: Disable enhanced atomics on AMD NBIO 7.7 and 7.11
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (455 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 456/877] x86/mce: Fix hardware debug register corruption on task migration Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 458/877] virtio_net: copy zerocopy frags in start_xmit without NAPI Greg Kroah-Hartman
` (427 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mikael Etienne, Arthur Husband,
Alvin Lim, Mario Limonciello, Bjorn Helgaas, David Laight,
John Smith, Lennert Buytenhek, Niklas Cassel, Roland Waltersson
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <mario.limonciello@amd.com>
commit 4fde448225123442c5796f54b7a4400e2d3cbaf6 upstream.
Multiple users report data corruption during 64-bit DMA transfers on
systems with AMD NBIO 7.7 and 7.11 controllers.
This occurs when BIOS enables AMD "enhanced atomic operations" on PCIe Root
Ports. When enhanced atomics are enabled, any 64-bit DMA access may be
corrupted.
Disable enhanced atomics using SMN for NBIO 7.7 and 7.11 based models.
Reported-by: Mikael Etienne <mikael1022bzh@gmail.com>
Closes: https://lore.kernel.org/178789300872.392066.15963676631650361573@gmail.com/
Reported-by: Arthur Husband <artmoty@gmail.com>
Closes: https://lore.kernel.org/20260406222335.379935-1-artmoty@gmail.com/
Reported-by: Alvin Lim <alvinwylim@gmail.com>
Closes: https://lore.kernel.org/20260621100844.1224301-1-alvinwylim@gmail.com/
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
[bhelgaas: commit log, s/IOVA/DMA/ in comment]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org
Cc: David Laight <david.laight.linux@gmail.com>
Cc: John Smith <imjohnsmith4000@gmail.com>
Cc: Lennert Buytenhek <kernel@wantstofly.org>
Cc: Niklas Cassel <cassel@kernel.org>
Cc: Roland Waltersson <roland.waltersson@netinsight.net>
Link: https://patch.msgid.link/20260908190600.226485-2-mario.limonciello@amd.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/pci/fixup.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 99 insertions(+)
--- a/arch/x86/pci/fixup.c
+++ b/arch/x86/pci/fixup.c
@@ -846,6 +846,105 @@ static void quirk_clear_strap_no_soft_re
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15b8, quirk_clear_strap_no_soft_reset_dev2_f0);
+
+/*
+ * Enhanced atomic operations can cause corruption with 64-bit DMA
+ * on these devices.
+ */
+#define RX_ENH_ATOMIC_EN BIT(8)
+
+static const u32 nbio_7_7_pcie_smn_addrs[] = {
+ 0x111401d0,
+ 0x111411d0,
+ 0x111421d0,
+ 0x111431d0,
+ 0x111441d0,
+ 0x112401d0,
+ 0x112411d0,
+ 0x112421d0,
+ 0x112431d0,
+ 0x112441d0,
+ 0x112451d0,
+ 0x113401d0,
+ 0x114401d0,
+};
+
+static const u32 nbio_7_11_pcie_smn_addrs[] = {
+ 0x112401d0,
+ 0x112411d0,
+ 0x112421d0,
+ 0x112431d0,
+ 0x112441d0,
+ 0x112451d0,
+ 0x113401d0,
+ 0x113411d0,
+ 0x113421d0,
+ 0x113431d0,
+ 0x113441d0,
+ 0x113451d0,
+};
+
+static void quirk_amd_nbio_enhanced_atomic(struct pci_dev *host_bridge,
+ const u32 *smn_addrs,
+ size_t nr_smn_addrs)
+{
+ bool changed = false;
+ size_t i;
+ u32 data;
+ int ret;
+
+ for (i = 0; i < nr_smn_addrs; i++) {
+ ret = amd_smn_read(0, smn_addrs[i], &data);
+ if (ret)
+ continue;
+ if (!(data & RX_ENH_ATOMIC_EN))
+ continue;
+ data = data & ~RX_ENH_ATOMIC_EN;
+ ret = amd_smn_write(0, smn_addrs[i], data);
+ if (ret)
+ continue;
+ if (changed)
+ continue;
+ ret = amd_smn_read(0, smn_addrs[i], &data);
+ if (ret)
+ continue;
+ if (data & RX_ENH_ATOMIC_EN)
+ continue;
+ changed = true;
+ }
+
+ if (changed)
+ pci_info(host_bridge, "enhanced atomics disabled\n");
+}
+
+static void quirk_amd_nbio_7_7_disable_enhanced_atomic(struct pci_dev *dev)
+{
+ quirk_amd_nbio_enhanced_atomic(dev, nbio_7_7_pcie_smn_addrs,
+ ARRAY_SIZE(nbio_7_7_pcie_smn_addrs));
+}
+
+static void quirk_amd_nbio_7_11_disable_enhanced_atomic(struct pci_dev *dev)
+{
+ quirk_amd_nbio_enhanced_atomic(dev, nbio_7_11_pcie_smn_addrs,
+ ARRAY_SIZE(nbio_7_11_pcie_smn_addrs));
+}
+
+/* Phoenix, Hawk Point (NBIO 7.7) */
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x14E8,
+ quirk_amd_nbio_7_7_disable_enhanced_atomic);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x14E8,
+ quirk_amd_nbio_7_7_disable_enhanced_atomic);
+
+/* Strix, Krackan, Strix Halo (NBIO 7.11) */
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1507,
+ quirk_amd_nbio_7_11_disable_enhanced_atomic);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1507,
+ quirk_amd_nbio_7_11_disable_enhanced_atomic);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1122,
+ quirk_amd_nbio_7_11_disable_enhanced_atomic);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1122,
+ quirk_amd_nbio_7_11_disable_enhanced_atomic);
+
#endif
/*
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 458/877] virtio_net: copy zerocopy frags in start_xmit without NAPI
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (456 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 457/877] x86/PCI: Disable enhanced atomics on AMD NBIO 7.7 and 7.11 Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 459/877] tipc: reject invalid and unexpected GRP_ACK_MSG to prevent bc_ackers underflow Greg Kroah-Hartman
` (426 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, mst, jasowangio, Willem de Bruijn,
Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Willem de Bruijn <willemb@google.com>
commit 07e1a9408b6c2f9d0cfb757b67dabb52da7a32b2 upstream.
Virtio-net without NAPI frees completed skbs lazily on the next
start_xmit. Senders waiting for in-flight zerocopy buffers can
deadlock if they cannot transmit more packets, as then no
completed packets will be freed.
When !use_napi, virtio-net already calls skb_orphan to avoid waiting
up for transmitted skbs to be freed. For zerocopy packets that
require deep copying on orphan (i.e. those that do not set
SKBFL_DONT_ORPHAN, such as PACKET_TX_RING), call skb_orphan_frags
before orphaning to release the buffers.
This fixes the tpacket_snd slot reuse bug on skb_orphan for
virtio-net, and prevents PACKET_TX_RING from running out of slots.
This fix also touches vhost_net zerocopy packets, which also do not
set SKBFL_DONT_ORPHAN. This is fine: vhost_net packets only encounter
virtio-net in nested virtualization, and only if napi_tx is
explicitly disabled (it has been default-enabled since Linux 4.12).
In that rare case, copying the frags is desirable anyway to prevent
holding guest descriptors pinned across unbounded intervals.
This is a prerequisite for the next patch, which converts
PACKET_TX_RING to standard zerocopy completion. Without this patch
first, a bounded ring sender can stall indefinitely behind a
virtio-net virtqueue that cannot reclaim.
Fixes: 5cd8d46ea156 ("packet: copy user buffers before orphan or clone")
Cc: stable@vger.kernel.org
Cc: mst@redhat.com
Cc: jasowangio@gmail.com
Signed-off-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260919004748.1463985-2-willemdebruijn.kernel@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/virtio_net.c | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -3141,6 +3141,14 @@ static netdev_tx_t start_xmit(struct sk_
} while (use_napi && !xmit_more &&
unlikely(!virtqueue_enable_cb_delayed(sq->vq)));
+ if (!use_napi &&
+ unlikely(skb_orphan_frags(skb, GFP_ATOMIC))) {
+ DEV_STATS_INC(dev, tx_dropped);
+ dev_kfree_skb_any(skb);
+ kick = !xmit_more || netif_xmit_stopped(txq);
+ goto kick_vq;
+ }
+
/* timestamp packet in software */
skb_tx_timestamp(skb);
@@ -3170,6 +3178,7 @@ static netdev_tx_t start_xmit(struct sk_
kick = use_napi ? __netdev_tx_sent_queue(txq, skb->len, xmit_more) :
!xmit_more || netif_xmit_stopped(txq);
+kick_vq:
if (kick) {
if (virtqueue_kick_prepare(sq->vq) && virtqueue_notify(sq->vq)) {
u64_stats_update_begin(&sq->stats.syncp);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 459/877] tipc: reject invalid and unexpected GRP_ACK_MSG to prevent bc_ackers underflow
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (457 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 458/877] virtio_net: copy zerocopy frags in start_xmit without NAPI Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 460/877] tcp: prevent collapsing skbs across boundary in rtx queue Greg Kroah-Hartman
` (425 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, James Burton, Eric Dumazet,
Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
commit 99cc2a62e07a44a22254d7beca9ef1f8ad886d0d upstream.
Commit 48a5fe38772b ("tipc: fix bc_ackers underflow on duplicate
GRP_ACK_MSG") rejected duplicate/stale ACKs in tipc_group_proto_rcv()
by returning early when less_eq(acked, m->bc_acked).
However, that check remains incomplete in two ways:
1. When grp->bc_ackers is zero (e.g. on a quiet group, when replicast
ACKs were not requested, or after all expected members have already
acknowledged), an unexpected GRP_ACK_MSG with acked > m->bc_acked
passes less_eq() and unconditionally decrements grp->bc_ackers.
Because bc_ackers is a u16, this wraps to 65535, causing
tipc_group_bc_cong() to permanently report congestion and blocking
all future group broadcasts on the socket.
2. During an active broadcast round (grp->bc_ackers > 0), the sender
transmits packet S and advances grp->bc_snd_nxt to S + 1. Receivers
increment their expected counter to S + 1 upon consuming packet S,
so the only valid ACK value for the current round is strictly
acked == grp->bc_snd_nxt.
However, tipc_group_update_bc_members() initializes each member's
m->bc_acked to prev = grp->bc_snd_nxt - 1 (S - 1 before increment).
This leaves a 2-sequence gap (S - 1 to S + 1) in sequence space.
An incoming ACK is therefore neither rejected as duplicate nor
prevented from decrementing grp->bc_ackers if an unexpected or stale
value (such as S) is received. A member sending acked = S followed
by acked = S + 1 could decrement grp->bc_ackers twice in the same
round, prematurely clearing bc_ackers or underflowing it.
Fix this by:
- Dropping GRP_ACK_MSG immediately if grp->bc_ackers is zero.
- Requiring acked == grp->bc_snd_nxt and rejecting duplicates where
m->bc_acked == acked. Because replicast broadcast rounds are strictly
sequential, only grp->bc_snd_nxt can be acknowledged, and each member
can acknowledge at most once per round.
Note that a related pre-existing issue in tipc_group_delete_member()
(where grp->bc_ackers decrementing to zero upon member departure does
not restore *grp->open or trigger a socket wakeup) will be addressed
in a separate patch.
Fixes: 48a5fe38772b ("tipc: fix bc_ackers underflow on duplicate GRP_ACK_MSG")
Fixes: 2f487712b893 ("tipc: guarantee that group broadcast doesn't bypass group unicast")
Reported-by: James Burton <jamesburton@meta.com>
Cc: stable@vger.kernel.org
Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260913044233.193927-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/tipc/group.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/net/tipc/group.c
+++ b/net/tipc/group.c
@@ -797,10 +797,10 @@ void tipc_group_proto_rcv(struct tipc_gr
tipc_group_open(m, usr_wakeup);
return;
case GRP_ACK_MSG:
- if (!m)
+ if (!m || !grp->bc_ackers)
return;
acked = msg_grp_bc_acked(hdr);
- if (less_eq(acked, m->bc_acked))
+ if (acked != grp->bc_snd_nxt || m->bc_acked == acked)
return;
m->bc_acked = acked;
if (--grp->bc_ackers)
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 460/877] tcp: prevent collapsing skbs across boundary in rtx queue
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (458 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 459/877] tipc: reject invalid and unexpected GRP_ACK_MSG to prevent bc_ackers underflow Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 461/877] sctp: discard the rest of the packet on a stale-cookie error Greg Kroah-Hartman
` (424 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Willem de Bruijn, Eric Dumazet,
Daniel Zahka, Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Willem de Bruijn <willemb@google.com>
commit fc6d80eb504458d6416b75a94188b268c95c6533 upstream.
tcp_write_collapse_fence() sets TCP_SKB_CB(skb)->eor = 1 on
tcp_write_queue_tail(sk) to prevent skbs queued after a switch to
device encryption from being collapsed into earlier skbs.
The fence is a no-op if all earlier data has already been transmitted
when the switch happens: sk->sk_write_queue is empty. The not yet
acknowledged earlier skbs wait in sk->tcp_rtx_queue with eor 0.
On a subsequent retransmit or SACK shift, tcp_retrans_try_collapse() or
tcp_shift_skb_data() can then merge an skb queued after the switch into
one queued before it.
Both users of the fence are affected:
- psp: devices only encrypt skbs with skb->decrypted set. The merged skb
keeps decrypted = 0 from the earlier skb, so merged data sent after
psp_sock_assoc_set_tx() is retransmitted in cleartext.
- tls device offload: the merged skb straddles the start marker set in
tls_set_device_offload(). The software fallback (fill_sg_in() returns
-EINVAL) and the mlx5, nfp and funeth drivers cannot handle such an
skb and drop it. Every retransmit rebuilds the same skb, so the
connection stalls.
Fix this in two places, for defense in depth:
1. Fall back to tcp_rtx_queue_tail(sk) in tcp_write_collapse_fence()
when tcp_write_queue_tail(sk) is NULL.
2. Check !skb_cmp_decrypted(to, from) in tcp_skb_can_collapse(), as
tcp_skb_can_collapse_rx() does on receive. skb_shift(), which both
collapse paths call, already has a DEBUG_NET_WARN_ON_ONCE() for this
condition.
Fixes: e8f69799810c ("net/tls: Add generic NIC offload infrastructure")
Cc: stable@vger.kernel.org
Signed-off-by: Willem de Bruijn <willemb@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Daniel Zahka <daniel.zahka@gmail.com>
Link: https://patch.msgid.link/20260924154427.953800-1-willemdebruijn.kernel@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/net/tcp.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1058,9 +1058,9 @@ static inline bool tcp_skb_can_collapse_
static inline bool tcp_skb_can_collapse(const struct sk_buff *to,
const struct sk_buff *from)
{
- /* skb_cmp_decrypted() not needed, use tcp_write_collapse_fence() */
return likely(tcp_skb_can_collapse_to(to) &&
mptcp_skb_can_collapse(to, from) &&
+ !skb_cmp_decrypted(to, from) &&
skb_pure_zcopy_same(to, from) &&
skb_frags_readable(to) == skb_frags_readable(from));
}
@@ -2119,7 +2119,7 @@ static inline void tcp_rtx_queue_unlink_
static inline void tcp_write_collapse_fence(struct sock *sk)
{
- struct sk_buff *skb = tcp_write_queue_tail(sk);
+ struct sk_buff *skb = tcp_write_queue_tail(sk) ?: tcp_rtx_queue_tail(sk);
if (skb)
TCP_SKB_CB(skb)->eor = 1;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 461/877] sctp: discard the rest of the packet on a stale-cookie error
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (459 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 460/877] tcp: prevent collapsing skbs across boundary in rtx queue Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 462/877] af_packet: fix integer overflow in prb_calc_retire_blk_tmo() Greg Kroah-Hartman
` (423 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xin Long, TencentOS Corvus AI,
Aohan Mei, Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aohan Mei <henrymei@tencent.com>
commit 4498467a8af06cfa3d71cb04bd7c4170dec8f449 upstream.
When an association is in COOKIE-ECHOED state and the peer sends a
bundled [ERROR(Stale Cookie)][DATA] packet from one of its non-primary
addresses, processing the ERROR chunk takes the non-fatal stale-cookie
retry path sctp_sf_do_5_2_6_stale(), which queues
SCTP_CMD_DEL_NON_PRIMARY while keeping the association alive.
sctp_cmd_del_non_primary() removes every non-primary transport -
including the very transport this packet arrived on, which is still
referenced by the receive lookup and shared by all chunks of the
packet via chunk->transport.
sctp_assoc_rm_peer() does redirect asoc->peer.last_data_from away from
the removed transport, but right afterwards the bundled DATA chunk
makes sctp_assoc_bh_rcv() re-register
asoc->peer.last_data_from = chunk->transport unconditionally, undoing
the redirection with the just-removed transport.
Once the packet is done, the receive reference is dropped and the
transport is RCU-freed, while the surviving association keeps the
dangling last_data_from. A later FWD-TSN (or the delayed SACK timer)
makes sctp_gen_sack() dereference it (->param_flags and friends), and
sctp_make_sack()/sctp_outq_select_transport() may write to the freed
object and link it into the live transport list. This is a
use-after-free triggerable by any malicious SCTP peer (or a local
unprivileged user acting as one) with no capabilities required:
BUG: KASAN: slab-use-after-free in sctp_do_sm+0x498a/0x5660
Read of size 4 at addr ffff88800e1e356c by task poc/115
Call Trace: sctp_do_sm <- sctp_assoc_bh_rcv <- sctp_inq_push <-
sctp_rcv <- ip_protocol_deliver_rcu <- ip_rcv
Allocated: sctp_transport_new <- sctp_assoc_add_peer <-
sctp_process_init (INIT-ACK processing)
Freed: kfree <- sctp_transport_destroy_rcu <- rcu_core
(call_rcu queued by sctp_transport_put at end of sctp_rcv)
The buggy address is located 364 bytes inside of freed 1024-byte
region [ffff88800e1e3400, ffff88800e1e3800), cache kmalloc-1k
Note that commit 03a9d10ecf71 ("sctp: drop a chunk if its transport
was removed") only covers the window between the receive lookup and
the chunk processing (e.g. an ASCONF DEL-IP racing the socket backlog);
here the transport is removed *while* the packet is being processed,
by an earlier chunk of the same packet, so the drop in sctp_inq_push()
does not reach this path. Verified with the bundled [ERROR(Stale
Cookie)][DATA] + FWD-TSN reproducer: the KASAN report above still
fires with that commit applied, and is gone with this patch on top.
Fix it by discarding the rest of the packet on this path, as suggested
by Xin. After the stale-cookie ERROR has sent the association back to
COOKIE-WAIT and removed the non-primary transports, the remaining
chunks of the packet can only run against the restarted handshake
while referencing the removed arrival transport through
chunk->transport: besides the last_data_from registration above,
sctp_cmd_setup_t2() and the sctp_make_*() reply builders would also
copy that pointer into association-lifetime state that
sctp_assoc_rm_peer() has already sanitized. Let the peer retransmit
them, in line with what sctp_inq_push() does for chunks whose
transport was removed before processing.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Suggested-by: Xin Long <lucien.xin@gmail.com>
Reported-by: TencentOS Corvus AI <corvus@tencent.com>
Cc: stable@vger.kernel.org
Signed-off-by: Aohan Mei <henrymei@tencent.com>
Acked-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/20260921093707.1432184-1-ljp1205831794@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/sctp/sm_statefuns.c | 2 ++
1 file changed, 2 insertions(+)
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -2624,6 +2624,8 @@ static enum sctp_disposition sctp_sf_do_
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
+ sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL());
+
return SCTP_DISPOSITION_CONSUME;
nomem:
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 462/877] af_packet: fix integer overflow in prb_calc_retire_blk_tmo()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (460 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 461/877] sctp: discard the rest of the packet on a stale-cookie error Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 463/877] ata: libata-scsi: bound the ATA passthru sense descriptor writes Greg Kroah-Hartman
` (422 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dairui Zhang, Willem de Bruijn,
Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dairui Zhang <zhangdairui@gmail.com>
commit 56d82862a0a243ac14ba11b6d7b57ddc2d064b95 upstream.
prb_calc_retire_blk_tmo() computes in 32-bit int arithmetic:
mbits = (blk_size_in_bytes * 8) / (1024 * 1024);
If I'm reading the validation right, tp_block_size is user
controlled and packet_set_ring() only rejects values that are <= 0
as int or not page aligned, so a 256MiB block goes right through
(and alloc_one_pg_vec_page() even has a vzalloc fallback for it).
0x10000000 * 8 wraps to INT_MIN, and on a NIC reporting 1 Gbps
(div == 1) the function ends up returning -2047.
The condition is actually (8 * size) mod 2^32 >= 2^31 && div == 1,
so the trigger set is [256,512), [768,1024), [1280,1536) and
[1792,2048) MiB. Other sizes wrap to non-negative values and faster
links divide the unsigned value back below 2^31, which is why this
doesn't blow up for everyone.
What makes it fatal is what happens next in init_prb_bdqc():
p1->interval_ktime = ms_to_ktime(prb_calc_retire_blk_tmo(...));
hrtimer_start(&p1->retire_blk_timer, p1->interval_ktime,
HRTIMER_MODE_REL_SOFT);
A negative relative timeout expires immediately. The callback
unconditionally returns HRTIMER_RESTART, and hrtimer_forward() turns
the negative interval into hrtimer_resolution:
if (interval < hrtimer_resolution)
interval = hrtimer_resolution;
So the SOFT timer re-fires at the maximum rate forever, holding
sk_receive_queue.lock each pass. One CPU spins in softirq until the
socket is closed. Repeat with more rings and the machine is gone.
The overflow itself is ancient - it was introduced together with
TPACKET_V3 in f6fb8f100b80 ("af-packet: TPACKET_V3 flexible buffer
implementation."). Its effect prior to f7460d2989fa ("net:
af_packet: Use hrtimer to do the retire operation", v6.18) was not
as clear-cut, though: the return value was stored into an unsigned
short retire_blk_tov, so a negative result was truncated, and a
0-jiffy delay loop could be programmed as well. Neither is nearly
as detrimental as the immediate maximum-rate spin the hrtimer
conversion turned it into.
(Unrelated to CVE-2019-20812 - that one was the ethtool failure path
returning 0, which now returns DEFAULT_PRB_RETIRE_TOV.)
Reproducer, needs CAP_NET_RAW (a --network host container has it by
default) and a 1 Gbps NIC (QEMU e1000 works):
int fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
bind(fd, ...);
int v = TPACKET_V3;
setsockopt(fd, SOL_PACKET, PACKET_VERSION, &v, sizeof(v));
struct tpacket_req3 req = {
.tp_block_size = 0x10000000,
.tp_block_nr = 1,
.tp_frame_size = 2048,
.tp_frame_nr = 0x10000000 / 2048,
.tp_retire_blk_tov = 0,
};
setsockopt(fd, SOL_PACKET, PACKET_RX_RING, &req, sizeof(req));
Compute in 64 bits instead. The operands are already bounded by the
existing validation, so nothing else changes. If you'd prefer a
different fix, just say so and I'll respin.
Fixes: f6fb8f100b80 ("af-packet: TPACKET_V3 flexible buffer implementation.")
Cc: stable@vger.kernel.org
Signed-off-by: Dairui Zhang <zhangdairui@gmail.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260923050101.1510064-1-zhangdairui@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/packet/af_packet.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -636,7 +636,7 @@ static int prb_calc_retire_blk_tmo(struc
return DEFAULT_PRB_RETIRE_TOV;
div = ecmd.base.speed / 1000;
- mbits = (blk_size_in_bytes * 8) / (1024 * 1024);
+ mbits = (u64)blk_size_in_bytes * 8 / (1024 * 1024);
if (div)
mbits /= div;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 463/877] ata: libata-scsi: bound the ATA passthru sense descriptor writes
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (461 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 462/877] af_packet: fix integer overflow in prb_calc_retire_blk_tmo() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 464/877] cgroup/pids: Restore pids.events notifications in local mode Greg Kroah-Hartman
` (421 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Damien Le Moal, Matthias Goergens,
Niklas Cassel
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthias Goergens <matthias.goergens@gmail.com>
commit 80320b278fea07ffcda3f57b67b61658e0a4e1ca upstream.
When an ATA PASS-THROUGH command to an ATAPI device fails, the sense
buffer holds the device's REQUEST SENSE reply, and
ata_scsi_set_passthru_sense_fields() trusts its additional length
byte, sb[7], when adding the ATA Status Return descriptor. A faulty
or malicious device can use that to make the kernel read and write
past the 96-byte buffer in three ways:
- scsi_sense_desc_find() is passed sb[7] + 8 as the buffer length, so
its clamp against sb[7] does nothing and the walk runs off the end.
- A type-9 descriptor found near the end is filled in unchecked.
- A new descriptor at sb[8 + len] needs len + 22 bytes, not len + 14,
so len 75..82 writes up to 8 bytes past the end.
Reproduced with KASAN under qemu, with the emulated ATAPI REQUEST SENSE
reply patched:
BUG: KASAN: slab-out-of-bounds in scsi_sense_desc_find+0x1a5/0x210
BUG: KASAN: slab-out-of-bounds in ata_scsi_qc_complete+0x1a15/0x1a50
Both are gone with this patch, and a valid descriptor is still filled
in.
Fixes: 97981926224a ("ata: libata-scsi: Do not overwrite valid sense data when CK_COND=1")
Cc: stable@vger.kernel.org
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Matthias Goergens <matthias.goergens@gmail.com>
Link: https://lore.kernel.org/r/20260923175203.1576825-1-matthias.goergens@gmail.com
Signed-off-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/ata/libata-scsi.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -257,12 +257,18 @@ static void ata_scsi_set_passthru_sense_
/* descriptor format */
len = sb[7];
- desc = (char *)scsi_sense_desc_find(sb, len + 8, 9);
+ desc = (char *)scsi_sense_desc_find(sb, SCSI_SENSE_BUFFERSIZE, 9);
if (!desc) {
- if (SCSI_SENSE_BUFFERSIZE < len + 14)
+ /*
+ * The descriptor is written at sb[8 + len] and is 14
+ * bytes long, so it needs len + 22 bytes of buffer.
+ */
+ if (len + 22 > SCSI_SENSE_BUFFERSIZE)
return;
sb[7] = len + 14;
desc = sb + 8 + len;
+ } else if (desc - sb > SCSI_SENSE_BUFFERSIZE - 14) {
+ return;
}
desc[0] = 9;
desc[1] = 12;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 464/877] cgroup/pids: Restore pids.events notifications in local mode
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (462 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 463/877] ata: libata-scsi: bound the ATA passthru sense descriptor writes Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 465/877] fou: reject omitted FOU_ATTR_IPPROTO on FOU_ENCAP_DIRECT Greg Kroah-Hartman
` (420 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guopeng Zhang, Tejun Heo
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guopeng Zhang <zhangguopeng@kylinos.cn>
commit 1765a153d985c231357145e26798f9408db10e42 upstream.
A fork rejected by the pids controller increments the counter reported by
pids.events. When local event accounting is selected, however, pids_event()
returns after notifying only events_local_file, leaving pids.events pollers
asleep.
On legacy hierarchies, pids.events.local does not exist. With
pids_localevents, pids.events reports the same local counter. In both
cases, pids.events changes without generating a notification.
This can be reproduced with a pids_localevents mount:
mkdir /tmp/test
mount -t cgroup2 -o pids_localevents none /tmp/test
mkdir /tmp/test/t
echo 1 > /tmp/test/t/pids.max
cat /tmp/test/t/pids.events # max 0
timeout 3 inotifywait -e modify /tmp/test/t/pids.events &
sh -c 'echo $$ > /tmp/test/t/cgroup.procs; (true &)' 2>/dev/null
wait
cat /tmp/test/t/pids.events # max 1
Without this patch, inotifywait times out without reporting an event.
Notify pids.events before returning from the local event path.
Fixes: 3f26a885a068 ("cgroup/pids: Add pids.events.local")
Cc: stable@vger.kernel.org # v6.11+
Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/cgroup/pids.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/kernel/cgroup/pids.c b/kernel/cgroup/pids.c
index ecbb839d2acb..78cdc0558d0c 100644
--- a/kernel/cgroup/pids.c
+++ b/kernel/cgroup/pids.c
@@ -253,6 +253,11 @@ static void pids_event(struct pids_cgroup *pids_forking,
}
if (!cgroup_subsys_on_dfl(pids_cgrp_subsys) ||
cgrp_dfl_root.flags & CGRP_ROOT_PIDS_LOCAL_EVENTS) {
+ /*
+ * pids.events reports the local counter on legacy hierarchies
+ * and when pids_localevents is enabled.
+ */
+ cgroup_file_notify(&p->events_file);
cgroup_file_notify(&p->events_local_file);
return;
}
--
2.55.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 465/877] fou: reject omitted FOU_ATTR_IPPROTO on FOU_ENCAP_DIRECT
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (463 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 464/877] cgroup/pids: Restore pids.events notifications in local mode Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 466/877] fs/ntfs3: use d_instantiate_new() in ntfs_create_inode() and murder syzbots "WARNING in do_new_mount" saga Greg Kroah-Hartman
` (419 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hui Peng, Hangbin Liu,
Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Peng <benquike@gmail.com>
commit d22609f3d13fc5baacd92c222731b03c593401db upstream.
Commit 7a9bc9e3f423 ("fou: Don't allow 0 for FOU_ATTR_IPPROTO.") added
NLA_POLICY_MIN(NLA_U8, 1) to fou_nl_policy[FOU_ATTR_IPPROTO], which
rejects an explicitly supplied FOU_ATTR_IPPROTO == 0 attribute with
-ERANGE.
However, FOU_ATTR_IPPROTO is an optional netlink attribute. When a user
sends FOU_CMD_ADD with FOU_ATTR_TYPE set to FOU_ENCAP_DIRECT and omits
FOU_ATTR_IPPROTO entirely, nla_policy validation succeeds and
parse_nl_config() leaves cfg->protocol as 0 (from memset(cfg, 0,
sizeof(*cfg))). fou_create() then creates a FOU_ENCAP_DIRECT socket with
fou->protocol == 0.
In fou_udp_recv(), returning -fou->protocol to udp_queue_rcv_one_skb()
triggers IP protocol resubmission when fou->protocol > 0, whereas
returning 0 tells the UDP tunnel layer that the skb was consumed without
freeing it. When fou->protocol == 0, every packet received on the socket
returns 0 from fou_udp_recv() and leaks the sk_buff.
Reject FOU_ENCAP_DIRECT when !cfg->protocol in fou_create() so that
creating a direct encapsulation port without FOU_ATTR_IPPROTO fails with
-EINVAL while leaving FOU_CMD_DEL and FOU_CMD_GET (which share
parse_nl_config()) unaffected.
Tested in QEMU against Linux 7.3.0-rc3 by sending a FOU_CMD_ADD Generic
Netlink request with FOU_ATTR_PORT = 5555 and FOU_ATTR_TYPE =
FOU_ENCAP_DIRECT while omitting FOU_ATTR_IPPROTO. On the unfixed kernel,
FOU_CMD_ADD succeeds (err = 0), FOU_CMD_GET reports fou->type = 1 and
fou->protocol = 0, and sending 4000 UDP packets to 127.0.0.1:5555 leaks
all 4000 sk_buffs (SUnreclaim in /proc/meminfo grows from 41456 kB to
59008 kB, +17552 kB); with this patch applied, FOU_CMD_ADD is rejected
with -EINVAL (-22).
Fixes: 23461551c006 ("fou: Support for foo-over-udp RX path")
Fixes: 7a9bc9e3f423 ("fou: Don't allow 0 for FOU_ATTR_IPPROTO.")
Cc: stable@vger.kernel.org
Signed-off-by: Hui Peng <benquike@gmail.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Link: https://patch.msgid.link/20260921045920.1613098-1-benquike@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/fou_core.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/net/ipv4/fou_core.c
+++ b/net/ipv4/fou_core.c
@@ -607,6 +607,10 @@ static int fou_create(struct net *net, s
/* Initial for fou type */
switch (cfg->type) {
case FOU_ENCAP_DIRECT:
+ if (!cfg->protocol) {
+ err = -EINVAL;
+ goto error;
+ }
tunnel_cfg.encap_rcv = fou_udp_recv;
tunnel_cfg.gro_receive = fou_gro_receive;
tunnel_cfg.gro_complete = fou_gro_complete;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 466/877] fs/ntfs3: use d_instantiate_new() in ntfs_create_inode() and murder syzbots "WARNING in do_new_mount" saga
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (464 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 465/877] fou: reject omitted FOU_ATTR_IPPROTO on FOU_ENCAP_DIRECT Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 467/877] writeback: bound cleanup_offline_cgwb() rescans by rotating scanned inodes Greg Kroah-Hartman
` (418 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jan Kara,
syzbot+2a13ad6914e6fcec716c, Christian Brauner (Amutable)
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit 1abd643f3783ea8f8e273c18697ff0413aa92dc7 upstream.
ntfs_create_inode() creates a new inode via ntfs_new_inode(). It hashes
it with insert_inode_locked() and so it's marked as I_NEW until
unlock_new_inode().
ntfs 3 calls d_instantiate() in between though... Since the dentry was
already hashed by the lookup before the create any path walk finds it
without touching the parent's i_rwsem and so can lock the inode.
If the inode is a directory unlock_new_inode() calls
lockdep_annotate_inode_mutex_key() and marks i_rwsem with the
i_mutex_dir_key class.
That resets the count and the owner of a lock somebody else may already
hold by now...
syzbot has been spamming us with the same godforsaken bug
"WARNING in do_new_mount"
since 2023. I can't take it anymore so I went looking. Afaict, syzbot's
executor chdirs into a freshly mounted ntfs3 image, creates a
directory and then mounts some pseudofs on it. Everytime the mkdir()
takes longer than syzbot waits mount() runs concurrently:
mkdir("./sys") mount(NULL, "./sys", "sysfs")
ntfs_create_inode()
d_instantiate()
user_path_at() finds the dentry
do_lock_mount()
inode_lock(inode)
namespace_lock()
unlock_new_inode()
lockdep_annotate_inode_mutex_key()
init_rwsem(&inode->i_rwsem)
unlock_mount()
inode_unlock(inode)
The mount side then releases a lock that according to the rwsem nobody
holds:
DEBUG_RWSEMS_WARN_ON((rwsem_owner(sem) != current) && ...):
count = 0x0, magic = 0xffff888043a854e8, owner = 0x0,
curr 0xffff888000244880, list empty
WARNING: CPU: 0 PID: 5346 at kernel/locking/rwsem.c:1368 __up_write
Call Trace:
inode_unlock include/linux/fs.h:877 [inline]
unlock_mount fs/namespace.c:2892 [inline]
do_new_mount_fc fs/namespace.c:3828 [inline]
do_new_mount+0x777/0xa40 fs/namespace.c:3887
On PREEMPT_RT the same thing shows up as
DEBUG_LOCKS_WARN_ON(rt_mutex_owner(lock) != current)
WARNING: kernel/locking/rtmutex_common.h:193 at rt_mutex_slowunlock
The up_write() underflows the reset count. A following inode_lock() on
that directory then never returns. A path walk into the new directory
racing with the mkdir() corrupts the lock the same way via
inode_lock_shared() in lookup_slow().
Switch to d_instantiate_new() and drop the trailing unlock_new_inode().
All error paths bail out before that point with I_NEW still set and
keep using discard_new_inode().
May we never see this fscking bug report again.
Link: https://patch.msgid.link/20260909-work-ntfs3-d_instantiate_new-v1-1-2db697162ce8@kernel.org
Fixes: 82cae269cfa9 ("fs/ntfs3: Add initialization of super block")
Reviewed-by: Jan Kara <jack@suse.cz>
Cc: stable@vger.kernel.org # v5.15+
Reported-by: syzbot+2a13ad6914e6fcec716c@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/6a9beced.a5e650b3.26d8a.000b.GAE@google.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/ntfs3/inode.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
--- a/fs/ntfs3/inode.c
+++ b/fs/ntfs3/inode.c
@@ -1677,10 +1677,10 @@ int ntfs_create_inode(struct mnt_idmap *
goto out6;
/*
- * Call 'd_instantiate' after inode->i_op is set
+ * Call 'd_instantiate_new' after inode->i_op is set
* but before finish_open.
*/
- d_instantiate(dentry, inode);
+ d_instantiate_new(dentry, inode);
/* Set original time. inode times (i_ctime) may be changed in ntfs_init_acl. */
inode_set_atime_to_ts(inode, ni->i_crtime);
@@ -1728,9 +1728,6 @@ out1:
if (!fnd)
ni_unlock(dir_ni);
- if (!err)
- unlock_new_inode(inode);
-
return err;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 467/877] writeback: bound cleanup_offline_cgwb() rescans by rotating scanned inodes
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (465 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 466/877] fs/ntfs3: use d_instantiate_new() in ntfs_create_inode() and murder syzbots "WARNING in do_new_mount" saga Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 468/877] workqueue: Fix NULL current_pwq deref in flush dependency check Greg Kroah-Hartman
` (417 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tejun Heo, Roman Gushchin,
Patrick Lu (Anthropic), Jan Kara, Christian Brauner (Amutable)
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Patrick Lu (Anthropic) <perf.patrick.lu@gmail.com>
commit f6988c90671e83db79df1b7b9d6fdb0e5947fd84 upstream.
cleanup_offline_cgwb() prepares at most WB_MAX_INODES_PER_ISW inodes
per call and is called again until the dying wb is drained, but every
call walks wb->b_attached and then wb->b_dirty_time from the same end.
Inodes already prepared (they stay on the list with I_WB_SWITCH set
until the switch worker runs) and inodes that cannot be switched
(I_FREEING, I_WILL_FREE, !SB_ACTIVE, DAX, already on the target wb)
stay where they are, so each pass rescans a growing run of them under
wb->list_lock and a full drain is quadratic in the number of inodes on
the list. With ~17M inodes attached to one dying cgwb we saw this end
in soft lockups, with CPUs reported stuck for 21-48s.
Walk both lists from the oldest end and move every scanned inode to
the newest end, so the next pass starts where the previous one stopped
and the drain becomes linear. b_attached is unordered, so nobody sees
the reorder there. b_dirty_time is ordered by dirtied_when, but the
oldest unscanned inode stays at the end move_expired_inodes() picks
from, sync takes the whole list regardless of order, and prepared
inodes leave the list as soon as the switch work runs and get a new
dirtied_time_when on the new wb anyway, so the only inodes left out of
order are the ones that can never switch (DAX), and only on the dying
wb.
Fixes: c22d70a162d3 ("writeback, cgroup: release dying cgwbs by switching attached inodes")
Cc: stable@vger.kernel.org
Acked-by: Tejun Heo <tj@kernel.org>
Acked-by: Roman Gushchin <roman.gushchin@linux.dev>
Signed-off-by: Patrick Lu (Anthropic) <perf.patrick.lu@gmail.com>
Link: https://patch.msgid.link/20260911-wb-cgwb-rotate-v2-1-a9ab253a1295@gmail.com
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/fs-writeback.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -693,19 +693,34 @@ static bool isw_prepare_wbs_switch(struc
struct inode_switch_wbs_context *isw,
struct list_head *list, int *nr)
{
- struct inode *inode;
+ struct inode *inode, *tmp;
+ LIST_HEAD(scanned);
+ bool full = false;
+
+ /*
+ * Walk from the oldest end and move scanned inodes to the newest
+ * end, so the next scan resumes at unscanned inodes instead of
+ * re-walking an ever-growing run of prepared and skipped ones.
+ * For b_dirty_time this keeps the oldest unscanned inode at the
+ * end move_expired_inodes() picks from; b_attached is unordered.
+ */
+ list_for_each_entry_safe_reverse(inode, tmp, list, i_io_list) {
+ list_move(&inode->i_io_list, &scanned);
- list_for_each_entry(inode, list, i_io_list) {
if (!inode_prepare_wbs_switch(inode, new_wb))
continue;
isw->inodes[*nr] = inode;
(*nr)++;
- if (*nr >= WB_MAX_INODES_PER_ISW - 1)
- return true;
+ if (*nr >= WB_MAX_INODES_PER_ISW - 1) {
+ full = true;
+ break;
+ }
}
- return false;
+ list_splice(&scanned, list);
+
+ return full;
}
/**
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 468/877] workqueue: Fix NULL current_pwq deref in flush dependency check
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (466 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 467/877] writeback: bound cleanup_offline_cgwb() rescans by rotating scanned inodes Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 469/877] writeback: report a Tasks-RCU quiescent state per cgwb drain pass Greg Kroah-Hartman
` (416 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Pavankumar Kondeti, Tejun Heo
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavankumar Kondeti <pavan.kondeti@oss.qualcomm.com>
commit db6365ced4d5855e321f772b240c0e473bcfcdd5 upstream.
check_flush_dependency() uses current_wq_worker() to determine whether
the caller is a workqueue worker and then dereferences worker->current_pwq
to test whether the current workqueue is WQ_MEM_RECLAIM.
current_wq_worker() only means that %current has PF_WQ_WORKER set. A
kworker can reach check_flush_dependency() while it is not executing a
work item. One such path is worker_thread() acting as the pool manager,
where create_worker() does GFP_KERNEL allocation and the allocation path
invokes the OOM notifier. In that state worker->current_pwq is NULL
because current_pwq is set only by process_one_work() and cleared again
after the work function returns.
[ 416.760634][ T375] Call trace:
[ 416.760638][ T375] check_flush_dependency+0x80/0x120 (P)
[ 416.760648][ T375] __flush_work+0x98/0x224
[ 416.760657][ T375] flush_work+0x30/0x44
[ 416.760665][ T375] ...
[ 416.760710][ T375] blocking_notifier_call_chain+0x58/0xa0
[ 416.760719][ T375] out_of_memory+0xb4/0x458
[ 416.760730][ T375] __alloc_pages_may_oom+0x11c/0x1a8
[ 416.760739][ T375] __alloc_pages_slowpath+0x314/0x46c
[ 416.760746][ T375] __alloc_frozen_pages_noprof+0x110/0x1a4
[ 416.760753][ T375] new_slab+0x12c/0x484
[ 416.760759][ T375] ___slab_alloc+0x7a8/0xc7c
[ 416.760765][ T375] __slab_alloc+0x74/0xd8
[ 416.760772][ T375] __kmalloc_cache_node_noprof+0x2ac/0x304
[ 416.760779][ T375] alloc_worker+0x28/0x60
[ 416.760785][ T375] create_worker+0x4c/0x20c
[ 416.760790][ T375] worker_thread+0xe8/0x2b8
[ 416.760796][ T375] kthread+0x1a8/0x200
[ 416.760805][ T375] ret_from_fork+0x10/0x20
Guard the WQ_MEM_RECLAIM-worker warning with worker->current_pwq. If the
kworker is not currently executing a work item, there is no current
workqueue to diagnose with that warning. The PF_MEMALLOC warning is left
unchanged so explicit reclaim context flushing a !WQ_MEM_RECLAIM target
is still reported.
Fixes: fca839c00a12 ("workqueue: warn if memory reclaim tries to flush !WQ_MEM_RECLAIM workqueue")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Pavankumar Kondeti <pavan.kondeti@oss.qualcomm.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/workqueue.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -3762,7 +3762,7 @@ static void check_flush_dependency(struc
WARN_ONCE(current->flags & PF_MEMALLOC,
"workqueue: PF_MEMALLOC task %d(%s) is flushing !WQ_MEM_RECLAIM %s:%ps",
current->pid, current->comm, target_wq->name, target_func);
- WARN_ONCE(worker && ((worker->current_pwq->wq->flags &
+ WARN_ONCE(worker && worker->current_pwq && ((worker->current_pwq->wq->flags &
(WQ_MEM_RECLAIM | __WQ_LEGACY)) == WQ_MEM_RECLAIM),
"workqueue: WQ_MEM_RECLAIM %s:%ps is flushing !WQ_MEM_RECLAIM %s:%ps",
worker->current_pwq->wq->name, worker->current_func,
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 469/877] writeback: report a Tasks-RCU quiescent state per cgwb drain pass
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (467 preceding siblings ...)
2026-09-30 15:22 ` [PATCH 6.12 468/877] workqueue: Fix NULL current_pwq deref in flush dependency check Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 470/877] fsl/fman: Fix clk reference leak in read_dts_node() Greg Kroah-Hartman
` (415 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Andrew Morton,
Tejun Heo, Roman Gushchin, Jan Kara, Lorenzo Stoakes (ARM),
David Hildenbrand, Dennis Zhou, Liam R. Howlett,
Matthew Wilcox (Oracle), Michal Hocko, Mike Rapoport,
Paul E . McKenney, Suren Baghdasaryan, Vlastimil Babka
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
commit 407a5d205179a4ab186571b0e16ec42725dc77bc upstream.
cleanup_offline_cgwbs_workfn() drains a dying cgwb by calling
cleanup_offline_cgwb() until it returns false, with a cond_resched()
between passes. On a CONFIG_PREEMPTION kernel that cond_resched() does
nothing: _cond_resched() is a plain "return 0", and under PREEMPT_DYNAMIC
the full and lazy modes disable it. Since commit 7dadeaa6e851 ("sched:
Further restrict the preemption modes") those are the only two models on
the architectures with PREEMPT_LAZY support, arm64 and x86 among them, so
the drain loop never reports a Tasks-RCU quiescent state.
A worker draining a cgwb with millions of attached inodes runs for
minutes. On a 6.18 arm64 host in lazy mode the cgwb worker drained one
dying cgroup's writeback domain for over 11 minutes. A BPF program unlink
(bpf_trampoline_unlink_prog -> bpf_trampoline_update ->
unregister_ftrace_direct -> ftrace_shutdown -> synchronize_rcu_tasks())
waited on that grace period while holding the trampoline mutex, 42 tasks
queued behind it in D state, and the hung task detector fired at 614 s and
panicked the host. Any BPF or ftrace detach during a long drain inherits
the drain's length.
Fix this by calling cond_resched_tasks_rcu_qs() so we do not stall out
anybody who calls sycnrhonize_rcu_tasks(). We put this in a do { } while
loop because if we have many small cgroups cleanup_offline_cgwb() will
return false and we will never call cond_resched_tasks_rcu_qs(), creating
the same problem.
Link: https://lore.kernel.org/20260909-cgwb-tasks-rcu-qs-v1-1-967a7754771f@toxicpanda.com
Fixes: c22d70a162d3 ("writeback, cgroup: release dying cgwbs by switching attached inodes")
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Link: https://lore.kernel.org/bpf/9d444098-7c03-4163-af12-bd0a79a51443@paulmck-laptop/
Assisted-by: LLM
Acked-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Roman Gushchin <roman.gushchin@linux.dev>
Reviewed-by: Jan Kara <jack@suse.cz>
Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Dennis Zhou <dennis@kernel.org>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: "Paul E . McKenney" <paulmck@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
mm/backing-dev.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -910,8 +910,9 @@ static void cleanup_offline_cgwbs_workfn
continue;
spin_unlock_irq(&cgwb_lock);
- while (cleanup_offline_cgwb(wb))
- cond_resched();
+ do {
+ cond_resched_tasks_rcu_qs();
+ } while (cleanup_offline_cgwb(wb));
spin_lock_irq(&cgwb_lock);
wb_put(wb);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 470/877] fsl/fman: Fix clk reference leak in read_dts_node()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (468 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 469/877] writeback: report a Tasks-RCU quiescent state per cgwb drain pass Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 471/877] ipe: protect the dm-verity root hash with RCU Greg Kroah-Hartman
` (414 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Simon Horman,
Paolo Abeni
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit a644f09b2090ad22a13fbcf9d141084f573108ef upstream.
of_clk_get() returns a clock with its reference count incremented, but
read_dts_node() only uses it to read the rate and never calls clk_put().
The clock is not stored anywhere, so the reference cannot be released
later either.
Release the clock once its rate has been read, which also covers the
error path taken when the rate is zero.
Fixes: 414fd46e7762 ("fsl/fman: Add FMan support")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260917110135.2148068-1-vulab@iscas.ac.cn
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/freescale/fman/fman.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -2747,6 +2747,7 @@ static struct fman *read_dts_node(struct
}
clk_rate = clk_get_rate(clk);
+ clk_put(clk);
if (!clk_rate) {
err = -EINVAL;
dev_err(&of_dev->dev, "%s: Failed to determine FM%d clock rate\n",
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 471/877] ipe: protect the dm-verity root hash with RCU
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (469 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 470/877] fsl/fman: Fix clk reference leak in read_dts_node() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 472/877] ipv6: do not let ipv6_find_hdr() return an offset past the packet end Greg Kroah-Hartman
` (413 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <wufan@kernel.org>
commit 2776e9c28513a1c855a94792b292cbcc533418c8 upstream.
ipe_bdev_setintegrity() frees the old root hash when dm-verity publishes
a new one on ->preresume, while policy evaluation can still be
dereferencing it.
Protect the root hash with RCU. The evaluation path already runs under
rcu_read_lock().
Fixes: e155858dd995 ("ipe: add support for dm-verity as a trust provider")
Cc: stable@vger.kernel.org
Assisted-by: LLM
[FW: remove model name according to latest guideline]
Signed-off-by: Fan Wu <wufan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
security/ipe/eval.c | 12 ++++++++----
security/ipe/eval.h | 2 +-
security/ipe/hooks.c | 22 +++++++++++++++++-----
3 files changed, 26 insertions(+), 10 deletions(-)
--- a/security/ipe/eval.c
+++ b/security/ipe/eval.c
@@ -134,10 +134,14 @@ static bool evaluate_boot_verified(const
static bool evaluate_dmv_roothash(const struct ipe_eval_ctx *const ctx,
struct ipe_prop *p)
{
- return !!ctx->ipe_bdev &&
- !!ctx->ipe_bdev->root_hash &&
- ipe_digest_eval(p->value,
- ctx->ipe_bdev->root_hash);
+ const struct digest_info *root_hash;
+
+ if (!ctx->ipe_bdev)
+ return false;
+
+ root_hash = rcu_dereference(ctx->ipe_bdev->root_hash);
+
+ return root_hash && ipe_digest_eval(p->value, root_hash);
}
#else
static bool evaluate_dmv_roothash(const struct ipe_eval_ctx *const ctx,
--- a/security/ipe/eval.h
+++ b/security/ipe/eval.h
@@ -27,7 +27,7 @@ struct ipe_bdev {
#ifdef CONFIG_IPE_PROP_DM_VERITY_SIGNATURE
bool dm_verity_signed;
#endif /* CONFIG_IPE_PROP_DM_VERITY_SIGNATURE */
- struct digest_info *root_hash;
+ struct digest_info __rcu *root_hash;
};
#endif /* CONFIG_IPE_PROP_DM_VERITY */
--- a/security/ipe/hooks.c
+++ b/security/ipe/hooks.c
@@ -9,6 +9,7 @@
#include <linux/binfmts.h>
#include <linux/mman.h>
#include <linux/blk_types.h>
+#include <linux/rcupdate.h>
#include "ipe.h"
#include "hooks.h"
@@ -204,7 +205,20 @@ void ipe_bdev_free_security(struct block
{
struct ipe_bdev *blob = ipe_bdev(bdev);
- ipe_digest_free(blob->root_hash);
+ ipe_digest_free(rcu_access_pointer(blob->root_hash));
+}
+
+static void ipe_set_dmverity_roothash(struct ipe_bdev *blob,
+ struct digest_info *info)
+{
+ struct digest_info *old;
+
+ /* Protected by device-mapper's md->suspend_lock */
+ old = rcu_replace_pointer(blob->root_hash, info, true);
+ if (old) {
+ synchronize_rcu();
+ ipe_digest_free(old);
+ }
}
#ifdef CONFIG_IPE_PROP_DM_VERITY_SIGNATURE
@@ -252,8 +266,7 @@ int ipe_bdev_setintegrity(struct block_d
return -EINVAL;
if (!value) {
- ipe_digest_free(blob->root_hash);
- blob->root_hash = NULL;
+ ipe_set_dmverity_roothash(blob, NULL);
return 0;
}
@@ -273,8 +286,7 @@ int ipe_bdev_setintegrity(struct block_d
info->digest_len = digest->digest_len;
- ipe_digest_free(blob->root_hash);
- blob->root_hash = info;
+ ipe_set_dmverity_roothash(blob, info);
return 0;
err:
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 472/877] ipv6: do not let ipv6_find_hdr() return an offset past the packet end
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (470 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 471/877] ipe: protect the dm-verity root hash with RCU Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 473/877] ipv6: sr: enforce exact attribute length for SEG6_ATTR_DST Greg Kroah-Hartman
` (412 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ilya Maximets, Eric Dumazet,
Norbert Szetei, Ido Schimmel, Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Norbert Szetei <norbert@doyensec.com>
commit ee319bd3a0e976af5087cbe59ebc50a66f31d202 upstream.
ipv6_find_hdr() walks the extension header chain, skipping each header by
the length that header itself declares. ipv6_optlen() returns up to 2048,
and the skip is never checked against skb->len, so the offset stored in
*offset can point past the end of the packet.
openvswitch installs that offset as the transport header, and
update_ipv6_checksum() then reads and writes the transport checksum field
out of bounds:
BUG: KASAN: slab-use-after-free in inet_proto_csum_replace16+0x445/0x470
Read of size 2 at addr ffff88810b754b06 by task ovs_ipv6_oob/629
CPU: 4 UID: 1000 PID: 629 Comm: ovs_ipv6_oob Tainted: G N 7.3.0-rc3+ #348
Call Trace:
inet_proto_csum_replace16+0x445/0x470
set_ipv6_addr+0x3dd/0x460
do_execute_actions+0x6a3d/0x7c40
ovs_execute_actions+0xfd/0x480
ovs_packet_cmd_execute+0xc38/0xf20
genl_rcv_msg+0x59e/0x870
netlink_rcv_skb+0x18b/0x450
genl_rcv+0x2d/0x40
netlink_unicast+0x6bc/0xa20
The buggy address belongs to the object at ffff88810b754980
which belongs to the cache skbuff_small_head of size 704
The buggy address is located 390 bytes inside of
freed 704-byte region [ffff88810b754980, ffff88810b754c40)
Other callers use that offset too, so bound it here rather than in one
caller.
Reject a header whose declared length does not fit in the packet.
ipv6_find_hdr() already fails with -EBADMSG on a malformed chain, so this
adds no new failure mode.
Fixes: f8f626754ebe ("ipv6: Move ipv6_find_hdr() out of Netfilter code.")
Suggested-by: Ilya Maximets <i.maximets@ovn.org>
Suggested-by: Eric Dumazet <edumazet@google.com>
Cc: stable@vger.kernel.org
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Ilya Maximets <i.maximets@ovn.org>
Link: https://patch.msgid.link/8F80BA1A-DDFD-432D-9075-242A3435FEB5@doyensec.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv6/exthdrs_core.c | 3 +++
1 file changed, 3 insertions(+)
--- a/net/ipv6/exthdrs_core.c
+++ b/net/ipv6/exthdrs_core.c
@@ -271,6 +271,9 @@ int ipv6_find_hdr(const struct sk_buff *
hdrlen = ipv6_optlen(hp);
if (!found) {
+ if (skb->len - start < hdrlen)
+ return -EBADMSG;
+
nexthdr = hp->nexthdr;
start += hdrlen;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 473/877] ipv6: sr: enforce exact attribute length for SEG6_ATTR_DST
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (471 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 472/877] ipv6: do not let ipv6_find_hdr() return an offset past the packet end Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 474/877] gpio: arizona: Fix runtime PM leak in arizona_gpio_direction_out() Greg Kroah-Hartman
` (411 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hui Peng, Hangbin Liu, Justin Iurman,
Andrea Mayer, Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Peng <benquike@gmail.com>
commit 2d959c75c27f90e9ec489d18ce5ee6b852ad4741 upstream.
In seg6_genl_policy, SEG6_ATTR_DST is defined with .type = NLA_BINARY and
.len = sizeof(struct in6_addr). For NLA_BINARY, .len only enforces the
maximum payload length and permits shorter payloads (e.g., 0 bytes).
When seg6_genl_set_tunsrc() copies sizeof(struct in6_addr) bytes via
kmemdup(val, sizeof(*val), GFP_KERNEL), a short SEG6_ATTR_DST attribute
triggers a 16-byte out-of-bounds read past skb->tail into uninitialized
skb->head memory, which is stored in sdata->tun_src and leaked back to
userspace via SEG6_CMD_GET_TUNSRC.
Switch SEG6_ATTR_DST in seg6_genl_policy to
NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)) so that generic netlink
validation rejects any attribute whose length is not exactly
sizeof(struct in6_addr) with -ERANGE.
Tested in QEMU against Linux 7.3.0-rc3 by sending a SEG6_CMD_SET_TUNSRC
Generic Netlink message with a 0-byte SEG6_ATTR_DST attribute followed
by SEG6_CMD_GET_TUNSRC. On the unfixed kernel, SEG6_CMD_SET_TUNSRC
succeeds (err = 0) and SEG6_CMD_GET_TUNSRC leaks 16 bytes of
uninitialized kernel heap memory (tun_src =
836a61ecc4d25a1042a8d60411cfb378); with this patch applied,
SEG6_CMD_SET_TUNSRC is rejected by netlink policy validation with
-ERANGE (-34) and tun_src remains zeroed.
Fixes: 915d7e5e5930 ("ipv6: sr: add code base for control plane support of SR-IPv6")
Cc: stable@vger.kernel.org
Signed-off-by: Hui Peng <benquike@gmail.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Reviewed-by: Justin Iurman <justin.iurman@gmail.com>
Reviewed-by: Andrea Mayer <andrea.mayer@uniroma2.it>
Link: https://patch.msgid.link/20260921044025.1535982-1-benquike@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv6/seg6.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/net/ipv6/seg6.c
+++ b/net/ipv6/seg6.c
@@ -138,8 +138,8 @@ out:
static struct genl_family seg6_genl_family;
static const struct nla_policy seg6_genl_policy[SEG6_ATTR_MAX + 1] = {
- [SEG6_ATTR_DST] = { .type = NLA_BINARY,
- .len = sizeof(struct in6_addr) },
+ [SEG6_ATTR_DST] =
+ NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
[SEG6_ATTR_DSTLEN] = { .type = NLA_S32, },
[SEG6_ATTR_HMACKEYID] = { .type = NLA_U32, },
[SEG6_ATTR_SECRET] = { .type = NLA_BINARY, },
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 474/877] gpio: arizona: Fix runtime PM leak in arizona_gpio_direction_out()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (472 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 473/877] ipv6: sr: enforce exact attribute length for SEG6_ATTR_DST Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 475/877] gpio: zynq: fix runtime PM leak on request error path Greg Kroah-Hartman
` (410 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Wentao Liang, Charles Keepax,
Bartosz Golaszewski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit e9d810279f84b30738f7790c0ed15f8dd5b9024a upstream.
Switching a persistent GPIO line from input to output acquires a
runtime PM reference on the parent device, but if the subsequent
regmap_update_bits() fails the reference is never dropped and no later
direction_in() can balance it since the direction was never changed.
Drop the reference on the update failure path.
Fixes: 27a49ed17e22 ("gpio: arizona: Add support for GPIOs that need to be maintained")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://patch.msgid.link/20260916094701.2007509-1-vulab@iscas.ac.cn
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpio/gpio-arizona.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
--- a/drivers/gpio/gpio-arizona.c
+++ b/drivers/gpio/gpio-arizona.c
@@ -117,8 +117,12 @@ static int arizona_gpio_direction_out(st
if (value)
value = ARIZONA_GPN_LVL;
- return regmap_update_bits(arizona->regmap, ARIZONA_GPIO1_CTRL + offset,
- ARIZONA_GPN_DIR | ARIZONA_GPN_LVL, value);
+ ret = regmap_update_bits(arizona->regmap, ARIZONA_GPIO1_CTRL + offset,
+ ARIZONA_GPN_DIR | ARIZONA_GPN_LVL, value);
+ if (ret < 0 && (val & ARIZONA_GPN_DIR) && persistent)
+ pm_runtime_put_autosuspend(chip->parent);
+
+ return ret;
}
static void arizona_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 475/877] gpio: zynq: fix runtime PM leak on request error path
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (473 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 474/877] gpio: arizona: Fix runtime PM leak in arizona_gpio_direction_out() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 476/877] llc: reserve device headroom for allocated frames Greg Kroah-Hartman
` (409 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ridham Khurana, Bartosz Golaszewski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ridham Khurana <khurana.ridham222@gmail.com>
commit e9438ab5328a177c9c0e5df87eb92a7162841e98 upstream.
pm_runtime_get_sync() leaves the usage counter incremented even when it
fails, and zynq_gpio_request() returns the error without dropping it.
gpiolib does not call ->free() when ->request() fails, so zynq_gpio_free(),
which holds the only matching pm_runtime_put(), never runs. The reference
is leaked and the controller can no longer runtime-suspend, so its clock
stays enabled.
Switch to pm_runtime_resume_and_get(), which only increments the usage
counter on success.
Fixes: 3242ba117e9b ("gpio: Add driver for Zynq GPIO controller")
Cc: stable@vger.kernel.org
Signed-off-by: Ridham Khurana <khurana.ridham222@gmail.com>
Link: https://patch.msgid.link/20260922092102.1053513-1-khurana.ridham222@gmail.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpio/gpio-zynq.c | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
--- a/drivers/gpio/gpio-zynq.c
+++ b/drivers/gpio/gpio-zynq.c
@@ -795,15 +795,7 @@ static int __maybe_unused zynq_gpio_runt
static int zynq_gpio_request(struct gpio_chip *chip, unsigned int offset)
{
- int ret;
-
- ret = pm_runtime_get_sync(chip->parent);
-
- /*
- * If the device is already active pm_runtime_get() will return 1 on
- * success, but gpio_request still needs to return 0.
- */
- return ret < 0 ? ret : 0;
+ return pm_runtime_resume_and_get(chip->parent);
}
static void zynq_gpio_free(struct gpio_chip *chip, unsigned int offset)
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 476/877] llc: reserve device headroom for allocated frames
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (474 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 475/877] gpio: zynq: fix runtime PM leak on request error path Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 477/877] mctp: route: iterate socket tag list in mctp_lookup_prealloc_tag() Greg Kroah-Hartman
` (408 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, VEGA, Zixuan Chai, Ren Wei,
Eric Dumazet, Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zixuan Chai <petalzu987@gmail.com>
commit 72b5b9a28b996e09b8b5b944370c79851bb68f52 upstream.
llc_alloc_frame() reserves link-layer headroom using the device type.
This is insufficient for stacked Ethernet devices such as VLAN devices,
where vlan_dev_hard_header() pushes a VLAN header before the lower
device's Ethernet header. An LLC response on such a device can
therefore underflow skb headroom in eth_header().
Use LL_RESERVED_SPACE() to account for the device's actual required
headroom while preserving the existing LLC device-type check.
Fixes: bf9ae5386bca ("llc: use dev_hard_header")
Cc: stable@vger.kernel.org
Reported-by: VEGA <vega@nebusec.ai>
Signed-off-by: Zixuan Chai <petalzu987@gmail.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260924012613.2533934-1-weir@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/llc/llc_sap.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/net/llc/llc_sap.c
+++ b/net/llc/llc_sap.c
@@ -25,12 +25,12 @@
#include <linux/llc.h>
#include <linux/slab.h>
-static int llc_mac_header_len(unsigned short devtype)
+static int llc_mac_header_len(struct net_device *dev)
{
- switch (devtype) {
+ switch (dev->type) {
case ARPHRD_ETHER:
case ARPHRD_LOOPBACK:
- return sizeof(struct ethhdr);
+ return LL_RESERVED_SPACE(dev);
}
return 0;
}
@@ -51,7 +51,7 @@ struct sk_buff *llc_alloc_frame(struct s
int hlen = type == LLC_PDU_TYPE_U ? 3 : 4;
struct sk_buff *skb;
- hlen += llc_mac_header_len(dev->type);
+ hlen += llc_mac_header_len(dev);
skb = alloc_skb(hlen + data_size, GFP_ATOMIC);
if (skb) {
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 477/877] mctp: route: iterate socket tag list in mctp_lookup_prealloc_tag()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (475 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 476/877] llc: reserve device headroom for allocated frames Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 478/877] rds: ib: Clear the sg list when mapping an MR fails Greg Kroah-Hartman
` (407 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jeremy Kerr, Hui Peng,
Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Peng <benquike@gmail.com>
commit 26cc0e69cce062cd3aa6fae33074684669c35a71 upstream.
When a socket transmits a packet with MCTP_TAG_PREALLOC set,
mctp_lookup_prealloc_tag() iterates over the per-netns &mns->keys list
and matches netid, req_tag, peer_addr, and manual_alloc, without
checking whether tmp->sk == &msk->sk. This allows any MCTP socket in the
same network namespace to use and consume another socket's preallocated
tag.
Iterate the socket's own tag list (&msk->keys via sklist) instead of the
namespace-wide &mns->keys list in mctp_lookup_prealloc_tag(), ensuring
that only tags allocated by msk are matched.
Tested in QEMU against Linux 7.3.0-rc3 by allocating a manual tag
(0x18) on socket A via SIOCMCTPALLOCTAG for peer EID 9 and sending a
4-byte message with MCTP_TAG_PREALLOC from socket B in the same network
namespace. On the unfixed kernel, sendto(sock_b) using socket A's
preallocated tag succeeds (ret = 4); with this patch applied,
sendto(sock_b) fails with -ENOENT (errno = 2) while sendto(sock_a)
succeeds (ret = 4).
Fixes: 63ed1aab3d40 ("mctp: Add SIOCMCTP{ALLOC,DROP}TAG ioctls for tag control")
Suggested-by: Jeremy Kerr <jk@codeconstruct.com.au>
Cc: stable@vger.kernel.org
Signed-off-by: Hui Peng <benquike@gmail.com>
Link: https://patch.msgid.link/20260921051002.1656692-1-benquike@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/mctp/route.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/mctp/route.c
+++ b/net/mctp/route.c
@@ -775,7 +775,7 @@ static struct mctp_sk_key *mctp_lookup_p
spin_lock_irqsave(&mns->keys_lock, flags);
- hlist_for_each_entry(tmp, &mns->keys, hlist) {
+ hlist_for_each_entry(tmp, &msk->keys, sklist) {
if (tmp->net != netid)
continue;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 478/877] rds: ib: Clear the sg list when mapping an MR fails
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (476 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 477/877] mctp: route: iterate socket tag list in mctp_lookup_prealloc_tag() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 479/877] drm/imagination: Propagate map failures correctly from pvr_mmu_map_sgl() Greg Kroah-Hartman
` (406 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dongliang Qin, Allison Henderson,
Paolo Abeni
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dongliang Qin <cccccccccccc777777@gmail.com>
commit 58eb1b3325edac42dc6df72c80962bd53a3c8ca7 upstream.
rds_ib_map_frmr() stores the caller's scatterlist in the MR before DMA
mapping and registration can fail. On failure, __rds_rdma_map() unpins
the pages and frees the scatterlist, but rds_ib_free_frmr() can still
return the MR to the pool with the stale pointer set.
This leaves the pool with a dangling scatterlist and can lead to local
privilege escalation. KASAN detects the resulting use-after-free when the
MR is later torn down:
BUG: KASAN: slab-use-after-free in __rds_ib_teardown_mr
Read of size 8
Call Trace:
__rds_ib_teardown_mr
rds_ib_unreg_frmr
rds_ib_flush_mr_pool
rds_ib_flush_mrs
rds_free_mr
rds_setsockopt
Store the scatterlist in the MR only after DMA mapping succeeds. If DMA
mapping fails, return directly while the MR fields remain clear; the caller
keeps ownership of the scatterlist and its pinned pages. If a later
registration step fails, unmap the scatterlist and clear the MR fields
before returning.
Fixes: 1659185fb4d0 ("RDS: IB: Support Fastreg MR (FRMR) memory registration mode")
Cc: stable@vger.kernel.org
Signed-off-by: Dongliang Qin <cccccccccccc777777@gmail.com>
Reviewed-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20260922031546.3874605-1-cccccccccccc777777@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/rds/ib_frmr.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
--- a/net/rds/ib_frmr.c
+++ b/net/rds/ib_frmr.c
@@ -204,19 +204,16 @@ static int rds_ib_map_frmr(struct rds_ib
*/
rds_ib_teardown_mr(ibmr);
- ibmr->sg = sg;
- ibmr->sg_len = sg_len;
- ibmr->sg_dma_len = 0;
frmr->sg_byte_len = 0;
- WARN_ON(ibmr->sg_dma_len);
- ibmr->sg_dma_len = ib_dma_map_sg(dev, ibmr->sg, ibmr->sg_len,
+ ibmr->sg_dma_len = ib_dma_map_sg(dev, sg, sg_len,
DMA_BIDIRECTIONAL);
if (unlikely(!ibmr->sg_dma_len)) {
pr_warn("RDS/IB: %s failed!\n", __func__);
return -EBUSY;
}
- frmr->sg_byte_len = 0;
+ ibmr->sg = sg;
+ ibmr->sg_len = sg_len;
frmr->dma_npages = 0;
len = 0;
@@ -264,6 +261,8 @@ out_unmap:
ib_dma_unmap_sg(rds_ibdev->dev, ibmr->sg, ibmr->sg_len,
DMA_BIDIRECTIONAL);
ibmr->sg_dma_len = 0;
+ ibmr->sg = NULL;
+ ibmr->sg_len = 0;
return ret;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 479/877] drm/imagination: Propagate map failures correctly from pvr_mmu_map_sgl()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (477 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 478/877] rds: ib: Clear the sg list when mapping an MR fails Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 480/877] drm/imagination: Fix page count for page table for map() interface Greg Kroah-Hartman
` (405 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alexandru Dadu, Alessio Belle,
Brajesh Gupta
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brajesh Gupta <brajesh.gupta@imgtec.com>
commit 7b824c293a6b56de8285a97984c507cba56bc4c4 upstream.
Map failure from pvr_mmu_map_sgl() interface was not returned correctly
to pvr_mmu_map() interface. This resulted in pvr_mmu_map() interface to
continue instead of returning an error to caller.
Fix it by returning a proper error code from pvr_mmu_map_sgl() interface.
Call stack for crash:
[ 1179.286237] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008
[ 1179.295067] Mem abort info:
[ 1179.297877] ESR = 0x0000000096000004
[ 1179.301656] EC = 0x25: DABT (current EL), IL = 32 bits
[ 1179.306987] SET = 0, FnV = 0
[ 1179.310048] EA = 0, S1PTW = 0
[ 1179.313198] FSC = 0x04: level 0 translation fault
[ 1179.318096] Data abort info:
[ 1179.320993] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
[ 1179.326483] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[ 1179.331546] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[ 1179.336895] user pgtable: 4k pages, 48-bit VAs, pgdp=000000009822a000
[ 1179.343402] [0000000000000008] pgd=0000000000000000, p4d=0000000000000000
[ 1179.350243] Internal error: Oops: 0000000096000004 [#2] SMP
[ 1179.355908] Modules linked in: powervr gpu_sched drm_shmem_helper drm_gpuvm drm_exec xhci_plat_hcd xhci_hcd dwc3 usbcore usb_common snd_soc_simple_card snd_soc_simple_card_utils dwc3_am62 at24 sa2ul sha512 libsha512 sha256 authenc sch_fq_codel fuse dm_mod ipv6
[ 1179.378992] CPU: 1 UID: 1000 PID: 680 Comm: deqp-vk Tainted: G D 6.17.0 #1 PREEMPT
[ 1179.388120] Tainted: [D]=DIE
[ 1179.390994] Hardware name: Texas Instruments AM625 SK (DT)
[ 1179.396467] pstate: 00000005 (nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 1179.403415] pc : pvr_mmu_op_context_unmap_curr_page+0x6c/0x134 [powervr]
[ 1179.410140] lr : pvr_mmu_op_context_unmap_curr_page+0x58/0x134 [powervr]
[ 1179.416848] sp : ffff8000839ab8c0
[ 1179.420153] x29: ffff8000839ab8c0 x28: 0000000000000001 x27: 000000008f386000
[ 1179.427283] x26: ffff000016d1df98 x25: 0000000000247000 x24: 00000000000001e6
[ 1179.434413] x23: 0000000000000002 x22: 000000000000ffff x21: 0000000000000247
[ 1179.441540] x20: 0000000000000245 x19: ffff000016d1df60 x18: 0000000000000002
[ 1179.448668] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000001
[ 1179.455793] x14: 0000000000060810 x13: ffff80007fffffff x12: ffff000004190480
[ 1179.462921] x11: ffff8000853f7000 x10: ffff8000811ae000 x9 : ffff0000041900b8
[ 1179.470051] x8 : 0000000000000000 x7 : 00000000990c4001 x6 : 0000000000000007
[ 1179.477177] x5 : ffff000016d1df60 x4 : 0000000000000000 x3 : ffff00000a7d8000
[ 1179.484306] x2 : 00000000000001ff x1 : 0000000000000000 x0 : 0000000000000000
[ 1179.491433] Call trace:
[ 1179.493872] pvr_mmu_op_context_unmap_curr_page+0x6c/0x134 [powervr] (P)
[ 1179.500582] pvr_mmu_map+0x31c/0x388 [powervr]
[ 1179.505027] pvr_vm_gpuva_map+0x40/0x88 [powervr]
[ 1179.509732] __drm_gpuvm_sm_map+0x250/0x44c [drm_gpuvm]
[ 1179.514952] drm_gpuvm_sm_map+0x48/0x5c [drm_gpuvm]
[ 1179.519822] pvr_vm_bind_op_exec+0x64/0x70 [powervr]
[ 1179.524785] pvr_vm_map+0x1f8/0x2a8 [powervr]
[ 1179.529142] pvr_ioctl_vm_map+0x12c/0x188 [powervr]
[ 1179.534018] drm_ioctl_kernel+0xb8/0x128
[ 1179.537941] drm_ioctl+0x21c/0x4ec
[ 1179.541337] __arm64_sys_ioctl+0xac/0x108
[ 1179.545344] invoke_syscall+0x44/0x100
[ 1179.549091] el0_svc_common.constprop.0+0x40/0xe0
[ 1179.553790] do_el0_svc+0x1c/0x28
[ 1179.557106] el0_svc+0x34/0xf0
[ 1179.560159] el0t_64_sync_handler+0xd0/0xe4
[ 1179.564334] el0t_64_sync+0x198/0x19c
[ 1179.567996] Code: 54000300 35000360 f9402261 79409a62 (f9400421)
[ 1179.574081] ---[ end trace 0000000000000000 ]---
Fixes: ff5f643de0bf ("drm/imagination: Add GEM and VM related code")
Reviewed-by: Alexandru Dadu <alexandru.dadu@imgtec.com>
Reviewed-by: Alessio Belle <alessio.belle@imgtec.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260922-mmu_fix-v4-1-12f1a871456a@imgtec.com
Signed-off-by: Brajesh Gupta <brajesh.gupta@imgtec.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/imagination/pvr_mmu.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/imagination/pvr_mmu.c
+++ b/drivers/gpu/drm/imagination/pvr_mmu.c
@@ -12,6 +12,7 @@
#include "pvr_rogue_mmu_defs.h"
#include <drm/drm_drv.h>
+#include <drm/drm_print.h>
#include <linux/atomic.h>
#include <linux/bitops.h>
#include <linux/dma-mapping.h>
@@ -2550,7 +2551,9 @@ pvr_mmu_map_sgl(struct pvr_mmu_op_contex
err_destroy_pages:
memcpy(&op_ctx->curr_page, &ptr_copy, sizeof(op_ctx->curr_page));
- err = pvr_mmu_op_context_unmap_curr_page(op_ctx, page);
+ if (pvr_mmu_op_context_unmap_curr_page(op_ctx, page))
+ drm_err(from_pvr_device(op_ctx->mmu_ctx->pvr_dev),
+ "%s : Failure in unmapping pages\n", __func__);
return err;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 480/877] drm/imagination: Fix page count for page table for map() interface
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (478 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 479/877] drm/imagination: Propagate map failures correctly from pvr_mmu_map_sgl() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 481/877] drm/i915: fix incorrect RCU teardown order Greg Kroah-Hartman
` (404 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alexandru Dadu, Alessio Belle,
Brajesh Gupta
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brajesh Gupta <brajesh.gupta@imgtec.com>
commit 0a8224058a5835297dcf4a46bbcd16f77a9fe424 upstream.
The GPU virtual start address wasn't included in the calculation for the
amount of page tables required for mapping a BO object in map() interface.
It resulted in map failure later due to not enough pages at L0/L1 level.
Update pvr_mmu_op_context_create() interface to pass device address as well
to allow correct calculation for page table memory.
If L0 tables cover 2MB (0x200000), the range defined by device address
0x80001ff000 (general heap at 2MB - 4KB) and size 0x2000 (two 4KB pages)
requires two L0 pages to be mapped, but without the base
address a range of 0x2000 computes to a single L0 page which is not enough.
Fixes: ff5f643de0bf ("drm/imagination: Add GEM and VM related code")
Reviewed-by: Alexandru Dadu <alexandru.dadu@imgtec.com>
Reviewed-by: Alessio Belle <alessio.belle@imgtec.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260922-mmu_fix-v4-2-12f1a871456a@imgtec.com
Signed-off-by: Brajesh Gupta <brajesh.gupta@imgtec.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/imagination/pvr_mmu.c | 14 ++++++++------
drivers/gpu/drm/imagination/pvr_mmu.h | 2 +-
drivers/gpu/drm/imagination/pvr_vm.c | 4 ++--
3 files changed, 11 insertions(+), 9 deletions(-)
--- a/drivers/gpu/drm/imagination/pvr_mmu.c
+++ b/drivers/gpu/drm/imagination/pvr_mmu.c
@@ -2332,6 +2332,7 @@ void pvr_mmu_op_context_destroy(struct p
* pvr_mmu_op_context_create() - Create an MMU op context.
* @ctx: MMU context associated with owning VM context.
* @sgt: Scatter gather table containing pages pinned for use by this context.
+ * @device_addr: Virtual device address at the start of the requested mapping.
* @sgt_offset: Start offset of the requested device-virtual memory mapping.
* @size: Size in bytes of the requested device-virtual memory mapping. For an
* unmapping, this should be zero so that no page tables are allocated.
@@ -2343,8 +2344,9 @@ void pvr_mmu_op_context_destroy(struct p
*/
struct pvr_mmu_op_context *
pvr_mmu_op_context_create(struct pvr_mmu_context *ctx, struct sg_table *sgt,
- u64 sgt_offset, u64 size)
+ u64 device_addr, u64 sgt_offset, u64 size)
{
+ u64 start_addr = device_addr + sgt_offset;
int err;
struct pvr_mmu_op_context *op_ctx =
@@ -2361,16 +2363,16 @@ pvr_mmu_op_context_create(struct pvr_mmu
if (size) {
/*
* The number of page table objects we need to prealloc is
- * indicated by the mapping size, start offset and the sizes
+ * indicated by the mapping size, start address and the sizes
* of the areas mapped per PT or PD. The range calculation is
* identical to that for the index into a table for a device
* address, so we reuse those functions here.
*/
- const u32 l1_start_idx = pvr_page_table_l2_idx(sgt_offset);
- const u32 l1_end_idx = pvr_page_table_l2_idx(sgt_offset + size);
+ const u32 l1_start_idx = pvr_page_table_l2_idx(start_addr);
+ const u32 l1_end_idx = pvr_page_table_l2_idx(start_addr + size);
const u32 l1_count = l1_end_idx - l1_start_idx + 1;
- const u32 l0_start_idx = pvr_page_table_l1_idx(sgt_offset);
- const u32 l0_end_idx = pvr_page_table_l1_idx(sgt_offset + size);
+ const u32 l0_start_idx = pvr_page_table_l1_idx(start_addr);
+ const u32 l0_end_idx = pvr_page_table_l1_idx(start_addr + size);
const u32 l0_count = l0_end_idx - l0_start_idx + 1;
/*
--- a/drivers/gpu/drm/imagination/pvr_mmu.h
+++ b/drivers/gpu/drm/imagination/pvr_mmu.h
@@ -99,7 +99,7 @@ dma_addr_t pvr_mmu_get_root_table_dma_ad
void pvr_mmu_op_context_destroy(struct pvr_mmu_op_context *op_ctx);
struct pvr_mmu_op_context *
pvr_mmu_op_context_create(struct pvr_mmu_context *ctx,
- struct sg_table *sgt, u64 sgt_offset, u64 size);
+ struct sg_table *sgt, u64 device_addr, u64 sgt_offset, u64 size);
int pvr_mmu_map(struct pvr_mmu_op_context *op_ctx, u64 size, u64 flags,
u64 device_addr);
--- a/drivers/gpu/drm/imagination/pvr_vm.c
+++ b/drivers/gpu/drm/imagination/pvr_vm.c
@@ -270,7 +270,7 @@ pvr_vm_bind_op_map_init(struct pvr_vm_bi
goto err_bind_op_fini;
bind_op->mmu_op_ctx =
- pvr_mmu_op_context_create(vm_ctx->mmu_ctx, sgt, offset, size);
+ pvr_mmu_op_context_create(vm_ctx->mmu_ctx, sgt, device_addr, offset, size);
err = PTR_ERR_OR_ZERO(bind_op->mmu_op_ctx);
if (err) {
bind_op->mmu_op_ctx = NULL;
@@ -312,7 +312,7 @@ pvr_vm_bind_op_unmap_init(struct pvr_vm_
}
bind_op->mmu_op_ctx =
- pvr_mmu_op_context_create(vm_ctx->mmu_ctx, NULL, 0, 0);
+ pvr_mmu_op_context_create(vm_ctx->mmu_ctx, NULL, device_addr, 0, 0);
err = PTR_ERR_OR_ZERO(bind_op->mmu_op_ctx);
if (err) {
bind_op->mmu_op_ctx = NULL;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 481/877] drm/i915: fix incorrect RCU teardown order
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (479 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 480/877] drm/imagination: Fix page count for page table for map() interface Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 482/877] drm/amd/display: Fix dc stream excess put in dm_update_crtc_state() Greg Kroah-Hartman
` (403 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian König, Tvrtko Ursulin,
Tvrtko Ursulin, Jani Nikula
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian König <ckoenig.leichtzumerken@gmail.com>
commit d2da6696e0c4e60414706e607029d0bb0330c67e upstream.
i915_gem_busy_ioctl uses dma_resv_for_each_fence_unlocked() to iterate
over the fences in an GEM object without holding a reference but only
the RCU read side lock.
What can happen here is that the GEM object is destroyed concurrently
while i915_gem_busy_ioctl is still running. This won't free the GEM
objects memory, but still drops all the dma_fence references.
Now when dma_resv_for_each_fence_unlocked() sees a destroyed dma_fence it
assumes that a new fence list was installed and re-starts the loop.
But in the case of a destroyed GEM object a new fence list is never
installed, only the old one freed and therefore the iteration never
finishes resulting in an endless loop.
The solution is to drop the fence references only after the RCU grace
period.
The fixes tag is not necessary the patch introducing the problem, but the
one making it so worse that we need to address it.
This problem was pointed out by Sashiko-bot.
Signed-off-by: Christian König <christian.koenig@amd.com>
Fixes: 912ff2ebd695 ("drm/i915: use the new iterator in i915_gem_busy_ioctl v2")
CC: stable@vger.kernel.org
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
Link: https://lore.kernel.org/r/20260903113621.54660-1-christian.koenig@amd.com
(cherry picked from commit 5113479556025093bf8133bb2dcaa33be2d50921)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/i915/gem/i915_gem_object.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -87,6 +87,7 @@ struct drm_i915_gem_object *i915_gem_obj
void i915_gem_object_free(struct drm_i915_gem_object *obj)
{
+ dma_resv_fini(&obj->base._resv);
return kmem_cache_free(slab_objects, obj);
}
@@ -142,7 +143,6 @@ void __i915_gem_object_fini(struct drm_i
{
mutex_destroy(&obj->mm.get_page.lock);
mutex_destroy(&obj->mm.get_dma_page.lock);
- dma_resv_fini(&obj->base._resv);
}
/**
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 482/877] drm/amd/display: Fix dc stream excess put in dm_update_crtc_state()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (480 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 481/877] drm/i915: fix incorrect RCU teardown order Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 483/877] drm/amd/display: Bump frame warning limit for clang builds of dml Greg Kroah-Hartman
` (402 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Alex Deucher
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit c5fd4eaad50d620c7e09ac2082b2fb55ee54170e upstream.
In dm_update_crtc_state(), when a modeset is required the newly created
stream is stored in dm_new_crtc_state->stream and an extra reference is
taken with dc_stream_retain(). The reference returned by
create_validate_stream_for_sink() is released as an extra reference at
the skip_modeset label, leaving the stream owned by the new CRTC state.
If amdgpu_dm_check_crtc_color_mgmt() fails afterwards, the code jumps
to the fail label which releases new_stream again. Since the extra
reference was already released at skip_modeset, this drops the
reference owned by dm_new_crtc_state->stream and the stream is
released while the atomic state still points to it, leading to a
premature free of the dc stream.
Set new_stream to NULL after releasing the extra reference at the
skip_modeset label so that a later goto fail cannot release the
reference owned by the new CRTC state.
Fixes: 7cd4b70091a5 ("drm/amd/display: Rework CRTC color management")
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 102a47065a62dc8f6bbbb47cf082a2934282eb08)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10834,8 +10834,10 @@ static int dm_update_crtc_state(struct a
skip_modeset:
/* Release extra reference */
- if (new_stream)
+ if (new_stream) {
dc_stream_release(new_stream);
+ new_stream = NULL;
+ }
new_stream = NULL;
/*
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 483/877] drm/amd/display: Bump frame warning limit for clang builds of dml
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (481 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 482/877] drm/amd/display: Fix dc stream excess put in dm_update_crtc_state() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 484/877] drm/amdgpu: Fix last_update fence leak in amdgpu_vm_init() Greg Kroah-Hartman
` (401 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ivan Lipski, Alex Deucher
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Lipski <ivan.lipski@amd.com>
commit 18779dd84515db093fedb4ebaf0998c9b165a5fb upstream.
[Why&How]
When building the DML files with clang without any sanitizer or LTO,
the following -Wframe-larger-than errors break the build under
CONFIG_WERROR:
display_mode_vba_30.c: error: stack frame size (2512) exceeds limit
(2048) in 'dml30_ModeSupportAndSystemConfigurationFull'
display_mode_vba_31.c: error: stack frame size (2416) exceeds limit
(2048) in 'dml31_ModeSupportAndSystemConfigurationFull'
display_mode_vba_314.c: error: stack frame size (2392) exceeds limit
(2048) in 'dml314_ModeSupportAndSystemConfigurationFull'
Clang consistently spills more than gcc, pushing the frame past the 2048
byte limit.
Apply an existing approach of increasing the warn stack size to the
non-sanitizer path so plain clang builds use a 3072 byte limit.
Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/5642
Signed-off-by: Ivan Lipski <ivan.lipski@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 21711b6e66bb7b41b1aec67b2d99aafe768c8fcb)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/display/dc/dml/Makefile | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/display/dc/dml/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile
@@ -36,7 +36,11 @@ ifneq ($(CONFIG_FRAME_WARN),0)
frame_warn_limit := 3072
endif
else
- frame_warn_limit := 2048
+ ifeq ($(CONFIG_CC_IS_CLANG),y)
+ frame_warn_limit := 3072
+ else
+ frame_warn_limit := 2048
+ endif
endif
ifeq ($(call test-lt, $(CONFIG_FRAME_WARN), $(frame_warn_limit)),y)
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 484/877] drm/amdgpu: Fix last_update fence leak in amdgpu_vm_init()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (482 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 483/877] drm/amd/display: Bump frame warning limit for clang builds of dml Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 485/877] drm/amdgpu: Fix runtime PM leak in amdgpu_debugfs_test_ib_show() Greg Kroah-Hartman
` (400 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Alex Deucher
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit b4f7b4459b1b155e4c4977a6482b5df2cf08758c upstream.
amdgpu_vm_init() initializes vm->last_update, vm->last_unlocked and
vm->last_tlb_flush with references to the stub fence taken via
dma_fence_get_stub(). The error label at the end of the function
releases the last_unlocked and last_tlb_flush references with
dma_fence_put(), but the reference stored in vm->last_update is never
dropped, so whenever the page table root creation, the reservation of
the root BO or the PASID registration fails, the stub fence reference
leaks.
Drop the vm->last_update reference together with the other stub fence
references on the error path.
Fixes: 187916e6ed9d ("drm/amdgpu: install stub fence into potential unused fence pointers")
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit e7979c84fc05a176bdf855ee664871b1648404c9)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -2498,6 +2498,7 @@ error_free_root:
amdgpu_bo_unref(&root_bo);
error_free_delayed:
+ dma_fence_put(vm->last_update);
dma_fence_put(vm->last_tlb_flush);
dma_fence_put(vm->last_unlocked);
ttm_lru_bulk_move_fini(&adev->mman.bdev, &vm->lru_bulk_move);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 485/877] drm/amdgpu: Fix runtime PM leak in amdgpu_debugfs_test_ib_show()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (483 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 484/877] drm/amdgpu: Fix last_update fence leak in amdgpu_vm_init() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 486/877] drm/amdgpu: Fix vmid_wait fence leak in amdgpu_ring_init() Greg Kroah-Hartman
` (399 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Alex Deucher
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit 2b86ab1bd6673c525adda88819d7658ba9e784ec upstream.
amdgpu_debugfs_test_ib_show() resumes the device with
pm_runtime_get_sync() before taking the reset domain semaphore with
down_write_killable(). If the write lock acquisition is interrupted,
the function returns without calling pm_runtime_put_autosuspend(),
leaking the runtime PM reference acquired for the device and keeping
the GPU awake.
Drop the runtime PM reference on the interrupted down_write_killable()
error path before returning.
Fixes: 6049db43d6dd ("drm/amdgpu: change reset lock from mutex to rw_semaphore")
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit ec30a576c2d4c0364549e6c04218f50704ef56c8)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
@@ -1671,8 +1671,10 @@ static int amdgpu_debugfs_test_ib_show(s
/* Avoid accidently unparking the sched thread during GPU reset */
r = down_write_killable(&adev->reset_domain->sem);
- if (r)
+ if (r) {
+ pm_runtime_put_autosuspend(dev->dev);
return r;
+ }
/* hold on the scheduler */
for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 486/877] drm/amdgpu: Fix vmid_wait fence leak in amdgpu_ring_init()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (484 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 485/877] drm/amdgpu: Fix runtime PM leak in amdgpu_debugfs_test_ib_show() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 487/877] drm/nouveau/uvmm: fix UAF in nouveau_uvmm_sm when BO is in TTM_PL_SYSTEM Greg Kroah-Hartman
` (398 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Alex Deucher
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit aea841bc62a76242396610d22d8ff40c13065f64 upstream.
amdgpu_ring_init() initializes ring->vmid_wait with a reference to the
stub fence taken via dma_fence_get_stub(). When a later step of the
initialization fails, e.g. amdgpu_fence_driver_init_ring(), a writeback
slot allocation or the ring buffer allocation, the function returns an
error without releasing the stub fence reference and the reference is
leaked if the ring is torn down without amdgpu_ring_fini().
Move the stub fence assignment to the end of the initialization, right
before the ring is registered with the GPU scheduler, where no further
failure is possible. The stub fence is only consumed by command
submission handling in amdgpu_ids.c once the ring is up and running, so
nothing reads it during the error-prone part of the initialization.
Fixes: 48e9fbd1a284 ("drm/amdgpu: initialize the vmid_wait with the stub fence")
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit f2b96986851203e9c50ca0d13aaa3581ca3e8ebd)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -226,7 +226,6 @@ int amdgpu_ring_init(struct amdgpu_devic
ring->adev = adev;
ring->num_hw_submission = sched_hw_submission;
ring->sched_score = sched_score;
- ring->vmid_wait = dma_fence_get_stub();
if (!ring->is_mes_queue) {
ring->idx = adev->num_rings++;
@@ -355,6 +354,7 @@ int amdgpu_ring_init(struct amdgpu_devic
ring->max_dw = max_dw;
ring->hw_prio = hw_prio;
+ ring->vmid_wait = dma_fence_get_stub();
if (!ring->no_scheduler && ring->funcs->type < AMDGPU_HW_IP_NUM) {
hw_ip = ring->funcs->type;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 487/877] drm/nouveau/uvmm: fix UAF in nouveau_uvmm_sm when BO is in TTM_PL_SYSTEM
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (485 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 486/877] drm/amdgpu: Fix vmid_wait fence leak in amdgpu_ring_init() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 488/877] drm/nouveau: fix autosuspend cleanup during teardown Greg Kroah-Hartman
` (397 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Peiyang He, Lyude Paul
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peiyang He <peiyang_he@smail.nju.edu.cn>
commit 3359a372efb6d585c97019ee1b7f1874442bcebe upstream.
nouveau_uvmm_sm() calls op_map(), which passes bo->resource through
nouveau_mem() to nouveau_uvma_map(). nouveau_uvmm_vmm_map() then reads
mem->mem.type.
But this is only valid when bo->resource is backed by struct nouveau_mem,
as is the case for VRAM and TT resources. If the BO is left in
TTM_PL_SYSTEM, bo->resource is only a struct ttm_resource. Treating it
as struct nouveau_mem makes the mem->mem.type read past the end of the
resource, causing a KASAN: slab-use-after-free Read in nouveau_uvmm_sm
report:
BUG: KASAN: slab-use-after-free in nouveau_uvmm_vmm_map drivers/gpu/drm/nouveau/nouveau_uvmm.c:152 [inline]
BUG: KASAN: slab-use-after-free in nouveau_uvma_map drivers/gpu/drm/nouveau/nouveau_uvmm.c:199 [inline]
BUG: KASAN: slab-use-after-free in op_map drivers/gpu/drm/nouveau/nouveau_uvmm.c:849 [inline]
BUG: KASAN: slab-use-after-free in nouveau_uvmm_sm.constprop.0+0x6ab/0x900 drivers/gpu/drm/nouveau/nouveau_uvmm.c:903
Read of size 1 at addr ffff888127d3e3a0 by task kworker/0:1/11
CPU: 0 UID: 0 PID: 11 Comm: kworker/0:1 Not tainted 7.2.0 #5 PREEMPT(lazy)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Workqueue: nouveau_sched_wq_2224 drm_sched_run_job_work
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0x95/0xe0 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:378 [inline]
print_report+0xcb/0x5a0 mm/kasan/report.c:482
kasan_report+0xca/0x100 mm/kasan/report.c:595
nouveau_uvmm_vmm_map drivers/gpu/drm/nouveau/nouveau_uvmm.c:152 [inline]
nouveau_uvma_map drivers/gpu/drm/nouveau/nouveau_uvmm.c:199 [inline]
op_map drivers/gpu/drm/nouveau/nouveau_uvmm.c:849 [inline]
nouveau_uvmm_sm.constprop.0+0x6ab/0x900 drivers/gpu/drm/nouveau/nouveau_uvmm.c:903
nouveau_uvmm_sm_unmap drivers/gpu/drm/nouveau/nouveau_uvmm.c:932 [inline]
nouveau_uvmm_bind_job_run+0xd6/0x250 drivers/gpu/drm/nouveau/nouveau_uvmm.c:1532
nouveau_job_run drivers/gpu/drm/nouveau/nouveau_sched.c:350 [inline]
nouveau_sched_run_job+0x62/0xd0 drivers/gpu/drm/nouveau/nouveau_sched.c:364
drm_sched_run_job_work+0x356/0xa10 drivers/gpu/drm/scheduler/sched_main.c:1061
process_one_work+0x8a5/0x1900 kernel/workqueue.c:3322
process_scheduled_works kernel/workqueue.c:3405 [inline]
worker_thread+0x5dd/0xd80 kernel/workqueue.c:3486
kthread+0x31d/0x420 kernel/kthread.c:436
ret_from_fork+0x662/0x940 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
</TASK>
Allocated by task 2224 on cpu 0 at 66.550027s:
kasan_save_stack+0x24/0x50 mm/kasan/common.c:57
kasan_save_track+0x17/0x60 mm/kasan/common.c:78
poison_kmalloc_redzone mm/kasan/common.c:398 [inline]
__kasan_kmalloc+0xaa/0xb0 mm/kasan/common.c:415
kasan_kmalloc include/linux/kasan.h:263 [inline]
__do_kmalloc_node mm/slub.c:5334 [inline]
__kmalloc_noprof+0x304/0x7c0 mm/slub.c:5359
_kmalloc_noprof include/linux/slab.h:992 [inline]
dma_resv_list_alloc+0x27/0x90 drivers/dma-buf/dma-resv.c:106
dma_resv_reserve_fences+0x60e/0xa30 drivers/dma-buf/dma-resv.c:205
ttm_bo_alloc_resource+0x12c/0xbd0 drivers/gpu/drm/ttm/ttm_bo.c:721
ttm_bo_validate+0x1bc/0x4a0 drivers/gpu/drm/ttm/ttm_bo.c:856
ttm_bo_init_reserved+0x2c3/0x570 drivers/gpu/drm/ttm/ttm_bo.c:970
nouveau_bo_init+0x159/0x2c0 drivers/gpu/drm/nouveau/nouveau_bo.c:359
nouveau_gem_new+0x234/0x5f0 drivers/gpu/drm/nouveau/nouveau_gem.c:272
nouveau_gem_ioctl_new+0x1eb/0x420 drivers/gpu/drm/nouveau/nouveau_gem.c:352
drm_ioctl_kernel+0x192/0x350 drivers/gpu/drm/drm_ioctl.c:817
drm_ioctl+0x4f8/0xb40 drivers/gpu/drm/drm_ioctl.c:914
nouveau_drm_ioctl+0xea/0x2c0 drivers/gpu/drm/nouveau/nouveau_drm.c:1338
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl fs/ioctl.c:583 [inline]
__x64_sys_ioctl+0x180/0x1d0 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x115/0x690 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 2223 on cpu 0 at 66.554063s:
kasan_save_stack+0x24/0x50 mm/kasan/common.c:57
kasan_save_track+0x17/0x60 mm/kasan/common.c:78
kasan_save_free_info+0x3b/0x60 mm/kasan/generic.c:584
poison_slab_object mm/kasan/common.c:253 [inline]
__kasan_slab_free+0x61/0x80 mm/kasan/common.c:285
kasan_slab_free include/linux/kasan.h:235 [inline]
slab_free_hook mm/slub.c:2677 [inline]
__rcu_free_sheaf_prepare+0xb6/0x2e0 mm/slub.c:2928
rcu_free_sheaf+0x1b/0x120 mm/slub.c:5978
rcu_do_batch kernel/rcu/tree.c:2645 [inline]
rcu_core+0x521/0x1490 kernel/rcu/tree.c:2897
handle_softirqs+0x1b1/0x8a0 kernel/softirq.c:622
__do_softirq kernel/softirq.c:656 [inline]
invoke_softirq kernel/softirq.c:496 [inline]
__irq_exit_rcu+0x137/0x1c0 kernel/softirq.c:735
irq_exit_rcu+0x9/0x20 kernel/softirq.c:752
instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1062 [inline]
sysvec_apic_timer_interrupt+0x70/0x80 arch/x86/kernel/apic/apic.c:1062
asm_sysvec_apic_timer_interrupt+0x1a/0x20 arch/x86/include/asm/idtentry.h:674
The buggy address belongs to the object at ffff888127d3e380
which belongs to the cache kmalloc-96 of size 96
The buggy address is located 32 bytes inside of
freed 96-byte region [ffff888127d3e380, ffff888127d3e3e0)
The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x127d3e
flags: 0x200000000000000(node=0|zone=2)
page_type: f5(slab)
raw: 0200000000000000 ffff888100041280 dead000000000122 0000000000000000
raw: 0000000000000000 0000000000200020 00000000f5000000 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff888127d3e280: 00 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc
ffff888127d3e300: 00 00 00 00 00 00 00 00 00 00 00 fc fc fc fc fc
>ffff888127d3e380: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
^
ffff888127d3e400: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
ffff888127d3e480: 00 00 00 00 00 00 00 00 00 00 fc fc fc fc fc fc
Fix by resetting the placement to the BO's valid domains before
calling nouveau_bo_validate(), matching the handling in
nouveau_uvmm_bo_validate(), so map jobs do not run for SYSTEM resources;
Reject BO that cannot reside in VRAM or GART;
Also skip op_map() when the GPUVA has been invalidated, matching the
handling in the unmap and remap paths.
Found when fuzzing the nouveau driver with a modified Syzkaller.
Fixes: b88baab82871 ("drm/nouveau: implement new VM_BIND uAPI")
Cc: stable@vger.kernel.org
Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn>
Assisted-by: Codex:gpt-5.5
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/0D77BEC410CE0129+20260907052204.1431488-1-peiyang_he@smail.nju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/nouveau/nouveau_uvmm.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
@@ -780,6 +780,9 @@ op_map(struct nouveau_uvma *uvma)
{
struct nouveau_bo *nvbo = nouveau_gem_object(uvma->va.gem.obj);
+ if (drm_gpuva_invalidated(&uvma->va))
+ return;
+
nouveau_uvma_map(uvma, nouveau_mem(nvbo->bo.resource));
}
@@ -1164,6 +1167,7 @@ bind_lock_validate(struct nouveau_job *j
drm_gpuva_for_each_op(va_op, op->ops) {
struct drm_gem_object *obj = op_gem_obj(va_op);
+ struct nouveau_bo *nvbo;
if (unlikely(!obj))
continue;
@@ -1178,8 +1182,13 @@ bind_lock_validate(struct nouveau_job *j
if (va_op->op == DRM_GPUVA_OP_UNMAP)
continue;
- ret = nouveau_bo_validate(nouveau_gem_object(obj),
- true, false);
+ nvbo = nouveau_gem_object(obj);
+ if (!(nvbo->valid_domains &
+ (NOUVEAU_GEM_DOMAIN_VRAM | NOUVEAU_GEM_DOMAIN_GART)))
+ return -EINVAL;
+
+ nouveau_bo_placement_set(nvbo, nvbo->valid_domains, 0);
+ ret = nouveau_bo_validate(nvbo, true, false);
if (ret)
return ret;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 488/877] drm/nouveau: fix autosuspend cleanup during teardown
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (486 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 487/877] drm/nouveau/uvmm: fix UAF in nouveau_uvmm_sm when BO is in TTM_PL_SYSTEM Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 489/877] drm/nouveau: Fix bridge reference leak in nv1a_ram_new() Greg Kroah-Hartman
` (396 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Lyude Paul
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <lgs201920130244@gmail.com>
commit fefd9480ec361969f1a836df46326a1801062c26 upstream.
nouveau_drm_device_init() calls pm_runtime_use_autosuspend(), but
nouveau_drm_device_fini() does not call the matching
pm_runtime_dont_use_autosuspend().
If the autosuspend delay is set to a negative value while autosuspend
is enabled, the runtime PM core increments usage_count to prevent
runtime suspend. Without calling pm_runtime_dont_use_autosuspend()
during teardown, this reference is not dropped and usage_count remains
unbalanced.
The documentation for pm_runtime_use_autosuspend() also notes that it
is important to undo it with pm_runtime_dont_use_autosuspend() at
driver exit time, unless runtime PM was initially enabled with
devm_pm_runtime_enable().
Add the missing pm_runtime_dont_use_autosuspend() call to the common
device teardown path.
This issue was found by manual code inspection.
Fixes: 5addcf0a5f0f ("nouveau: add runtime PM support (v0.9)")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/20260808134137.2864847-1-lgs201920130244@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/nouveau/nouveau_drm.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -563,6 +563,7 @@ nouveau_drm_device_fini(struct nouveau_d
if (nouveau_pmops_runtime()) {
pm_runtime_get_sync(dev->dev);
pm_runtime_forbid(dev->dev);
+ pm_runtime_dont_use_autosuspend(dev->dev);
}
nouveau_led_fini(dev);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 489/877] drm/nouveau: Fix bridge reference leak in nv1a_ram_new()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (487 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 488/877] drm/nouveau: fix autosuspend cleanup during teardown Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 490/877] drm/nouveau: fix double-free in nvif_vmm_dtor Greg Kroah-Hartman
` (395 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Lyude Paul
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit 67b4411538c8341692548429d43256f25be99f7a upstream.
pci_get_domain_bus_and_slot() takes a reference to the PCI device,
which is never released once the memory size has been read from its
config space. Drop the reference before returning.
Fixes: 2fa6d6cdaf283c05 ("drm/nouveau: deprecate pci_get_bus_and_slot()")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/20260916180036.2090118-1-vulab@iscas.ac.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c
@@ -51,6 +51,8 @@ nv1a_ram_new(struct nvkm_fb *fb, struct
mib = ((mem >> 4) & 127) + 1;
}
+ pci_dev_put(bridge);
+
return nvkm_ram_new_(&nv04_ram_func, fb, NVKM_RAM_TYPE_STOLEN,
mib * 1024 * 1024, pram);
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 490/877] drm/nouveau: fix double-free in nvif_vmm_dtor
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (488 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 489/877] drm/nouveau: Fix bridge reference leak in nv1a_ram_new() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 491/877] drm/nouveau: Fix gem reference leak in validate_init() Greg Kroah-Hartman
` (394 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Peiyang He, Lyude Paul
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peiyang He <peiyang_he@smail.nju.edu.cn>
commit 97077ac87afe9e91ec074ef0be64454e7ccbf344 upstream.
On failure, nouveau_cli_init() calls nouveau_cli_fini() to tear
the client down. Then, nouveau_drm_open() also enters into its
cleanup path and calls nouveau_cli_fini() AGAIN. nouveau_cli_fini()
calls nouveau_vmm_fini():
void
nouveau_vmm_fini(struct nouveau_vmm *vmm)
{
nouveau_svmm_fini(&vmm->svmm);
nvif_vmm_dtor(&vmm->vmm);
vmm->cli = NULL;
}
Inside nvif_vmm_dtor(), vmm->page is freed unconditionally:
void
nvif_vmm_dtor(struct nvif_vmm *vmm)
{
kfree(vmm->page);
nvif_object_dtor(&vmm->object);
}
vmm->page is never cleared after being freed, so the second call of
nvif_vmm_dtor() will cause a double-free.
Found by fuzzing the nouveau driver with a modified Syzkaller:
BUG: KASAN: double-free in nvif_vmm_dtor+0x31/0x50 drivers/gpu/drm/nouveau/nvif/vmm.c:194
Free of addr ffff888010fcdc30 by task syz.0.173/2567
CPU: 1 UID: 0 PID: 2567 Comm: syz.0.173 Not tainted 7.2.0 #24 PREEMPT(lazy)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0x95/0xe0 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:378 [inline]
print_report+0xcb/0x5a0 mm/kasan/report.c:482
kasan_report_invalid_free+0xaa/0xd0 mm/kasan/report.c:557
check_slab_allocation+0xe4/0x110 mm/kasan/common.c:235
kasan_slab_pre_free include/linux/kasan.h:199 [inline]
slab_free_hook mm/slub.c:2622 [inline]
slab_free mm/slub.c:6377 [inline]
kfree+0x192/0x590 mm/slub.c:6692
nvif_vmm_dtor+0x31/0x50 drivers/gpu/drm/nouveau/nvif/vmm.c:194
nouveau_vmm_fini+0x16/0x50 drivers/gpu/drm/nouveau/nouveau_vmm.c:127
nouveau_cli_fini+0x10e/0x210 drivers/gpu/drm/nouveau/nouveau_drm.c:225
nouveau_drm_open+0x24e/0x740 drivers/gpu/drm/nouveau/nouveau_drm.c:1255
drm_file_alloc+0x5f2/0xad0 drivers/gpu/drm/drm_file.c:176
drm_open_helper+0x1d7/0x4a0 drivers/gpu/drm/drm_file.c:335
drm_open+0x190/0x3d0 drivers/gpu/drm/drm_file.c:388
drm_stub_open+0x1f2/0x460 drivers/gpu/drm/drm_drv.c:1211
chrdev_open+0x21c/0x660 fs/char_dev.c:411
do_dentry_open+0x59d/0x12b0 fs/open.c:947
vfs_open+0x82/0x390 fs/open.c:1052
do_open fs/namei.c:4700 [inline]
path_openat+0x2345/0x3420 fs/namei.c:4863
do_file_open+0x207/0x460 fs/namei.c:4892
do_sys_openat2+0xd1/0x1d0 fs/open.c:1368
do_sys_open fs/open.c:1374 [inline]
__do_sys_openat fs/open.c:1390 [inline]
__se_sys_openat fs/open.c:1385 [inline]
__x64_sys_openat+0x144/0x200 fs/open.c:1385
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x115/0x690 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fc6d687594d
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fc6d5295008 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
RAX: ffffffffffffffda RBX: 00007fc6d6b06180 RCX: 00007fc6d687594d
RDX: 0000000000022501 RSI: 0000200000000000 RDI: ffffffffffffff9c
RBP: 00007fc6d691c303 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007fc6d6b06218 R14: 00007fc6d6b06180 R15: 00007ffd9451d760
</TASK>
Allocated by task 2567 on cpu 1 at 163.593900s:
kasan_save_stack+0x24/0x50 mm/kasan/common.c:57
kasan_save_track+0x17/0x60 mm/kasan/common.c:78
poison_kmalloc_redzone mm/kasan/common.c:398 [inline]
__kasan_kmalloc+0xaa/0xb0 mm/kasan/common.c:415
kasan_kmalloc include/linux/kasan.h:263 [inline]
__do_kmalloc_node mm/slub.c:5334 [inline]
__kmalloc_noprof+0x304/0x7c0 mm/slub.c:5359
_kmalloc_noprof include/linux/slab.h:992 [inline]
nvif_vmm_ctor+0x3c0/0x7e0 drivers/gpu/drm/nouveau/nvif/vmm.c:237
nouveau_vmm_init+0x40/0x90 drivers/gpu/drm/nouveau/nouveau_vmm.c:134
nouveau_cli_init+0x7b9/0xe10 drivers/gpu/drm/nouveau/nouveau_drm.c:293
nouveau_drm_open+0x236/0x740 drivers/gpu/drm/nouveau/nouveau_drm.c:1243
drm_file_alloc+0x5f2/0xad0 drivers/gpu/drm/drm_file.c:176
drm_open_helper+0x1d7/0x4a0 drivers/gpu/drm/drm_file.c:335
drm_open+0x190/0x3d0 drivers/gpu/drm/drm_file.c:388
drm_stub_open+0x1f2/0x460 drivers/gpu/drm/drm_drv.c:1211
chrdev_open+0x21c/0x660 fs/char_dev.c:411
do_dentry_open+0x59d/0x12b0 fs/open.c:947
vfs_open+0x82/0x390 fs/open.c:1052
do_open fs/namei.c:4700 [inline]
path_openat+0x2345/0x3420 fs/namei.c:4863
do_file_open+0x207/0x460 fs/namei.c:4892
do_sys_openat2+0xd1/0x1d0 fs/open.c:1368
do_sys_open fs/open.c:1374 [inline]
__do_sys_openat fs/open.c:1390 [inline]
__se_sys_openat fs/open.c:1385 [inline]
__x64_sys_openat+0x144/0x200 fs/open.c:1385
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x115/0x690 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 2567 on cpu 1 at 163.601355s:
kasan_save_stack+0x24/0x50 mm/kasan/common.c:57
kasan_save_track+0x17/0x60 mm/kasan/common.c:78
kasan_save_free_info+0x3b/0x60 mm/kasan/generic.c:584
poison_slab_object mm/kasan/common.c:253 [inline]
__kasan_slab_free+0x61/0x80 mm/kasan/common.c:285
kasan_slab_free include/linux/kasan.h:235 [inline]
slab_free_hook mm/slub.c:2677 [inline]
slab_free mm/slub.c:6377 [inline]
kfree+0x383/0x590 mm/slub.c:6692
nvif_vmm_dtor+0x31/0x50 drivers/gpu/drm/nouveau/nvif/vmm.c:194
nouveau_vmm_fini+0x16/0x50 drivers/gpu/drm/nouveau/nouveau_vmm.c:127
nouveau_cli_fini+0x10e/0x210 drivers/gpu/drm/nouveau/nouveau_drm.c:225
nouveau_cli_init+0x593/0xe10 drivers/gpu/drm/nouveau/nouveau_drm.c:324
nouveau_drm_open+0x236/0x740 drivers/gpu/drm/nouveau/nouveau_drm.c:1243
drm_file_alloc+0x5f2/0xad0 drivers/gpu/drm/drm_file.c:176
drm_open_helper+0x1d7/0x4a0 drivers/gpu/drm/drm_file.c:335
drm_open+0x190/0x3d0 drivers/gpu/drm/drm_file.c:388
drm_stub_open+0x1f2/0x460 drivers/gpu/drm/drm_drv.c:1211
chrdev_open+0x21c/0x660 fs/char_dev.c:411
do_dentry_open+0x59d/0x12b0 fs/open.c:947
vfs_open+0x82/0x390 fs/open.c:1052
do_open fs/namei.c:4700 [inline]
path_openat+0x2345/0x3420 fs/namei.c:4863
do_file_open+0x207/0x460 fs/namei.c:4892
do_sys_openat2+0xd1/0x1d0 fs/open.c:1368
do_sys_open fs/open.c:1374 [inline]
__do_sys_openat fs/open.c:1390 [inline]
__se_sys_openat fs/open.c:1385 [inline]
__x64_sys_openat+0x144/0x200 fs/open.c:1385
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x115/0x690 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
The buggy address belongs to the object at ffff888010fcdc30
which belongs to the cache kmalloc-16 of size 16
The buggy address is located 0 bytes inside of
16-byte region [ffff888010fcdc30, ffff888010fcdc40)
The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10fcd
flags: 0x100000000000000(node=0|zone=1)
page_type: f5(slab)
raw: 0100000000000000 ffff88800d441640 dead000000000100 dead000000000122
raw: 0000000000000000 0000000000550055 00000000f5000000 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff888010fcdb00: fc fc 00 04 fc fc fc fc fa fb fc fc fc fc fa fb
ffff888010fcdb80: fc fc fc fc fa fb fc fc fc fc 00 07 fc fc fc fc
>ffff888010fcdc00: fa fb fc fc fc fc fa fb fc fc fc fc fa fb fc fc
^
ffff888010fcdc80: fc fc fa fb fc fc fc fc 00 04 fc fc fc fc fa fb
ffff888010fcdd00: fc fc fc fc 00 00 fc fc fc fc fa fb fc fc fc fc
Fix by removing the redundant teardown in nouveau_drm_open(),
since nouveau_cli_init() already does the cleanup work.
Also clear vmm->page after its freeing.
Cc: stable@vger.kernel.org
Fixes: 20d8a88e557a ("drm/nouveau: tidy up the client init/fini interfaces")
Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn>
Assisted-by: LLM
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/03BA723D9E5FF725+20260916103138.2651605-1-peiyang_he@smail.nju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/nouveau/nouveau_drm.c | 4 +---
drivers/gpu/drm/nouveau/nvif/vmm.c | 1 +
2 files changed, 2 insertions(+), 3 deletions(-)
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -1192,10 +1192,8 @@ nouveau_drm_open(struct drm_device *dev,
mutex_unlock(&drm->clients_lock);
done:
- if (ret && cli) {
- nouveau_cli_fini(cli);
+ if (ret && cli)
kfree(cli);
- }
pm_runtime_mark_last_busy(dev->dev);
pm_runtime_put_autosuspend(dev->dev);
--- a/drivers/gpu/drm/nouveau/nvif/vmm.c
+++ b/drivers/gpu/drm/nouveau/nvif/vmm.c
@@ -192,6 +192,7 @@ void
nvif_vmm_dtor(struct nvif_vmm *vmm)
{
kfree(vmm->page);
+ vmm->page = NULL;
nvif_object_dtor(&vmm->object);
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 491/877] drm/nouveau: Fix gem reference leak in validate_init()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (489 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 490/877] drm/nouveau: fix double-free in nvif_vmm_dtor Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 492/877] drm/nouveau: Fix runtime PM leak in nouveau_connector_detect() Greg Kroah-Hartman
` (393 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Lyude Paul
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit 5ea72f7b7139b123713a7983448f910bc4514d9e upstream.
On the ttm_bo_reserve() failure and "vma not found" error paths, the
loop breaks without adding the looked-up object to any validate list,
so the reference taken by drm_gem_object_lookup() is never released;
validate_fini() only walks the spliced lists. Drop the reference
before breaking out on both paths.
Fixes: 19ca10d82e33bcfe ("drm/nouveau/gem: lookup VMAs for buffers referenced by pushbuf ioctl")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/20260916180202.2090231-1-vulab@iscas.ac.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/nouveau/nouveau_gem.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -522,6 +522,7 @@ retry:
if (unlikely(ret)) {
if (ret != -ERESTARTSYS)
NV_PRINTK(err, cli, "fail reserve\n");
+ drm_gem_object_put(gem);
break;
}
}
@@ -531,6 +532,7 @@ retry:
struct nouveau_vma *vma = nouveau_vma_find(nvbo, vmm);
if (!vma) {
NV_PRINTK(err, cli, "vma not found!\n");
+ drm_gem_object_put(gem);
ret = -EINVAL;
break;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 492/877] drm/nouveau: Fix runtime PM leak in nouveau_connector_detect()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (490 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 491/877] drm/nouveau: Fix gem reference leak in validate_init() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 493/877] drm/nouveau: RCU-free the scheduler-containing nouveau_sched Greg Kroah-Hartman
` (392 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Lyude Paul
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit 1e04611d3735543bd80a67d9d13dc13f503746fb upstream.
If nvif_outp_edid_get() fails, nouveau_connector_detect() returns
early without dropping the runtime PM reference taken at the start
of the function, keeping the device powered on until the next
successful detect.
Balance the reference on the error path like the other exit paths
do.
Fixes: 0cd7e0718139 ("drm/nouveau/disp: add output method to fetch edid")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/20260916180342.2090360-1-vulab@iscas.ac.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/nouveau/nouveau_connector.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -601,8 +601,11 @@ nouveau_connector_detect(struct drm_conn
new_edid = drm_get_edid(connector, nv_encoder->i2c);
} else {
ret = nvif_outp_edid_get(&nv_encoder->outp, (u8 **)&new_edid);
- if (ret < 0)
+ if (ret < 0) {
+ pm_runtime_mark_last_busy(dev->dev);
+ pm_runtime_put_autosuspend(dev->dev);
return connector_status_disconnected;
+ }
}
nouveau_connector_set_edid(nv_connector, new_edid);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 493/877] drm/nouveau: RCU-free the scheduler-containing nouveau_sched
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (491 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 492/877] drm/nouveau: Fix runtime PM leak in nouveau_connector_detect() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 494/877] drm/nouveau: dont bump pin count on failed re-pin in nouveau_bo_pin_locked() Greg Kroah-Hartman
` (391 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jonghyuk Kim(MalHyuk), Lyude Paul
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonghyuk Kim(MalHyuk) <malhyuk97@gmail.com>
commit f7eae6d8d768fabd6b59779ca7da79e02c74e113 upstream.
struct nouveau_sched embeds a struct drm_gpu_scheduler (base).
nouveau_sched_destroy() calls nouveau_sched_fini() (which does
drm_sched_fini(&sched->base)) and then frees the object with plain
kfree(sched).
drm_sched_fence_get_timeline_name() returns fence->sched->name, and the
scheduler fence keeps a .release callback so it is not ops-detached on
signalling. A finished fence exported to userspace via drm_syncobj /
sync_file therefore keeps pointing at &sched->base after nouveau_sched_destroy(),
and a later get_timeline_name() -- reachable unprivileged through
SYNC_IOC_FILE_INFO -- dereferences freed memory (KASAN slab-use-after-free
read).
Per the dma-fence lifetime contract the exporter must keep the data backing a
signalled fence alive for an RCU grace period. Free the scheduler-containing
object with kfree_rcu() instead of kfree().
Fixes: 5f03a507b29e ("drm/nouveau: implement 1:1 scheduler - entity relationship")
Cc: stable@vger.kernel.org
Signed-off-by: Jonghyuk Kim(MalHyuk) <malhyuk97@gmail.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/20260902012717.880724-1-malhyuk97@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/nouveau/nouveau_sched.c | 2 +-
drivers/gpu/drm/nouveau/nouveau_sched.h | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/nouveau/nouveau_sched.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sched.c
@@ -512,7 +512,7 @@ nouveau_sched_destroy(struct nouveau_sch
struct nouveau_sched *sched = *psched;
nouveau_sched_fini(sched);
- kfree(sched);
+ kfree_rcu(sched, rcu);
*psched = NULL;
}
--- a/drivers/gpu/drm/nouveau/nouveau_sched.h
+++ b/drivers/gpu/drm/nouveau/nouveau_sched.h
@@ -98,6 +98,7 @@ void nouveau_job_free(struct nouveau_job
struct nouveau_sched {
struct drm_gpu_scheduler base;
+ struct rcu_head rcu;
struct drm_sched_entity entity;
struct workqueue_struct *wq;
struct mutex mutex;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 494/877] drm/nouveau: dont bump pin count on failed re-pin in nouveau_bo_pin_locked()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (492 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 493/877] drm/nouveau: RCU-free the scheduler-containing nouveau_sched Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 495/877] drm/xe: Limit sg segment size to PAGE_SIZE on Xen PV Greg Kroah-Hartman
` (390 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Peiyang He, Lyude Paul
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peiyang He <peiyang_he@smail.nju.edu.cn>
commit 6a6870d3077faa501ca97760057ddca22b68418d upstream.
nouveau_bo_pin_locked() checks whether an already pinned BO is in a
memory domain compatible with a new pin request. When the domains are
incompatible, it sets -EBUSY but still calls ttm_bo_pin() before
returning.
Callers treat a failed nouveau_bo_pin() as not having acquired a new pin,
so the extra pin count is never decreased by a matching unpin.
This triggers the warning in ttm_bo_release():
WARN_ON_ONCE(bo->pin_count);
Found when fuzzing the nouveau driver with a modified Syzkaller:
WARNING: drivers/gpu/drm/ttm/ttm_bo.c:256 at ttm_bo_release+0x827/0x9e0 drivers/gpu/drm/ttm/ttm_bo.c:256, CPU#1: syz.3.24/2212
Modules linked in:
CPU: 1 UID: 0 PID: 2212 Comm: syz.3.24 Not tainted 7.2.0 #24 PREEMPT(lazy)
nouveau 0000:01:00.0: gsp:msg fn:103 len:0x40/0x20 res:0x19 resp:0x19
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
RIP: 0010:ttm_bo_release+0x827/0x9e0 drivers/gpu/drm/ttm/ttm_bo.c:256
Code: 02 00 0f 85 51 01 00 00 48 8b 7b 08 e8 d2 20 01 00 e9 80 fd ff ff e8 d8 15 c0 fe 90 0f 0b 90 e9 e1 f8 ff ff e8 ca 15 c0 fe 90 <0f> 0b 90 e9 a4 f8 ff ff e8 bc 15 c0 fe be 03 00 00 00 4c 89 e7 e8
msg: 00000000: 05 00 d0 c1 04 00 f0 f1 01 30 00 00 2d 90 00 00 .........0..-...
RSP: 0018:ffffc9000f5cf710 EFLAGS: 00010293
RAX: 0000000000000000 RBX: ffff888018e5d2a8 RCX: ffffffff82bb1b36
RDX: ffff888017b68000 RSI: 0000000000000004 RDI: ffff888018e5d2a8
msg: 00000010: 19 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
RBP: ffff88801261c720 R08: 0000000000000001 R09: ffffed10031cba55
R10: ffff888018e5d2ab R11: 00000000000000f3 R12: ffff888018e5d290
R13: ffff888018e5d2d4 R14: ffff88801b219c18 R15: dffffc0000000000
FS: 0000000000000000(0000) GS:ffff8880e0f6f000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000001b31223ffc CR3: 0000000028e00005 CR4: 0000000000770ef0
PKRU: 80000000
Call Trace:
<TASK>
kref_put include/linux/kref.h:65 [inline]
ttm_bo_put drivers/gpu/drm/ttm/ttm_bo.c:325 [inline]
ttm_bo_fini+0x55/0x80 drivers/gpu/drm/ttm/ttm_bo.c:330
nouveau_gem_object_del+0xb2/0x1b0 drivers/gpu/drm/nouveau/nouveau_gem.c:90
drm_gem_object_free+0x5f/0x90 drivers/gpu/drm/drm_gem.c:1165
kref_put include/linux/kref.h:65 [inline]
__drm_gem_object_put include/drm/drm_gem.h:562 [inline]
drm_gem_object_put include/drm/drm_gem.h:575 [inline]
nouveau_abi16_chan_fini.constprop.0+0x44f/0x5a0 drivers/gpu/drm/nouveau/nouveau_abi16.c:195
nouveau 0000:01:00.0: syz.2.23[2209]: Unknown handle 0x00000000
nouveau_abi16_fini+0x1d0/0x340 drivers/gpu/drm/nouveau/nouveau_abi16.c:225
nouveau_drm_postclose+0x18b/0x3e0 drivers/gpu/drm/nouveau/nouveau_drm.c:1284
nouveau 0000:01:00.0: syz.2.23[2209]: validate_init
drm_file_free.part.0+0x6d6/0xb60 drivers/gpu/drm/drm_file.c:267
drm_file_free drivers/gpu/drm/drm_file.c:237 [inline]
drm_close_helper.isra.0+0x11a/0x160 drivers/gpu/drm/drm_file.c:290
drm_release+0x1ab/0x330 drivers/gpu/drm/drm_file.c:438
__fput+0x39c/0xa60 fs/file_table.c:512
nouveau 0000:01:00.0: syz.2.23[2209]: validate: -2
task_work_run+0x15a/0x230 kernel/task_work.c:233
exit_task_work include/linux/task_work.h:40 [inline]
do_exit+0x82b/0x25a0 kernel/exit.c:1009
do_group_exit+0xc2/0x280 kernel/exit.c:1152
get_signal+0x1d6e/0x1f30 kernel/signal.c:3046
arch_do_signal_or_restart+0x7d/0x6e0 arch/x86/kernel/signal.c:337
__exit_to_user_mode_loop kernel/entry/common.c:66 [inline]
exit_to_user_mode_loop+0xdf/0x440 kernel/entry/common.c:101
__exit_to_user_mode_prepare include/linux/irq-entry-common.h:207 [inline]
syscall_exit_to_user_mode_prepare include/linux/irq-entry-common.h:230 [inline]
syscall_exit_to_user_mode include/linux/entry-common.h:318 [inline]
do_syscall_64+0x4f8/0x690 arch/x86/entry/syscall_64.c:100
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f12bac8594d
Code: Unable to access opcode bytes at 0x7f12bac85923.
RSP: 002b:00007f12b96e70d8 EFLAGS: 00000246 ORIG_RAX: 00000000000000ca
RAX: 0000000000000001 RBX: 00007f12baf15fa8 RCX: 00007f12bac8594d
RDX: 00000000000f4240 RSI: 0000000000000081 RDI: 00007f12baf15fac
RBP: 00007f12baf15fa0 R08: 00007f12baee8000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f12baf16038 R14: 0000000000000006 R15: 00007ffe2ed394b0
</TASK>
irq event stamp: 47867
hardirqs last enabled at (47883): [<ffffffff815cafc6>] __up_console_sem+0x66/0x70 kernel/printk/printk.c:347
hardirqs last disabled at (47892): [<ffffffff815cafab>] __up_console_sem+0x4b/0x70 kernel/printk/printk.c:345
softirqs last enabled at (47880): [<ffffffff81434277>] __do_softirq kernel/softirq.c:656 [inline]
softirqs last enabled at (47880): [<ffffffff81434277>] invoke_softirq kernel/softirq.c:496 [inline]
softirqs last enabled at (47880): [<ffffffff81434277>] __irq_exit_rcu+0x137/0x1c0 kernel/softirq.c:735
softirqs last disabled at (47875): [<ffffffff81434277>] __do_softirq kernel/softirq.c:656 [inline]
softirqs last disabled at (47875): [<ffffffff81434277>] invoke_softirq kernel/softirq.c:496 [inline]
softirqs last disabled at (47875): [<ffffffff81434277>] __irq_exit_rcu+0x137/0x1c0 kernel/softirq.c:735
Fix by calling ttm_bo_pin() only when the existing placement is compatible
with the new pin request. This matches the correct behavior in other DRM
drivers such as amdgpu_bo_pin() in amdgpu.
Cc: stable@vger.kernel.org
Fixes: ad76b3f7c7a0 ("drm/nouveau: teach nouveau_bo_pin() how to force a contig vram allocation")
Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn>
Assisted-by: LLM
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/EACEF2F4E098413F+20260918025312.2814889-1-peiyang_he@smail.nju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/nouveau/nouveau_bo.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -501,8 +501,9 @@ int nouveau_bo_pin_locked(struct nouveau
"0x%08x vs 0x%08x\n", bo,
bo->resource->mem_type, domain);
ret = -EBUSY;
+ } else {
+ ttm_bo_pin(&nvbo->bo);
}
- ttm_bo_pin(&nvbo->bo);
goto out;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 495/877] drm/xe: Limit sg segment size to PAGE_SIZE on Xen PV
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (493 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 494/877] drm/nouveau: dont bump pin count on failed re-pin in nouveau_bo_pin_locked() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 496/877] drm/virtio: fix memory leak of fence event on execbuffer failure Greg Kroah-Hartman
` (389 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Marek Marczykowski-Górecki,
Christoph Hellwig, Robert Beckett, Szymon Acedański,
Thomas Hellström, Rodrigo Vivi
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Szymon Acedański <accek@invisiblethingslab.com>
commit 141008dec73521ccf64878517460cec8b3297251 upstream.
Fix display corruption on Xen PV dom0, where DMA buffers are not
guaranteed machine-contiguous, in which case bounce buffering kicks
in, breaking xe's memory coherency assumptions.
Apply the same workaround i915 carries in i915_sg_segment_size() since
commit 78a07fe777c4 ("drm/i915: stop abusing swiotlb_max_segment").
Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs")
Reported-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/work_items/8382
Link: https://lore.kernel.org/xen-devel/aYtznP_tT6xNPwf-@mail-itl/
Link: https://lore.kernel.org/all/20221020110308.1582518-1-hch@lst.de/ # i915 counterpart
Cc: Christoph Hellwig <hch@lst.de>
Cc: Robert Beckett <bob.beckett@collabora.com>
Cc: stable@vger.kernel.org # v6.8+
Signed-off-by: Szymon Acedański <accek@invisiblethingslab.com>
Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Link: https://patch.msgid.link/20260916173030.3223833-1-accek@invisiblethingslab.com
(cherry picked from commit 77f704158f099b952681f207478a22d5b8218edb)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/xe/xe_bo.h | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
--- a/drivers/gpu/drm/xe/xe_bo.h
+++ b/drivers/gpu/drm/xe/xe_bo.h
@@ -8,6 +8,8 @@
#include <drm/ttm/ttm_tt.h>
+#include <xen/xen.h>
+
#include "xe_bo_types.h"
#include "xe_macros.h"
#include "xe_vm_types.h"
@@ -328,6 +330,23 @@ static inline unsigned int xe_sg_segment
struct scatterlist __maybe_unused sg;
size_t max = BIT_ULL(sizeof(sg.length) * 8) - 1;
+ /*
+ * For Xen PV guests pages aren't contiguous in DMA (machine) address
+ * space. The DMA API takes care of that both in dma_alloc_* (by
+ * calling into the hypervisor to make the pages contiguous) and in
+ * dma_map_* (by bounce buffering). But xe (like i915, see commit
+ * 78a07fe777c4) ignores the coherency aspects of the DMA API and thus
+ * can't cope with bounce buffering actually happening, so add a hack
+ * here to force small allocations and mappings when running in PV
+ * mode on Xen.
+ *
+ * Note this will still break if bounce buffering is required for other
+ * reasons, like confidential computing hypervisors or PCIe root ports
+ * with addressing limitations.
+ */
+ if (xen_pv_domain())
+ return PAGE_SIZE;
+
max = min_t(size_t, max, dma_max_mapping_size(dev));
/*
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 496/877] drm/virtio: fix memory leak of fence event on execbuffer failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (494 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 495/877] drm/xe: Limit sg segment size to PAGE_SIZE on Xen PV Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 497/877] drm/virtio: fix NULL pointer dereference on fence allocation failure Greg Kroah-Hartman
` (388 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Peiyang He, Dmitry Osipenko
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peiyang He <peiyang_he@smail.nju.edu.cn>
commit b74aad23d99b279bb34d135795f39a6d8ecdc075 upstream.
virtio_gpu_execbuffer_ioctl() reserves a DRM event with
drm_event_reserve_init() when VIRTGPU_EXECBUF_RING_IDX selects a ring that
userspace has enabled polling for. virtio_gpu_init_submit() does this
before the BO handles, the command buffer, the syncobj arrays and the
in-fence are processed, so every later error path runs with the event
already pending, including plain argument validation failures such as an
invalid bo_handle or an in-syncobj that carries no fence.
On those paths, virtio_gpu_cleanup_submit() drops the out-fence without
cancelling the event. The fence is freed without ever having been emitted,
taking the only driver-side pointer to the event with it. Closing the DRM
file does not help. drm_events_release() unlinks pending events but
deliberately leaves the freeing to the driver's later drm_send_event(),
which never runs for an orphaned event, so the allocation is leaked
permanently.
Found when fuzzing the virtio driver with Syzkaller:
BUG: memory leak
unreferenced object 0xffff88802c176e80 (size 96):
comm "syz.1.367", pid 10561, jiffies 4294960122
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
c8 6e 17 2c 80 88 ff ff 00 00 00 00 00 00 00 00 .n.,............
backtrace (crc e1973c6b):
kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
slab_post_alloc_hook mm/slub.c:4597 [inline]
slab_alloc_node mm/slub.c:4917 [inline]
__kmalloc_cache_noprof+0x49d/0x6f0 mm/slub.c:5485
_kmalloc_noprof include/linux/slab.h:988 [inline]
_kzalloc_noprof include/linux/slab.h:1309 [inline]
virtio_gpu_fence_event_create drivers/gpu/drm/virtio/virtgpu_submit.c:282 [inline]
virtio_gpu_init_submit drivers/gpu/drm/virtio/virtgpu_submit.c:398 [inline]
virtio_gpu_execbuffer_ioctl+0xbbf/0x1aa0 drivers/gpu/drm/virtio/virtgpu_submit.c:505
drm_ioctl_kernel+0x1f4/0x3e0 drivers/gpu/drm/drm_ioctl.c:817
drm_ioctl+0x5f4/0xc70 drivers/gpu/drm/drm_ioctl.c:914
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl fs/ioctl.c:583 [inline]
__x64_sys_ioctl+0x18e/0x210 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x116/0x800 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Fix by cancelling and freeing the DRM event on the execbuffer error path
before dropping the fence. Clear the fence's event pointer after
cancellation so it does not retain a dangling pointer.
Fixes: cd7f5ca33585 ("drm/virtio: implement context init: add virtio_gpu_fence_event")
Cc: stable@vger.kernel.org
Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn>
Assisted-by: Codex:gpt-5.6-luna
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patch.msgid.link/D320EAB5680C1411+20260908121323.2405044-1-peiyang_he@smail.nju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/virtio/virtgpu_submit.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/gpu/drm/virtio/virtgpu_submit.c
+++ b/drivers/gpu/drm/virtio/virtgpu_submit.c
@@ -538,6 +538,10 @@ int virtio_gpu_execbuffer_ioctl(struct d
virtio_gpu_process_post_deps(&submit);
virtio_gpu_complete_submit(&submit);
cleanup:
+ if (ret && submit.out_fence && submit.out_fence->e) {
+ drm_event_cancel_free(dev, &submit.out_fence->e->base);
+ submit.out_fence->e = NULL;
+ }
virtio_gpu_cleanup_submit(&submit);
return ret;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 497/877] drm/virtio: fix NULL pointer dereference on fence allocation failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (495 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 496/877] drm/virtio: fix memory leak of fence event on execbuffer failure Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 498/877] gpio: tps65219: Fix GPIO input value reads Greg Kroah-Hartman
` (387 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Peiyang He, Dmitry Osipenko
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peiyang He <peiyang_he@smail.nju.edu.cn>
commit 846b3c64fe3e77d9db20a7e3e62dbbb637c773e1 upstream.
virtio_gpu_fence_alloc() can fail due to memory pressure and return NULL,
but its caller like virtio_gpu_init_submit() never checks it. Later,
virtio_gpu_init_submit() passes the NULL fence to
virtio_gpu_fence_event_create(), which unconditionally dereferences it.
Found when fuzzing the virtio driver with Syzkaller:
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000012: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000090-0x0000000000000097]
CPU: 1 UID: 0 PID: 9991 Comm: syz.0.121 Not tainted 7.2.0 #4 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
RIP: 0010:virtio_gpu_fence_event_create drivers/gpu/drm/virtio/virtgpu_submit.c:295 [inline]
RIP: 0010:virtio_gpu_init_submit drivers/gpu/drm/virtio/virtgpu_submit.c:398 [inline]
RIP: 0010:virtio_gpu_execbuffer_ioctl+0xc78/0x1aa0 drivers/gpu/drm/virtio/virtgpu_submit.c:505
Code: 85 ed 0f 85 21 09 00 00 e8 05 5a c9 fb 48 8b 44 24 10 48 8d b8 90 00 00 00 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 9a 0d 00 00 48 8b 44 24 10 4c 89 b0 90 00 00 00
RSP: 0018:ffffc900039dfad0 EFLAGS: 00010216
RAX: dffffc0000000000 RBX: ffffc900039dfdd8 RCX: ffffffff85f6fd3d
RDX: 0000000000000012 RSI: ffffffff85f6fd4b RDI: 0000000000000090
RBP: 0000000000000000 R0virtio_gpu_virgl_process_cmd: ctrl 0x102, error 0x1203
R10: 0000000000000000 R11: 0000000000000000 R12: ffff8880132c4000
R13: 0000000000000000 R14: ffff888073b6c700 R15: 000000000000003b
FS: 00007fab480b96c0(0000) GS:ffff8880eb6e9000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007effbf5e55a8 CR3: 0000000048d19000 CR4: 0000000000350ef0
Call Trace:
<TASK>
drm_ioctl_kernel+0x1f4/0x3e0 drivers/gpu/drm/drm_ioctl.c:817
drm_ioctl+0x5f4/0xc70 drivers/gpu/drm/drm_ioctl.c:914
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl fs/ioctl.c:583 [inline]
__x64_sys_ioctl+0x18e/0x210 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x116/0x800 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fab471a82bd
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fab480b9018 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007fab47435fa0 RCX: 00007fab471a82bd
RDX: 00002000000000c0 RSI: 00000000c0406442 RDI: 0000000000000003
RBP: 00007fab480b9080 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001
R13: 00007fab47436038 R14: 00007fab47435fa0 R15: 00007ffe85ab0740
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:virtio_gpu_fence_event_create drivers/gpu/drm/virtio/virtgpu_submit.c:295 [inline]
RIP: 0010:virtio_gpu_init_submit drivers/gpu/drm/virtio/virtgpu_submit.c:398 [inline]
RIP: 0010:virtio_gpu_execbuffer_ioctl+0xc78/0x1aa0 drivers/gpu/drm/virtio/virtgpu_submit.c:505
Code: 85 ed 0f 85 21 09 00 00 e8 05 5a c9 fb 48 8b 44 24 10 48 8d b8 90 00 00 00 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 9a 0d 00 00 48 8b 44 24 10 4c 89 b0 90 00 00 00
RSP: 0018:ffffc900039dfad0 EFLAGS: 00010216
RAX: dffffc0000000000 RBX: ffffc900039dfdd8 RCX: ffffffff85f6fd3d
RDX: 0000000000000012 RSI: ffffffff85f6fd4b RDI: 0000000000000090
RBP: 0000000000000000 R08: 0000000000000005 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: ffff8880132c4000
R13: 0000000000000000 R14: ffff888073b6c700 R15: 000000000000003b
FS: 00007fab480b96c0(0000) GS:ffff888098ae9000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f24c3759000 CR3: 0000000048d19000 CR4: 0000000000350ef0
----------------
Code disassembly (best guess):
0: 85 ed test %ebp,%ebp
2: 0f 85 21 09 00 00 jne 0x929
8: e8 05 5a c9 fb call 0xfbc95a12
d: 48 8b 44 24 10 mov 0x10(%rsp),%rax
12: 48 8d b8 90 00 00 00 lea 0x90(%rax),%rdi
19: 48 b8 00 00 00 00 00 movabs $0xdffffc0000000000,%rax
20: fc ff df
23: 48 89 fa mov %rdi,%rdx
26: 48 c1 ea 03 shr $0x3,%rdx
* 2a: 80 3c 02 00 cmpb $0x0,(%rdx,%rax,1) <-- trapping instruction
2e: 0f 85 9a 0d 00 00 jne 0xdce
34: 48 8b 44 24 10 mov 0x10(%rsp),%rax
39: 4c 89 b0 90 00 00 00 mov %r14,0x90(%rax)
Fix by checking virtio_gpu_fence_alloc() in virtio_gpu_init_submit() and
returning -ENOMEM before any later code can dereference the NULL fence.
Fixes: 70d1ace56db6 ("drm/virtio: Conditionally allocate virtio_gpu_fence")
Cc: stable@vger.kernel.org
Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn>
Assisted-by: Codex:gpt-5.5
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patch.msgid.link/00EFE4BA92889B14+20260909091114.2622550-1-peiyang_he@smail.nju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/virtio/virtgpu_submit.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/virtio/virtgpu_submit.c
+++ b/drivers/gpu/drm/virtio/virtgpu_submit.c
@@ -389,10 +389,13 @@ static int virtio_gpu_init_submit(struct
if ((exbuf->flags & VIRTGPU_EXECBUF_FENCE_FD_OUT) ||
exbuf->num_out_syncobjs ||
exbuf->num_bo_handles ||
- drm_fence_event)
+ drm_fence_event) {
out_fence = virtio_gpu_fence_alloc(vgdev, fence_ctx, ring_idx);
- else
+ if (!out_fence)
+ return -ENOMEM;
+ } else {
out_fence = NULL;
+ }
if (drm_fence_event) {
err = virtio_gpu_fence_event_create(dev, file, out_fence, ring_idx);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 498/877] gpio: tps65219: Fix GPIO input value reads
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (496 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 497/877] drm/virtio: fix NULL pointer dereference on fence allocation failure Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 499/877] mm/hugetlb: preserve mremap address delta when skipping page tables Greg Kroah-Hartman
` (386 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Jonathan Cormier,
Bartosz Golaszewski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
commit 4cbe530c0233c7413aaaeb029a4f32dd6aadacbb upstream.
TPS65219_MFP_GPIO_STATUS_MASK is already BIT(4). Passing it to BIT()
again tests bit 16, which cannot be set in the 8-bit MFP_CTRL register,
so GPIO0 is always reported low when configured as an input.
Test the register value with the mask directly.
Fixes: 57e30e00bd5b ("gpio: tps65219: add GPIO support for TPS65219 PMIC")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Jonathan Cormier <jcormier@criticallink.com>
Link: https://patch.msgid.link/20260919171100.90430-2-kmehltretter@gmail.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpio/gpio-tps65219.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpio/gpio-tps65219.c
+++ b/drivers/gpio/gpio-tps65219.c
@@ -53,7 +53,7 @@ static int tps65219_gpio_get(struct gpio
if (ret)
return ret;
- ret = !!(val & BIT(TPS65219_MFP_GPIO_STATUS_MASK));
+ ret = !!(val & TPS65219_MFP_GPIO_STATUS_MASK);
dev_warn(dev, "GPIO%d = %d, MULTI_DEVICE_ENABLE, not a standard GPIO\n", offset, ret);
/*
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 499/877] mm/hugetlb: preserve mremap address delta when skipping page tables
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (497 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 498/877] gpio: tps65219: Fix GPIO input value reads Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 500/877] PCI: of_property: Omit bus properties without a subordinate bus Greg Kroah-Hartman
` (385 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jaewook You, Andrew Morton,
David Hildenbrand (Arm), Johan Hovold, Muchun Song,
Oscar Salvador
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jaewook You <jaewook376@gmail.com>
commit 9bdad082d44bdcf93716973dcba6be77e8a06e7b upstream.
move_hugetlb_page_tables() optimizes mremap() by advancing to the last
entry in the page table when the source page table does not exist, either
initially or after unsharing a PMD table. The common loop increment then
steps to the first entry in the next page table.
However, the code advances both the source and destination addresses to
the last entries in their respective page tables, which is wrong. The
destination address must be advanced only by the same amount as the source
address.
If the source and destination offsets within their page tables differ, the
destination address can be advanced too far, causing follow-up issues.
Fix this by advancing the destination address by the source advance
distance.
With a reproducer, we were able to trigger a kernel panic on x86-64. With
this fix in place, we can no longer reproduce the issue.
Link: https://lore.kernel.org/20260914132352.472-1-jaewook376@gmail.com
Fixes: e95a9851787b ("hugetlb: skip to end of PT page mapping when pte not present")
Fixes: 4ddb4d91b82f ("hugetlb: do not update address in huge_pmd_unshare")
Signed-off-by: Jaewook You <jaewook376@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Johan Hovold <johan@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: <stable@vger.kernel.org>
Assisted-by: LLM
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
mm/hugetlb.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -5473,18 +5473,21 @@ int move_hugetlb_page_tables(struct vm_a
hugetlb_vma_lock_write(vma);
i_mmap_lock_write(mapping);
for (; old_addr < old_end; old_addr += sz, new_addr += sz) {
+ const unsigned long offset_to_last_entry =
+ (old_addr | last_addr_mask) - old_addr;
+
src_pte = hugetlb_walk(vma, old_addr, sz);
if (!src_pte) {
- old_addr |= last_addr_mask;
- new_addr |= last_addr_mask;
+ old_addr += offset_to_last_entry;
+ new_addr += offset_to_last_entry;
continue;
}
if (huge_pte_none(huge_ptep_get(mm, old_addr, src_pte)))
continue;
if (huge_pmd_unshare(&tlb, vma, old_addr, src_pte)) {
- old_addr |= last_addr_mask;
- new_addr |= last_addr_mask;
+ old_addr += offset_to_last_entry;
+ new_addr += offset_to_last_entry;
continue;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 500/877] PCI: of_property: Omit bus properties without a subordinate bus
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (498 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 499/877] mm/hugetlb: preserve mremap address delta when skipping page tables Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 501/877] HID: alps: fix use-after-free on input2 registration failure Greg Kroah-Hartman
` (384 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Angel J, Bjorn Helgaas
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Angel J <iamanaws@httpd.dev>
commit 8805840aad73df7146778be243a196d48b4f6430 upstream.
A bridge (a device with a Type 1 header) may not have a secondary bus
allocated (pdev->subordinate), e.g., if there are no available bus numbers
or the bridge secondary/subordinate bus numbers are not writable.
The dynamic OF helpers of_pci_prop_bus_range() and of_pci_prop_intr_map()
dereference pdev->subordinate without checking it. When
CONFIG_PCI_DYNAMIC_OF_NODES is enabled, this can cause a NULL pointer
dereference and early boot hang.
Generate 'bus-range' and 'interrupt-map' properties only when a subordinate
bus exists. Keep the node and its remaining properties for bridges without
one.
The problem was latent since 407d1a51921e ("PCI: Create device tree node
for bridge"), but wasn't reachable until 1f340724419e ("PCI: of: Create
device tree PCI host bridge node"), which appeared in v6.15. Before
1f340724419e, of_pci_make_dev_node() returned early because the parent OF
node was missing.
Fixes: 407d1a51921e ("PCI: Create device tree node for bridge")
Signed-off-by: Angel J <iamanaws@httpd.dev>
[bhelgaas: move pdev->subordinate test to callees, commit log]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org # v6.6+
Link: https://patch.msgid.link/20260918195540.GA1187209@bhelgaas
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/pci/of_property.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
--- a/drivers/pci/of_property.c
+++ b/drivers/pci/of_property.c
@@ -91,9 +91,13 @@ static int of_pci_prop_bus_range(struct
struct of_changeset *ocs,
struct device_node *np)
{
- u32 bus_range[] = { pdev->subordinate->busn_res.start,
- pdev->subordinate->busn_res.end };
+ u32 bus_range[2];
+ if (!pdev->subordinate)
+ return 0;
+
+ bus_range[0] = pdev->subordinate->busn_res.start;
+ bus_range[1] = pdev->subordinate->busn_res.end;
return of_changeset_add_prop_u32_array(ocs, np, "bus-range", bus_range,
ARRAY_SIZE(bus_range));
}
@@ -216,6 +220,9 @@ static int of_pci_prop_intr_map(struct p
int ret;
u8 pin;
+ if (!pdev->subordinate)
+ return 0;
+
pnode = pci_device_to_OF_node(pdev->bus->self);
if (!pnode)
pnode = pci_bus_to_OF_node(pdev->bus);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 501/877] HID: alps: fix use-after-free on input2 registration failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (499 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 500/877] PCI: of_property: Omit bus properties without a subordinate bus Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 502/877] HID: quirks: add ALWAYS_POLL quirk for SDINNOVATION gaming keyboard Greg Kroah-Hartman
` (383 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chen Changcheng, Jiri Kosina
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Changcheng <chenchangcheng@kylinos.cn>
commit d3aba3442798ce4a4c8ce3104d7b286d61e605f9 upstream.
alps_input_configured() stores data->input2 before calling
input_register_device(). If registration fails, input_free_device()
frees the input device but data->input2 still points to the freed memory.
alps_input_configured() calls hid_hw_open() before allocating input2, so
URBs are already active and raw_event can fire during the failure window.
A U1_SP_ABSOLUTE_REPORT_ID report arriving then causes u1_raw_event()
to dereference the freed data->input2 -> use-after-free.
Fix by only storing input2 into drvdata after successful registration
and adding a NULL guard in the raw_event path.
Fixes: 2562756dde55 ("HID: add Alps I2C HID Touchpad-Stick support")
Cc: stable@vger.kernel.org
Signed-off-by: Chen Changcheng <chenchangcheng@kylinos.cn>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hid/hid-alps.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/hid/hid-alps.c
+++ b/drivers/hid/hid-alps.c
@@ -407,6 +407,8 @@ static int u1_raw_event(struct alps_dev
return 1;
case U1_SP_ABSOLUTE_REPORT_ID:
+ if (!hdata->input2)
+ return 0;
sp_x = get_unaligned_le16(data+2);
sp_y = get_unaligned_le16(data+4);
@@ -738,7 +740,6 @@ static int alps_input_configured(struct
goto exit;
}
- data->input2 = input2;
input2->phys = input->phys;
input2->name = "DualPoint Stick";
input2->id.bustype = BUS_I2C;
@@ -762,11 +763,12 @@ static int alps_input_configured(struct
__set_bit(INPUT_PROP_POINTER, input2->propbit);
__set_bit(INPUT_PROP_POINTING_STICK, input2->propbit);
- if (input_register_device(data->input2)) {
+ if (input_register_device(input2)) {
input_free_device(input2);
ret = -ENOENT;
goto exit;
}
+ data->input2 = input2;
}
exit:
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 502/877] HID: quirks: add ALWAYS_POLL quirk for SDINNOVATION gaming keyboard
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (500 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 501/877] HID: alps: fix use-after-free on input2 registration failure Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 503/877] HID: wacom: fix OOB read in wacom_wac_pen_serial_enforce() Greg Kroah-Hartman
` (382 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Marco Carvalho, Junjie Cao,
Benjamin Tissoires
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junjie Cao <junjie.cao@intel.com>
commit cdb669a3b8f844aca71fc3224990157d61562165 upstream.
The SDINNOVATION gaming keyboard (USB ID 36ae:feab) stops reporting
input events after its RGB lighting mode is switched about twice.
Disabling USB autosuspend and unbinding the other HID interfaces make
no difference; the issue does not occur on Windows.
HID_QUIRK_ALWAYS_POLL alone resolves it, verified on 7.1.8 via
usbhid.quirks=0x36ae:0xfeab:0x400.
Reported-by: Marco Carvalho <marcocarvalho.web@gmail.com>
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2514627
Cc: stable@vger.kernel.org
Signed-off-by: Junjie Cao <junjie.cao@intel.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hid/hid-ids.h | 3 +++
drivers/hid/hid-quirks.c | 1 +
2 files changed, 4 insertions(+)
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -1218,6 +1218,9 @@
#define USB_DEVICE_ID_SAMSUNG_WIRELESS_UNIVERSAL_KBD 0xa006
#define USB_DEVICE_ID_SAMSUNG_WIRELESS_MULTI_HOGP_KBD 0xa064
+#define USB_VENDOR_ID_SDINNOVATION 0x36ae
+#define USB_DEVICE_ID_SDINNOVATION_GAMING_KBD 0xfeab
+
#define USB_VENDOR_ID_SEMICO 0x1a2c
#define USB_DEVICE_ID_SEMICO_USB_KEYKOARD 0x0023
#define USB_DEVICE_ID_SEMICO_USB_KEYKOARD2 0x0027
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -182,6 +182,7 @@ static const struct hid_device_id hid_qu
{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52_2), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52_PRO), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X65), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
+ { HID_USB_DEVICE(USB_VENDOR_ID_SDINNOVATION, USB_DEVICE_ID_SDINNOVATION_GAMING_KBD), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD2), HID_QUIRK_NO_INIT_REPORTS },
{ HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD), HID_QUIRK_NO_INIT_REPORTS },
{ HID_USB_DEVICE(USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB), HID_QUIRK_NOGET },
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 503/877] HID: wacom: fix OOB read in wacom_wac_pen_serial_enforce()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (501 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 502/877] HID: quirks: add ALWAYS_POLL quirk for SDINNOVATION gaming keyboard Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 504/877] net/mlx5: Fix rev_entry reference leak in mlx5_tc_ct_shared_counter_get() Greg Kroah-Hartman
` (381 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jason Gerecke, Wei Jie Law,
Jason Gerecke, Jiri Kosina
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Jie LAW <98lawweijie@gmail.com>
commit 9aa237cf66495b2426ddde8532e9b08a0ed83aaa upstream.
The 'wacom_wac_pen_serial_enforce()' function may calculate and pass an
invalid offset to hid_field_extract(), resulting in memory reads at
incorrect addresses -- possibly beyond the end of the report. If a
field in the HID descriptor lists more usages than its Report Count
actually reserves space for, the function's inner 'j' will walk past
the end of the field:
for (i = 0; i < report->maxfield; i++) {
for (j = 0; j < report->field[i]->maxusage; j++) {
...
value = hid_field_extract(hdev, raw_data + 1,
offset + j * size, size);
A descriptor listing 12288 usages against Report Count 1 has the loop
extract the usage at index 12287 from bit offset 98296 -- about 12 KB
past a 2-byte received report. The value is stored in
wacom_wac->serial[0] and can reach userspace as an MSC_SERIAL event,
making this an information disclosure.
Clamp the loop to field->report_count, the number of value slots the
report holds. Value slots past the last declared usage are still
scanned; they reuse that usage (HID 1.11, 6.2.2.8).
Verified on v6.12.105 with a UHID reproducer: a 2-byte report from
such a descriptor trips KASAN before the patch and not after it.
Fixes: 83417206427b ("HID: wacom: Queue events with missing type/serial data for later processing")
Suggested-by: Jason Gerecke <killertofu@gmail.com>
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Assisted-by: GLM:glm-5.3
Signed-off-by: Wei Jie Law <98lawweijie@gmail.com>
Reviewed-by: Jason Gerecke <jason.gerecke@wacom.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hid/wacom_sys.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -97,8 +97,9 @@ static int wacom_wac_pen_serial_enforce(
/* Queue events which have invalid tool type or serial number */
for (i = 0; i < report->maxfield; i++) {
- for (j = 0; j < report->field[i]->maxusage; j++) {
- struct hid_field *field = report->field[i];
+ struct hid_field *field = report->field[i];
+
+ for (j = 0; j < field->report_count; j++) {
struct hid_usage *usage = &field->usage[j];
unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid);
unsigned int offset;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 504/877] net/mlx5: Fix rev_entry reference leak in mlx5_tc_ct_shared_counter_get()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (502 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 503/877] HID: wacom: fix OOB read in wacom_wac_pen_serial_enforce() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 505/877] net/mlx5e: advertise MACsec offload only when supported Greg Kroah-Hartman
` (380 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Wentao Liang, Tariq Toukan,
Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit 0bf6bb567f0edaa771e7dd208ef98da50e6a4485 upstream.
When the reverse entry is found but its counter is already being
released, refcount_inc_not_zero() fails and the reference taken by
mlx5_tc_ct_entry_get() is never dropped before falling through to
create_counter. Drop it so the reverse entry is not kept alive forever
by a shared counter lookup that did not use it.
Fixes: 1edae2335adf ("net/mlx5e: CT: Use the same counter for both directions")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260917113131.2149024-1-vulab@iscas.ac.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
@@ -1082,6 +1082,9 @@ mlx5_tc_ct_shared_counter_get(struct mlx
spin_unlock_bh(&ct_priv->ht_lock);
+ if (rev_entry)
+ mlx5_tc_ct_entry_put(rev_entry);
+
create_counter:
shared_counter = mlx5_tc_ct_counter_create(ct_priv);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 505/877] net/mlx5e: advertise MACsec offload only when supported
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (503 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 504/877] net/mlx5: Fix rev_entry reference leak in mlx5_tc_ct_shared_counter_get() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 506/877] net/sched: reject IDR error pointers when deleting actions Greg Kroah-Hartman
` (379 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Tariq Toukan, Ralf Lici,
Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ralf Lici <ralf@mandelbit.com>
commit 4581c3d2adc3c73a019bc38db64ca11f28bbd7fd upstream.
Commit 339ccec8d43d ("net/mlx5: Enable MACsec offload feature for VLAN
interface") added NETIF_F_HW_MACSEC unconditionally to vlan_features so
that VLAN devices could inherit MACsec offload support.
mlx5e_build_nic_netdev subsequently copies vlan_features into
hw_features and features. As a result, all mlx5e NIC netdevices
advertise MACsec hardware offload, even when the firmware does not
support it and the driver does not install macsec_ops.
Set the MACsec feature bits in mlx5e_macsec_build_netdev, after device
capabilities have been validated. This preserves MACsec-over-VLAN
support and the ethtool feature control on capable devices, without
advertising either on unsupported hardware.
Fixes: 339ccec8d43d ("net/mlx5: Enable MACsec offload feature for VLAN interface")
Cc: stable@vger.kernel.org
Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
Signed-off-by: Ralf Lici <ralf@mandelbit.com>
Link: https://patch.msgid.link/20260917122724.654639-1-ralf@mandelbit.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c | 2 ++
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 1 -
2 files changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
@@ -1727,6 +1727,8 @@ void mlx5e_macsec_build_netdev(struct ml
mlx5_core_dbg(priv->mdev, "mlx5e: MACsec acceleration enabled\n");
netdev->macsec_ops = &macsec_offload_ops;
netdev->features |= NETIF_F_HW_MACSEC;
+ netdev->hw_features |= NETIF_F_HW_MACSEC;
+ netdev->vlan_features |= NETIF_F_HW_MACSEC;
netif_keep_dst(netdev);
}
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -5433,7 +5433,6 @@ static void mlx5e_build_nic_netdev(struc
netdev->vlan_features |= NETIF_F_SG;
netdev->vlan_features |= NETIF_F_HW_CSUM;
- netdev->vlan_features |= NETIF_F_HW_MACSEC;
netdev->vlan_features |= NETIF_F_GRO;
netdev->vlan_features |= NETIF_F_TSO;
netdev->vlan_features |= NETIF_F_TSO6;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 506/877] net/sched: reject IDR error pointers when deleting actions
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (504 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 505/877] net/mlx5e: advertise MACsec offload only when supported Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 507/877] net: arp: terminate device name before lookup Greg Kroah-Hartman
` (378 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Xiang Mei, Weiming Shi,
Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <bestswngs@gmail.com>
commit c82b797abe668d0b668601a93ba2c0b071a63574 upstream.
tcf_action_delete() drops the reference held by its lookup before calling
tcf_idr_delete_index() with the saved action index. An unlocked
classifier can remove that action and reserve the same IDR slot with
ERR_PTR(-EBUSY) in between.
tcf_idr_delete_index() only checks the lookup result for NULL. It
therefore treats the reservation as a tc_action and dereferences
tcfa_bindcnt. A hardware execution breakpoint was used to schedule the
interleaving without changing the kernel source. KASAN reported this
decoded trace:
BUG: KASAN: null-ptr-deref in tca_action_gd+0x5b9/0x1010
Read of size 4 at addr 0000000000000010 by task poc/150
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000002
RIP: tca_action_gd+0x5c0/0x1010:
arch_atomic_read at arch/x86/include/asm/atomic.h:23
raw_atomic_read at include/linux/atomic/atomic-arch-fallback.h:457
atomic_read at include/linux/atomic/atomic-instrumented.h:33
tcf_idr_delete_index at net/sched/act_api.c:766
tcf_action_delete at net/sched/act_api.c:1859
tcf_del_notify at net/sched/act_api.c:2014
tca_action_gd at net/sched/act_api.c:2064
R13: 0000000000000010 R15: fffffffffffffff0
Kernel panic - not syncing: Fatal exception
R15 contains ERR_PTR(-EBUSY), and adding the tcfa_bindcnt offset produces
the address in R13. With the guard applied, the same reproducer returned
-ENOENT without a KASAN report or panic. Treat error pointers as absent
and return -ENOENT.
Fixes: 0190c1d452a9 ("net: sched: atomically check-allocate action")
Cc: stable@vger.kernel.org
Reported-by: Xiang Mei <xmei5@asu.edu>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Link: https://patch.msgid.link/20260914065123.4109709-2-bestswngs@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/sched/act_api.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -714,7 +714,7 @@ static int tcf_idr_delete_index(struct t
mutex_lock(&idrinfo->lock);
p = idr_find(&idrinfo->action_idr, index);
- if (!p) {
+ if (IS_ERR_OR_NULL(p)) {
mutex_unlock(&idrinfo->lock);
return -ENOENT;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 507/877] net: arp: terminate device name before lookup
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (505 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 506/877] net/sched: reject IDR error pointers when deleting actions Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 508/877] net: atl1: fix soft lockup on out-of-range cmb_tpd_next_to_clean read Greg Kroah-Hartman
` (377 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Zijie Huang, Ren Wei,
Ido Schimmel, Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zijie Huang <milkory@outlook.com>
commit d8b6529e80bcb4fb8177121404cbb3377acaebd2 upstream.
The ARP ioctl copies a user-provided struct arpreq into a stack object. Its
arp_dev field may contain IFNAMSIZ bytes without a NUL terminator.
Such input is passed to dev_get_by_name_rcu() or __dev_get_by_name(), where
strcmp() can read past the end of the stack object when a matching
alternative interface name exists.
Terminate the field before the lookup to prevent the out-of-bounds read.
Fixes: 36fbf1e52bd3 ("net: rtnetlink: add linkprop commands to add and delete alternative ifnames")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zijie Huang <milkory@outlook.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/fabf02a70787d17299e4b3153eadffaf20d154b3.1789910973.git.milkory@outlook.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/arp.c | 1 +
1 file changed, 1 insertion(+)
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1276,6 +1276,7 @@ int arp_ioctl(struct net *net, unsigned
err = copy_from_user(&r, arg, sizeof(struct arpreq));
if (err)
return -EFAULT;
+ r.arp_dev[IFNAMSIZ - 1] = '\0';
break;
default:
return -EINVAL;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 508/877] net: atl1: fix soft lockup on out-of-range cmb_tpd_next_to_clean read
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (506 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 507/877] net: arp: terminate device name before lookup Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 509/877] net: hisilicon: hns_dsaf_mac: fix mdio device leak in hns_mac_register_phy() Greg Kroah-Hartman
` (376 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Gajdos Tamás, Paolo Abeni
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gajdos Tamás <tamas@rimpianto.com>
commit 43e746821f5f5afbbf68e388bf9fbe221e03bfca upstream.
Same issue as atl1c (see the first commit in this series, "net:
atl1c: fix soft lockup on out-of-range tpd_cons read"): the hardware
can report an out-of-range cmb_tpd_next_to_clean (seen as 0xffff)
while the PCIe link/MAC is resetting. An out-of-range value can
never be reached and the loop below would spin forever. Treat it as
"nothing new to clean" instead.
Fixes: f3cc28c797604f ("Add Attansic L1 ethernet driver.")
Cc: stable@vger.kernel.org
Signed-off-by: Gajdos Tamás <tamas@rimpianto.com>
Link: https://patch.msgid.link/20260921091334.3571525-4-tamas@rimpianto.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/atheros/atlx/atl1.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/net/ethernet/atheros/atlx/atl1.c
+++ b/drivers/net/ethernet/atheros/atlx/atl1.c
@@ -2066,6 +2066,9 @@ static int atl1_intr_tx(struct atl1_adap
sw_tpd_next_to_clean = atomic_read(&tpd_ring->next_to_clean);
cmb_tpd_next_to_clean = le16_to_cpu(adapter->cmb.cmb->tpd_cons_idx);
+ if (unlikely(cmb_tpd_next_to_clean >= tpd_ring->count))
+ cmb_tpd_next_to_clean = sw_tpd_next_to_clean;
+
while (cmb_tpd_next_to_clean != sw_tpd_next_to_clean) {
buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean];
if (buffer_info->dma) {
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 509/877] net: hisilicon: hns_dsaf_mac: fix mdio device leak in hns_mac_register_phy()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (507 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 508/877] net: atl1: fix soft lockup on out-of-range cmb_tpd_next_to_clean read Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 510/877] net: openvswitch: conntrack: avoid modifying shared unconfirmed ct entry Greg Kroah-Hartman
` (375 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Simon Horman,
Paolo Abeni
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit 999e8295bc41d6ce45b8e54f88150efa96f3f01e upstream.
hns_dsaf_find_platform_device() returns the mdio platform device with its
reference count incremented. hns_mac_register_phy() never drops that
reference, so the mdio device can not be released.
Release the reference on both the deferred probe and the normal path.
Fixes: 1d1afa2ebf82 ("net: hns: register phy device in each mac initial sequence")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260917110828.2148390-1-vulab@iscas.ac.cn
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
@@ -793,6 +793,7 @@ static int hns_mac_register_phy(struct h
dev_err(mac_cb->dev,
"mac%d mdio is NULL, dsaf will probe again later\n",
mac_cb->mac_id);
+ put_device(&pdev->dev);
return -EPROBE_DEFER;
}
@@ -801,6 +802,8 @@ static int hns_mac_register_phy(struct h
dev_dbg(mac_cb->dev, "mac%d register phy addr:%d\n",
mac_cb->mac_id, addr);
+ put_device(&pdev->dev);
+
return rc;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 510/877] net: openvswitch: conntrack: avoid modifying shared unconfirmed ct entry
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (508 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 509/877] net: hisilicon: hns_dsaf_mac: fix mdio device leak in hns_mac_register_phy() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 511/877] net: openvswitch: conntrack: remove add_helper dead code Greg Kroah-Hartman
` (374 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Axel Mierczuk, Ilya Maximets,
Aaron Conole, Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilya Maximets <i.maximets@ovn.org>
commit 26b2bd70d22457556e2fa01cbf1192cb1a94d619 upstream.
In a case where skb with an unconfirmed ct entry gets cloned, we may
end up committing both but with different sets of extensions.
The series of events:
1. The first clone wants to commit and runs the helpers wiring up
the extension pointer into the expectation list.
2. Then it looses the confirmation keeping the entry unconfirmed.
3. Second clone now wants to commit labels and adds the new extension
for that breaking the pointer in the expectation list causing
UAF on the destruction path later.
While this is possible to trigger, there should be no practical
network pipeline where committing both clones without modifications
into the same zone is needed. So, let's just reset the entry in case
for some reason we got an skb with a shared one during commit. This
doesn't affect any known use cases, but avoids any potential problems
with sharing and modification of the unconfirmed ct entry.
The fixes tag points to the introduction of helpers, since that's the
main UAF trigger for the sharing.
Fixes: cae3a2627520 ("openvswitch: Allow attaching helpers to ct action")
Cc: stable@vger.kernel.org
Reported-by: Axel Mierczuk <axel.mierczuk@1password.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Reviewed-by: Aaron Conole <aconole@redhat.com>
Link: https://patch.msgid.link/20260921145655.3167436-2-i.maximets@ovn.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/net/netfilter/nf_conntrack.h | 5 +++++
net/openvswitch/conntrack.c | 12 ++++++++++++
2 files changed, 17 insertions(+)
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -186,6 +186,11 @@ static inline void nf_ct_put(struct nf_c
nf_ct_destroy(&ct->ct_general);
}
+static inline bool nf_ct_shared(const struct nf_conn *ct)
+{
+ return refcount_read(&ct->ct_general.use) > 1;
+}
+
/* load module; enable/disable conntrack in this namespace */
int nf_ct_netns_get(struct net *net, u8 nfproto);
void nf_ct_netns_put(struct net *net, u8 nfproto);
--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -734,6 +734,18 @@ static int __ovs_ct_lookup(struct net *n
enum ip_conntrack_info ctinfo;
struct nf_conn *ct;
+ /* If the ct entry is not confirmed and shared with some other skb,
+ * e.g., a cloned one, we can't just modify it with the commit as we
+ * must not modify the extension set. Reset.
+ */
+ if (cached && info->commit) {
+ ct = nf_ct_get(skb, &ctinfo);
+ if (ct && !nf_ct_is_confirmed(ct) && nf_ct_shared(ct)) {
+ nf_reset_ct(skb);
+ cached = false;
+ }
+ }
+
if (!cached) {
struct nf_hook_state state = {
.hook = NF_INET_PRE_ROUTING,
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 511/877] net: openvswitch: conntrack: remove add_helper dead code
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (509 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 510/877] net: openvswitch: conntrack: avoid modifying shared unconfirmed ct entry Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 512/877] net: openvswitch: conntrack: fix helper UAF due to extensions realloc Greg Kroah-Hartman
` (373 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ilya Maximets, Aaron Conole,
Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilya Maximets <i.maximets@ovn.org>
commit 5e6c14dd42a1c1fe938e573dc6c9098145b2b0c4 upstream.
This variable can only become 'true' when the connection is not
confirmed, but it is only checked when it is confirmed. So, it can be
treated as being always false and just removed.
Fixes: 3c1860543fcc ("openvswitch: add nf_ct_is_confirmed check before assigning the helper")
Cc: stable@vger.kernel.org
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Reviewed-by: Aaron Conole <aconole@redhat.com>
Link: https://patch.msgid.link/20260921145655.3167436-3-i.maximets@ovn.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/openvswitch/conntrack.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -779,8 +779,6 @@ static int __ovs_ct_lookup(struct net *n
ct = nf_ct_get(skb, &ctinfo);
if (ct) {
- bool add_helper = false;
-
/* Packets starting a new connection must be NATted before the
* helper, so that the helper knows about the NAT. We enforce
* this by delaying both NAT and helper calls for unconfirmed
@@ -812,7 +810,6 @@ static int __ovs_ct_lookup(struct net *n
GFP_ATOMIC);
if (err)
return err;
- add_helper = true;
/* helper installed, add seqadj if NAT is required */
if (info->nat && !nfct_seqadj(ct)) {
@@ -822,13 +819,10 @@ static int __ovs_ct_lookup(struct net *n
}
/* Call the helper only if:
- * - nf_conntrack_in() was executed above ("!cached") or a
- * helper was just attached ("add_helper") for a confirmed
- * connection, or
+ * - nf_conntrack_in() was executed above ("!cached"), or
* - When committing an unconfirmed connection.
*/
- if ((nf_ct_is_confirmed(ct) ? !cached || add_helper :
- info->commit)) {
+ if ((nf_ct_is_confirmed(ct) ? !cached : info->commit)) {
int err = nf_ct_helper(skb, ct, ctinfo, info->family);
err = verdict_to_errno(err);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 512/877] net: openvswitch: conntrack: fix helper UAF due to extensions realloc
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (510 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 511/877] net: openvswitch: conntrack: remove add_helper dead code Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 513/877] net: atl1c: fix soft lockup on out-of-range tpd_cons read Greg Kroah-Hartman
` (372 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Axel Mierczuk, Ilya Maximets,
Aaron Conole, Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilya Maximets <i.maximets@ovn.org>
commit 1a4151e6be57b098b7a5ebfbde58585e83200cdc upstream.
While calling the helpers, a raw pointer to the extensions area is
wired into expectations list:
-> nf_ct_helper()
-> helper->help()
-> nf_ct_expect_related_report()
-> nf_ct_expect_insert()
-> hlist_add_head_rcu(&exp->lnode, &master_help->expectations)
In case the connection is not confirmed yet, more extensions can be
added afterwards with *_ext_add() calls reallocating the extension
space and leaving the now invalid pointer in the expectations list
that is later accessed while removing the expectation.
Make sure that helpers are called at the end after all the other
extensions are already added.
Note that the helper rejection now leaves the mark and labels set,
but that's not different from how the NAT was handled before or how
the mark and the labels were handled on confirmation failure. And
there are no atomicity guarantees provided by the API anyway.
Fixes: cae3a2627520 ("openvswitch: Allow attaching helpers to ct action")
Cc: stable@vger.kernel.org
Reported-by: Axel Mierczuk <axel.mierczuk@1password.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Reviewed-by: Aaron Conole <aconole@redhat.com>
Link: https://patch.msgid.link/20260921145655.3167436-4-i.maximets@ovn.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/openvswitch/conntrack.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -818,11 +818,14 @@ static int __ovs_ct_lookup(struct net *n
}
}
- /* Call the helper only if:
- * - nf_conntrack_in() was executed above ("!cached"), or
- * - When committing an unconfirmed connection.
+ /* Call the helper only if nf_conntrack_in() was executed
+ * above ("!cached").
+ *
+ * For unconfirmed connections it will be called later during
+ * commit as we need to have all the other extensions allocated
+ * before the call.
*/
- if ((nf_ct_is_confirmed(ct) ? !cached : info->commit)) {
+ if (nf_ct_is_confirmed(ct) && !cached) {
int err = nf_ct_helper(skb, ct, ctinfo, info->family);
err = verdict_to_errno(err);
@@ -1025,6 +1028,14 @@ static int ovs_ct_commit(struct net *net
return err;
nf_conn_act_ct_ext_add(skb, ct, ctinfo);
+
+ /* Call the helpers now. We couldn't do this before as
+ * all the extensions must be allocated before the call.
+ */
+ err = nf_ct_helper(skb, ct, ctinfo, info->family);
+ err = verdict_to_errno(err);
+ if (err)
+ return err;
} else if (IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS) &&
labels_nonzero(&info->labels.mask)) {
err = ovs_ct_set_labels(ct, key, &info->labels.value,
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 513/877] net: atl1c: fix soft lockup on out-of-range tpd_cons read
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (511 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 512/877] net: openvswitch: conntrack: fix helper UAF due to extensions realloc Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 514/877] net: atl1e: fix soft lockup on out-of-range hw_next_to_clean read Greg Kroah-Hartman
` (371 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Gajdos Tamás, Paolo Abeni
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gajdos Tamás <tamas@rimpianto.com>
commit 36c2009d90f2210ef92e6f4f2850e8b57b09e754 upstream.
The hardware can report an out-of-range tpd_cons (seen as 0xffff)
while the PCIe link/MAC is resetting. An out-of-range value can
never be reached and the loop below would spin forever. To avoid
a soft lockup treat it as "nothing new to clean" instead.
Reproduced on two machines, same NIC (Qualcomm Atheros AR8151 v2.0,
4-port), triggered by rebooting a Mikrotik CCR2004 PCIe card that
the ports are directly linked to:
- Ubuntu 26.04.1 LTS, kernel 7.0.0-31-generic. The link-flap
precursor, before the lockup was captured with a full trace
elsewhere:
atl1c 0000:05:00.0 enp5s0f0: NETDEV WATCHDOG: CPU: 4: transmit queue 2 timed out 489984 ms
atl1c 0000:05:00.0: MAC state machine can't be idle since disabled for 10ms second
atl1c 0000:05:00.0: atl1c: enp5s0f0 NIC Link is Up<65535 Mbps Full Duplex>
65535 (0xffff) here is the same value tpd_cons reads back once the
loop below gets stuck.
- Proxmox VE, kernel 7.0.14-11-pve. Same NIC/trigger, this time
caught by the soft lockup watchdog with a full stack trace:
watchdog: BUG: soft lockup - CPU#12 stuck for 354s! [napi/eth%d-0:329]
CPU: 12 UID: 0 PID: 329 Comm: napi/eth%d-0 Tainted: P O L 7.0.14-11-pve #1 PREEMPT(lazy)
RIP: 0010:atl1c_clean_tx+0x142/0x2d0 [atl1c]
Call Trace:
<TASK>
__napi_poll+0x32/0x1e0
napi_threaded_poll_loop+0x286/0x2e0
napi_threaded_poll+0xfd/0x140
kthread+0xf7/0x130
ret_from_fork+0x2da/0x3a0
ret_from_fork_asm+0x1a/0x30
</TASK>
Fixes: 43250ddd75a35d ("atl1c: Atheros L1C Gigabit Ethernet driver")
Cc: stable@vger.kernel.org
Signed-off-by: Gajdos Tamás <tamas@rimpianto.com>
Link: https://patch.msgid.link/20260921091334.3571525-2-tamas@rimpianto.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -1602,6 +1602,9 @@ static int atl1c_clean_tx(struct napi_st
AT_READ_REGW(&adapter->hw, atl1c_qregs[tpd_ring->num].tpd_cons,
&hw_next_to_clean);
+ if (unlikely(hw_next_to_clean >= tpd_ring->count))
+ hw_next_to_clean = next_to_clean;
+
while (next_to_clean != hw_next_to_clean) {
buffer_info = &tpd_ring->buffer_info[next_to_clean];
if (buffer_info->skb) {
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 514/877] net: atl1e: fix soft lockup on out-of-range hw_next_to_clean read
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (512 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 513/877] net: atl1c: fix soft lockup on out-of-range tpd_cons read Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 515/877] net: bridge: mdb: restart port group walk after deletion Greg Kroah-Hartman
` (370 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Gajdos Tamás, Paolo Abeni
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gajdos Tamás <tamas@rimpianto.com>
commit 374bf9e4b90f979e052332c4faca2d745c491a12 upstream.
Same issue as atl1c (see the first commit in this series, "net:
atl1c: fix soft lockup on out-of-range tpd_cons read"): the hardware
can report an out-of-range hw_next_to_clean (seen as 0xffff) while
the PCIe link/MAC is resetting. An out-of-range value can never be
reached and the loop below would spin forever. Treat it as "nothing
new to clean" instead.
Fixes: a6a5325239c202 ("atl1e: Atheros L1E Gigabit Ethernet driver")
Cc: stable@vger.kernel.org
Signed-off-by: Gajdos Tamás <tamas@rimpianto.com>
Link: https://patch.msgid.link/20260921091334.3571525-3-tamas@rimpianto.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
@@ -1234,6 +1234,9 @@ static bool atl1e_clean_tx_irq(struct at
u16 hw_next_to_clean = AT_READ_REGW(&adapter->hw, REG_TPD_CONS_IDX);
u16 next_to_clean = atomic_read(&tx_ring->next_to_clean);
+ if (unlikely(hw_next_to_clean >= tx_ring->count))
+ hw_next_to_clean = next_to_clean;
+
while (next_to_clean != hw_next_to_clean) {
tx_buffer = &tx_ring->tx_buffer[next_to_clean];
if (tx_buffer->dma) {
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 515/877] net: bridge: mdb: restart port group walk after deletion
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (513 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 514/877] net: atl1e: fix soft lockup on out-of-range hw_next_to_clean read Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 516/877] net: usb: cdc_mbim: add MeiG Smart SRM821 to ZLP whitelist Greg Kroah-Hartman
` (369 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Fourie Zhang, Nikolay Aleksandrov,
Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fourie Zhang <littleddfu@gmail.com>
commit ab1404ac81154a89fb61ac50ae9a04cd8d4834dc upstream.
br_mdb_flush_pgs() keeps a pointer-to-pointer cursor while walking
mp->ports. br_multicast_del_pg() can re-enter the same MDB entry through
br_multicast_sg_del_exclude_ports() and unlink other port groups. If the
cursor points into one of those groups, the next iteration dereferences a
stale cursor and can leave mp->ports pointing at freed memory.
A following RTM_GETMDB exposes the dangling pointer:
BUG: KASAN: slab-use-after-free in br_mdb_dump
Read of size 8
br_mdb_dump
rtnl_mdb_dump
rtnl_dumpit
netlink_dump
Reset the cursor to mp->ports after every deletion. The deletion removes at
least the selected group, so the restarted walk always makes progress.
Fixes: a6acb535afb2 ("bridge: mdb: Add MDB bulk deletion support")
Cc: stable@vger.kernel.org
Signed-off-by: Fourie Zhang <fouriezhang@tencent.com>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/20260920110852.60293-1-fouriezhang@tencent.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bridge/br_mdb.c | 2 ++
1 file changed, 2 insertions(+)
--- a/net/bridge/br_mdb.c
+++ b/net/bridge/br_mdb.c
@@ -1505,6 +1505,8 @@ static void br_mdb_flush_pgs(struct net_
}
br_multicast_del_pg(mp, p, pp);
+ /* br_multicast_del_pg() can remove other groups from this list. */
+ pp = &mp->ports;
}
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 516/877] net: usb: cdc_mbim: add MeiG Smart SRM821 to ZLP whitelist
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (514 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 515/877] net: bridge: mdb: restart port group walk after deletion Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 517/877] net: usb: lan78xx: Fix URB reference leak in lan78xx_submit_deferred_urbs() Greg Kroah-Hartman
` (368 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ming Wang, Jakub Kicinski
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Wang <wangming01@loongson.cn>
commit f75f21ef36285e5f56ee0c428bd2909ee81165b9 upstream.
The MeiG Smart SRM821 5G module (0x2dee:0x4d53) crashes and drops off
the USB bus when it receives a Zero Length Packet (ZLP) after sending
or receiving an NTB of exactly 16384 bytes (tx_max).
According to the MBIM specification, devices do not require a ZLP
if the NTB size is exactly dwNtbOutMaxSize. However, the cdc_mbim
driver defaults to sending ZLPs for devices not explicitly whitelisted
to accommodate non-conformant hardware. This default behavior breaks
the strictly conformant MeiG SRM821 module.
Add this device to the ZLP conformance whitelist (cdc_mbim_info) so
the driver will pad the NTB to avoid sending ZLPs, preventing the
device firmware from crashing.
Cc: stable@vger.kernel.org
Signed-off-by: Ming Wang <wangming01@loongson.cn>
Link: https://patch.msgid.link/20260920074500.826121-1-wangming01@loongson.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/usb/cdc_mbim.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/drivers/net/usb/cdc_mbim.c
+++ b/drivers/net/usb/cdc_mbim.c
@@ -634,6 +634,11 @@ static const struct usb_device_id mbim_d
.driver_info = (unsigned long)&cdc_mbim_info,
},
+ /* MeiG Smart SRM821 ZLP conformance */
+ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d53, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long)&cdc_mbim_info,
+ },
+
/* Some Huawei devices, ME906s-158 (12d1:15c1) and E3372
* (12d1:157d), are known to fail unless the NDP is placed
* after the IP packets. Applying the quirk to all Huawei
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 517/877] net: usb: lan78xx: Fix URB reference leak in lan78xx_submit_deferred_urbs()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (515 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 516/877] net: usb: cdc_mbim: add MeiG Smart SRM821 to ZLP whitelist Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 518/877] netfilter: ip6t_rpfilter: reject routes without inet6_dev Greg Kroah-Hartman
` (367 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Paolo Abeni
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit 17741334d00bf5ebd37f8c1c36bc9c146a351deb upstream.
usb_get_from_anchor() hands over a reference to the URB, which the caller
must release. lan78xx_submit_deferred_urbs() never does, so every deferred
Tx URB keeps an extra reference: the counter grows on each suspend/resume
cycle and the URBs are never freed when the buffers are released. Drop
the reference after submitting, and on the path that drops the packet
instead of submitting it.
Fixes: 5f4cc6e25148 ("lan78xx: Fix race conditions in suspend/resume handling")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Link: https://patch.msgid.link/20260917115811.2150119-1-vulab@iscas.ac.cn
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/usb/lan78xx.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -4932,10 +4932,12 @@ static bool lan78xx_submit_deferred_urbs
!netif_carrier_ok(dev->net) ||
pipe_halted) {
lan78xx_release_tx_buf(dev, skb);
+ usb_put_urb(urb);
continue;
}
ret = usb_submit_urb(urb, GFP_ATOMIC);
+ usb_put_urb(urb);
if (ret == 0) {
netif_trans_update(dev->net);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 518/877] netfilter: ip6t_rpfilter: reject routes without inet6_dev
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (516 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 517/877] net: usb: lan78xx: Fix URB reference leak in lan78xx_submit_deferred_urbs() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 519/877] netfilter: ip6t_rt: fix zero-address non-strict match out-of-bounds read Greg Kroah-Hartman
` (366 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, co+459f67f4d8af8ce6,
Florian Westphal, Weiming Shi, Pablo Neira Ayuso
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <bestswngs@gmail.com>
commit 1b9b5323725e458906c7620a3bc10398b51ad954 upstream.
ip6_route_lookup() can return an error-free route whose rt6i_idev is
NULL. Lowering an external nexthop device's MTU below IPV6_MIN_MTU tears
down its inet6_dev while fib6_ifdown() leaves routes using nexthop objects
in the FIB. An unprivileged user can construct this state with rtnetlink
in a private user and network namespace, then trigger a NULL dereference
through an IPv6 rpfilter lookup:
Oops: general protection fault, probably for non-canonical address
0xdffffc0000000000
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
RIP: rpfilter_mt (net/ipv6/netfilter/ip6t_rpfilter.c:75)
Call Trace:
ip6t_do_table (net/ipv6/netfilter/ip6_tables.c:316)
nf_hook_slow (net/netfilter/core.c:619)
ipv6_rcv (net/ipv6/ip6_input.c:351)
__netif_receive_skb_one_core (net/core/dev.c:6216)
process_backlog (net/core/dev.c:6680)
__napi_poll (net/core/dev.c:7739)
net_rx_action (net/core/dev.c:7959)
handle_softirqs (kernel/softirq.c:622)
do_softirq.part.0 (kernel/softirq.c:523)
__local_bh_enable_ip (kernel/softirq.c:450)
__dev_queue_xmit (net/core/dev.c:4913)
packet_sendmsg (net/packet/af_packet.c:3139)
__sys_sendto (net/socket.c:2252)
__x64_sys_sendto (net/socket.c:2259)
do_syscall_64 (arch/x86/entry/syscall_64.c:94)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
Kernel panic - not syncing: Fatal exception in interrupt
Reject routes without an inet6_dev immediately after lookup. Such routes
are not eligible for reverse-path filtering, and the check protects all
later rt6i_idev dereferences.
Fixes: e26f9a480fb6 ("netfilter: add ipv6 reverse path filter match")
Reported-by: co+459f67f4d8af8ce6@bugs.sh
Closes: https://lore.kernel.org/all/VtWUkE8QzJt5CroTj2V2v3ZQ0gwbXZ7nq7I3@bugs.sh/
Suggested-by: Florian Westphal <fw@strlen.de>
Assisted-by: Claude:gpt-5
Cc: stable@vger.kernel.org
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv6/netfilter/ip6t_rpfilter.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/ipv6/netfilter/ip6t_rpfilter.c
+++ b/net/ipv6/netfilter/ip6t_rpfilter.c
@@ -61,7 +61,7 @@ static bool rpfilter_lookup_reverse6(str
fl6.flowi6_oif = dev->ifindex;
rt = (void *)ip6_route_lookup(net, &fl6, skb, lookup_flags);
- if (rt->dst.error)
+ if (rt->dst.error || !rt->rt6i_idev)
goto out;
if (rt->rt6i_flags & (RTF_REJECT|RTF_ANYCAST))
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 519/877] netfilter: ip6t_rt: fix zero-address non-strict match out-of-bounds read
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (517 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 518/877] netfilter: ip6t_rpfilter: reject routes without inet6_dev Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 520/877] netfilter: nf_tables: skip expired catchall elements on insert and delete Greg Kroah-Hartman
` (365 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Florian Westphal, Luxiao Xu,
Ren Wei, Pablo Neira Ayuso
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luxiao Xu <rakukuip@gmail.com>
commit 82313c169eddc02b1bf5ba6b427803e272d3ec42 upstream.
rt_mt6_check() permits rules to be configured with rtinfo->addrnr == 0
even when address matching (IP6T_RT_FST_MASK) is requested.
In the IP6T_RT_FST_NSTRICT path, rt_mt6() evaluates packet routing
addresses against rtinfo->addrs[i] and terminates backwards at the bottom
of the loop:
if (ipv6_addr_equal(ap, &rtinfo->addrs[i])) {
i++;
}
if (i == rtinfo->addrnr)
break;
When addrnr is 0, if the first packet address matches rtinfo->addrs[0],
i is incremented to 1. Because i is now strictly greater than addrnr (0),
the loop termination condition (i == rtinfo->addrnr) is bypassed and will
never be satisfied.
If a crafted IPv6 packet contains matching routing addresses, i will
advance past IP6T_RT_HOPS (16). The subsequent call to ipv6_addr_equal()
reads beyond struct ip6t_rt, triggering UBSAN/KASAN out-of-bounds warnings
or kernel panics.
Fix this by:
1. Rejecting rules in rt_mt6_check() where IP6T_RT_FST_MASK is set but
rtinfo->addrnr is zero.
2. In rt_mt6(), moving the termination condition (i < rtinfo->addrnr)
into the for-loop header condition and removing the backwards break
at the end of the loop body.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Suggested-by: Florian Westphal <fw@strlen.de>
Assisted-by: LLM
Signed-off-by: Luxiao Xu <rakukuip@gmail.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv6/netfilter/ip6t_rt.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
--- a/net/ipv6/netfilter/ip6t_rt.c
+++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -96,7 +96,8 @@ static bool rt_mt6(const struct sk_buff
unsigned int i = 0;
for (temp = 0;
- temp < (unsigned int)((hdrlen - 8) / 16);
+ temp < (unsigned int)((hdrlen - 8) / 16) &&
+ i < rtinfo->addrnr;
temp++) {
ap = skb_header_pointer(skb,
ptr
@@ -112,8 +113,6 @@ static bool rt_mt6(const struct sk_buff
if (ipv6_addr_equal(ap, &rtinfo->addrs[i]))
i++;
- if (i == rtinfo->addrnr)
- break;
}
if (i == rtinfo->addrnr)
return ret;
@@ -162,6 +161,12 @@ static int rt_mt6_check(const struct xt_
pr_debug("too many addresses specified\n");
return -EINVAL;
}
+
+ if ((rtinfo->flags & IP6T_RT_FST_MASK) && !rtinfo->addrnr) {
+ pr_info_ratelimited("address list match requested but addrnr is 0\n");
+ return -EINVAL;
+ }
+
if ((rtinfo->flags & (IP6T_RT_RES | IP6T_RT_FST_MASK)) &&
(!(rtinfo->flags & IP6T_RT_TYP) ||
(rtinfo->rt_type != 0) ||
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 520/877] netfilter: nf_tables: skip expired catchall elements on insert and delete
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (518 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 519/877] netfilter: ip6t_rt: fix zero-address non-strict match out-of-bounds read Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 521/877] nfc: fix use-after-free in nfc_get_local_general_bytes Greg Kroah-Hartman
` (364 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, TencentOS Corvus AI, Aohan Mei,
Pablo Neira Ayuso
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aohan Mei <henrymei@tencent.com>
commit 70194dc37670bd08e44b471389861cc01bd3a3c9 upstream.
nft_setelem_catchall_insert() looks up duplicates with
nft_set_elem_active() only, while nft_set_catchall_lookup() and the
dump path additionally skip expired elements.
Once a catchall element with a timeout expires, this predicate drift
makes it invisible to userspace dumps, yet it still blocks
re-insertion: with NLM_F_EXCL the request fails with -EEXIST, and
without it the request reports success but silently inserts nothing.
The stale entry only goes away when the (user-tunable) gc interval
elapses, so the catchall rule may silently stop matching for an
arbitrarily long time after its first expiration.
The delete path shows the same drift: nft_setelem_catchall_deactivate()
picks the first active-next entry in the catchall list, so with an
expired entry still pending GC it retires the stale entry instead of
the fresh one, and it deactivates an element that userspace no longer
sees instead of failing with -ENOENT.
Align both walks with the lookup and dump predicates: only an element
that is active and not expired counts as a duplicate or delete
candidate, using the per-netns timestamp taken at transaction start,
in line with the set backend .insert/.deactivate and catchall GC sync
paths.
Reported-by: TencentOS Corvus AI <corvus@tencent.com>
Cc: stable@vger.kernel.org
Fixes: aaa31047a6d2 ("netfilter: nftables: add catch-all set element support")
Assisted-by: CodeBuddy:Kimi-K3
Signed-off-by: Aohan Mei <henrymei@tencent.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/netfilter/nf_tables_api.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -6617,11 +6617,14 @@ static int nft_setelem_catchall_insert(c
{
struct nft_set_elem_catchall *catchall;
u8 genmask = nft_genmask_next(net);
+ u64 tstamp = nft_net_tstamp(net);
struct nft_set_ext *ext;
list_for_each_entry(catchall, &set->catchall_list, list) {
ext = nft_set_elem_ext(set, catchall->elem);
- if (nft_set_elem_active(ext, genmask)) {
+ if (nft_set_elem_active(ext, genmask) &&
+ !__nft_set_elem_expired(ext, tstamp) &&
+ !nft_set_elem_is_dead(ext)) {
*priv = catchall->elem;
return -EEXIST;
}
@@ -6682,11 +6685,14 @@ static int nft_setelem_catchall_deactiva
struct nft_set_elem *elem)
{
struct nft_set_elem_catchall *catchall;
+ u64 tstamp = nft_net_tstamp(net);
struct nft_set_ext *ext;
list_for_each_entry(catchall, &set->catchall_list, list) {
ext = nft_set_elem_ext(set, catchall->elem);
- if (!nft_is_active_next(net, ext))
+ if (!nft_is_active_next(net, ext) ||
+ __nft_set_elem_expired(ext, tstamp) ||
+ nft_set_elem_is_dead(ext))
continue;
kfree(elem->priv);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 521/877] nfc: fix use-after-free in nfc_get_local_general_bytes
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (519 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 520/877] netfilter: nf_tables: skip expired catchall elements on insert and delete Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 522/877] nfc: llcp: drop truncated I/RR/RNR PDUs in nfc_llcp_recv_hdlc() Greg Kroah-Hartman
` (363 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Luxiao Xu, Ren Wei,
Simon Horman, David Heidelberg
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luxiao Xu <rakukuip@gmail.com>
commit dcab71a7011918f6fdba7adcec02d217dcb84b8d upstream.
Commit 6709d4b7bc2e ("net: nfc: Fix use-after-free caused by
nfc_llcp_find_local") attempted to fix a use-after-free (UAF) issue by
invoking nfc_llcp_local_put(local) after accessing local->gb. However,
if the reference count drops to zero, local is freed immediately,
leading to a use-after-free when callers access the returned pointer.
Alternative approaches using dynamic allocation (e.g. kmemdup) introduced
memory leaks because callers consistently treat the returned pointer as
borrowed memory.
Fix this properly by refactoring nfc_llcp_general_bytes() and
nfc_get_local_general_bytes() to accept a caller-provided output buffer
(out_gb) and its maximum length (gb_max_len). The general bytes are
safely copied into out_gb before calling nfc_llcp_local_put(local),
ensuring safe lifetime management without ownership transfer complications.
Update all callers across drivers (microread, pn533, pn544, st21nfca,
digital_dep, and nci) to provide their own destination buffers and pass
them to nfc_get_local_general_bytes().
Fixes: 6709d4b7bc2e ("net: nfc: Fix use-after-free caused by nfc_llcp_find_local")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Signed-off-by: Luxiao Xu <rakukuip@gmail.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/3cbaac3bee23f8ff3a3284ed32d347696eb1d208.1788841683.git.rakukuip@gmail.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nfc/microread/microread.c | 6 +++---
drivers/nfc/pn533/pn533.c | 14 ++++++++------
drivers/nfc/pn533/pn533.h | 4 +++-
drivers/nfc/pn544/pn544.c | 7 +++----
drivers/nfc/st21nfca/core.c | 8 ++++----
include/net/nfc/hci.h | 2 +-
include/net/nfc/nfc.h | 3 ++-
net/nfc/core.c | 15 +++++++--------
net/nfc/digital_dep.c | 8 ++++----
net/nfc/llcp_core.c | 17 +++++++++++++----
net/nfc/nci/core.c | 10 +++++-----
net/nfc/nfc.h | 3 ++-
12 files changed, 55 insertions(+), 42 deletions(-)
--- a/drivers/nfc/microread/microread.c
+++ b/drivers/nfc/microread/microread.c
@@ -251,9 +251,9 @@ static int microread_start_poll(struct n
param[1] |= (1 << 1);
if ((im_protocols | tm_protocols) & NFC_PROTO_NFC_DEP_MASK) {
- hdev->gb = nfc_get_local_general_bytes(hdev->ndev,
- &hdev->gb_len);
- if (hdev->gb == NULL || hdev->gb_len == 0) {
+ nfc_get_local_general_bytes(hdev->ndev, hdev->gb,
+ sizeof(hdev->gb), &hdev->gb_len);
+ if (hdev->gb_len == 0) {
im_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
}
--- a/drivers/nfc/pn533/pn533.c
+++ b/drivers/nfc/pn533/pn533.c
@@ -1355,10 +1355,11 @@ static int pn533_poll_dep(struct nfc_dev
u8 *next, nfcid3[NFC_NFCID3_MAXSIZE];
u8 passive_data[PASSIVE_DATA_LEN] = {0x00, 0xff, 0xff, 0x00, 0x3};
- if (!dev->gb) {
- dev->gb = nfc_get_local_general_bytes(nfc_dev, &dev->gb_len);
-
- if (!dev->gb || !dev->gb_len) {
+ if (!dev->gb_len) {
+ nfc_get_local_general_bytes(nfc_dev, dev->gb,
+ sizeof(dev->gb),
+ &dev->gb_len);
+ if (!dev->gb_len) {
dev->poll_dep = 0;
queue_work(dev->wq, &dev->rf_work);
}
@@ -1660,8 +1661,9 @@ static int pn533_start_poll(struct nfc_d
}
if (tm_protocols) {
- dev->gb = nfc_get_local_general_bytes(nfc_dev, &dev->gb_len);
- if (dev->gb == NULL)
+ nfc_get_local_general_bytes(nfc_dev, dev->gb,
+ sizeof(dev->gb), &dev->gb_len);
+ if (dev->gb_len == 0)
tm_protocols = 0;
}
--- a/drivers/nfc/pn533/pn533.h
+++ b/drivers/nfc/pn533/pn533.h
@@ -6,6 +6,8 @@
* Copyright (C) 2012-2013 Tieto Poland
*/
+#include <net/nfc/nfc.h>
+
#define PN533_DEVICE_STD 0x1
#define PN533_DEVICE_PASORI 0x2
#define PN533_DEVICE_ACR122U 0x3
@@ -166,7 +168,7 @@ struct pn533 {
struct timer_list listen_timer;
int cancel_listen;
- u8 *gb;
+ u8 gb[NFC_MAX_GT_LEN];
size_t gb_len;
u8 tgt_available_prots;
--- a/drivers/nfc/pn544/pn544.c
+++ b/drivers/nfc/pn544/pn544.c
@@ -377,10 +377,9 @@ static int pn544_hci_start_poll(struct n
return r;
if ((im_protocols | tm_protocols) & NFC_PROTO_NFC_DEP_MASK) {
- hdev->gb = nfc_get_local_general_bytes(hdev->ndev,
- &hdev->gb_len);
- pr_debug("generate local bytes %p\n", hdev->gb);
- if (hdev->gb == NULL || hdev->gb_len == 0) {
+ nfc_get_local_general_bytes(hdev->ndev, hdev->gb,
+ sizeof(hdev->gb), &hdev->gb_len);
+ if (hdev->gb_len == 0) {
im_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
}
--- a/drivers/nfc/st21nfca/core.c
+++ b/drivers/nfc/st21nfca/core.c
@@ -351,10 +351,10 @@ static int st21nfca_hci_start_poll(struc
if (r < 0)
return r;
} else {
- hdev->gb = nfc_get_local_general_bytes(hdev->ndev,
- &hdev->gb_len);
-
- if (hdev->gb == NULL || hdev->gb_len == 0) {
+ nfc_get_local_general_bytes(hdev->ndev, hdev->gb,
+ sizeof(hdev->gb),
+ &hdev->gb_len);
+ if (hdev->gb_len == 0) {
im_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
}
--- a/include/net/nfc/hci.h
+++ b/include/net/nfc/hci.h
@@ -144,7 +144,7 @@ struct nfc_hci_dev {
data_exchange_cb_t async_cb;
void *async_cb_context;
- u8 *gb;
+ u8 gb[NFC_MAX_GT_LEN];
size_t gb_len;
unsigned long quirks;
--- a/include/net/nfc/nfc.h
+++ b/include/net/nfc/nfc.h
@@ -269,7 +269,8 @@ struct sk_buff *nfc_alloc_recv_skb(unsig
int nfc_set_remote_general_bytes(struct nfc_dev *dev,
const u8 *gt, u8 gt_len);
-u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, size_t *gb_len);
+u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, u8 *out_gb,
+ size_t gb_max_len, size_t *gb_len);
int nfc_fw_download_done(struct nfc_dev *dev, const char *firmware_name,
u32 result);
--- a/net/nfc/core.c
+++ b/net/nfc/core.c
@@ -279,10 +279,10 @@ static struct nfc_target *nfc_find_targe
int nfc_dep_link_up(struct nfc_dev *dev, int target_index, u8 comm_mode)
{
- int rc = 0;
- u8 *gb;
- size_t gb_len;
struct nfc_target *target;
+ u8 gb[NFC_MAX_GT_LEN];
+ size_t gb_len = 0;
+ int rc = 0;
pr_debug("dev_name=%s comm %d\n", dev_name(&dev->dev), comm_mode);
@@ -301,7 +301,7 @@ int nfc_dep_link_up(struct nfc_dev *dev,
goto error;
}
- gb = nfc_llcp_general_bytes(dev, &gb_len);
+ nfc_get_local_general_bytes(dev, gb, sizeof(gb), &gb_len);
if (gb_len > NFC_MAX_GT_LEN) {
rc = -EINVAL;
goto error;
@@ -644,11 +644,10 @@ int nfc_set_remote_general_bytes(struct
}
EXPORT_SYMBOL(nfc_set_remote_general_bytes);
-u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, size_t *gb_len)
+u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, u8 *out_gb,
+ size_t gb_max_len, size_t *gb_len)
{
- pr_debug("dev_name=%s\n", dev_name(&dev->dev));
-
- return nfc_llcp_general_bytes(dev, gb_len);
+ return nfc_llcp_general_bytes(dev, out_gb, gb_max_len, gb_len);
}
EXPORT_SYMBOL(nfc_get_local_general_bytes);
--- a/net/nfc/digital_dep.c
+++ b/net/nfc/digital_dep.c
@@ -1490,14 +1490,14 @@ static int digital_tg_send_atr_res(struc
struct digital_atr_req *atr_req)
{
struct digital_atr_res *atr_res;
+ u8 gb[NFC_MAX_GT_LEN];
struct sk_buff *skb;
- u8 *gb, payload_bits;
+ u8 payload_bits;
size_t gb_len;
int rc;
- gb = nfc_get_local_general_bytes(ddev->nfc_dev, &gb_len);
- if (!gb)
- gb_len = 0;
+ nfc_get_local_general_bytes(ddev->nfc_dev, gb, sizeof(gb),
+ &gb_len);
skb = digital_skb_alloc(ddev, sizeof(struct digital_atr_res) + gb_len);
if (!skb)
--- a/net/nfc/llcp_core.c
+++ b/net/nfc/llcp_core.c
@@ -651,23 +651,32 @@ out:
return ret;
}
-u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len)
+u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, u8 *out_gb, size_t gb_max_len,
+ size_t *general_bytes_len)
{
struct nfc_llcp_local *local;
+ if (!out_gb || !general_bytes_len)
+ return NULL;
+
local = nfc_llcp_find_local(dev);
- if (local == NULL) {
+ if (!local) {
*general_bytes_len = 0;
return NULL;
}
nfc_llcp_build_gb(local);
- *general_bytes_len = local->gb_len;
+ if (local->gb_len) {
+ *general_bytes_len = min_t(size_t, local->gb_len, gb_max_len);
+ memcpy(out_gb, local->gb, *general_bytes_len);
+ } else {
+ *general_bytes_len = 0;
+ }
nfc_llcp_local_put(local);
- return local->gb;
+ return out_gb;
}
int nfc_llcp_set_remote_gb(struct nfc_dev *dev, const u8 *gb, u8 gb_len)
--- a/net/nfc/nci/core.c
+++ b/net/nfc/nci/core.c
@@ -772,15 +772,15 @@ static int nci_set_local_general_bytes(s
{
struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
struct nci_set_config_param param;
+ u8 gb[NFC_MAX_GT_LEN];
int rc;
- param.val = nfc_get_local_general_bytes(nfc_dev, ¶m.len);
- if ((param.val == NULL) || (param.len == 0))
+ nfc_get_local_general_bytes(nfc_dev, gb, sizeof(gb),
+ ¶m.len);
+ if (param.len == 0)
return 0;
- if (param.len > NFC_MAX_GT_LEN)
- return -EINVAL;
-
+ param.val = gb;
param.id = NCI_PN_ATR_REQ_GEN_BYTES;
rc = nci_request(ndev, nci_set_config_req, ¶m,
--- a/net/nfc/nfc.h
+++ b/net/nfc/nfc.h
@@ -49,7 +49,8 @@ void nfc_llcp_mac_is_up(struct nfc_dev *
int nfc_llcp_register_device(struct nfc_dev *dev);
void nfc_llcp_unregister_device(struct nfc_dev *dev);
int nfc_llcp_set_remote_gb(struct nfc_dev *dev, const u8 *gb, u8 gb_len);
-u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len);
+u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, u8 *out_gb, size_t gb_max_len,
+ size_t *general_bytes_len);
int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb);
struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev);
int nfc_llcp_local_put(struct nfc_llcp_local *local);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 522/877] nfc: llcp: drop truncated I/RR/RNR PDUs in nfc_llcp_recv_hdlc()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (520 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 521/877] nfc: fix use-after-free in nfc_get_local_general_bytes Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 523/877] nfc: port100: reject frames whose declared length exceeds the received data Greg Kroah-Hartman
` (362 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aamir Ahmed, Simon Horman,
David Heidelberg
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aamir Ahmed <elb12345@hotmail.co.uk>
commit 273f9d667cde649f8de9d72b1303cc2f4b658c50 upstream.
nfc_llcp_recv_hdlc() reads the sequence byte skb->data[2], via
nfc_llcp_ns()/nfc_llcp_nr(), before any length check. The receive path
only guarantees the two-byte LLCP header -- __nfc_llcp_recv() checks it
with pskb_may_pull() and nfc_llcp_recv_agf() admits two-byte inner PDUs
-- so a two-byte I, RR or RNR PDU reads one byte of uninitialised skb
tailroom. The byte becomes N(R)/N(S); a peer can already set those with
a well-formed PDU, so this is acting on uninitialised memory, not new
peer control.
Guard the read with pskb_may_pull(), as commit 95674f506c63 ("nfc: llcp:
reject PDUs shorter than the LLCP header") did for the two-byte header,
so the sequence byte is present and linear before it is read. RR and RNR
PDUs are LLCP_HEADER_SIZE + LLCP_SEQUENCE_SIZE bytes and an I PDU is
longer, so no valid frame is rejected; a truncated PDU is malformed, so
return without a DM reply.
Fixes: d646960f7986 ("NFC: Initial LLCP support")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Aamir Ahmed <elb12345@hotmail.co.uk>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/AS8P251MB0001789BBF04B72745C7D96BC8BA2@AS8P251MB0001.EURP251.PROD.OUTLOOK.COM
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/nfc/llcp_core.c | 3 +++
1 file changed, 3 insertions(+)
--- a/net/nfc/llcp_core.c
+++ b/net/nfc/llcp_core.c
@@ -1099,6 +1099,9 @@ static void nfc_llcp_recv_hdlc(struct nf
struct sock *sk;
u8 dsap, ssap, ptype, ns, nr;
+ if (!pskb_may_pull(skb, LLCP_HEADER_SIZE + LLCP_SEQUENCE_SIZE))
+ return;
+
ptype = nfc_llcp_ptype(skb);
dsap = nfc_llcp_dsap(skb);
ssap = nfc_llcp_ssap(skb);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 523/877] nfc: port100: reject frames whose declared length exceeds the received data
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (521 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 522/877] nfc: llcp: drop truncated I/RR/RNR PDUs in nfc_llcp_recv_hdlc() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 524/877] scsi: libiscsi_tcp: Check the data direction of a Data-In PDU Greg Kroah-Hartman
` (361 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Doruk Tan Ozturk, Simon Horman,
David Heidelberg
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Doruk Tan Ozturk <doruk@0sec.ai>
commit 092c6a605cbd6414ef499834c2e0da69c2c3388e upstream.
port100_recv_response() passes the URB transfer buffer to
port100_rx_frame_is_valid(), which checksums le16_to_cpu(frame->datalen)
bytes of frame->data. datalen is a 16-bit field supplied by the device
and is never checked against the number of bytes actually received
(urb->actual_length), so a device reporting a datalen larger than the
received frame makes port100_data_checksum() read out of bounds past the
transfer buffer.
Reject a response whose declared frame size does not fit the received
length before validating it.
Found by 0sec (https://0sec.ai) using automated source analysis; the
missing bound is evident from source. Compile-tested.
Fixes: 562d4d59b8a1 ("NFC: Sony Port-100 Series driver")
Cc: stable@vger.kernel.org
Assisted-by: 0sec:claude-opus-4-8
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260711123651.32595-1-doruk@0sec.ai
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nfc/port100.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/drivers/nfc/port100.c
+++ b/drivers/nfc/port100.c
@@ -636,6 +636,13 @@ static void port100_recv_response(struct
in_frame = dev->in_urb->transfer_buffer;
+ if (urb->actual_length < PORT100_FRAME_HEADER_LEN ||
+ urb->actual_length < port100_rx_frame_size(in_frame)) {
+ nfc_err(&dev->interface->dev, "Received a truncated frame\n");
+ cmd->status = -EIO;
+ goto sched_wq;
+ }
+
if (!port100_rx_frame_is_valid(in_frame)) {
nfc_err(&dev->interface->dev, "Received an invalid frame\n");
cmd->status = -EIO;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 524/877] scsi: libiscsi_tcp: Check the data direction of a Data-In PDU
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (522 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 523/877] nfc: port100: reject frames whose declared length exceeds the received data Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 525/877] perf/core: Fix NULL pmu_ctx passed to pmu->sched_task() Greg Kroah-Hartman
` (360 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yehyeong Lee, Mike Christie,
Martin K. Petersen (Oracle)
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
commit bce07e2f37b5e4a427d36fd6b1c14067b27591db upstream.
The Data-In branch of iscsi_tcp_hdr_dissect() resolves the ITT to a task
and copies the PDU's data segment into that command's scatterlist without
asking whether the command was reading. iscsi_tcp_r2t_rsp() in the same
file does ask, and rejects an R2T for a command that is not DMA_TO_DEVICE.
A target that answers a WRITE command's ITT with a Data-In therefore has
the initiator write target-supplied bytes into the pages that write was
about to send. Those are the caller's own pinned pages for an O_DIRECT
write, and page cache pages for a buffered one.
Observed against a test target that emits one 512-byte Data-In naming a 128
KB write's ITT, after the R2T for that write. With O_DIRECT the caller's
buffer ends up holding 512 bytes of the target's data while pwrite()
returns 131072. Buffered is quieter: pwrite() and fsync() both succeed,
nothing is logged, and reading those blocks back returns the target's bytes
out of the page cache without a command going on the wire.
Check the direction before using the scatterlist, the way the R2T path
already does.
Cc: stable@vger.kernel.org
Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Link: https://patch.msgid.link/20260801133635.1986706-1-yhlee@isslab.korea.ac.kr
Fixes: a081c13e39b5 ("[SCSI] iscsi_tcp: split module into lib and lld")
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/scsi/libiscsi_tcp.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/scsi/libiscsi_tcp.c
+++ b/drivers/scsi/libiscsi_tcp.c
@@ -491,6 +491,9 @@ static int iscsi_tcp_data_in(struct iscs
int datasn = be32_to_cpu(rhdr->datasn);
unsigned total_in_length = task->sc->sdb.length;
+ if (task->sc->sc_data_direction != DMA_FROM_DEVICE)
+ return ISCSI_ERR_PROTO;
+
/*
* lib iscsi will update this in the completion handling if there
* is status.
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 525/877] perf/core: Fix NULL pmu_ctx passed to pmu->sched_task()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (523 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 524/877] scsi: libiscsi_tcp: Check the data direction of a Data-In PDU Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 526/877] perf/core: Run sched_task() for PMUs with only CPU-wide events Greg Kroah-Hartman
` (359 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Puranjay Mohan,
Peter Zijlstra (Intel), Yifan Wu
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Puranjay Mohan <puranjay@kernel.org>
commit 36bb85cf36cab15fb611cb44b78a5df06e4e69a2 upstream.
perf_pmu_sched_task() returns early when cpuctx->task_ctx is set, and
cpc->task_epc is only non-NULL while a task context is scheduled in on
this CPU. __perf_pmu_sched_task() therefore always passes NULL:
Unable to handle kernel NULL pointer dereference at virtual address 00
pc : armv8pmu_sched_task+0x14/0x50
Call trace:
armv8pmu_sched_task+0x14/0x50 (P)
perf_pmu_sched_task+0xac/0x108
__perf_event_task_sched_out+0x6c/0xe0
Pass &cpc->epc instead, the CPU-wide context for this PMU, which the
function already dereferences a few lines up to find pmu.
armv8pmu_sched_task() is the only in-tree implementation that
dereferences the argument, and it only reads ->pmu, so the oops needs
BRBE, added in v6.17.
Fixes: bd2756811766 ("perf: Rewrite core context handling")
Signed-off-by: Puranjay Mohan <puranjay@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: Yifan Wu <wuyifan50@huawei.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260810133540.1947118-2-puranjay@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/events/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3754,7 +3754,7 @@ static void __perf_pmu_sched_task(struct
perf_ctx_lock(cpuctx, cpuctx->task_ctx);
perf_pmu_disable(pmu);
- pmu->sched_task(cpc->task_epc, task, sched_in);
+ pmu->sched_task(&cpc->epc, task, sched_in);
perf_pmu_enable(pmu);
perf_ctx_unlock(cpuctx, cpuctx->task_ctx);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 526/877] perf/core: Run sched_task() for PMUs with only CPU-wide events
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (524 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 525/877] perf/core: Fix NULL pmu_ctx passed to pmu->sched_task() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 527/877] pinctrl: single: free the IRQ on domain creation failure Greg Kroah-Hartman
` (358 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Puranjay Mohan,
Peter Zijlstra (Intel), Yifan Wu
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Puranjay Mohan <puranjay@kernel.org>
commit 3d8d74100954a3b17e5c5e37adfe14e16b1db103 upstream.
perf_pmu_sched_task() returns early when cpuctx->task_ctx is set and
leaves the work to perf_ctx_sched_task_cb(), which only walks
ctx->pmu_ctx_list. A PMU whose events are all CPU-wide is not on that
list, so nothing calls its sched_task(). With
perf record -b -e cycles -a -- ls
armv8pmu_sched_task() is skipped on every switch to a task that has a
perf context but no event on that PMU, and BRBE records leak across the
task boundary. intel_pmu_lbr_add() calls perf_sched_cb_inc()
unconditionally too, so LBR records leak the same way on x86.
Drop the early return and skip only the CPCs that
perf_ctx_sched_task_cb() handles. That one needs a gate of its own to
make the split exact: it tests cpc->sched_cb_usage, which
perf_sched_cb_inc() sets per CPU for every branch stack user, so a task
with an event for that PMU pinned to another CPU would be handled twice.
On x86 the second __intel_pmu_lbr_restore() finds lbr_stack_state ==
LBR_NONE and calls intel_pmu_lbr_reset(), throwing away the callstack
the first one restored.
cpc->task_epc is set only while a task context is scheduled in, and
there is one epc per PMU on ctx->pmu_ctx_list, so the two gates are
inverses.
For the CPCs perf_pmu_sched_task() picks up, the callback now runs
outside the perf_ctx_disable() and perf_ctx_enable() pair in
perf_event_context_sched_in(). __perf_pmu_sched_task() disables the PMU
around the call itself.
Fixes: bd2756811766 ("perf: Rewrite core context handling")
Signed-off-by: Puranjay Mohan <puranjay@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: Yifan Wu <wuyifan50@huawei.com>
Link: https://patch.msgid.link/20260810133540.1947118-3-puranjay@kernel.org
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/events/core.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3603,6 +3603,9 @@ static void perf_ctx_sched_task_cb(struc
list_for_each_entry(pmu_ctx, &ctx->pmu_ctx_list, pmu_ctx_entry) {
cpc = this_cpu_ptr(pmu_ctx->pmu->cpu_pmu_context);
+ if (cpc->task_epc != pmu_ctx)
+ continue;
+
if (cpc->sched_cb_usage && pmu_ctx->pmu->sched_task)
pmu_ctx->pmu->sched_task(pmu_ctx, task, sched_in);
}
@@ -3764,15 +3767,17 @@ static void perf_pmu_sched_task(struct t
struct task_struct *next,
bool sched_in)
{
- struct perf_cpu_context *cpuctx = this_cpu_ptr(&perf_cpu_context);
struct perf_cpu_pmu_context *cpc, *cpc2;
- /* cpuctx->task_ctx will be handled in perf_event_context_sched_in/out */
- if (prev == next || cpuctx->task_ctx)
+ if (prev == next)
return;
- list_for_each_entry_safe(cpc, cpc2, this_cpu_ptr(&sched_cb_list), sched_cb_entry)
+ list_for_each_entry_safe(cpc, cpc2, this_cpu_ptr(&sched_cb_list), sched_cb_entry) {
+ if (cpc->task_epc)
+ continue;
+
__perf_pmu_sched_task(cpc, sched_in ? next : prev, sched_in);
+ }
}
static void perf_event_switch(struct task_struct *task,
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 527/877] pinctrl: single: free the IRQ on domain creation failure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (525 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 526/877] perf/core: Run sched_task() for PMUs with only CPU-wide events Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 528/877] pinctrl: sunxi: keep a shadow copy of the data register output latches Greg Kroah-Hartman
` (357 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ijae Kim, Myeonghun Pak,
Linus Walleij
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <mhun512@gmail.com>
commit 1d9bb9c870632adea249cfdec49ac37e6f069164 upstream.
pcs_irq_init_chained_handler() requests a shared IRQ on affected SoCs, but
its domain creation failure path only removes a chained handler. That does
not release the action installed by request_irq(). The probe can continue
without interrupt support while leaving the shared IRQ action registered.
Use pcs_irq_free() to undo the appropriate type of handler registration.
At this point pcs->domain is NULL, so the helper only releases the parent
IRQ handler. Then mark the IRQ invalid, as the other initialization error
paths already do, to prevent another release from a later probe unwind or
remove.
This issue was identified during our ongoing static-analysis research while
reviewing kernel code.
Fixes: 3e6cee1786a1 ("pinctrl: single: Add support for wake-up interrupts")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Signed-off-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/pinctrl/pinctrl-single.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -1626,7 +1626,8 @@ static int pcs_irq_init_chained_handler(
&pcs_irqdomain_ops,
pcs_soc);
if (!pcs->domain) {
- irq_set_chained_handler(pcs_soc->irq, NULL);
+ pcs_irq_free(pcs);
+ pcs_soc->irq = -1;
return -EINVAL;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 528/877] pinctrl: sunxi: keep a shadow copy of the data register output latches
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (526 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 527/877] pinctrl: single: free the IRQ on domain creation failure Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 529/877] s390/cio: Fix NULL pointer dereference in ccw_device_get_util_str() Greg Kroah-Hartman
` (356 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ilya Titov, Linus Walleij
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilya Titov <ilya.titov@wirenboard.com>
commit a13f7f5d14af9baf34eb12c25962f8d3542b281d upstream.
On Allwinner SoCs, reading a bank's data register returns the pin level,
not the output latch, for pins that are muxed as inputs. Writing a GPIO
therefore corrupts the output latches of all input-muxed pins in the
same bank: the read-modify-write in sunxi_pinctrl_gpio_set() reads back
their pin levels and writes those into their latches.
This breaks emulated open-drain lines (e.g. a bit-banged I2C bus from
i2c-gpio). Such a line is released high by muxing it as input and
letting the pull-up raise it, so any concurrent GPIO write in the same
bank stores 1 into its latch. Driving the line low afterwards is a
non-atomic data-then-mux sequence in sunxi_pinctrl_gpio_direction_output();
if the poisoning write lands between the two steps, the pin actively
drives high (push-pull) instead of low.
Observed in practice as sporadic glitches on a T507 board bit-banging
I2C on port E while other PE GPIOs are toggled. On a scope the failure
is unmistakable: on a clock pulse where SCL should fall to GND, the line
instead steps *above* its idle high level for the whole low phase — the
pad drives a strong push-pull 3.3 V high, higher than the level the
pull-up sustains on the loaded bus — before the next transition recovers
it. The same can hit SDA, corrupting data instead of clocks.
Steps to reproduce on any sunxi board with a bit-banged (i2c-gpio) bus:
# background: toggle any other GPIO of the same bank, e.g. line 21
gpioset -c <chip> --toggle 100us 21=0 &
# foreground: keep the bit-banged bus busy
while :; do i2cdetect -y <bus> 0x50 0x57; done
# watch SCL/SDA with a scope or logic analyzer: sporadic clock-low
# phases driven high (above the pull-up level) instead of low
The bank spinlock cannot help: the racing write is a perfectly valid
whole-register RMW that faithfully writes back what the hardware
returned. There are no set/clear registers on this IP to write a single
bit atomically.
Fix it the same way gpio-mmio handles hardware whose data register read
does not return the output latch: keep a shadow copy of each bank's
latches, base the read-modify-write on the shadow, and only write the
register. The shadow is seeded from the hardware at probe time so pins
left in output mode by the bootloader keep their state. Pins that reach
output mode through the gpiolib paths write their value (and thereby
their shadow bit) before the mux switch in
sunxi_pinctrl_gpio_direction_output(); pins muxed to gpio_out directly
through a pinmux node bypass that path, so sunxi_pmx_set() refreshes
their shadow bit from the latch (readable once the pin is in output
mode) to keep them driving their pre-existing level.
Seeding the shadow reads the PIO registers at probe time, which requires
the bus clock to be enabled. The clock was only requested at the very
end of probe, after devm_pinctrl_register() had already claimed the pin
hogs described in the device tree - which mux pins, and thus access
registers, with the clock still gated. Move the request ahead of both.
Boards whose bootloader leaves the PIO clock running are unaffected,
which is why the pre-existing hog problem has gone unnoticed since
commit 950707c0eb5c ("pinctrl: sunxi: add clock support").
Fixes: df7b34f4c3d2 ("pinctrl: sunxi: Fix gpio_set behaviour")
Cc: stable@vger.kernel.org
Signed-off-by: Ilya Titov <ilya.titov@wirenboard.com>
Signed-off-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/pinctrl/sunxi/pinctrl-sunxi.c | 76 +++++++++++++++++++++++++++-------
drivers/pinctrl/sunxi/pinctrl-sunxi.h | 7 +++
2 files changed, 68 insertions(+), 15 deletions(-)
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -792,6 +792,21 @@ static void sunxi_pmx_set(struct pinctrl
writel((readl(pctl->membase + reg) & ~mask) | config << shift,
pctl->membase + reg);
+ /*
+ * A pin muxed to gpio_out directly through a pinmux node bypasses
+ * sunxi_pinctrl_gpio_set() and drives whatever its output latch
+ * holds. Now that the pin is in output mode the data register
+ * reads back the latch, so refresh the shadow to keep such pins
+ * driving their pre-existing level.
+ */
+ if (config == SUN4I_FUNC_OUTPUT) {
+ u32 *shadow = &pctl->dat_shadow[pin / PINS_PER_BANK];
+
+ sunxi_data_reg(pctl, pin, ®, &shift, &mask);
+ *shadow = (*shadow & ~mask) |
+ (readl(pctl->membase + reg) & mask);
+ }
+
raw_spin_unlock_irqrestore(&pctl->lock, flags);
}
@@ -948,21 +963,29 @@ static void sunxi_pinctrl_gpio_set(struc
unsigned offset, int value)
{
struct sunxi_pinctrl *pctl = gpiochip_get_data(chip);
- u32 reg, shift, mask, val;
+ u32 *shadow = &pctl->dat_shadow[offset / PINS_PER_BANK];
+ u32 reg, shift, mask;
unsigned long flags;
sunxi_data_reg(pctl, offset, ®, &shift, &mask);
raw_spin_lock_irqsave(&pctl->lock, flags);
- val = readl(pctl->membase + reg);
-
+ /*
+ * Reading the data register returns the pin level, not the output
+ * latch, for pins muxed as inputs. A read-modify-write based on
+ * the register would therefore corrupt the latches of input-muxed
+ * pins in the same bank (e.g. an emulated open-drain I2C line
+ * released high), making them drive the wrong level once switched
+ * to output. Base the read-modify-write on a shadow copy of the
+ * latches instead.
+ */
if (value)
- val |= mask;
+ *shadow |= mask;
else
- val &= ~mask;
+ *shadow &= ~mask;
- writel(val, pctl->membase + reg);
+ writel(*shadow, pctl->membase + reg);
raw_spin_unlock_irqrestore(&pctl->lock, flags);
}
@@ -1486,7 +1509,7 @@ int sunxi_pinctrl_init_with_variant(stru
struct pinctrl_pin_desc *pins;
struct sunxi_pinctrl *pctl;
struct pinmux_ops *pmxops;
- int i, ret, last_pin, pin_idx;
+ int i, ret, last_pin, pin_idx, nbanks;
struct clk *clk;
pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
@@ -1520,6 +1543,37 @@ int sunxi_pinctrl_init_with_variant(stru
if (!pctl->irq_array)
return -ENOMEM;
+ /*
+ * The bus clock has to be enabled before the pinctrl device
+ * registers, as the pin hogs claimed from there access registers.
+ */
+ ret = of_clk_get_parent_count(node);
+ clk = devm_clk_get_enabled(&pdev->dev, ret == 1 ? NULL : "apb");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ /*
+ * Seed the output latch shadow from the hardware so pins the
+ * bootloader left in output mode keep their state; see
+ * sunxi_pinctrl_gpio_set() for why a shadow is needed. This must
+ * happen before the pinctrl device registers, as pin hogs can mux
+ * pins to gpio_out and thereby update the shadow.
+ */
+ last_pin = pctl->desc->pins[pctl->desc->npins - 1].pin.number;
+ nbanks = DIV_ROUND_UP(last_pin + 1 - pctl->desc->pin_base,
+ PINS_PER_BANK);
+ pctl->dat_shadow = devm_kcalloc(&pdev->dev, nbanks,
+ sizeof(*pctl->dat_shadow), GFP_KERNEL);
+ if (!pctl->dat_shadow)
+ return -ENOMEM;
+
+ for (i = 0; i < nbanks; i++) {
+ u32 reg, shift, mask;
+
+ sunxi_data_reg(pctl, i * PINS_PER_BANK, ®, &shift, &mask);
+ pctl->dat_shadow[i] = readl(pctl->membase + reg);
+ }
+
ret = sunxi_pinctrl_build_state(pdev);
if (ret) {
dev_err(&pdev->dev, "dt probe failed: %d\n", ret);
@@ -1574,7 +1628,6 @@ int sunxi_pinctrl_init_with_variant(stru
if (!pctl->chip)
return -ENOMEM;
- last_pin = pctl->desc->pins[pctl->desc->npins - 1].pin.number;
pctl->chip->owner = THIS_MODULE;
pctl->chip->request = gpiochip_generic_request;
pctl->chip->free = gpiochip_generic_free;
@@ -1607,13 +1660,6 @@ int sunxi_pinctrl_init_with_variant(stru
goto gpiochip_error;
}
- ret = of_clk_get_parent_count(node);
- clk = devm_clk_get_enabled(&pdev->dev, ret == 1 ? NULL : "apb");
- if (IS_ERR(clk)) {
- ret = PTR_ERR(clk);
- goto gpiochip_error;
- }
-
pctl->irq = devm_kcalloc(&pdev->dev,
pctl->desc->irq_banks,
sizeof(*pctl->irq),
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
@@ -80,6 +80,7 @@
#define IO_BIAS_MASK GENMASK(3, 0)
#define SUN4I_FUNC_INPUT 0
+#define SUN4I_FUNC_OUTPUT 1
#define SUN4I_FUNC_IRQ 6
#define PINCTRL_SUN5I_A10S BIT(1)
@@ -173,6 +174,12 @@ struct sunxi_pinctrl {
int *irq;
unsigned *irq_array;
raw_spinlock_t lock;
+ /*
+ * Output latch shadow, one word per bank. Seeded lockless at
+ * probe before the pinctrl device registers, protected by @lock
+ * afterwards.
+ */
+ u32 *dat_shadow;
struct pinctrl_dev *pctl_dev;
unsigned long variant;
u32 bank_mem_size;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 529/877] s390/cio: Fix NULL pointer dereference in ccw_device_get_util_str()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (527 preceding siblings ...)
2026-09-30 15:23 ` [PATCH 6.12 528/877] pinctrl: sunxi: keep a shadow copy of the data register output latches Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 530/877] s390/cmf: Fix virtual vs physical address confusion Greg Kroah-Hartman
` (355 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vineeth Vijayan, Peter Oberparleiter,
Heiko Carstens
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vineeth Vijayan <vneethv@linux.ibm.com>
commit 5b76268dac968612f7283d59b539036de955b7d9 upstream.
The channel path registry entry associated with a CHPID may be removed
while the subchannel's PMCW still references that CHPID. In this case,
chpid_to_chp() can return NULL, leading to a NULL pointer dereference.
Add the missing NULL check before dereferencing the returned pointer.
Fixes: 199652309a4d ("s390/cio: add helper to query utility strings per given ccw device")
Cc: stable@vger.kernel.org
Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/s390/cio/device_ops.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -517,6 +517,8 @@ u8 *ccw_device_get_util_str(struct ccw_d
chp_id_init(&chpid);
chpid.id = sch->schib.pmcw.chpid[chp_idx];
chp = chpid_to_chp(chpid);
+ if (!chp)
+ return NULL;
util_str = kmalloc(sizeof(chp->desc_fmt3.util_str), GFP_KERNEL);
if (!util_str)
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 530/877] s390/cmf: Fix virtual vs physical address confusion
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (528 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 529/877] s390/cio: Fix NULL pointer dereference in ccw_device_get_util_str() Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 531/877] s390/vfio-ap: fix KVM GISC and page leak when queue removed from host config Greg Kroah-Hartman
` (354 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Peter Oberparleiter, Heiko Carstens
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Oberparleiter <oberpar@linux.ibm.com>
commit f4d04425e66af2ecee9d1a49ae0484436f3c2fd1 upstream.
The measurement block address is an absolute address. Define the
associated schib_config and schib fields as dma64_t to enable automatic
detection of incorrect assignments. Also add the missing virt_to_dma64()
translation.
Without this fix, a wrong address will be used by firmware when storing
extended format channel measurement data on kernels built with
CONFIG_RANDOMIZE_IDENTITY_BASE=y.
Fixes: 14edd0d73bfe ("s390/cmf: fix virtual vs physical address confusion")
Cc: stable@vger.kernel.org
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/s390/cio/cio.h | 5 +++--
drivers/s390/cio/cmf.c | 2 +-
2 files changed, 4 insertions(+), 3 deletions(-)
--- a/drivers/s390/cio/cio.h
+++ b/drivers/s390/cio/cio.h
@@ -7,6 +7,7 @@
#include <linux/mod_devicetable.h>
#include <asm/chpid.h>
#include <asm/cio.h>
+#include <asm/dma-types.h>
#include <asm/fcx.h>
#include <asm/schid.h>
#include <asm/tpi.h>
@@ -49,7 +50,7 @@ struct pmcw {
/* Target SCHIB configuration. */
struct schib_config {
- u64 mba;
+ dma64_t mba;
u32 intparm;
u16 mbi;
u32 isc:3;
@@ -66,7 +67,7 @@ struct schib_config {
struct schib {
struct pmcw pmcw; /* path management control word */
union scsw scsw; /* subchannel status word */
- __u64 mba; /* measurement block address */
+ dma64_t mba; /* measurement block address */
__u8 mda[4]; /* model dependent area */
} __attribute__ ((packed,aligned(4)));
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -184,7 +184,7 @@ static int set_schib(struct ccw_device *
sch->config.mbfc = mbfc;
/* address can be either a block address or a block index */
if (mbfc)
- sch->config.mba = address;
+ sch->config.mba = address ? virt_to_dma64((void *)address) : 0;
else
sch->config.mbi = address;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 531/877] s390/vfio-ap: fix KVM GISC and page leak when queue removed from host config
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (529 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 530/877] s390/cmf: Fix virtual vs physical address confusion Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 532/877] KVM: Ensure memory attributes xarray nodes are accounted to the callers memcg Greg Kroah-Hartman
` (353 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Anthony Krowiak, Matthew Rosato,
Halil Pasic, Claudio Imbrenda
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anthony Krowiak <akrowiak@linux.ibm.com>
commit 65e05ec252a9b79e75930d3c4dd42d8877db04c5 upstream.
Three related problems exist in the handling of KVM interrupt and page
resources when a queue is removed from the host's AP configuration
while assigned to a mediated device (mdev).
Problem 1:
~~~~~~~~~
AP_RESPONSE_Q_NOT_AVAIL not handled in vfio_ap_mdev_reset_queue()
When the AP bus removes a queue device whose adapter or domain has
been removed from the host's AP configuration,
vfio_ap_mdev_remove_queue() is called. If the queue is still in the
host's AP configuration at that point, it calls
vfio_ap_mdev_reset_queue(), which issues a PQAP(ZAPQ). Since the
adapter is already gone from the host configuration, ap_zapq() returns
AP_RESPONSE_Q_NOT_AVAIL (0x01). This response code is not handled in
vfio_ap_mdev_reset_queue()'s switch statement and falls through to
the default case, which issues a WARN but does not call
vfio_ap_free_aqic_resources(). As a result, if IRQ handling was
enabled for the queue by the guest, the KVM GISC registration and
the pinned guest page holding the notification indicator byte (NIB)
are both leaked.
This is fixed by adding AP_RESPONSE_Q_NOT_AVAIL to the same case as
AP_RESPONSE_DECONFIGURED and AP_RESPONSE_CHECKSTOPPED in
vfio_ap_mdev_reset_queue(). Like those response codes, Q_NOT_AVAIL
indicates the queue is not operational and no further reset attempts
are possible; the correct action is to free the IRQ resources
immediately.
Problem 2:
~~~~~~~~~
AP_RESPONSE_Q_NOT_AVAIL not handled in apq_status_check()
In vfio_ap_mdev_reset_queue(), there are four cases that indicate a queue
reset has not yet completed, in which case apq_reset_check() is queued to
a work queue to verify completion of the reset operation. This function
uses the PQAP(TAPQ) function to get the queue's status and calls
apq_status_check() to verify whether the reset has completed, failed or
needs to be executed again. As described in Problem #1 above,
apq_reset_check() does not specifically check for AP_RESPONSE_Q_NOT_AVAIL,
thereby potentially leaking KVM GISC registration and the pinned guest page
holding the NIB.
This is fixed by adding a case statement for AP_RESPONSE_Q_NOT_AVAIL to
apq_status_check() and returning -ENODEV for that case. The caller,
apq_reset_check() will then check for this return code and call
vfio_ap_free_aqic_resources() to prevent the leak.
Problem 3:
~~~~~~~~~
vfio_ap_free_aqic_resources() leaks saved_isc when kvm is NULL
vfio_ap_free_aqic_resources() guards the call to
kvm_s390_gisc_unregister() with:
if (q->saved_isc != VFIO_AP_ISC_INVALID &&
!WARN_ON(!(q->matrix_mdev && q->matrix_mdev->kvm)))
If matrix_mdev->kvm is NULL -- which can happen when
vfio_ap_mdev_unset_kvm() has already run and cleared kvm before a
subsequent cleanup path reaches this function -- the WARN_ON fires
and the entire block is skipped. This leaves q->saved_isc set to a
non-invalid value, creating a potential double-free on any subsequent
call to this function.
When kvm is NULL the KVM guest is already torn down, so
kvm_s390_gisc_unregister() need not and cannot be called; however,
q->saved_isc must always be cleared. Fix this by separating the
kvm_s390_gisc_unregister() call from the q->saved_isc reset. The
WARN_ON now guards only the genuinely impossible case of matrix_mdev
being NULL. A NULL kvm is handled gracefully by skipping only the
unregister call, and q->saved_isc = VFIO_AP_ISC_INVALID is set
unconditionally whenever saved_isc was not already invalid.
Additionally, add an else clause to the host-config check in
vfio_ap_mdev_remove_queue() to call vfio_ap_free_aqic_resources()
directly when the queue is not in the host's AP configuration. This
serves as a backstop: when the AP bus fires the driver .remove
callback after an adapter is removed from the host config, the queue
is by definition no longer addressable, so vfio_ap_mdev_reset_queue()
would always return Q_NOT_AVAIL. The else clause handles this case
directly without the unnecessary ap_zapq() call, and ensures cleanup
occurs even if kvm has already been set to NULL by a prior call to
vfio_ap_mdev_unset_kvm().
Fixes: b9bd10c43456d ("s390/vfio-ap: do not reset queue removed from host config")
Cc: stable@vger.kernel.org
Signed-off-by: Anthony Krowiak <akrowiak@linux.ibm.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Acked-by: Halil Pasic <pasic@linux.ibm.com>
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Message-ID: <20260818193349.1877940-2-akrowiak@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/s390/crypto/vfio_ap_ops.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -277,9 +277,9 @@ static void vfio_ap_free_aqic_resources(
{
if (!q)
return;
- if (q->saved_isc != VFIO_AP_ISC_INVALID &&
- !WARN_ON(!(q->matrix_mdev && q->matrix_mdev->kvm))) {
- kvm_s390_gisc_unregister(q->matrix_mdev->kvm, q->saved_isc);
+ if (q->saved_isc != VFIO_AP_ISC_INVALID) {
+ if (!WARN_ON(!q->matrix_mdev) && q->matrix_mdev->kvm)
+ kvm_s390_gisc_unregister(q->matrix_mdev->kvm, q->saved_isc);
q->saved_isc = VFIO_AP_ISC_INVALID;
}
if (q->saved_iova && !WARN_ON(!q->matrix_mdev)) {
@@ -1926,6 +1926,8 @@ static int apq_status_check(int apqn, st
* a value indicating a reset needs to be performed again.
*/
return -EAGAIN;
+ case AP_RESPONSE_Q_NOT_AVAIL:
+ return -ENODEV;
default:
WARN(true,
"failed to verify reset of queue %02x.%04x: TAPQ rc=%u\n",
@@ -1952,6 +1954,10 @@ static void apq_reset_check(struct work_
ret = apq_status_check(q->apqn, &status);
if (ret == -EIO)
return;
+ if (ret == -ENODEV) {
+ vfio_ap_free_aqic_resources(q);
+ return;
+ }
if (ret == -EBUSY) {
pr_notice_ratelimited(WAIT_MSG, elapsed,
AP_QID_CARD(q->apqn),
@@ -1995,6 +2001,7 @@ static void vfio_ap_mdev_reset_queue(str
break;
case AP_RESPONSE_DECONFIGURED:
case AP_RESPONSE_CHECKSTOPPED:
+ case AP_RESPONSE_Q_NOT_AVAIL:
vfio_ap_free_aqic_resources(q);
break;
default:
@@ -2470,12 +2477,15 @@ void vfio_ap_mdev_remove_queue(struct ap
/*
* If the queue is not in the host's AP configuration, then resetting
* it will fail with response code 01, (APQN not valid); so, let's make
- * sure it is in the host's config.
+ * sure it is in the host's config. If it is not, free the KVM GISC
+ * resources.
*/
if (test_bit_inv(apid, (unsigned long *)matrix_dev->info.apm) &&
test_bit_inv(apqi, (unsigned long *)matrix_dev->info.aqm)) {
vfio_ap_mdev_reset_queue(q);
flush_work(&q->reset_work);
+ } else {
+ vfio_ap_free_aqic_resources(q);
}
done:
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 532/877] KVM: Ensure memory attributes xarray nodes are accounted to the callers memcg
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (530 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 531/877] s390/vfio-ap: fix KVM GISC and page leak when queue removed from host config Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 533/877] KVM: Dont treat reserved xarray entries as having memory attributes Greg Kroah-Hartman
` (352 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, David Ballesteros,
Sean Christopherson
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Ballesteros <davimaba.v@proton.me>
commit 382e5d514b6f35bdda2ab9044b4eed23d2ec4254 upstream.
Explicitly instantiate the memory attributes xarray with XA_FLAGS_ACCOUNT
to ensure that all allocations are accounted to the memcg. Frustratingly,
memory allocations done in the "fastpath" do not honor the passed in gfp,
even for an explicit xa_reserve(). Only the rare, slow path __xas_nomem()
honors the original gfp. E.g.
xa_reserve(..., GFP_KERNEL_ACCOUNT)
|
-> ...
|
-> __xa_cmpxchg_raw()
|
-> xas_store() <== does not take @gfp
|
-> xas_create()
|
-> xas_alloc()
The bug was confirmed by observing that a process in a cgroup limited to
256 MiB grew radix_tree_node slab by ~512 MiB while its memory.current
stayed near 0.
Fixes: 5a475554db1e ("KVM: Introduce per-page memory attributes")
Cc: stable@vger.kernel.org
Assisted-by: Claude-Code:claude-opus-5
Signed-off-by: David Ballesteros <davimaba.v@proton.me>
Link: https://patch.msgid.link/20260915175335.138547-4-davimaba.v@proton.me
[sean: rewrite changelog, tag for stable]
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
virt/kvm/kvm_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1164,7 +1164,7 @@ static struct kvm *kvm_create_vm(unsigne
rcuwait_init(&kvm->mn_memslots_update_rcuwait);
xa_init(&kvm->vcpu_array);
#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES
- xa_init(&kvm->mem_attr_array);
+ xa_init_flags(&kvm->mem_attr_array, XA_FLAGS_ACCOUNT);
#endif
INIT_LIST_HEAD(&kvm->gpc_list);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 533/877] KVM: Dont treat reserved xarray entries as having memory attributes
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (531 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 532/877] KVM: Ensure memory attributes xarray nodes are accounted to the callers memcg Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 534/877] KVM: arm64: Fix spurious warning for benign stage 2 teardown race Greg Kroah-Hartman
` (351 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sean Christopherson,
David Ballesteros, Zeng Chi
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zeng Chi <zengchi@kylinos.cn>
commit 277d3623d99a4fc2623bfb7d191b649ca380605d upstream.
kvm_vm_set_mem_attributes() reserves an xarray entry for every gfn in
the range before storing the new attributes, so that the store loop
can't fail partway through. If one of the reservations fails, e.g. with
-ENOMEM, the entries that were already reserved are left in the array.
That is harmless as far as xa_reserve() is concerned, as the reserved
entries read back as NULL via xa_load(), but it confuses the "does this
range have no attributes at all" check:
if (!attrs)
return !xas_find(&xas, end - 1);
A reserved entry is XA_ZERO_ENTRY, not NULL, and xas_find() returns it
as present. So a leftover reservation makes KVM report that a fully
shared range has attributes even though kvm_get_memory_attributes()
returns none for every gfn in the range. On x86, the next time
mixed-attribute tracking is recomputed for the range (memslot creation,
or a later attribute change that straddles the 2MiB page),
hugepage_has_attrs() treats a fully shared 2MiB range as mixed and
refuses to map it with a hugepage, until userspace happens to set
attributes on the range again.
Drop the shortcut and handle the !attrs case in the per-index loop,
using xas_next_entry() to find the next non-NULL entry. xas_next_entry()
is essentially an optimized xas_find(), so the effective change is that
the !attrs lookup now goes through xas_retry() like the attrs != 0 case,
i.e. reserved entries are skipped and retry entries restart the walk.
Don't check the index when no entry is found, as the xarray leaves the
xas index in a bogus state in that case; no entry simply means the rest
of the range has no attributes.
KVM never stores a non-NULL entry with a value of zero (clearing stores
NULL), but such an entry would be returned by xas_next_entry() and trip
the index check, so WARN if one is ever seen.
Fixes: 5a475554db1e ("KVM: Introduce per-page memory attributes")
Cc: stable@vger.kernel.org
Suggested-by: Sean Christopherson <seanjc@google.com>
Cc: David Ballesteros <davimaba.v@proton.me>
Signed-off-by: Zeng Chi <zengchi@kylinos.cn>
Link: https://patch.msgid.link/20260921102442.1232375-1-zeng_chi911@163.com
[sean: expand comment to elaborate on xarray APIs, split optimization out]
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
virt/kvm/kvm_main.c | 28 +++++++++++++++++++++++++---
1 file changed, 25 insertions(+), 3 deletions(-)
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2429,14 +2429,36 @@ bool kvm_range_has_memory_attributes(str
return (kvm_get_memory_attributes(kvm, start) & mask) == attrs;
guard(rcu)();
- if (!attrs)
- return !xas_find(&xas, end - 1);
+ /*
+ * Lookup the entry for each index instead of iterating over the xarray
+ * as KVM deletes/nullifies entries to represent "no attributes", and
+ * the xas index is effectively invalid when no entry is found. I.e.
+ * matching non-zero attributes for *every* entry effectively requires
+ * a manually lookup for each index.
+ *
+ * Skip pre-allocated, reserved entries, or restart the lookup if the
+ * xarray was concurrently modified, via xas_retry() ("retry" means the
+ * entry holds an internal xarray value, i.e. is either invalid or NULL
+ * from the caller's perspective).
+ *
+ * Use xas_next() when looking for non-zero attributes to optimize for
+ * the case where the start of the range (or the entire range) doesn't
+ * have any attributes, as xas_next() returns literally the next entry,
+ * whereas xas_next_entry() returns the next non-NULL entry (bounded by
+ * a maximum index).
+ */
for (index = start; index < end; index++) {
do {
- entry = xas_next(&xas);
+ entry = attrs ? xas_next(&xas) :
+ xas_next_entry(&xas, end - 1);
} while (xas_retry(&xas, entry));
+ if (!entry)
+ return !attrs;
+
+ WARN_ON_ONCE(!xa_to_value(entry));
+
if (xas.xa_index != index ||
(xa_to_value(entry) & mask) != attrs)
return false;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 534/877] KVM: arm64: Fix spurious warning for benign stage 2 teardown race
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (532 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 533/877] KVM: Dont treat reserved xarray entries as having memory attributes Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 535/877] RISC-V: KVM: Synchronize hrtimer callback during teardown Greg Kroah-Hartman
` (350 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yuan Yao, Marc Zyngier,
Lorenzo Stoakes (ARM), Oliver Upton
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Stoakes (ARM) <ljs@kernel.org>
commit 38b70fc453c3112f1a62583b89903ae41116cc27 upstream.
kvmtool was used to establish an L1 guest with 8 CPUs and 8 GiB of RAM, an
L2 guest with 4 CPUs and 4 GiB of RAM and an L3 guest with 2 CPUs and 2 GiB
of RAM, all of which was then exited.
Under memory pressure in the L0 host warnings were observed due to
migration triggered by compaction:
WARNING: arch/arm64/kvm/mmu.c:336 at __unmap_stage2_range+0x64/0x80,
CPU#5: kcompactd0/66
Which was, in turn, triggered by an MMU notifier for the host invalidation:
mmu_notifier_invalidate_range_start()
-> ... -> kvm_mmu_notifier_invalidate_range_start()
-> kvm_mmu_unmap_gfn_range()
-> kvm_unmap_gfn_range()
-> kvm_nested_s2_unmap()
-> kvm_stage2_unmap_range()
-> __unmap_stage2_range()
-> stage2_apply_range()
<- -EINVAL, triggering a WARN_ON()
Racing with L0's teardown of stage 2 page tables:
exit_mm()
-> mmput()
-> __mmput()
-> exit_mmap()
-> mmu_notifier_release()
-> ... -> kvm_mmu_notifier_release()
-> kvm_flush_shadow_all()
-> kvm_arch_flush_shadow_all()
-> kvm_free_stage2_pgd()
-> [ acquire kvm->mmu_lock for write ]
-> mmu->pgt = NULL [ among other tasks ]
-> [ release kvm->mmu_lock for write ]
It turns out there is a benign race resulting in a spurious warning:
Thread A - notify: migration | Thread B - notify: release
-------------------------------|---------------------------------
< kvm->mmu_lock held > |
stage2_apply_range() |
get mmu->pgt, check !NULL |
... | kvm_arch_flush_shadow_all()
cond_resched_rwlock_write(); | < contend, sleep kvm->mmu_lock >
< drop kvm->mmu_lock > | < acquire kvm->mmu_lock>
| ...
| kvm_free_stage2_pgd()
| mmu->pgt = NULL
| < invalidate MMU >
| ...
| < release kvm->mmu_lock >
[ scheduled ] |
stage2_apply_range() |
< loop to next > |
get, mmu->pgt, check !NULL |
is NULL, return -EINVAL |
__unmap_stage2_range() |
WARN_ON(-EINVAL) <--- entirely spurious - the race was handled
correctly.
Fix the spurious warning by updating stage2_apply_range() to no longer
treat concurrent PGT teardown on lock release as an error - whether the
walker is tearing down page tables or doing something else this is a
legitimate reason to abort the operation without error.
This keeps the warning in place for all other circumstances.
In practice only __unmap_stage2_range() actually does anything with the
error so this only impacts that.
Fixes: ec14c272408a ("KVM: arm64: nv: Unmap/flush shadow stage 2 page tables")
Cc: stable@vger.kernel.org
Reviewed-by: Yuan Yao <yaoyuan@linux.alibaba.com>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Link: https://patch.msgid.link/20260901-kvm-arm-nested-virt-fix-v3-1-b154676f7e4c@kernel.org
Signed-off-by: Oliver Upton <oupton@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arm64/kvm/mmu.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -53,27 +53,36 @@ static phys_addr_t stage2_range_addr_end
* long will also starve other vCPUs. We have to also make sure that the page
* tables are not freed while we released the lock.
*/
-static int stage2_apply_range(struct kvm_s2_mmu *mmu, phys_addr_t addr,
+static int stage2_apply_range(struct kvm_s2_mmu *mmu, phys_addr_t start,
phys_addr_t end,
int (*fn)(struct kvm_pgtable *, u64, u64),
bool resched)
{
struct kvm *kvm = kvm_s2_mmu_to_kvm(mmu);
+ bool lock_dropped = false;
+ phys_addr_t addr = start;
int ret;
u64 next;
do {
struct kvm_pgtable *pgt = mmu->pgt;
+ /*
+ * We may be raced on PGT teardown when we release the
+ * kvm->mmu_lock. That's fine as the PGT is legitimately no
+ * longer present.
+ */
if (!pgt)
- return -EINVAL;
+ return lock_dropped ? 0 : -EINVAL;
next = stage2_range_addr_end(addr, end);
ret = fn(pgt, addr, next - addr);
if (ret)
break;
- if (resched && next != end)
+ if (resched && next != end) {
cond_resched_rwlock_write(&kvm->mmu_lock);
+ lock_dropped = true;
+ }
} while (addr = next, addr != end);
return ret;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 535/877] RISC-V: KVM: Synchronize hrtimer callback during teardown
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (533 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 534/877] KVM: arm64: Fix spurious warning for benign stage 2 teardown race Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 536/877] RISC-V: KVM: Fix HSM hart status error propagation Greg Kroah-Hartman
` (349 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Myeonghun Pak, Anup Patel
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <mhun512@gmail.com>
commit aaad136d56d91252517272b68cd533e5714698d5 upstream.
The non-Sstc hrtimer callback clears next_set before its final uses of
the enclosing vCPU. If teardown observes next_set as false while the
callback is still running, kvm_riscv_vcpu_timer_cancel() skips
hrtimer_cancel() and kvm_destroy_vcpus() can free the vCPU before the
callback enters kvm_riscv_vcpu_set_interrupt().
A guest can arm the timer with SBI TIME and request shutdown with SBI
legacy shutdown or SRST. A VMM that honors KVM_EXIT_SYSTEM_EVENT and
destroys the VM supplies the teardown side of the race; no post-launch
host ioctl is needed to arm or request teardown.
On upstream master 62cc90241548, generic KASAN reported:
BUG: KASAN: slab-use-after-free in do_raw_spin_lock
Write of size 4 at addr ff60000005e58898
kvm_riscv_vcpu_set_interrupt
kvm_riscv_vcpu_hrtimer_expired
__hrtimer_run_queues
hrtimer_interrupt
The object was allocated by KVM_CREATE_VCPU and freed concurrently by:
kvm_destroy_vcpus
kvm_arch_destroy_vm
kvm_destroy_vm
__fput
For deterministic validation, I added mdelay(1000) immediately after
the existing next_set = false assignment. This only widens the
existing post-clear callback window. A no-delay trace build naturally
reached the callback-after-teardown-start/before-deinit ordering in 12
of 200 runs, but 1,500 stock-kernel stress iterations did not produce a
KASAN report, so natural reproduction is timing-sensitive.
Always invoke hrtimer_cancel() for an initialized timer. Preserve the
existing -EINVAL result when the timer is no longer set, but only after
synchronizing with a running callback.
With this patch, hrtimer_cancel() blocked for the full widened callback
window before vCPU destruction. KASAN reported no error in 100
fixed-and-widened runs or 200 fix-only timing-sweep runs.
Fixes: 3a9f66cb25e1 ("RISC-V: KVM: Add timer functionality")
Cc: stable@vger.kernel.org
Assisted-by: OpenAI:GPT-5.6
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260731163550.46991-1-mhun512@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/riscv/kvm/vcpu_timer.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/arch/riscv/kvm/vcpu_timer.c
+++ b/arch/riscv/kvm/vcpu_timer.c
@@ -60,10 +60,13 @@ static enum hrtimer_restart kvm_riscv_vc
static int kvm_riscv_vcpu_timer_cancel(struct kvm_vcpu_timer *t)
{
- if (!t->init_done || !t->next_set)
+ if (!t->init_done)
return -EINVAL;
hrtimer_cancel(&t->hrt);
+
+ if (!t->next_set)
+ return -EINVAL;
t->next_set = false;
return 0;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 536/877] RISC-V: KVM: Fix HSM hart status error propagation
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (534 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 535/877] RISC-V: KVM: Synchronize hrtimer callback during teardown Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 537/877] Bluetooth: hci_conn: fix CIS hold ownership on reuse Greg Kroah-Hartman
` (348 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Tan Chi, Anup Patel
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tan Chi <tanchi25@mails.ucas.ac.cn>
commit 41e81f7e3ef96594fb840445343c0ee7723aa550 upstream.
kvm_sbi_hsm_vcpu_get_status() returns SBI_ERR_INVALID_PARAM when
the requested hart does not exist. However, the HART_STATUS case
returns from the SBI handler without storing this error in
retdata->err_val.
As a result, a guest querying the status of a non-existent hart
observes SBI_SUCCESS instead of SBI_ERR_INVALID_PARAM.
Use the common SBI error handling path for HART_STATUS after
saving a valid hart state in retdata->out_val. This preserves
the returned error when kvm_sbi_hsm_vcpu_get_status() fails.
Fixes: bae0dfd74e01 ("RISC-V: KVM: Modify SBI extension handler to return SBI error code")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Tan Chi <tanchi25@mails.ucas.ac.cn>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260914031146.446157-1-tanchi25@mails.ucas.ac.cn
Signed-off-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/riscv/kvm/vcpu_sbi_hsm.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/riscv/kvm/vcpu_sbi_hsm.c
+++ b/arch/riscv/kvm/vcpu_sbi_hsm.c
@@ -106,9 +106,9 @@ static int kvm_sbi_ext_hsm_handler(struc
ret = kvm_sbi_hsm_vcpu_get_status(vcpu);
if (ret >= 0) {
retdata->out_val = ret;
- retdata->err_val = 0;
+ ret = 0;
}
- return 0;
+ break;
case SBI_EXT_HSM_HART_SUSPEND:
switch (lower_32_bits(cp->a0)) {
case SBI_HSM_SUSPEND_RET_DEFAULT:
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 537/877] Bluetooth: hci_conn: fix CIS hold ownership on reuse
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (535 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 536/877] RISC-V: KVM: Fix HSM hart status error propagation Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 538/877] Bluetooth: hci_sock: validate event length before filtering Greg Kroah-Hartman
` (347 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aldo Ariel Panzardo,
Luiz Augusto von Dentz
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
commit e06d549fcd4a0ba381ed67ddf1ab3c7a6ca4314c upstream.
Commit 69997d50ec57 ("Bluetooth: ISO: handle bound CIS cleanup via
hci_conn") made hci_bind_cis() and hci_connect_cis() return a
connection with one hold for the ISO layer. hci_bind_cis() currently
takes that hold only after configuring a CIS, so its BT_CONNECTED and
matching BT_BOUND paths return a bare lookup result. Its configuration
failure path can likewise call hci_conn_drop() before taking a hold.
Take the hold before any state-dependent return or configuration error
so every successful return follows the documented ownership contract
and every error drop is balanced.
hci_connect_cis() also assumes hci_conn_link() always takes a new CIS
hold before dropping the one returned by hci_bind_cis(). However, the
helper returns an existing link without taking another hold. In that
case, preserve the CIS hold for the caller and drop the redundant LE
hold because the existing link already owns its parent hold. Returning
early also avoids changing an existing CIS back to BT_CONNECT.
Fixes: 69997d50ec57 ("Bluetooth: ISO: handle bound CIS cleanup via hci_conn")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/hci_conn.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -1937,6 +1937,8 @@ struct hci_conn *hci_bind_cis(struct hci
cis->iso_qos.ucast.cis = BT_ISO_QOS_CIS_UNSET;
}
+ hci_conn_hold(cis);
+
if (cis->state == BT_CONNECTED)
return cis;
@@ -1978,7 +1980,6 @@ struct hci_conn *hci_bind_cis(struct hci
return ERR_PTR(-EINVAL);
}
- hci_conn_hold(cis);
cis->state = BT_BOUND;
return cis;
@@ -2340,6 +2341,12 @@ struct hci_conn *hci_connect_cis(struct
hci_conn_drop(le);
return cis;
}
+
+ /* The existing link already owns the hold on its parent. */
+ if (cis->link) {
+ hci_conn_drop(le);
+ return cis;
+ }
link = hci_conn_link(le, cis);
hci_conn_drop(cis);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 538/877] Bluetooth: hci_sock: validate event length before filtering
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (536 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 537/877] Bluetooth: hci_conn: fix CIS hold ownership on reuse Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 539/877] Bluetooth: hci_sock: reject out-of-range OCF values Greg Kroah-Hartman
` (346 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aldo Ariel Panzardo,
Luiz Augusto von Dentz
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
commit b0a6cf99afd57a39598b1beca0e86ef5004980de upstream.
is_filtered_packet() reads the event code from skb->data[0] without first
checking that the skb is nonempty. When an opcode filter is configured,
it also reads the command opcode at offsets 3 or 4 without checking that
a Command Complete or Command Status event is long enough.
hci_send_to_sock() invokes the filter before hci_event_packet() validates
the event header. A malformed event supplied by a controller or a vhci
device can therefore cause an out-of-bounds read.
Keep the unmasked event code for the opcode checks. The masked value is
needed for the 64-bit event bitmap, but using it to identify command events
aliases event codes above 0x3f. In particular, Synchronous Train Complete
(0x4f) was treated as Command Status (0x0f) even though its payload has no
opcode.
Reject actual command events that are too short for the field being
inspected. A truncated command event cannot match a configured opcode.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/hci_sock.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -166,6 +166,7 @@ static bool is_filtered_packet(struct so
{
struct hci_filter *flt;
int flt_type, flt_event;
+ u8 event;
/* Apply filter */
flt = &hci_pi(sk)->filter;
@@ -179,7 +180,11 @@ static bool is_filtered_packet(struct so
if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT)
return false;
- flt_event = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
+ if (skb->len < 1)
+ return true;
+
+ event = *(__u8 *)skb->data;
+ flt_event = event & HCI_FLT_EVENT_BITS;
if (!hci_test_bit(flt_event, &flt->event_mask))
return true;
@@ -188,11 +193,17 @@ static bool is_filtered_packet(struct so
if (!flt->opcode)
return false;
- if (flt_event == HCI_EV_CMD_COMPLETE &&
+ if (event == HCI_EV_CMD_COMPLETE && skb->len < 5)
+ return true;
+
+ if (event == HCI_EV_CMD_COMPLETE &&
flt->opcode != get_unaligned((__le16 *)(skb->data + 3)))
return true;
- if (flt_event == HCI_EV_CMD_STATUS &&
+ if (event == HCI_EV_CMD_STATUS && skb->len < 6)
+ return true;
+
+ if (event == HCI_EV_CMD_STATUS &&
flt->opcode != get_unaligned((__le16 *)(skb->data + 4)))
return true;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 539/877] Bluetooth: hci_sock: reject out-of-range OCF values
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (537 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 538/877] Bluetooth: hci_sock: validate event length before filtering Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 540/877] Bluetooth: ISO: balance the parent hold in hci_bind_bis() Greg Kroah-Hartman
` (345 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aldo Ariel Panzardo,
Luiz Augusto von Dentz
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
commit e93fad891c72deb84cae49430163b384ebcc92b1 upstream.
The raw HCI socket security filter has 128 OCF bits per supported OGF,
but masks the 10-bit OCF with 127 before looking up the command. An
unprivileged socket can therefore submit a reserved OCF that aliases an
allowlisted command modulo 128.
A conforming controller should reject reserved opcodes. Nevertheless,
the security decision must apply to the opcode that will actually be
sent, especially since controller-specific behavior is outside the host
stack's control.
Reject OCF values that cannot be represented by the security filter
instead of aliasing them onto an unrelated command.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/hci_sock.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -1886,7 +1886,8 @@ static int hci_sock_sendmsg(struct socke
u16 ocf = hci_opcode_ocf(opcode);
if (((ogf > HCI_SFLT_MAX_OGF) ||
- !hci_test_bit(ocf & HCI_FLT_OCF_BITS,
+ (ocf > HCI_FLT_OCF_BITS) ||
+ !hci_test_bit(ocf,
&hci_sec_filter.ocf_mask[ogf])) &&
!capable(CAP_NET_RAW)) {
err = -EPERM;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 540/877] Bluetooth: ISO: balance the parent hold in hci_bind_bis()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (538 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 539/877] Bluetooth: hci_sock: reject out-of-range OCF values Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 541/877] Bluetooth: L2CAP: validate frame length before control and FCS access Greg Kroah-Hartman
` (344 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aldo Ariel Panzardo,
Luiz Augusto von Dentz
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
commit 4c94557dd02569efa6c1072a0439addaef9a5224 upstream.
hci_conn_link() takes a lifetime reference to its parent with
hci_conn_get(), but only takes an operational hold on the child.
hci_conn_unlink() later balances both a hold and a reference on the
parent.
The SCO and CIS paths pass a parent acquired from a connect helper, so
it already has a hold. For an additional BIS, hci_bind_bis() obtains the
parent from hci_conn_hash_lookup_big(), which returns a bare pointer.
Unlinking the child then drops the parent's existing hold and can
schedule it for disconnection while its socket is still using it.
Take a hold on the parent before linking it and drop that hold if linking
fails. A successful link transfers the hold to hci_conn_unlink().
Fixes: fa224d0c094a ("Bluetooth: ISO: Reassociate a socket with an active BIS")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/hci_conn.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -2234,10 +2234,13 @@ struct hci_conn *hci_bind_bis(struct hci
parent = hci_conn_hash_lookup_big(hdev,
conn->iso_qos.bcast.big);
if (parent && parent != conn) {
+ hci_conn_hold(parent);
link = hci_conn_link(parent, conn);
hci_conn_drop(conn);
- if (!link)
+ if (!link) {
+ hci_conn_drop(parent);
return ERR_PTR(-ENOLINK);
+ }
}
return conn;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 541/877] Bluetooth: L2CAP: validate frame length before control and FCS access
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (539 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 540/877] Bluetooth: ISO: balance the parent hold in hci_bind_bis() Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 542/877] Bluetooth: mgmt: fix race in read_unconf_index_list() Greg Kroah-Hartman
` (343 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aldo Ariel Panzardo,
Luiz Augusto von Dentz
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
commit 6c78a213d9070b610c7f418af2c25b66180b7e37 upstream.
l2cap_data_rcv() unpacks either a two-byte or four-byte control field
without first ensuring that it is present. A short ERTM or streaming-mode
frame can therefore cause an out-of-bounds read.
There is a second short-frame case when CRC16 is enabled. After the
control field is pulled, l2cap_check_fcs() subtracts two from skb->len
without checking it. If fewer than two bytes remain, the subtraction
wraps; skb_trim() leaves the buffer unchanged and the subsequent FCS
load reads past the logical end of the frame.
Validate that the frame contains both its control field and, when
enabled, its FCS before either field is accessed.
Fixes: 1c2acffb76d4 ("Bluetooth: Add initial support for ERTM packets transfers")
Fixes: fcc203c30d72 ("Bluetooth: Add support for FCS option to L2CAP")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/l2cap_core.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -6681,9 +6681,17 @@ static int l2cap_stream_rx(struct l2cap_
static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
{
struct l2cap_ctrl *control = &bt_cb(skb)->l2cap;
- u16 len;
+ u16 len, min_len;
u8 event;
+ min_len = test_bit(FLAG_EXT_CTRL, &chan->flags) ?
+ L2CAP_EXT_CTRL_SIZE : L2CAP_ENH_CTRL_SIZE;
+ if (chan->fcs == L2CAP_FCS_CRC16)
+ min_len += L2CAP_FCS_SIZE;
+
+ if (skb->len < min_len)
+ goto drop;
+
__unpack_control(chan, skb);
len = skb->len;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 542/877] Bluetooth: mgmt: fix race in read_unconf_index_list()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (540 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 541/877] Bluetooth: L2CAP: validate frame length before control and FCS access Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 543/877] Bluetooth: RFCOMM: fix NULL dereference of dlc->session in RFCOMM_CONNINFO Greg Kroah-Hartman
` (342 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aldo Ariel Panzardo,
Luiz Augusto von Dentz
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
commit b5dbb41b212c50c095a4dbee3017a84fe94f033b upstream.
read_unconf_index_list() counts unconfigured controllers before allocating
its response, then checks the device flags again while filling it.
hci_dev_list_lock stabilizes list membership, but it does not serialize the
per-device flags. During asynchronous controller setup, the worker can set
HCI_UNCONFIGURED and clear HCI_SETUP between the two passes. A controller
omitted from the allocation count can then become eligible for the fill
pass, causing an out-of-bounds write to rp->index[].
Allocate space for every device on hci_dev_list. Since list membership
cannot change while hci_dev_list_lock is held, the response remains large
enough regardless of flag transitions. The reported count and response
length still include only eligible unconfigured controllers.
Fixes: 73d1df2a7a10 ("Bluetooth: Add support for Read Unconfigured Index List command")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/mgmt.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -498,13 +498,9 @@ static int read_unconf_index_list(struct
read_lock(&hci_dev_list_lock);
- count = 0;
- list_for_each_entry(d, &hci_dev_list, list) {
- if (hci_dev_test_flag(d, HCI_UNCONFIGURED))
- count++;
- }
+ count = list_count_nodes(&hci_dev_list);
- rp_len = sizeof(*rp) + (2 * count);
+ rp_len = sizeof(*rp) + (sizeof(__le16) * count);
rp = kmalloc(rp_len, GFP_ATOMIC);
if (!rp) {
read_unlock(&hci_dev_list_lock);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 543/877] Bluetooth: RFCOMM: fix NULL dereference of dlc->session in RFCOMM_CONNINFO
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (541 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 542/877] Bluetooth: mgmt: fix race in read_unconf_index_list() Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 544/877] smb: client: fix create context out-of-bounds reads Greg Kroah-Hartman
` (341 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hui Peng, Luiz Augusto von Dentz
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Peng <benquike@gmail.com>
commit 46f8ffd0a1f1eb6cbc94946a92c11ef601e228a1 upstream.
The RFCOMM_CONNINFO getsockopt handler accepts a socket that is not
connected as long as deferred setup is enabled:
if (sk->sk_state != BT_CONNECTED &&
!rfcomm_pi(sk)->dlc->defer_setup) {
err = -ENOTCONN;
break;
}
l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk;
dlc->defer_setup is set in rfcomm_sock_init() when rfcomm_connect_ind()
creates a child socket for an incoming connection on a listening socket
that has BT_DEFER_SETUP enabled. It is never cleared afterwards. The
session, however, can go away underneath it.
rfcomm_recv_disc() forces the dlc state before tearing it down:
d->state = BT_CLOSED;
__rfcomm_dlc_close(d, err);
The RFCOMM_DEFER_SETUP early return in __rfcomm_dlc_close() only covers
BT_CONNECT, BT_CONFIG, BT_OPEN and BT_CONNECT2, so with the state
already BT_CLOSED that switch does not match and the function falls
through to rfcomm_dlc_unlink(), which sets d->session = NULL, while
d->defer_setup stays 1.
A getsockopt(SOL_RFCOMM, RFCOMM_CONNINFO) on the accepted socket after
that point therefore skips the -ENOTCONN path -- sk->sk_state is
BT_CLOSED, but dlc->defer_setup is still set -- and dereferences the
NULL session. No race is needed: once the DISC has been processed, the
dereference is unconditional.
Reproduced on a KASAN kernel under QEMU with a BR/EDR peer emulated over
/dev/vhci: the peer brings up an ACL link, opens L2CAP on the RFCOMM
PSM, starts a session and sends SABM for a channel bound with
BT_DEFER_SETUP, and sends DISC for that dlci after the socket has been
accepted. getsockopt(SOL_RFCOMM, RFCOMM_CONNINFO) on the accepted
socket then hits:
Oops: general protection fault, probably for non-canonical address
0xdffffc0000000002: 0000 [#1] SMP KASAN PTI
KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
CPU: 1 UID: 0 PID: 150 Comm: init Tainted: G B 7.3.0-rc3-g5dd1818b15d9
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996)
RIP: 0010:rfcomm_sock_getsockopt+0x529/0x780
Call Trace:
<TASK>
do_sock_getsockopt+0x3ad/0x7d0
__sys_getsockopt+0x10e/0x1b0
__x64_sys_getsockopt+0xc2/0x160
do_syscall_64+0xda/0x4b0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
</TASK>
0x10 is the offset of sock in struct rfcomm_session;
rfcomm_sock_getsockopt_old() is inlined into rfcomm_sock_getsockopt().
Commit 43a556b2fd43 ("Bluetooth: RFCOMM: take rfcomm_mutex for the
deferred setup accept") fixed the same "a remote DISC clears the session
while deferred setup is still flagged" problem in rfcomm_dlc_accept();
this is the remaining instance of it, in the getsockopt path.
Deferred setup only leaves a socket usable here once it has reached
BT_CONNECT2, so restrict the exception to that state and check that a
session is actually present before following it.
Fixes: bb23c0ab8246 ("Bluetooth: Add support for deferring RFCOMM connection setup")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Hui Peng <benquike@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/rfcomm/sock.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -785,8 +785,10 @@ static int rfcomm_sock_getsockopt_old(st
break;
case RFCOMM_CONNINFO:
- if (sk->sk_state != BT_CONNECTED &&
- !rfcomm_pi(sk)->dlc->defer_setup) {
+ if ((sk->sk_state != BT_CONNECTED &&
+ !(sk->sk_state == BT_CONNECT2 &&
+ rfcomm_pi(sk)->dlc->defer_setup)) ||
+ !rfcomm_pi(sk)->dlc->session) {
err = -ENOTCONN;
break;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 544/877] smb: client: fix create context out-of-bounds reads
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (542 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 543/877] Bluetooth: RFCOMM: fix NULL dereference of dlc->session in RFCOMM_CONNINFO Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 545/877] smb: client: clean up failed cached directory opens Greg Kroah-Hartman
` (340 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Luxing Yin, Zihan Xi,
Frank Sorenson, Paulo Alcantara
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zihan Xi <zihanx@nebusec.ai>
commit 67f4c1c6a1b51e203d986779299824d1c2c590a6 upstream.
smb2_parse_contexts() validates the complete create-context area but
does not limit each record to its Next field before dispatching it. A
malformed chain can therefore expose bytes beyond the current context to
a handler. The QFid handler also used a full response-structure cast
although it only reads DiskFileId.
The SMB2/SMB3 lease parsers made the same layout assumption: they read
LeaseState and LeaseFlags at canonical offsets rather than at
DataOffset. A valid non-canonical DataOffset could therefore yield
unrelated in-bounds data, while a short DataLength was still accepted.
Limit each context to its Next value, reject offsets before the context
header, and reject malformed chains. Bound the name range by the current
context and do not dispatch a known handler when DataLength is zero. Read
the QFid DiskFileId only when the context data covers that field. Parse the
lease context from DataOffset and require DataLength to match the v1 or v2
lease_context size used by ksmbd. A size mismatch skips lease parsing
without failing the open.
Fixes: b8c32dbb0deb ("CIFS: Request SMB2.1 leases")
Fixes: f047390a097e ("CIFS: Add create lease v2 context for SMB3")
Fixes: 89a5bfa350fa ("smb3: optimize open to not send query file internal info")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Co-developed-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Tested-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/smb2ops.c | 28 ++++++++++++++++++++--------
fs/smb/client/smb2pdu.c | 44 ++++++++++++++++++++++++++++++++++----------
2 files changed, 54 insertions(+), 18 deletions(-)
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -4405,25 +4405,37 @@ smb3_create_lease_buf(u8 *lease_key, u8
static __u8
smb2_parse_lease_buf(void *buf, __u16 *epoch, char *lease_key)
{
- struct create_lease *lc = (struct create_lease *)buf;
+ struct create_context *cc = buf;
+ struct lease_context lc;
*epoch = 0; /* not used */
- if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS_LE)
+ if (le32_to_cpu(cc->DataLength) != sizeof(lc))
+ return 0;
+
+ memcpy(&lc, (u8 *)cc + le16_to_cpu(cc->DataOffset), sizeof(lc));
+ if (lc.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS_LE)
return SMB2_OPLOCK_LEVEL_NOCHANGE;
- return le32_to_cpu(lc->lcontext.LeaseState);
+ return le32_to_cpu(lc.LeaseState);
}
static __u8
smb3_parse_lease_buf(void *buf, __u16 *epoch, char *lease_key)
{
- struct create_lease_v2 *lc = (struct create_lease_v2 *)buf;
+ struct create_context *cc = buf;
+ struct lease_context_v2 lc;
+
+ if (le32_to_cpu(cc->DataLength) != sizeof(lc)) {
+ *epoch = 0;
+ return 0;
+ }
- *epoch = le16_to_cpu(lc->lcontext.Epoch);
- if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS_LE)
+ memcpy(&lc, (u8 *)cc + le16_to_cpu(cc->DataOffset), sizeof(lc));
+ *epoch = le16_to_cpu(lc.Epoch);
+ if (lc.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS_LE)
return SMB2_OPLOCK_LEVEL_NOCHANGE;
if (lease_key)
- memcpy(lease_key, &lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
- return le32_to_cpu(lc->lcontext.LeaseState);
+ memcpy(lease_key, lc.LeaseKey, SMB2_LEASE_KEY_SIZE);
+ return le32_to_cpu(lc.LeaseState);
}
static unsigned int
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -2296,11 +2296,17 @@ create_reconnect_durable_buf(struct cifs
static void
parse_query_id_ctxt(struct create_context *cc, struct smb2_file_all_info *buf)
{
- struct create_disk_id_rsp *pdisk_id = (struct create_disk_id_rsp *)cc;
+ u16 doff = le16_to_cpu(cc->DataOffset);
+ u32 dlen = le32_to_cpu(cc->DataLength);
+ u8 *beg;
- cifs_dbg(FYI, "parse query id context 0x%llx 0x%llx\n",
- pdisk_id->DiskFileId, pdisk_id->VolumeId);
- buf->IndexNumber = pdisk_id->DiskFileId;
+ if (dlen < sizeof(__le64))
+ return;
+
+ beg = (u8 *)cc + doff;
+ memcpy(&buf->IndexNumber, beg, sizeof(__le64));
+ cifs_dbg(FYI, "parse query id context 0x%llx\n",
+ le64_to_cpu(buf->IndexNumber));
}
static void
@@ -2348,6 +2354,7 @@ int smb2_parse_contexts(struct TCP_Serve
struct smb2_create_rsp *rsp = rsp_iov->iov_base;
struct create_context *cc;
size_t rem, off, len;
+ size_t cc_len;
size_t doff, dlen;
size_t noff, nlen;
char *name;
@@ -2370,29 +2377,41 @@ int smb2_parse_contexts(struct TCP_Serve
buf->IndexNumber = 0;
while (rem >= sizeof(*cc)) {
+ off = le32_to_cpu(cc->Next);
+ if (off) {
+ if ((off & 0x7) || off >= rem || off < sizeof(*cc))
+ return -EINVAL;
+ cc_len = off;
+ } else {
+ cc_len = rem;
+ }
+
doff = le16_to_cpu(cc->DataOffset);
dlen = le32_to_cpu(cc->DataLength);
- if (check_add_overflow(doff, dlen, &len) || len > rem)
+ if (doff < sizeof(*cc) ||
+ check_add_overflow(doff, dlen, &len) || len > cc_len)
return -EINVAL;
noff = le16_to_cpu(cc->NameOffset);
nlen = le16_to_cpu(cc->NameLength);
- if (noff + nlen > doff)
+ if (noff < sizeof(*cc) ||
+ check_add_overflow(noff, nlen, &len) || len > cc_len ||
+ (dlen && len > doff))
return -EINVAL;
name = (char *)cc + noff;
switch (nlen) {
case 4:
- if (!strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4)) {
+ if (dlen && !strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4)) {
*oplock = server->ops->parse_lease_buf(cc, epoch,
lease_key);
- } else if (buf &&
+ } else if (dlen && buf &&
!strncmp(name, SMB2_CREATE_QUERY_ON_DISK_ID, 4)) {
parse_query_id_ctxt(cc, buf);
}
break;
case 16:
- if (posix && !memcmp(name, smb3_create_tag_posix, 16))
+ if (dlen && posix && !memcmp(name, smb3_create_tag_posix, 16))
parse_posix_ctxt(cc, buf, posix);
break;
default:
@@ -2404,13 +2423,18 @@ int smb2_parse_contexts(struct TCP_Serve
}
off = le32_to_cpu(cc->Next);
- if (!off)
+ if (!off) {
+ rem = 0;
break;
+ }
if (check_sub_overflow(rem, off, &rem))
return -EINVAL;
cc = (struct create_context *)((u8 *)cc + off);
}
+ if (rem)
+ return -EINVAL;
+
if (rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE)
*oplock = rsp->OplockLevel;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 545/877] smb: client: clean up failed cached directory opens
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (543 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 544/877] smb: client: fix create context out-of-bounds reads Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 546/877] smb: client: validate POSIX create context length Greg Kroah-Hartman
` (339 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Luxing Yin, Zihan Xi,
Frank Sorenson, Paulo Alcantara
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zihan Xi <zihanx@nebusec.ai>
commit d2ff5fb93ea83034025850266b5eed391f96b825 upstream.
open_cached_dir() sends CREATE and QUERY_INFO as a compound request. If
the CREATE succeeds but a later command returns an error, the function
must retain the CREATE FID so common cleanup can issue SMB2_close(). It
also must not treat a response error as a valid CREATE.
Validate the CREATE response before using its fields, record the FIDs, and
mark the handle open before handling errors from later compound commands.
Move the -EREMCHG reconnect handling before response validation so a
missing response does not hide the reconnect request. Count the handle
when it is marked open; confirmed close responses decrement the counter,
while existing close retry behavior remains best effort on transport
failures.
Fixes: b0f6df737a1c ("cifs: cache FILE_ALL_INFO for the shared root handle")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Co-developed-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Tested-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/cached_dir.c | 32 ++++++++++++++++++++++----------
1 file changed, 22 insertions(+), 10 deletions(-)
--- a/fs/smb/client/cached_dir.c
+++ b/fs/smb/client/cached_dir.c
@@ -8,6 +8,7 @@
#include <linux/namei.h>
#include "cifsglob.h"
#include "cifsproto.h"
+#include "../common/smb2status.h"
#include "cifs_debug.h"
#include "smb2proto.h"
#include "cached_dir.h"
@@ -294,25 +295,37 @@ replay_again:
rc = compound_send_recv(xid, ses, server,
flags, 2, rqst,
resp_buftype, rsp_iov);
- if (rc) {
- if (rc == -EREMCHG) {
- tcon->need_reconnect = true;
- pr_warn_once("server share %s deleted\n",
- tcon->tree_name);
- }
- goto oshr_free;
+ if (rc == -EREMCHG) {
+ tcon->need_reconnect = true;
+ pr_warn_once("server share %s deleted\n",
+ tcon->tree_name);
}
- cfid->is_open = true;
- spin_lock(&cfids->cfid_list_lock);
+ if (!rsp_iov[0].iov_base || rsp_iov[0].iov_len < sizeof(*o_rsp)) {
+ if (!rc)
+ rc = -EIO;
+ goto oshr_free;
+ }
o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
+ if (o_rsp->hdr.Status != STATUS_SUCCESS) {
+ if (!rc)
+ rc = -EIO;
+ goto oshr_free;
+ }
+
oparms.fid->persistent_fid = o_rsp->PersistentFileId;
oparms.fid->volatile_fid = o_rsp->VolatileFileId;
#ifdef CONFIG_CIFS_DEBUG2
oparms.fid->mid = le64_to_cpu(o_rsp->hdr.MessageId);
#endif /* CIFS_DEBUG2 */
+ cfid->is_open = true;
+ atomic_inc(&tcon->num_remote_opens);
+ if (rc)
+ goto oshr_free;
+
+ spin_lock(&cfids->cfid_list_lock);
if (o_rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE) {
spin_unlock(&cfids->cfid_list_lock);
@@ -378,7 +391,6 @@ out:
close_cached_dir(cfid);
} else {
*ret_cfid = cfid;
- atomic_inc(&tcon->num_remote_opens);
}
kfree(utf16_path);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 546/877] smb: client: validate POSIX create context length
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (544 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 545/877] smb: client: clean up failed cached directory opens Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 547/877] xfs: dont assert when XFS_SCRUB_TYPE_HEALTHY scans return corruption Greg Kroah-Hartman
` (338 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Luxing Yin, Zihan Xi,
Frank Sorenson, Paulo Alcantara
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zihan Xi <zihanx@nebusec.ai>
commit fa2e9900dd2a3f5a1e7ef5a8c5e8d435feedbfcc upstream.
parse_posix_ctxt() reads the fixed nlink, reparse_tag, and mode fields
before checking that the POSIX create context contains them. A short
context can pass the generic checks and still make these fixed-width
reads run past its declared data.
The current in-tree smb2_open_file() path passes a NULL posix pointer,
so this handler is not reached on the ordinary open path. Still require
the POSIX data to cover all three fields before reading them because the
helper performs those unguarded reads. Keep the existing soft-failure
behavior so malformed optional metadata does not fail the open.
Fixes: 69dda3059e7a ("cifs: add SMB2_open() arg to return POSIX data")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Co-developed-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Tested-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/smb2pdu.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -2313,12 +2313,15 @@ static void
parse_posix_ctxt(struct create_context *cc, struct smb2_file_all_info *info,
struct create_posix_rsp *posix)
{
- int sid_len;
u8 *beg = (u8 *)cc + le16_to_cpu(cc->DataOffset);
- u8 *end = beg + le32_to_cpu(cc->DataLength);
+ u32 dlen = le32_to_cpu(cc->DataLength);
+ u8 *end = beg + dlen;
+ int sid_len;
u8 *sid;
memset(posix, 0, sizeof(*posix));
+ if (dlen < 3 * sizeof(__le32))
+ return;
posix->nlink = get_unaligned_le32(beg);
posix->reparse_tag = get_unaligned_le32(beg + 4);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 547/877] xfs: dont assert when XFS_SCRUB_TYPE_HEALTHY scans return corruption
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (545 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 546/877] smb: client: validate POSIX create context length Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 548/877] xfs: fix attr fork block count checks in xrep_inode_blockcounts Greg Kroah-Hartman
` (337 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit afbccf99f7f82117cba9ad4b0b006692030f49e8 upstream.
XFS_SCRUB_TYPE_HEALTHY is a synthentic scrub type so that xfs_scrub can
tell the kernel "Hey, I finished a scan and saw no problems" and have
the kernel forget that it saw indirect evidence of corruption.
Unfortunately, as LOLLM points out, it's possible for the health system
to record a new corruption just before xfs_scrub gets to
XFS_SCRUB_TYPE_HEALTHY. In this case, the existing logic doesn't return
early and instead wanders into unknown regions of type_to_health_flag
and trips the assert because HEALTHY doesn't have a group assignment.
Fix the logic so that we always return early for a HEALTHY scrub type,
even if we decide not to call xchk_mark_all_healthy.
Cc: stable@vger.kernel.org # v6.9
Fixes: a1f3e0cca41036 ("xfs: update health status if we get a clean bill of health")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/health.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/fs/xfs/scrub/health.c
+++ b/fs/xfs/scrub/health.c
@@ -192,9 +192,9 @@ xchk_update_health(
* there's no sick flag defined for it, so we branch here ahead of the
* mask check.
*/
- if (sc->sm->sm_type == XFS_SCRUB_TYPE_HEALTHY &&
- !(sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) {
- xchk_mark_all_healthy(sc->mp);
+ if (sc->sm->sm_type == XFS_SCRUB_TYPE_HEALTHY) {
+ if (!(sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
+ xchk_mark_all_healthy(sc->mp);
return;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 548/877] xfs: fix attr fork block count checks in xrep_inode_blockcounts
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (546 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 547/877] xfs: dont assert when XFS_SCRUB_TYPE_HEALTHY scans return corruption Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 549/877] xfs: release orphanage dir inode if chown fails Greg Kroah-Hartman
` (336 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit bb991b7f79dd34cc5f24db0f736bf75630c970e7 upstream.
LOLLM points out that a file has an attr fork, it will call
xchk_inode_count_blocks to set @ablocks to the number of fsblocks mapped
by the attr fork; but then it'll compare @blocks (aka the count of
fsblocks mapped by the data fork). We already checked that and we never
do anything with @acount, so I think this is clearly a bug. Fix the
comparison.
Cc: stable@vger.kernel.org # v6.8
Fixes: 2d295fe65776d1 ("xfs: repair inode records")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/inode_repair.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/xfs/scrub/inode_repair.c
+++ b/fs/xfs/scrub/inode_repair.c
@@ -1513,7 +1513,7 @@ xrep_inode_blockcounts(
&nextents, &acount);
if (error)
return error;
- if (count >= sc->mp->m_sb.sb_dblocks)
+ if (acount >= sc->mp->m_sb.sb_dblocks)
return -EFSCORRUPTED;
error = xrep_ino_ensure_extent_count(sc, XFS_ATTR_FORK,
nextents);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 549/877] xfs: release orphanage dir inode if chown fails
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (547 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 548/877] xfs: fix attr fork block count checks in xrep_inode_blockcounts Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 550/877] xfs: use correct jiffies comparison function in xchk_maybe_relax Greg Kroah-Hartman
` (335 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 1c32cdc986467eaffeedb6c5334852809555b82d upstream.
LOLLM points out that we leak the igrab'd reference to the orphanage
directory inode if chowning it fails. Fix that.
Cc: stable@vger.kernel.org # v6.10
Fixes: 1e58a8ccf2597c ("xfs: move orphan files to the orphanage")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/orphanage.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/fs/xfs/scrub/orphanage.c
+++ b/fs/xfs/scrub/orphanage.c
@@ -193,12 +193,16 @@ xrep_orphanage_create(
/* Make sure the orphanage is owned by root. */
error = xrep_chown_orphanage(sc, XFS_I(orphanage_inode));
if (error)
- goto out_dput_orphanage;
+ goto out_rele_orphanage;
/* Stash the reference for later and bail out. */
sc->orphanage = XFS_I(orphanage_inode);
sc->orphanage_ilock_flags = 0;
+ orphanage_inode = NULL;
+out_rele_orphanage:
+ if (orphanage_inode)
+ xchk_irele(sc, XFS_I(orphanage_inode));
out_dput_orphanage:
dput(orphanage_dentry);
out_unlock_root:
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 550/877] xfs: use correct jiffies comparison function in xchk_maybe_relax
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (548 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 549/877] xfs: release orphanage dir inode if chown fails Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 551/877] xfs: check padding field in xfs_ioc_commit_range Greg Kroah-Hartman
` (334 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 984aab2d905a8557fafb27cd9e8713d6d12b3437 upstream.
LOLLM points out that we're supposed to use time_after_eq, not a raw >=
operation here, or else jiffies wraps can go unnoticed. Fix this.
Cc: stable@vger.kernel.org # v6.10
Fixes: 271557de7cbfde ("xfs: reduce the rate of cond_resched calls inside scrub")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/scrub.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/xfs/scrub/scrub.h b/fs/xfs/scrub/scrub.h
index 737a5d6db15f..b093945f3631 100644
--- a/fs/xfs/scrub/scrub.h
+++ b/fs/xfs/scrub/scrub.h
@@ -40,7 +40,7 @@ static inline int xchk_maybe_relax(struct xchk_relax *widget)
return 0;
widget->resched_nr = 0;
- if (unlikely(widget->next_resched <= jiffies)) {
+ if (unlikely(time_after_eq(jiffies, widget->next_resched))) {
cond_resched();
widget->next_resched = XCHK_RELAX_NEXT;
}
--
2.55.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 551/877] xfs: check padding field in xfs_ioc_commit_range
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (549 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 550/877] xfs: use correct jiffies comparison function in xchk_maybe_relax Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 552/877] xfs: dont call xfs_exchange_range_finish for a dry run Greg Kroah-Hartman
` (333 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 3083ba8dde765a9ab2337f3db68d00724a6b1202 upstream.
LOLLM points out that we don't check the ioctl padding field here, so
let's do that. I don't think there are many users yet since exchrange
requires a new feature flag, so it's a good time to try to plug this
hole.
Cc: stable@vger.kernel.org # v6.12
Fixes: 398597c3ef7fb1 ("xfs: introduce new file range commit ioctls")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/xfs_exchrange.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/xfs/xfs_exchrange.c
+++ b/fs/xfs/xfs_exchrange.c
@@ -905,7 +905,7 @@ xfs_ioc_commit_range(
if (copy_from_user(&args, argp, sizeof(args)))
return -EFAULT;
- if (args.flags & ~XFS_EXCHANGE_RANGE_ALL_FLAGS)
+ if (args.pad || (args.flags & ~XFS_EXCHANGE_RANGE_ALL_FLAGS))
return -EINVAL;
if (kern_f->magic != XCR_FRESH_MAGIC)
return -EBUSY;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 552/877] xfs: dont call xfs_exchange_range_finish for a dry run
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (550 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 551/877] xfs: check padding field in xfs_ioc_commit_range Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 553/877] xfs: check di_forkoff correctly in scrub Greg Kroah-Hartman
` (332 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 8fc18580ec17f90beac4c933fbe4c74dcd3b7f36 upstream.
LOLLM noticed that we strip file privileges and whatnot even for a dry
run. We also shouldn't flush dirty data to disk or trim COW staging
events for a dry run. Neither of those behaviors are allowed by the
manpage, so fix that by exiting early on DRY_RUN in various functions.
Cc: stable@vger.kernel.org # v6.10
Fixes: 42672471f938cd ("xfs: bind together the front and back ends of the file range exchange code")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/xfs_exchrange.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
--- a/fs/xfs/xfs_exchrange.c
+++ b/fs/xfs/xfs_exchrange.c
@@ -630,6 +630,9 @@ xfs_exchrange_prep(
if (error)
return error;
+ if (fxr->flags & XFS_EXCHANGE_RANGE_DRY_RUN)
+ return 0;
+
trace_xfs_exchrange_flush(fxr, ip1, ip2);
/* Flush the relevant ranges of both files. */
@@ -706,9 +709,11 @@ xfs_exchrange_contents(
* other file write would do. This may involve turning on support for
* logged xattrs if either file has security capabilities.
*/
- error = xfs_exchange_range_finish(fxr);
- if (error)
- goto out_unlock;
+ if (!(fxr->flags & XFS_EXCHANGE_RANGE_DRY_RUN)) {
+ error = xfs_exchange_range_finish(fxr);
+ if (error)
+ goto out_unlock;
+ }
out_unlock:
xfs_iunlock2_io_mmap(ip1, ip2);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 553/877] xfs: check di_forkoff correctly in scrub
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (551 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 552/877] xfs: dont call xfs_exchange_range_finish for a dry run Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 554/877] xfs: drop dquot flush lock when we cant find a buffer to flush Greg Kroah-Hartman
` (331 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit e9193f2f1ce32d02b9230094ffdbfab715ab6137 upstream.
The di_forkoff check in xchk_dinode is incorrect, according to LOLLM.
XFS_DFORK_BOFF returns a byte count relative to the start of the literal
area, not the start of the inode. Therefore, this check won't flag
di_forkoff values that are larger than the literal area but not the
inode size itself. Fix this check; sadly the old APTR code was correct.
Cc: stable@vger.kernel.org # v6.8
Fixes: 6b5d917780219d ("xfs: dont cast to char * for XFS_DFORK_*PTR macros")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/inode.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/xfs/scrub/inode.c
+++ b/fs/xfs/scrub/inode.c
@@ -560,7 +560,7 @@ xchk_dinode(
}
/* di_forkoff */
- if (XFS_DFORK_BOFF(dip) >= mp->m_sb.sb_inodesize)
+ if (dip->di_forkoff >= (XFS_LITINO(mp) >> 3))
xchk_ino_set_corrupt(sc, ino);
if (naextents != 0 && dip->di_forkoff == 0)
xchk_ino_set_corrupt(sc, ino);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 554/877] xfs: drop dquot flush lock when we cant find a buffer to flush
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (552 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 553/877] xfs: check di_forkoff correctly in scrub Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-10-01 20:21 ` Harshit Mogalapalli
2026-09-30 15:24 ` [PATCH 6.12 555/877] xfs: fix blockgc group quota scanning when usrquota isnt enforced Greg Kroah-Hartman
` (330 subsequent siblings)
884 siblings, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit ffb48dccce1960a9ea24463a2f3c21d124d6b672 upstream.
LOLLM noticed that xfs_qm_flush_one fails to drop the dquot flush lock
if it can't grab the buffer associated with the dquot. Since there's no
buffer, nobody else is going to drop the dqflock, so we need to do it
ourselves.
Cc: stable@vger.kernel.org # v6.13
Fixes: ca378189fdfa89 ("xfs: convert quotacheck to attach dquot buffers")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/xfs_qm.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -1317,16 +1317,22 @@ xfs_qm_flush_one(
error = xfs_dquot_use_attached_buf(dqp, &bp);
if (error)
- goto out_unlock;
+ goto out_dqflock;
if (!bp) {
error = -EFSCORRUPTED;
- goto out_unlock;
+ goto out_dqflock;
}
error = xfs_qm_dqflush(dqp, bp);
if (!error)
xfs_buf_delwri_queue(bp, buffer_list);
xfs_buf_relse(bp);
+ mutex_unlock(&dqp->q_qlock);
+ xfs_qm_dqrele(dqp);
+ return error;
+
+out_dqflock:
+ xfs_dqfunlock(dqp);
out_unlock:
xfs_dqunlock(dqp);
return error;
^ permalink raw reply [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 554/877] xfs: drop dquot flush lock when we cant find a buffer to flush
2026-09-30 15:24 ` [PATCH 6.12 554/877] xfs: drop dquot flush lock when we cant find a buffer to flush Greg Kroah-Hartman
@ 2026-10-01 20:21 ` Harshit Mogalapalli
2026-10-02 6:24 ` Greg Kroah-Hartman
2026-10-03 1:30 ` Sasha Levin
0 siblings, 2 replies; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-01 20:21 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable, Sasha Levin
Cc: patches, Darrick J. Wong, Christoph Hellwig, Carlos Maiolino
On 30/09/26 8:54 pm, Greg Kroah-Hartman wrote:
> 6.12-stable review patch. If anyone has any objections, please let me know.
>
> ------------------
>
> From: Darrick J. Wong <djwong@kernel.org>
>
> commit ffb48dccce1960a9ea24463a2f3c21d124d6b672 upstream.
>
> LOLLM noticed that xfs_qm_flush_one fails to drop the dquot flush lock
> if it can't grab the buffer associated with the dquot. Since there's no
> buffer, nobody else is going to drop the dqflock, so we need to do it
> ourselves.
>
> Cc: stable@vger.kernel.org # v6.13
> Fixes: ca378189fdfa89 ("xfs: convert quotacheck to attach dquot buffers")
> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> Assisted-by: LOLLM # finding obvious bugs
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Carlos Maiolino <cem@kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
> fs/xfs/xfs_qm.c | 10 ++++++++--
> 1 file changed, 8 insertions(+), 2 deletions(-)
>
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -1317,16 +1317,22 @@ xfs_qm_flush_one(
>
> error = xfs_dquot_use_attached_buf(dqp, &bp);
> if (error)
> - goto out_unlock;
> + goto out_dqflock;
> if (!bp) {
> error = -EFSCORRUPTED;
> - goto out_unlock;
> + goto out_dqflock;
> }
>
> error = xfs_qm_dqflush(dqp, bp);
> if (!error)
> xfs_buf_delwri_queue(bp, buffer_list);
> xfs_buf_relse(bp);
> + mutex_unlock(&dqp->q_qlock);
> + xfs_qm_dqrele(dqp);
^^
Hi Greg,
An AI assisted backport review flagged this, and I checked the upstream
code against the 6.12.y tip f4ffa8dc360b.
Upstream ffb48dccce19 acquires a temporary dquot reference and balances
it on the buffer-bearing return path:
if (!lockref_get_not_dead(&dqp->q_lockref))
return 0;
mutex_lock(&dqp->q_qlock);
/* ... intervening source omitted ... */
xfs_buf_relse(bp);
mutex_unlock(&dqp->q_qlock);
xfs_qm_dqrele(dqp);
return error;
6.12.y starts with a mutex-only xfs_dqlock(), but copies the release:
xfs_dqlock(dqp);
if (dqp->q_flags & XFS_DQFLAG_FREEING)
goto out_unlock;
if (!XFS_DQ_IS_DIRTY(dqp))
goto out_unlock;
/* ... intervening source omitted ... */
xfs_buf_relse(bp);
mutex_unlock(&dqp->q_qlock);
xfs_qm_dqrele(dqp);
return error;
Neither xfs_dqlock() nor the walker takes a reference. The new
xfs_qm_dqrele() releases an unowned reference and can assert/underflow
q_nrefs on dirty zero-reference dquots after quotacheck, potentially
blocking purge/teardown.
Could we replace the new mutex_unlock()/xfs_qm_dqrele() pair with
xfs_dqunlock(dqp), keeping the early return and out_dqflock cleanup?
or drop this fix for 6.12.y ?
thanks,
Harshit> + return error;
> +
> +out_dqflock:
> + xfs_dqfunlock(dqp);
> out_unlock:
> xfs_dqunlock(dqp);
> return error;
>
>
>
^ permalink raw reply [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 554/877] xfs: drop dquot flush lock when we cant find a buffer to flush
2026-10-01 20:21 ` Harshit Mogalapalli
@ 2026-10-02 6:24 ` Greg Kroah-Hartman
2026-10-03 1:30 ` Sasha Levin
1 sibling, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-02 6:24 UTC (permalink / raw)
To: Harshit Mogalapalli
Cc: stable, Sasha Levin, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
On Fri, Oct 02, 2026 at 01:51:58AM +0530, Harshit Mogalapalli wrote:
>
>
> On 30/09/26 8:54 pm, Greg Kroah-Hartman wrote:
> > 6.12-stable review patch. If anyone has any objections, please let me know.
> >
> > ------------------
> >
> > From: Darrick J. Wong <djwong@kernel.org>
> >
> > commit ffb48dccce1960a9ea24463a2f3c21d124d6b672 upstream.
> >
> > LOLLM noticed that xfs_qm_flush_one fails to drop the dquot flush lock
> > if it can't grab the buffer associated with the dquot. Since there's no
> > buffer, nobody else is going to drop the dqflock, so we need to do it
> > ourselves.
> >
> > Cc: stable@vger.kernel.org # v6.13
> > Fixes: ca378189fdfa89 ("xfs: convert quotacheck to attach dquot buffers")
> > Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> > Assisted-by: LOLLM # finding obvious bugs
> > Reviewed-by: Christoph Hellwig <hch@lst.de>
> > Signed-off-by: Carlos Maiolino <cem@kernel.org>
> > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > ---
> > fs/xfs/xfs_qm.c | 10 ++++++++--
> > 1 file changed, 8 insertions(+), 2 deletions(-)
> >
> > --- a/fs/xfs/xfs_qm.c
> > +++ b/fs/xfs/xfs_qm.c
> > @@ -1317,16 +1317,22 @@ xfs_qm_flush_one(
> > error = xfs_dquot_use_attached_buf(dqp, &bp);
> > if (error)
> > - goto out_unlock;
> > + goto out_dqflock;
> > if (!bp) {
> > error = -EFSCORRUPTED;
> > - goto out_unlock;
> > + goto out_dqflock;
> > }
> > error = xfs_qm_dqflush(dqp, bp);
> > if (!error)
> > xfs_buf_delwri_queue(bp, buffer_list);
> > xfs_buf_relse(bp);
> > + mutex_unlock(&dqp->q_qlock);
> > + xfs_qm_dqrele(dqp);
>
>
> ^^
>
> Hi Greg,
>
> An AI assisted backport review flagged this, and I checked the upstream
> code against the 6.12.y tip f4ffa8dc360b.
>
> Upstream ffb48dccce19 acquires a temporary dquot reference and balances
> it on the buffer-bearing return path:
>
> if (!lockref_get_not_dead(&dqp->q_lockref))
> return 0;
>
> mutex_lock(&dqp->q_qlock);
> /* ... intervening source omitted ... */
> xfs_buf_relse(bp);
> mutex_unlock(&dqp->q_qlock);
> xfs_qm_dqrele(dqp);
> return error;
>
> 6.12.y starts with a mutex-only xfs_dqlock(), but copies the release:
>
> xfs_dqlock(dqp);
> if (dqp->q_flags & XFS_DQFLAG_FREEING)
> goto out_unlock;
> if (!XFS_DQ_IS_DIRTY(dqp))
> goto out_unlock;
> /* ... intervening source omitted ... */
> xfs_buf_relse(bp);
> mutex_unlock(&dqp->q_qlock);
> xfs_qm_dqrele(dqp);
> return error;
>
> Neither xfs_dqlock() nor the walker takes a reference. The new
> xfs_qm_dqrele() releases an unowned reference and can assert/underflow
> q_nrefs on dirty zero-reference dquots after quotacheck, potentially
> blocking purge/teardown.
>
> Could we replace the new mutex_unlock()/xfs_qm_dqrele() pair with
> xfs_dqunlock(dqp), keeping the early return and out_dqflock cleanup?
>
> or drop this fix for 6.12.y ?
Now dropped from the 6.12.y queue, thanks.
greg k-h
^ permalink raw reply [flat|nested] 922+ messages in thread* Re: [PATCH 6.12 554/877] xfs: drop dquot flush lock when we cant find a buffer to flush
2026-10-01 20:21 ` Harshit Mogalapalli
2026-10-02 6:24 ` Greg Kroah-Hartman
@ 2026-10-03 1:30 ` Sasha Levin
1 sibling, 0 replies; 922+ messages in thread
From: Sasha Levin @ 2026-10-03 1:30 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: Sasha Levin, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino, Harshit Mogalapalli
> Could we replace the new mutex_unlock()/xfs_qm_dqrele() pair with
> xfs_dqunlock(dqp), keeping the early return and out_dqflock cleanup?
>
> or drop this fix for 6.12.y ?
Greg already dropped the 6.12 copy. The 6.18 queue had the same
unbalanced xfs_qm_dqrele(): 6.18 doesn't have 0c5e80bd579f7 ("xfs: use
a lockref for the xfs_dquot reference count", v6.19-rc1), so its
xfs_qm_flush_one() never takes the lockref_get_not_dead() reference
that the new exit path releases. I've dropped it from 6.18 as well.
7.2 has that reference, so it keeps the patch.
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 922+ messages in thread
* [PATCH 6.12 555/877] xfs: fix blockgc group quota scanning when usrquota isnt enforced
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (553 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 554/877] xfs: drop dquot flush lock when we cant find a buffer to flush Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 556/877] net: tls: fix silent data drop under pipe back-pressure Greg Kroah-Hartman
` (329 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit f8f6382ff13109e19d0fc1d0224ff7d29641e56a upstream.
LOLLM noticed the copy-paste error here -- if user quotas aren't
enforced but we're near the group quota limit, we fail to set FLAG_GID
and hence we might not actually free any preallocations, causing
unnecessary EDQUOT. Fix that.
Cc: stable@vger.kernel.org # v5.12
Fixes: c237dd7c709432 ("xfs: flush eof/cowblocks if we can't reserve quota for inode creation")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/xfs_icache.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -1593,7 +1593,7 @@ xfs_blockgc_free_dquots(
do_work = true;
}
- if (XFS_IS_UQUOTA_ENFORCED(mp) && gdqp && xfs_dquot_lowsp(gdqp)) {
+ if (XFS_IS_GQUOTA_ENFORCED(mp) && gdqp && xfs_dquot_lowsp(gdqp)) {
icw.icw_gid = make_kgid(mp->m_super->s_user_ns, gdqp->q_id);
icw.icw_flags |= XFS_ICWALK_FLAG_GID;
do_work = true;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 556/877] net: tls: fix silent data drop under pipe back-pressure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (554 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 555/877] xfs: fix blockgc group quota scanning when usrquota isnt enforced Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 557/877] perf test: Change all remaining #!/bin/sh to #!/bin/bash Greg Kroah-Hartman
` (328 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jakub Kicinski, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <kuba@kernel.org>
[ Upstream commit 7e7be31bfdb066c1c780dcd6b1224078fc54063f ]
tls_sw_splice_read() uses len when advancing rxm->offset / rxm->full_len
after skb_splice_bits(), rather than copied (the actual number of bytes
successfully spliced into the pipe). When the destination pipe cannot
accept all the requested bytes, splice_to_pipe() returns fewer bytes
than len, and 'len - copied' of data is effectively skipped over.
Fixes: e062fe99cccd ("tls: splice_read: fix accessing pre-processed records")
Link: https://patch.msgid.link/20260429222944.2139041-2-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/tls/tls_sw.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index a41fd85279bcd..323ac8b1ad0c8 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -2337,9 +2337,9 @@ ssize_t tls_sw_splice_read(struct socket *sock, loff_t *ppos,
if (copied < 0)
goto splice_requeue;
- if (chunk < rxm->full_len) {
- rxm->offset += len;
- rxm->full_len -= len;
+ if (copied < rxm->full_len) {
+ rxm->offset += copied;
+ rxm->full_len -= copied;
goto splice_requeue;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 922+ messages in thread* [PATCH 6.12 557/877] perf test: Change all remaining #!/bin/sh to #!/bin/bash
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (555 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 556/877] net: tls: fix silent data drop under pipe back-pressure Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 558/877] ring-buffer: Add helper functions for allocations Greg Kroah-Hartman
` (327 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, James Clark, Collin Funk,
Arnaldo Carvalho de Melo, Namhyung Kim, Salvatore Bonaccorso
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Clark <james.clark@linaro.org>
commit 2f5d370dec3f800b44bbf7b68875d521e0af43cd upstream.
There are 43 instances of posix shell tests and 35 instances of bash. To
give us a single consistent language for testing in, replace
all #!/bin/sh to #!/bin/bash. Common sources that are included in both
different shells will now work as expected. And we no longer have to fix
up bashisms that appear to work when someone's system has sh symlinked
to bash, but don't work on other systems that have both shells
installed.
Although we could have chosen sh, it's not backwards compatible so it
wouldn't be possible to bulk convert without re-writing the existing
bash tests.
Choosing bash also gives us some nicer features including 'local'
variable definitions and regexes in if statements that are already
widely used in the tests.
It's not expected that there are any users with only sh available due to
the large number of bash tests that exist.
Discussed in relation to running shellcheck here:
https://lore.kernel.org/linux-perf-users/e3751a74be34bbf3781c4644f518702a7270220b.1749785642.git.collin.funk1@gmail.com/
Signed-off-by: James Clark <james.clark@linaro.org>
Reviewed-by: Collin Funk <collin.funk1@gmail.com>
Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Link: https://lore.kernel.org/r/20250623-james-perf-bash-tests-v1-1-f572f54d4559@linaro.org
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
When commit b02027776ac5 ("perf tests: Fix flakiness in BPF counters
test on hybrid systems") was backported to several stable series
(v5.15.221, v6.1.188, v6.6.157, v6.12.110, v6.18.52, v7.2.6) it
introduced specific bash syntax. For versions after 2f5d370dec3f ("perf
test: Change all remaining #!/bin/sh to #!/bin/bash") in v6.17-rc1 this
is not a problem as the shebang was already hanged to #!/bin/bash. For
the older stable series this introduced invalid syntax if #!/bin/sh is
not bash:
$ sh -n tools/perf/tests/shell/stat_bpf_counters.sh
tools/perf/tests/shell/stat_bpf_counters.sh: 12: Syntax error: "(" unexpected
$ checkbashism tools/perf/tests/shell/stat_bpf_counters.sh
possible bashism in tools/perf/tests/shell/stat_bpf_counters.sh line 52 (bash arrays, ${name[0|*|@]}):
base_instructions=$(perf stat --no-big-num -e instructions:u -- "${workload[@]}" 2>&1 | \
awk -v i=0 -v c=0 '/instructions/ { \
if ($1 != "<not") { i++; c += $1 } \
} END { if (i > 0) printf "%.0f", c; else print "<not" }')
possible bashism in tools/perf/tests/shell/stat_bpf_counters.sh line 57 (bash arrays, ${name[0|*|@]}):
bpf_instructions=$(perf stat --no-big-num --bpf-counters -e instructions:u \
-- "${workload[@]}" 2>&1 | \
awk -v i=0 -v c=0 '/instructions/ { \
if ($1 != "<not") { i++; c += $1 } \
} END { if (i > 0) printf "%.0f", c; else print "<not" }')
possible bashism in tools/perf/tests/shell/stat_bpf_counters.sh line 68 (bash arrays, ${name[0|*|@]}):
stat_output=$(perf stat --no-big-num \
-e instructions/name=base_instructions/u,instructions/name=bpf_instructions/bu \
-- "${workload[@]}" 2>&1)
Change shebang for the stat_bpf_counters.sh script.
No upstream commit exists for this change as for versions post 6.17-rc1
the scripts were converted to #!/bin/bash already.
Signed-off-by: Salvatore Bonaccorso <carnil@debian.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
tools/perf/tests/shell/stat_bpf_counters.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/tools/perf/tests/shell/stat_bpf_counters.sh
+++ b/tools/perf/tests/shell/stat_bpf_counters.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
# perf stat --bpf-counters test
# SPDX-License-Identifier: GPL-2.0
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 558/877] ring-buffer: Add helper functions for allocations
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (556 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 557/877] perf test: Change all remaining #!/bin/sh to #!/bin/bash Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 559/877] ring-buffer: Fix subbuf resize race with ring_buffer_alloc_read_page() Greg Kroah-Hartman
` (326 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Masami Hiramatsu, Mathieu Desnoyers,
Linus Torvalds, Steven Rostedt (Google), Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit b1e7a590a0133606d3efd41aee38cdeac630b52f ]
The allocation of the per CPU buffer descriptor, the buffer page
descriptors and the buffer page data itself can be pretty ugly:
kzalloc_node(ALIGN(sizeof(struct buffer_page), cache_line_size()),
GFP_KERNEL, cpu_to_node(cpu));
And the data pages:
page = alloc_pages_node(cpu_to_node(cpu),
GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_COMP | __GFP_ZERO, order);
if (!page)
return NULL;
bpage->page = page_address(page);
rb_init_page(bpage->page);
Add helper functions to make the code easier to read.
This does make all allocations of the data page (bpage->page) allocated
with the __GFP_RETRY_MAYFAIL flag (and not just the bulk allocator). Which
is actually better, as allocating the data page for the ring buffer tracing
should try hard but not trigger the OOM killer.
Link: https://lore.kernel.org/all/CAHk-=wjMMSAaqTjBSfYenfuzE1bMjLj+2DLtLWJuGt07UGCH_Q@mail.gmail.com/
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Link: https://patch.msgid.link/20251125121153.35c07461@gandalf.local.home
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Stable backport adjustment for e743527c5bfd:
Keep only the read-page allocation refactor needed by the target. Express
alloc_cpu_data as a statement-expression macro instead of adding a C
function, retaining NUMA allocation, __GFP_RETRY_MAYFAIL, compound/zeroed
pages, NULL failure handling, and data-page initialization.
Rename the existing rb_init_page initializer to rb_init_data_page, without
changing its implementation, and update its callers. This supplies the
context expected by the target without importing the unrelated cleanup
from 7cf02d0aa6bd or introducing additional functions.
Drop the CPU-buffer and buffer-page descriptor refactors and the bulk and
internal reader-page allocator conversions. These are not needed by the
target; leaving them intact preserves this tree's ring_buffer_meta type,
__GFP_RETRY_MAYFAIL descriptor allocations, and the existing bpage->order
and resize-disabled fixes. Only newly allocated external read pages switch
from __GFP_NORETRY to __GFP_RETRY_MAYFAIL in this backport.
The target's change to allocate using the saved bpage->order is deliberately
left for e743527c5bfd itself.
Stable-dep-of: e743527c5bfd ("ring-buffer: Fix subbuf resize race with ring_buffer_alloc_read_page()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/ring_buffer.c | 50 ++++++++++++++++++++++++++-------------------
1 file changed, 29 insertions(+), 21 deletions(-)
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -382,7 +382,7 @@ struct buffer_page {
#define RB_WRITE_MASK 0xfffff
#define RB_WRITE_INTCNT (1 << 20)
-static void rb_init_page(struct buffer_data_page *bpage)
+static void rb_init_data_page(struct buffer_data_page *bpage)
{
local_set(&bpage->commit, 0);
}
@@ -411,6 +411,21 @@ static void free_buffer_page(struct buff
kfree(bpage);
}
+/* Try hard to allocate data pages without invoking the OOM killer. */
+#define alloc_cpu_data(cpu, order) ({ \
+ struct buffer_data_page *__rb_data = NULL; \
+ struct page *__rb_page; \
+ \
+ __rb_page = alloc_pages_node(cpu_to_node(cpu), \
+ GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_COMP | __GFP_ZERO, \
+ (order)); \
+ if (__rb_page) { \
+ __rb_data = page_address(__rb_page); \
+ rb_init_data_page(__rb_data); \
+ } \
+ __rb_data; \
+})
+
/*
* We need to fit the time_stamp delta into 27 bits.
*/
@@ -2016,7 +2031,7 @@ static void rb_range_meta_init(struct tr
*/
for (i = 0; i < meta->nr_subbufs; i++) {
meta->buffers[i] = i;
- rb_init_page(subbuf);
+ rb_init_data_page(subbuf);
subbuf += meta->subbuf_size;
}
}
@@ -2187,7 +2202,7 @@ static int __rb_allocate_pages(struct ri
if (!page)
goto free_pages;
bpage->page = page_address(page);
- rb_init_page(bpage->page);
+ rb_init_data_page(bpage->page);
}
bpage->order = cpu_buffer->buffer->subbuf_order;
@@ -2293,7 +2308,7 @@ rb_allocate_cpu_buffer(struct trace_buff
if (!page)
goto fail_free_reader;
bpage->page = page_address(page);
- rb_init_page(bpage->page);
+ rb_init_data_page(bpage->page);
}
INIT_LIST_HEAD(&cpu_buffer->reader_page->list);
@@ -6008,7 +6023,7 @@ static void rb_clear_buffer_page(struct
{
local_set(&page->write, 0);
local_set(&page->entries, 0);
- rb_init_page(page->page);
+ rb_init_data_page(page->page);
page->read = 0;
}
@@ -6394,7 +6409,6 @@ ring_buffer_alloc_read_page(struct trace
struct ring_buffer_per_cpu *cpu_buffer;
struct buffer_data_read_page *bpage = NULL;
unsigned long flags;
- struct page *page;
if (!cpumask_test_cpu(cpu, buffer->cpumask))
return ERR_PTR(-ENODEV);
@@ -6416,22 +6430,16 @@ ring_buffer_alloc_read_page(struct trace
arch_spin_unlock(&cpu_buffer->lock);
local_irq_restore(flags);
- if (bpage->data)
- goto out;
-
- page = alloc_pages_node(cpu_to_node(cpu),
- GFP_KERNEL | __GFP_NORETRY | __GFP_COMP | __GFP_ZERO,
- cpu_buffer->buffer->subbuf_order);
- if (!page) {
- kfree(bpage);
- return ERR_PTR(-ENOMEM);
+ if (bpage->data) {
+ rb_init_data_page(bpage->data);
+ } else {
+ bpage->data = alloc_cpu_data(cpu, cpu_buffer->buffer->subbuf_order);
+ if (!bpage->data) {
+ kfree(bpage);
+ return ERR_PTR(-ENOMEM);
+ }
}
- bpage->data = page_address(page);
-
- out:
- rb_init_page(bpage->data);
-
return bpage;
}
EXPORT_SYMBOL_GPL(ring_buffer_alloc_read_page);
@@ -6640,7 +6648,7 @@ int ring_buffer_read_page(struct trace_b
cpu_buffer->read_bytes += rb_page_size(reader);
/* swap the pages */
- rb_init_page(bpage);
+ rb_init_data_page(bpage);
bpage = reader->page;
reader->page = data_page->data;
local_set(&reader->write, 0);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 559/877] ring-buffer: Fix subbuf resize race with ring_buffer_alloc_read_page()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (557 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 558/877] ring-buffer: Add helper functions for allocations Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 560/877] sched: Rework prev_balance() to avoid stale prev references Greg Kroah-Hartman
` (325 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Vincent Donnefort,
Steven Rostedt, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Donnefort <vdonnefort@google.com>
[ Upstream commit e743527c5bfdceda1095bc0a9e596e2aebb6a9c3 ]
ring_buffer_alloc_read_page() is racy with ring_buffer_subbuf_order_set,
it can allocate a reader page with an outdated order. This isn't a big
issue, the user can still re-allocate a new reader page and try again.
However, what is more problematic is if the value of subbuf_order
changes in the middle of ring_buffer_alloc_read_page(). In that case,
bpage->order might not match the actual allocated memory.
Use bpage->order for the allocation to prevent this race.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260813131152.3589632-6-vdonnefort@google.com
Fixes: bce761d75745 ("ring-buffer: Read and write to ring buffers with custom sub buffer size")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/ring_buffer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -6433,7 +6433,7 @@ ring_buffer_alloc_read_page(struct trace
if (bpage->data) {
rb_init_data_page(bpage->data);
} else {
- bpage->data = alloc_cpu_data(cpu, cpu_buffer->buffer->subbuf_order);
+ bpage->data = alloc_cpu_data(cpu, bpage->order);
if (!bpage->data) {
kfree(bpage);
return ERR_PTR(-ENOMEM);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 560/877] sched: Rework prev_balance() to avoid stale prev references
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (558 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 559/877] ring-buffer: Fix subbuf resize race with ring_buffer_alloc_read_page() Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 561/877] sched/core: Make core-sched flips wait for in-flight selections Greg Kroah-Hartman
` (324 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, John Stultz, Peter Zijlstra (Intel),
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Stultz <jstultz@google.com>
[ Upstream commit 7a3a6bfbd62a2ba3e0ef1e92d6b71abb66890825 ]
Historically, the prev value from __schedule() was the rq->curr.
This prev value is passed down through numerous functions, and
used in the class scheduler implementations. The fact that
prev was on_cpu until the end of __schedule(), meant it was
stable across the rq lock drops that the class->balance()
implementations often do.
However, with proxy-exec, the prev passed to functions called
by __schedule() is rq->donor, which may not be the same as
rq->curr and may not be on_cpu, this makes the prev value
potentially unstable across rq lock drops.
A recently found issue with proxy-exec, is when we begin doing
return migration from try_to_wake_up(), its possible we may be
waking up the rq->donor. When we do this, we proxy_resched_idle()
to put_prev_set_next() setting the rq->donor to rq->idle, allowing
the rq->donor to be return migrated and allowed to run.
This however runs into trouble, as on another cpu we might be in
the middle of calling __schedule(). Conceptually the rq lock is
held for the majority of the time, but in calling prev_balance()
its possible the class->balance() handler call may briefly drop the rq lock.
This opens a window for try_to_wake_up() to wake and return migrate the
rq->donor before the class logic reacquires the rq lock.
Unfortunately prev_balance() pass in a prev argument, to which we pass
rq->donor. However this prev value can now become stale and incorrect across a
rq lock drop.
So, to correct this, rework the prev_balance() call so that it does not take a
"prev" argument.
Signed-off-by: John Stultz <jstultz@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260512025635.2840817-2-jstultz@google.com
Backport adaptation for Linux 6.12, as a dependency of f3629c63a4af
("sched/core: Make core-sched flips wait for in-flight selections"):
This tree has no proxy execution. Alias rq->donor and rq->curr in a union,
as upstream does without CONFIG_SCHED_PROXY_EXEC, so the existing curr
updates also provide the scheduling context without separate state.
Remove the prev parameter from prev_balance(), __pick_next_task(), and
both pick_next_task() variants, and read rq->donor at their call sites.
Keep the stable sched_class balance and pick_next_task interfaces and the
fair and sched_ext selection paths. Pass rq->donor to these existing
callbacks; it aliases the on-CPU current task and remains stable across
lock drops here. Drop the upstream deadline, RT, idle, and stop callback
signature changes, along with assumptions about newer selection APIs,
proxy execution, and lock annotations. No functions are added.
Label the CONFIG_SCHED_CORE closing directive in struct rq to match the
target's patch context. The unmodified target patch applies cleanly after
this adaptation. The core-selection counter fix remains in the target.
[ sashal: Reduced backport -- upstream 7a3a6bfbd62a2 touches 6 file(s), this
backport carries 2. Not backported here:
kernel/sched/deadline.c
kernel/sched/idle.c
kernel/sched/rt.c
kernel/sched/stop_task.c
This note is generated from the file lists only; see the resolution record
for the reasoning. ]
Stable-dep-of: f3629c63a4af ("sched/core: Make core-sched flips wait for in-flight selections")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/sched/core.c | 39 +++++++++++++++++++--------------------
kernel/sched/sched.h | 8 ++++++--
2 files changed, 25 insertions(+), 22 deletions(-)
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -5936,10 +5936,9 @@ static inline void schedule_debug(struct
schedstat_inc(this_rq()->sched_count);
}
-static void prev_balance(struct rq *rq, struct task_struct *prev,
- struct rq_flags *rf)
+static void prev_balance(struct rq *rq, struct rq_flags *rf)
{
- const struct sched_class *start_class = prev->sched_class;
+ const struct sched_class *start_class = rq->donor->sched_class;
const struct sched_class *class;
#ifdef CONFIG_SCHED_CLASS_EXT
@@ -5964,7 +5963,7 @@ static void prev_balance(struct rq *rq,
* a runnable task of @class priority or higher.
*/
for_active_class_range(class, start_class, &idle_sched_class) {
- if (class->balance && class->balance(rq, prev, rf))
+ if (class->balance && class->balance(rq, rq->donor, rf))
break;
}
}
@@ -5973,7 +5972,7 @@ static void prev_balance(struct rq *rq,
* Pick up the highest-prio task:
*/
static inline struct task_struct *
-__pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
+__pick_next_task(struct rq *rq, struct rq_flags *rf)
{
const struct sched_class *class;
struct task_struct *p;
@@ -5985,38 +5984,38 @@ __pick_next_task(struct rq *rq, struct t
/*
* Optimization: we know that if all tasks are in the fair class we can
- * call that function directly, but only if the @prev task wasn't of a
+ * call that function directly, but only if the current task wasn't of a
* higher scheduling class, because otherwise those lose the
* opportunity to pull in more work from other CPUs.
*/
- if (likely(!sched_class_above(prev->sched_class, &fair_sched_class) &&
+ if (likely(!sched_class_above(rq->donor->sched_class, &fair_sched_class) &&
rq->nr_running == rq->cfs.h_nr_queued)) {
- p = pick_next_task_fair(rq, prev, rf);
+ p = pick_next_task_fair(rq, rq->donor, rf);
if (unlikely(p == RETRY_TASK))
goto restart;
/* Assume the next prioritized class is idle_sched_class */
if (!p) {
p = pick_task_idle(rq);
- put_prev_set_next_task(rq, prev, p);
+ put_prev_set_next_task(rq, rq->donor, p);
}
return p;
}
restart:
- prev_balance(rq, prev, rf);
+ prev_balance(rq, rf);
for_each_active_class(class) {
if (class->pick_next_task) {
- p = class->pick_next_task(rq, prev);
+ p = class->pick_next_task(rq, rq->donor);
if (p)
return p;
} else {
p = class->pick_task(rq);
if (p) {
- put_prev_set_next_task(rq, prev, p);
+ put_prev_set_next_task(rq, rq->donor, p);
return p;
}
}
@@ -6065,7 +6064,7 @@ extern void task_vruntime_update(struct
static void queue_core_balance(struct rq *rq);
static struct task_struct *
-pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
+pick_next_task(struct rq *rq, struct rq_flags *rf)
{
struct task_struct *next, *p, *max = NULL;
const struct cpumask *smt_mask;
@@ -6077,7 +6076,7 @@ pick_next_task(struct rq *rq, struct tas
bool need_sync;
if (!sched_core_enabled(rq))
- return __pick_next_task(rq, prev, rf);
+ return __pick_next_task(rq, rf);
cpu = cpu_of(rq);
@@ -6090,7 +6089,7 @@ pick_next_task(struct rq *rq, struct tas
*/
rq->core_pick = NULL;
rq->core_dl_server = NULL;
- return __pick_next_task(rq, prev, rf);
+ return __pick_next_task(rq, rf);
}
/*
@@ -6114,7 +6113,7 @@ pick_next_task(struct rq *rq, struct tas
goto out_set_next;
}
- prev_balance(rq, prev, rf);
+ prev_balance(rq, rf);
smt_mask = cpu_smt_mask(cpu);
need_sync = !!rq->core->core_cookie;
@@ -6287,7 +6286,7 @@ pick_next_task(struct rq *rq, struct tas
}
out_set_next:
- put_prev_set_next_task(rq, prev, next);
+ put_prev_set_next_task(rq, rq->donor, next);
if (rq->core->core_forceidle_count && next == rq->idle)
queue_core_balance(rq);
@@ -6512,9 +6511,9 @@ static inline void sched_core_cpu_deacti
static inline void sched_core_cpu_dying(unsigned int cpu) {}
static struct task_struct *
-pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
+pick_next_task(struct rq *rq, struct rq_flags *rf)
{
- return __pick_next_task(rq, prev, rf);
+ return __pick_next_task(rq, rf);
}
#endif /* CONFIG_SCHED_CORE */
@@ -6682,7 +6681,7 @@ static void __sched notrace __schedule(i
switch_count = &prev->nvcsw;
}
- next = pick_next_task(rq, prev, &rf);
+ next = pick_next_task(rq, &rf);
picked:
clear_tsk_need_resched(prev);
clear_preempt_need_resched();
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1184,7 +1184,11 @@ struct rq {
*/
unsigned long nr_uninterruptible;
- struct task_struct __rcu *curr;
+ /* Scheduling and execution contexts coincide without proxy execution. */
+ union {
+ struct task_struct __rcu *donor;
+ struct task_struct __rcu *curr;
+ };
struct sched_dl_entity *dl_server;
struct task_struct *idle;
struct task_struct *stop;
@@ -1326,7 +1330,7 @@ struct rq {
unsigned int core_forceidle_seq;
unsigned int core_forceidle_occupation;
u64 core_forceidle_start;
-#endif
+#endif /* CONFIG_SCHED_CORE */
/* Scratch cpumask to be temporarily used under rq_lock */
cpumask_var_t scratch_mask;
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 561/877] sched/core: Make core-sched flips wait for in-flight selections
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (559 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 560/877] sched: Rework prev_balance() to avoid stale prev references Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 562/877] ASoC: codecs: aw88261: reduce log spam Greg Kroah-Hartman
` (323 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tejun Heo, Peter Zijlstra (Intel),
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tejun Heo <tj@kernel.org>
[ Upstream commit f3629c63a4af3e491381780bc6c123cb498c4c40 ]
Core scheduling's pick_next_task() operates on all sibling rqs under one
acquisition of the shared core-wide lock. A ->pick_task() that releases the
rq lock leaves every sibling __lock momentarily free, letting
__sched_core_flip(false) complete mid-selection and rebind rq_lockp() under
it. The selection resumes on the split locks, touching sibling state it no
longer protects, and __schedule() finally releases a lock that was never
taken while leaking the one that was.
Count in-flight core-wide selections in the leader's rq->core_pick_in_flight
and make __sched_core_flip() wait for the count to drain. The count only
changes under the shared lock, which the flip holds while sampling, so no
other ordering is needed. The wait can repeat while selections overlap, but
the flip backs off between samples and flips are rare cookie-lifetime
events.
sched_core_cpu_deactivate() moves the count to the new leader - a stale copy
left behind would bias it forever if that CPU later returns as its own
leader.
Fixes: 539f65125d20 ("sched: Add core wide task selection and scheduling")
Cc: stable@vger.kernel.org # v5.14+
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/sched/core.c | 22 ++++++++++++++++++++++
kernel/sched/sched.h | 1 +
2 files changed, 23 insertions(+)
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -401,6 +401,17 @@ static void __sched_core_flip(bool enabl
sched_core_lock(cpu, &flags);
+ /*
+ * A core-wide selection may have the shared rq lock temporarily
+ * released by a lock-dropping ->pick_task(). Flipping would
+ * rebind rq_lockp() under it. Wait it out.
+ */
+ while (cpu_rq(cpu)->core->core_pick_in_flight) {
+ sched_core_unlock(cpu, &flags);
+ cpu_relax();
+ sched_core_lock(cpu, &flags);
+ }
+
for_each_cpu(t, smt_mask)
cpu_rq(t)->core_enabled = enabled;
@@ -6092,6 +6103,8 @@ pick_next_task(struct rq *rq, struct rq_
return __pick_next_task(rq, rf);
}
+ rq->core->core_pick_in_flight++;
+
/*
* If there were no {en,de}queues since we picked (IOW, the task
* pointers are all still valid), and we haven't scheduled the last
@@ -6286,6 +6299,7 @@ pick_next_task(struct rq *rq, struct rq_
}
out_set_next:
+ rq->core->core_pick_in_flight--;
put_prev_set_next_task(rq, rq->donor, next);
if (rq->core->core_forceidle_count && next == rq->idle)
queue_core_balance(rq);
@@ -6483,6 +6497,13 @@ static void sched_core_cpu_deactivate(un
core_rq->core_forceidle_occupation = rq->core_forceidle_occupation;
/*
+ * A stale leftover would bias the count forever if this CPU later
+ * returns as its own leader. Move, don't copy.
+ */
+ core_rq->core_pick_in_flight = rq->core_pick_in_flight;
+ rq->core_pick_in_flight = 0;
+
+ /*
* Accounting edge for forced idle is handled in pick_next_task().
* Don't need another one here, since the hotplug thread shouldn't
* have a cookie.
@@ -8553,6 +8574,7 @@ void __init sched_init(void)
rq->core_forceidle_count = 0;
rq->core_forceidle_occupation = 0;
rq->core_forceidle_start = 0;
+ rq->core_pick_in_flight = 0;
rq->core_cookie = 0UL;
#endif
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1330,6 +1330,7 @@ struct rq {
unsigned int core_forceidle_seq;
unsigned int core_forceidle_occupation;
u64 core_forceidle_start;
+ unsigned int core_pick_in_flight;
#endif /* CONFIG_SCHED_CORE */
/* Scratch cpumask to be temporarily used under rq_lock */
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 562/877] ASoC: codecs: aw88261: reduce log spam
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (560 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 561/877] sched/core: Make core-sched flips wait for in-flight selections Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 563/877] ASoC: codecs: aw88261: only check PLL and clock state at power-up Greg Kroah-Hartman
` (322 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Val Packett, Luca Weiss, Mark Brown,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Val Packett <val@packett.cool>
[ Upstream commit d90c361af215a9fa2a986d9f47d554d0cf3401dd ]
This driver would create a wall of logspam during initialization due to
e.g. the PLL not being ready while waiting for it to stabilize. Change
intermediate dev_err() calls to dev_dbg() to reduce the noise.
While here, log the detected chip ID when that check fails.
Signed-off-by: Val Packett <val@packett.cool>
Tested-by: Luca Weiss <luca.weiss@fairphone.com>
Link: https://patch.msgid.link/20260529200550.529719-4-val@packett.cool
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 06b6f1245567 ("ASoC: codecs: aw88261: only check PLL and clock state at power-up")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/soc/codecs/aw88261.c | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
--- a/sound/soc/codecs/aw88261.c
+++ b/sound/soc/codecs/aw88261.c
@@ -150,7 +150,7 @@ static int aw88261_dev_get_iis_status(st
if (ret)
return ret;
if ((reg_val & AW88261_BIT_PLL_CHECK) != AW88261_BIT_PLL_CHECK) {
- dev_err(aw_dev->dev, "check pll lock fail,reg_val:0x%04x", reg_val);
+ dev_dbg(aw_dev->dev, "check pll lock fail,reg_val:0x%04x", reg_val);
return -EINVAL;
}
@@ -164,7 +164,7 @@ static int aw88261_dev_check_mode1_pll(s
for (i = 0; i < AW88261_DEV_SYSST_CHECK_MAX; i++) {
ret = aw88261_dev_get_iis_status(aw_dev);
if (ret) {
- dev_err(aw_dev->dev, "mode1 iis signal check error");
+ dev_dbg(aw_dev->dev, "mode1 iis signal check error");
usleep_range(AW88261_2000_US, AW88261_2000_US + 10);
} else {
return ret;
@@ -255,7 +255,7 @@ static int aw88261_dev_check_sysst(struc
check_val = reg_val & (~AW88261_BIT_SYSST_CHECK_MASK)
& AW88261_BIT_SYSST_CHECK;
if (check_val != AW88261_BIT_SYSST_CHECK) {
- dev_err(aw_dev->dev, "check sysst fail, reg_val=0x%04x, check:0x%x",
+ dev_dbg(aw_dev->dev, "check sysst fail, reg_val=0x%04x, check:0x%x",
reg_val, AW88261_BIT_SYSST_CHECK);
usleep_range(AW88261_2000_US, AW88261_2000_US + 10);
} else {
@@ -549,7 +549,7 @@ static int aw88261_dev_start(struct aw88
int ret;
if (aw_dev->status == AW88261_DEV_PW_ON) {
- dev_info(aw_dev->dev, "already power on");
+ dev_dbg(aw_dev->dev, "already power on");
return 0;
}
@@ -559,7 +559,7 @@ static int aw88261_dev_start(struct aw88
ret = aw88261_dev_check_syspll(aw_dev);
if (ret) {
- dev_err(aw_dev->dev, "pll check failed cannot start");
+ dev_dbg(aw_dev->dev, "pll check failed");
goto pll_check_fail;
}
@@ -570,7 +570,7 @@ static int aw88261_dev_start(struct aw88
/* check i2s status */
ret = aw88261_dev_check_sysst(aw_dev);
if (ret) {
- dev_err(aw_dev->dev, "sysst check failed");
+ dev_dbg(aw_dev->dev, "sysst check failed");
goto sysst_check_fail;
}
@@ -671,18 +671,22 @@ static void aw88261_start_pa(struct aw88
for (i = 0; i < AW88261_START_RETRIES; i++) {
ret = aw88261_reg_update(aw88261, aw88261->phase_sync);
if (ret) {
- dev_err(aw88261->aw_pa->dev, "fw update failed, cnt:%d\n", i);
+ dev_dbg(aw88261->aw_pa->dev,
+ "aw88261_reg_update failed, cnt:%d, ret:%d\n", i, ret);
continue;
}
ret = aw88261_dev_start(aw88261);
if (ret) {
- dev_err(aw88261->aw_pa->dev, "aw88261 device start failed. retry = %d", i);
+ dev_dbg(aw88261->aw_pa->dev,
+ "aw88261_dev_start failed, cnt:%d, ret:%d\n", i, ret);
continue;
} else {
- dev_info(aw88261->aw_pa->dev, "start success\n");
+ dev_dbg(aw88261->aw_pa->dev, "start success\n");
break;
}
}
+ if (ret != 0)
+ dev_err(aw88261->aw_pa->dev, "start failure (%d)\n", ret);
}
static void aw88261_startup_work(struct work_struct *work)
@@ -1200,7 +1204,7 @@ static int aw88261_init(struct aw88261 *
return ret;
}
if (chip_id != AW88261_CHIP_ID) {
- dev_err(&i2c->dev, "unsupported device");
+ dev_err(&i2c->dev, "unsupported device id = %x", chip_id);
return -ENXIO;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 563/877] ASoC: codecs: aw88261: only check PLL and clock state at power-up
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (561 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 562/877] ASoC: codecs: aw88261: reduce log spam Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 564/877] ring-buffer: Make cpu_buffer::free_page a buffer_data_read_page Greg Kroah-Hartman
` (321 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jorijn van der Graaf, Mark Brown,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
[ Upstream commit 06b6f1245567a4be862c3e1cc74577922ceb05fb ]
The SYSST check performed during device start requires SWS (amplifier
switching, bit 8) and BSTS (boost finished, bit 9) on top of PLL lock
and clock stability. Those bits cannot be asserted at this point in the
sequence: the check runs after amppd release but before the
hmute/ULS-hmute release, and the amplifier neither switches nor
finishes ramping its boost converter while it is still muted. With the
Fairphone (Gen. 6) firmware profile, aw88261_dev_start() therefore
always fails with
check sysst fail, reg_val=0x0011, check:0x311
and playback aborts, even though the amplifier is fine and PLL lock
and stable clocks are present.
Check only PLL lock and clock stability, for which a definition
already exists; this still re-validates the clocks after amppd release
(aw88261_dev_check_syspll() checked them before it). This matches the
vendor aw882xx driver, which only validates PLL lock and clock
stability at this stage, and the in-tree aw88399 driver, which skips
the SWS check whenever the amplifier may legitimately not be switching
(AW88399_BIT_SYSST_NOSWS_CHECK).
Fixes: 028a2ae25691 ("ASoC: codecs: Add aw88261 amplifier driver")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-fable-5
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
Link: https://patch.msgid.link/20260704192857.88366-1-jorijnvdgraaf@catcrafts.net
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/soc/codecs/aw88261.c | 6 +++---
sound/soc/codecs/aw88261.h | 6 ------
2 files changed, 3 insertions(+), 9 deletions(-)
--- a/sound/soc/codecs/aw88261.c
+++ b/sound/soc/codecs/aw88261.c
@@ -253,10 +253,10 @@ static int aw88261_dev_check_sysst(struc
return ret;
check_val = reg_val & (~AW88261_BIT_SYSST_CHECK_MASK)
- & AW88261_BIT_SYSST_CHECK;
- if (check_val != AW88261_BIT_SYSST_CHECK) {
+ & AW88261_BIT_PLL_CHECK;
+ if (check_val != AW88261_BIT_PLL_CHECK) {
dev_dbg(aw_dev->dev, "check sysst fail, reg_val=0x%04x, check:0x%x",
- reg_val, AW88261_BIT_SYSST_CHECK);
+ reg_val, AW88261_BIT_PLL_CHECK);
usleep_range(AW88261_2000_US, AW88261_2000_US + 10);
} else {
return 0;
--- a/sound/soc/codecs/aw88261.h
+++ b/sound/soc/codecs/aw88261.h
@@ -181,12 +181,6 @@
AW88261_OTHS_OT_VALUE | \
AW88261_PLLS_LOCKED_VALUE))
-#define AW88261_BIT_SYSST_CHECK \
- (AW88261_BSTS_FINISHED_VALUE | \
- AW88261_SWS_SWITCHING_VALUE | \
- AW88261_CLKS_STABLE_VALUE | \
- AW88261_PLLS_LOCKED_VALUE)
-
#define AW88261_ULS_HMUTE_START_BIT (14)
#define AW88261_ULS_HMUTE_BITS_LEN (1)
#define AW88261_ULS_HMUTE_MASK \
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 564/877] ring-buffer: Make cpu_buffer::free_page a buffer_data_read_page
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (562 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 563/877] ASoC: codecs: aw88261: only check PLL and clock state at power-up Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 565/877] dmaengine: Add devm_dma_request_chan() Greg Kroah-Hartman
` (320 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vincent Donnefort, Steven Rostedt,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Donnefort <vdonnefort@google.com>
[ Upstream commit 7a1fb95de5404134f8758c1295ce88986bdf117c ]
Discarding a cached reader page after a concurrent ring buffer resize
uses the new global subbuf_order for the free_pages() call. This
mismatched order may crashes the kernel or leaks memory because the cached
page was allocated under the old size.
Save the actual free_page order alongside the page address to ensure we
always refer to the correct value and do not rely on the potentially
stalled cpu_buffer->subbuf_order value. The simplest is to make
free_page a buffer_data_read_page which already covers exactly what we
need: a page address and a page order.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260813131152.3589632-4-vdonnefort@google.com
Fixes: 8e7b58c27b3c ("ring-buffer: Just update the subbuffers when changing their allocation order")
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
[ Changed upstream’s dpage variable to bpage in ring_buffer_free_read_page(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/ring_buffer.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -507,7 +507,7 @@ struct ring_buffer_per_cpu {
raw_spinlock_t reader_lock; /* serialize readers */
arch_spinlock_t lock;
struct lock_class_key lock_key;
- struct buffer_data_page *free_page;
+ struct buffer_data_read_page free_page;
unsigned long nr_pages;
unsigned int current_context;
struct list_head *pages;
@@ -2376,7 +2376,7 @@ static void rb_free_cpu_buffer(struct ri
free_buffer_page(bpage);
}
- free_pages((unsigned long)cpu_buffer->free_page, cpu_buffer->buffer->subbuf_order);
+ free_pages((unsigned long)cpu_buffer->free_page.data, cpu_buffer->free_page.order);
kfree(cpu_buffer);
}
@@ -6422,9 +6422,9 @@ ring_buffer_alloc_read_page(struct trace
local_irq_save(flags);
arch_spin_lock(&cpu_buffer->lock);
- if (cpu_buffer->free_page) {
- bpage->data = cpu_buffer->free_page;
- cpu_buffer->free_page = NULL;
+ if (cpu_buffer->free_page.data) {
+ *bpage = cpu_buffer->free_page;
+ cpu_buffer->free_page.data = NULL;
}
arch_spin_unlock(&cpu_buffer->lock);
@@ -6476,8 +6476,8 @@ void ring_buffer_free_read_page(struct t
local_irq_save(flags);
arch_spin_lock(&cpu_buffer->lock);
- if (!cpu_buffer->free_page) {
- cpu_buffer->free_page = bpage;
+ if (!cpu_buffer->free_page.data) {
+ cpu_buffer->free_page = *data_page;
bpage = NULL;
}
@@ -6838,7 +6838,7 @@ int ring_buffer_subbuf_order_set(struct
}
for_each_buffer_cpu(buffer, cpu) {
- struct buffer_data_page *old_free_data_page;
+ struct buffer_data_read_page old_free_data_page;
struct list_head old_pages;
unsigned long flags;
@@ -6881,7 +6881,7 @@ int ring_buffer_subbuf_order_set(struct
arch_spin_lock(&cpu_buffer->lock);
old_free_data_page = cpu_buffer->free_page;
- cpu_buffer->free_page = NULL;
+ cpu_buffer->free_page.data = NULL;
arch_spin_unlock(&cpu_buffer->lock);
rb_head_page_activate(cpu_buffer);
@@ -6893,7 +6893,7 @@ int ring_buffer_subbuf_order_set(struct
list_del_init(&bpage->list);
free_buffer_page(bpage);
}
- free_pages((unsigned long)old_free_data_page, old_order);
+ free_pages((unsigned long)old_free_data_page.data, old_free_data_page.order);
rb_check_pages(cpu_buffer);
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 565/877] dmaengine: Add devm_dma_request_chan()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (563 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 564/877] ring-buffer: Make cpu_buffer::free_page a buffer_data_read_page Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 566/877] i2c: mxs: fix DMA channel leak on probe error Greg Kroah-Hartman
` (319 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bence Csókás, Vinod Koul,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bence Csókás <csokas.bence@prolan.hu>
[ Upstream commit 08bf1663c21a3e815eda28fa242d84c945ca3b94 ]
Expand the arsenal of devm functions for DMA devices, this time for
requesting channels.
Signed-off-by: Bence Csókás <csokas.bence@prolan.hu>
Link: https://lore.kernel.org/r/20250610082256.400492-2-csokas.bence@prolan.hu
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Stable-dep-of: 777979e62711 ("i2c: mxs: fix DMA channel leak on probe error")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/dma/dmaengine.c | 30 ++++++++++++++++++++++++++++++
include/linux/dmaengine.h | 7 +++++++
2 files changed, 37 insertions(+)
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -933,6 +933,36 @@ void dma_release_channel(struct dma_chan
}
EXPORT_SYMBOL_GPL(dma_release_channel);
+static void dmaenginem_release_channel(void *chan)
+{
+ dma_release_channel(chan);
+}
+
+/**
+ * devm_dma_request_chan - try to allocate an exclusive slave channel
+ * @dev: pointer to client device structure
+ * @name: slave channel name
+ *
+ * Returns pointer to appropriate DMA channel on success or an error pointer.
+ *
+ * The operation is managed and will be undone on driver detach.
+ */
+
+struct dma_chan *devm_dma_request_chan(struct device *dev, const char *name)
+{
+ struct dma_chan *chan = dma_request_chan(dev, name);
+ int ret = 0;
+
+ if (!IS_ERR(chan))
+ ret = devm_add_action_or_reset(dev, dmaenginem_release_channel, chan);
+
+ if (ret)
+ return ERR_PTR(ret);
+
+ return chan;
+}
+EXPORT_SYMBOL_GPL(devm_dma_request_chan);
+
/**
* dmaengine_get - register interest in dma_channels
*/
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -1521,6 +1521,7 @@ struct dma_chan *__dma_request_channel(c
struct dma_chan *dma_request_chan(struct device *dev, const char *name);
struct dma_chan *dma_request_chan_by_mask(const dma_cap_mask_t *mask);
+struct dma_chan *devm_dma_request_chan(struct device *dev, const char *name);
void dma_release_channel(struct dma_chan *chan);
int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps);
@@ -1557,6 +1558,12 @@ static inline struct dma_chan *dma_reque
{
return ERR_PTR(-ENODEV);
}
+
+static inline struct dma_chan *devm_dma_request_chan(struct device *dev, const char *name)
+{
+ return ERR_PTR(-ENODEV);
+}
+
static inline void dma_release_channel(struct dma_chan *chan)
{
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 566/877] i2c: mxs: fix DMA channel leak on probe error
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (564 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 565/877] dmaengine: Add devm_dma_request_chan() Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 567/877] lockd: fix swapped arguments in nlmsvc_match_ip() Greg Kroah-Hartman
` (318 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ruoyu Wang, Frank Li, Andi Shyti,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ruoyu Wang <ruoyuw560@gmail.com>
[ Upstream commit 777979e627115734052b323d2721cdb500e81dcf ]
mxs_i2c_probe() requests an exclusive DMA channel before resetting the
controller and registering the I2C adapter. If either later operation
fails, probe returns without releasing the channel because the remove
callback is not invoked after a failed probe.
Use devm_dma_request_chan() so the device core releases the channel on
probe failure and driver detach. Remove the manual release from the
remove callback because the channel is now device-managed.
This issue was found by a static analysis checker and confirmed by
manual source review.
Fixes: 62885f59a261 ("MXS: Implement DMA support into mxs-i2c")
Assisted-by: unnamed:claude-opus-4.8 typestate
Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
Cc: <stable@vger.kernel.org> # v3.7+
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://patch.msgid.link/20260815151720.3757460-1-ruoyuw560@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/i2c/busses/i2c-mxs.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
--- a/drivers/i2c/busses/i2c-mxs.c
+++ b/drivers/i2c/busses/i2c-mxs.c
@@ -831,7 +831,7 @@ static int mxs_i2c_probe(struct platform
}
/* Setup the DMA */
- i2c->dmach = dma_request_chan(dev, "rx-tx");
+ i2c->dmach = devm_dma_request_chan(dev, "rx-tx");
if (IS_ERR(i2c->dmach)) {
return dev_err_probe(dev, PTR_ERR(i2c->dmach),
"Failed to request dma\n");
@@ -869,9 +869,6 @@ static void mxs_i2c_remove(struct platfo
i2c_del_adapter(&i2c->adapter);
- if (i2c->dmach)
- dma_release_channel(i2c->dmach);
-
writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET);
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 567/877] lockd: fix swapped arguments in nlmsvc_match_ip()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (565 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 566/877] i2c: mxs: fix DMA channel leak on probe error Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 568/877] firmware: qcom_scm: Rename peripheral as pas_id Greg Kroah-Hartman
` (317 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Oscar Ou, Chuck Lever, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oscar Ou <oscarou@synology.com>
[ Upstream commit b9060689f49dc663e9a3d069c4a65ff63a836e66 ]
When releasing locks by server IP address via /proc/fs/nfsd/unlock_ip,
nlmsvc_unlock_all_by_ip() calls nlm_traverse_files() with the server
sockaddr as the opaque @data argument:
nlm_traverse_files(server_addr, nlmsvc_match_ip, NULL);
The match callback is later invoked from nlm_traverse_locks() as:
match(lockhost, host);
where the first argument is the nlm_host that owns the lock, and the
second argument is the @data that was originally passed down (here the
server sockaddr). This is the convention every other match callback
relies on (nlmsvc_mark_host(), nlmsvc_same_host(), nlmsvc_is_client()):
arg1 is the real nlm_host, arg2 is the caller-supplied reference value.
nlmsvc_match_ip() has had these two arguments reversed ever since the
unlock-by-IP feature was introduced in commit 4373ea84c84d ("lockd:
unlock lockd locks associated with a given server ip"):
return rpc_cmp_addr(nlm_srcaddr(host), datap);
Here @host is actually the server sockaddr, so nlm_srcaddr(host)
dereferences a struct sockaddr as a struct nlm_host and reads garbage
at the offset of h_srcaddr; meanwhile @datap is actually the lock
owner's nlm_host but is compared as a sockaddr. As a result the
comparison practically never matches and locks are not released for the
requested IP.
Swap the arguments so the lock owner's source address is compared
against the requested server address:
return rpc_cmp_addr(nlm_srcaddr(datap), (struct sockaddr *)host);
Fixes: 4373ea84c84d ("lockd: unlock lockd locks associated with a given server ip")
Cc: stable@vger.kernel.org
Signed-off-by: Oscar Ou <oscarou@synology.com>
[ cel: fix the misleading typedef parameter names too ]
Link: https://patch.msgid.link/20260617075738.1151797-1-oscarou@synology.com
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/lockd/svcsubs.c | 2 +-
include/linux/lockd/lockd.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -493,7 +493,7 @@ EXPORT_SYMBOL_GPL(nlmsvc_unlock_all_by_s
static int
nlmsvc_match_ip(void *datap, struct nlm_host *host)
{
- return rpc_cmp_addr(nlm_srcaddr(host), datap);
+ return rpc_cmp_addr(nlm_srcaddr(datap), (struct sockaddr *)host);
}
/**
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -268,7 +268,7 @@ void nsm_release(struct nsm_handle *n
* This is used in garbage collection and resource reclaim
* A return value != 0 means destroy the lock/block/share
*/
-typedef int (*nlm_host_match_fn_t)(void *cur, struct nlm_host *ref);
+typedef int (*nlm_host_match_fn_t)(void *owner, struct nlm_host *ref);
/*
* Server-side lock handling
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 568/877] firmware: qcom_scm: Rename peripheral as pas_id
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (566 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 567/877] lockd: fix swapped arguments in nlmsvc_match_ip() Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 569/877] remoteproc: pas: Replace metadata context with PAS context structure Greg Kroah-Hartman
` (316 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bryan ODonoghue, Konrad Dybcio,
Mukesh Ojha, Bjorn Andersson, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
[ Upstream commit 69054348cc1c2d87acad90aec5e6e0d191012aff ]
Peripheral and pas_id refers to unique id for a subsystem and used only
when peripheral authentication service from secure world is utilized.
Lets rename peripheral to pas_id to reflect closer to its meaning.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260105-kvmrprocv10-v10-3-022e96815380@oss.qualcomm.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Stable-dep-of: c06c5ab49453 ("remoteproc: qcom: pas: Guard dtb metadata release with dtb_pas_id check")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/firmware/qcom/qcom_scm.c | 30 +++++++++++++++---------------
include/linux/firmware/qcom/qcom_scm.h | 10 +++++-----
2 files changed, 20 insertions(+), 20 deletions(-)
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -572,7 +572,7 @@ static void qcom_scm_set_download_mode(u
* qcom_scm_pas_init_image() - Initialize peripheral authentication service
* state machine for a given peripheral, using the
* metadata
- * @peripheral: peripheral id
+ * @pas_id: peripheral authentication service id
* @metadata: pointer to memory containing ELF header, program header table
* and optional blob of data used for authenticating the metadata
* and the rest of the firmware
@@ -585,7 +585,7 @@ static void qcom_scm_set_download_mode(u
* track the metadata allocation, this needs to be released by invoking
* qcom_scm_pas_metadata_release() by the caller.
*/
-int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
+int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
struct qcom_scm_pas_metadata *ctx)
{
dma_addr_t mdata_phys;
@@ -595,7 +595,7 @@ int qcom_scm_pas_init_image(u32 peripher
.svc = QCOM_SCM_SVC_PIL,
.cmd = QCOM_SCM_PIL_PAS_INIT_IMAGE,
.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_VAL, QCOM_SCM_RW),
- .args[0] = peripheral,
+ .args[0] = pas_id,
.owner = ARM_SMCCC_OWNER_SIP,
};
struct qcom_scm_res res;
@@ -668,20 +668,20 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_metadata_
/**
* qcom_scm_pas_mem_setup() - Prepare the memory related to a given peripheral
* for firmware loading
- * @peripheral: peripheral id
+ * @pas_id: peripheral authentication service id
* @addr: start address of memory area to prepare
* @size: size of the memory area to prepare
*
* Returns 0 on success.
*/
-int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size)
+int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size)
{
int ret;
struct qcom_scm_desc desc = {
.svc = QCOM_SCM_SVC_PIL,
.cmd = QCOM_SCM_PIL_PAS_MEM_SETUP,
.arginfo = QCOM_SCM_ARGS(3),
- .args[0] = peripheral,
+ .args[0] = pas_id,
.args[1] = addr,
.args[2] = size,
.owner = ARM_SMCCC_OWNER_SIP,
@@ -709,18 +709,18 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_mem_setup
/**
* qcom_scm_pas_auth_and_reset() - Authenticate the given peripheral firmware
* and reset the remote processor
- * @peripheral: peripheral id
+ * @pas_id: peripheral authentication service id
*
* Return 0 on success.
*/
-int qcom_scm_pas_auth_and_reset(u32 peripheral)
+int qcom_scm_pas_auth_and_reset(u32 pas_id)
{
int ret;
struct qcom_scm_desc desc = {
.svc = QCOM_SCM_SVC_PIL,
.cmd = QCOM_SCM_PIL_PAS_AUTH_AND_RESET,
.arginfo = QCOM_SCM_ARGS(1),
- .args[0] = peripheral,
+ .args[0] = pas_id,
.owner = ARM_SMCCC_OWNER_SIP,
};
struct qcom_scm_res res;
@@ -745,18 +745,18 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_auth_and_
/**
* qcom_scm_pas_shutdown() - Shut down the remote processor
- * @peripheral: peripheral id
+ * @pas_id: peripheral authentication service id
*
* Returns 0 on success.
*/
-int qcom_scm_pas_shutdown(u32 peripheral)
+int qcom_scm_pas_shutdown(u32 pas_id)
{
int ret;
struct qcom_scm_desc desc = {
.svc = QCOM_SCM_SVC_PIL,
.cmd = QCOM_SCM_PIL_PAS_SHUTDOWN,
.arginfo = QCOM_SCM_ARGS(1),
- .args[0] = peripheral,
+ .args[0] = pas_id,
.owner = ARM_SMCCC_OWNER_SIP,
};
struct qcom_scm_res res;
@@ -782,18 +782,18 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_shutdown)
/**
* qcom_scm_pas_supported() - Check if the peripheral authentication service is
* available for the given peripherial
- * @peripheral: peripheral id
+ * @pas_id: peripheral authentication service id
*
* Returns true if PAS is supported for this peripheral, otherwise false.
*/
-bool qcom_scm_pas_supported(u32 peripheral)
+bool qcom_scm_pas_supported(u32 pas_id)
{
int ret;
struct qcom_scm_desc desc = {
.svc = QCOM_SCM_SVC_PIL,
.cmd = QCOM_SCM_PIL_PAS_IS_SUPPORTED,
.arginfo = QCOM_SCM_ARGS(1),
- .args[0] = peripheral,
+ .args[0] = pas_id,
.owner = ARM_SMCCC_OWNER_SIP,
};
struct qcom_scm_res res;
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -72,13 +72,13 @@ struct qcom_scm_pas_metadata {
ssize_t size;
};
-int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
+int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
struct qcom_scm_pas_metadata *ctx);
void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx);
-int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size);
-int qcom_scm_pas_auth_and_reset(u32 peripheral);
-int qcom_scm_pas_shutdown(u32 peripheral);
-bool qcom_scm_pas_supported(u32 peripheral);
+int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size);
+int qcom_scm_pas_auth_and_reset(u32 pas_id);
+int qcom_scm_pas_shutdown(u32 pas_id);
+bool qcom_scm_pas_supported(u32 pas_id);
int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val);
int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 569/877] remoteproc: pas: Replace metadata context with PAS context structure
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (567 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 568/877] firmware: qcom_scm: Rename peripheral as pas_id Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 570/877] remoteproc: qcom: pas: Guard dtb metadata release with dtb_pas_id check Greg Kroah-Hartman
` (315 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mukesh Ojha, Bjorn Andersson,
Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
[ Upstream commit b13d8baf56016e7eec29395b52d18b91df081d48 ]
As a superset of the existing metadata context, the PAS context
structure enables both remoteproc and non-remoteproc subsystems to
better support scenarios where the SoC runs with or without the Gunyah
hypervisor. To reflect this, relevant SCM and metadata functions are
updated to incorporate PAS context awareness and remove metadata context
data structure completely.
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260105-kvmrprocv10-v10-5-022e96815380@oss.qualcomm.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Stable adaptation for c06c5ab4945392d2c2aded6d832ab6b58cabe351:
This tree has neither the PAS context allocator nor the later generic
PAS service and context-aware MDT loader. Define the PAS context in the
existing SCM header and allocate and initialize it in adsp_probe() using
devm_kzalloc(), without adding any functions. Keep the stable MDT loader
interfaces and update their existing context arguments and declarations.
Rename the existing metadata release implementation and its callers to
qcom_pas_metadata_release(), as used by the target fix. Keep the driver's
adsp names except for the local PAS pointer in adsp_load(). Handle DTB
initialization failure inline, preserving its existing cleanup behavior,
so that the target can remove the shared load-failure cleanup label. The
remaining load-failure path and its context now support a clean three-way
cherry-pick of the target without importing the newer loader helper.
Stable-dep-of: c06c5ab49453 ("remoteproc: qcom: pas: Guard dtb metadata release with dtb_pas_id check")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/firmware/qcom/qcom_scm.c | 14 ++---
drivers/remoteproc/qcom_q6v5_pas.c | 84 ++++++++++++++++++++-------------
drivers/soc/qcom/mdt_loader.c | 4 -
include/linux/firmware/qcom/qcom_scm.h | 10 ++-
include/linux/soc/qcom/mdt_loader.h | 6 +-
5 files changed, 72 insertions(+), 46 deletions(-)
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -577,16 +577,16 @@ static void qcom_scm_set_download_mode(u
* and optional blob of data used for authenticating the metadata
* and the rest of the firmware
* @size: size of the metadata
- * @ctx: optional metadata context
+ * @ctx: optional pas context
*
* Return: 0 on success.
*
* Upon successful return, the PAS metadata context (@ctx) will be used to
* track the metadata allocation, this needs to be released by invoking
- * qcom_scm_pas_metadata_release() by the caller.
+ * qcom_pas_metadata_release() by the caller.
*/
int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
- struct qcom_scm_pas_metadata *ctx)
+ struct qcom_scm_pas_context *ctx)
{
dma_addr_t mdata_phys;
void *mdata_buf;
@@ -649,10 +649,10 @@ out:
EXPORT_SYMBOL_GPL(qcom_scm_pas_init_image);
/**
- * qcom_scm_pas_metadata_release() - release metadata context
- * @ctx: metadata context
+ * qcom_pas_metadata_release() - release metadata context
+ * @ctx: pas context
*/
-void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx)
+void qcom_pas_metadata_release(struct qcom_scm_pas_context *ctx)
{
if (!ctx->ptr)
return;
@@ -663,7 +663,7 @@ void qcom_scm_pas_metadata_release(struc
ctx->phys = 0;
ctx->size = 0;
}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_metadata_release);
+EXPORT_SYMBOL_GPL(qcom_pas_metadata_release);
/**
* qcom_scm_pas_mem_setup() - Prepare the memory related to a given peripheral
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -115,8 +115,8 @@ struct qcom_adsp {
struct qcom_rproc_ssr ssr_subdev;
struct qcom_sysmon *sysmon;
- struct qcom_scm_pas_metadata pas_metadata;
- struct qcom_scm_pas_metadata dtb_pas_metadata;
+ struct qcom_scm_pas_context *pas_ctx;
+ struct qcom_scm_pas_context *dtb_pas_ctx;
};
static void adsp_segment_dump(struct rproc *rproc, struct rproc_dump_segment *segment,
@@ -203,47 +203,50 @@ static int adsp_unprepare(struct rproc *
struct qcom_adsp *adsp = rproc->priv;
/*
- * adsp_load() did pass pas_metadata to the SCM driver for storing
+ * adsp_load() did pass the PAS context to the SCM driver for storing
* metadata context. It might have been released already if
* auth_and_reset() was successful, but in other cases clean it up
* here.
*/
- qcom_scm_pas_metadata_release(&adsp->pas_metadata);
+ qcom_pas_metadata_release(adsp->pas_ctx);
if (adsp->dtb_pas_id)
- qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
+ qcom_pas_metadata_release(adsp->dtb_pas_ctx);
return 0;
}
static int adsp_load(struct rproc *rproc, const struct firmware *fw)
{
- struct qcom_adsp *adsp = rproc->priv;
+ struct qcom_adsp *pas = rproc->priv;
int ret;
/* Store firmware handle to be used in adsp_start() */
- adsp->firmware = fw;
+ pas->firmware = fw;
- if (adsp->lite_pas_id)
- ret = qcom_scm_pas_shutdown(adsp->lite_pas_id);
+ if (pas->lite_pas_id)
+ ret = qcom_scm_pas_shutdown(pas->lite_pas_id);
- if (adsp->dtb_pas_id) {
- ret = request_firmware(&adsp->dtb_firmware, adsp->dtb_firmware_name, adsp->dev);
+ if (pas->dtb_pas_id) {
+ ret = request_firmware(&pas->dtb_firmware, pas->dtb_firmware_name, pas->dev);
if (ret) {
- dev_err(adsp->dev, "request_firmware failed for %s: %d\n",
- adsp->dtb_firmware_name, ret);
+ dev_err(pas->dev, "request_firmware failed for %s: %d\n",
+ pas->dtb_firmware_name, ret);
return ret;
}
- ret = qcom_mdt_pas_init(adsp->dev, adsp->dtb_firmware, adsp->dtb_firmware_name,
- adsp->dtb_pas_id, adsp->dtb_mem_phys,
- &adsp->dtb_pas_metadata);
- if (ret)
- goto release_dtb_firmware;
+ ret = qcom_mdt_pas_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name,
+ pas->dtb_pas_id, pas->dtb_mem_phys,
+ pas->dtb_pas_ctx);
+ if (ret) {
+ release_firmware(pas->dtb_firmware);
+ return ret;
+ }
- ret = qcom_mdt_load_no_init(adsp->dev, adsp->dtb_firmware, adsp->dtb_firmware_name,
- adsp->dtb_pas_id, adsp->dtb_mem_region,
- adsp->dtb_mem_phys, adsp->dtb_mem_size,
- &adsp->dtb_mem_reloc);
+ ret = qcom_mdt_load_no_init(
+ pas->dev, pas->dtb_firmware, pas->dtb_firmware_name,
+ pas->dtb_pas_id, pas->dtb_mem_region,
+ pas->dtb_mem_phys, pas->dtb_mem_size,
+ &pas->dtb_mem_reloc);
if (ret)
goto release_dtb_metadata;
}
@@ -251,10 +254,8 @@ static int adsp_load(struct rproc *rproc
return 0;
release_dtb_metadata:
- qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
-
-release_dtb_firmware:
- release_firmware(adsp->dtb_firmware);
+ qcom_pas_metadata_release(pas->dtb_pas_ctx);
+ release_firmware(pas->dtb_firmware);
return ret;
}
@@ -302,7 +303,7 @@ static int adsp_start(struct rproc *rpro
}
ret = qcom_mdt_pas_init(adsp->dev, adsp->firmware, rproc->firmware, adsp->pas_id,
- adsp->mem_phys, &adsp->pas_metadata);
+ adsp->mem_phys, adsp->pas_ctx);
if (ret)
goto disable_px_supply;
@@ -328,9 +329,9 @@ static int adsp_start(struct rproc *rpro
goto release_pas_metadata;
}
- qcom_scm_pas_metadata_release(&adsp->pas_metadata);
+ qcom_pas_metadata_release(adsp->pas_ctx);
if (adsp->dtb_pas_id)
- qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
+ qcom_pas_metadata_release(adsp->dtb_pas_ctx);
/* Remove pointer to the loaded firmware, only valid in adsp_load() & adsp_start() */
adsp->firmware = NULL;
@@ -338,9 +339,9 @@ static int adsp_start(struct rproc *rpro
return 0;
release_pas_metadata:
- qcom_scm_pas_metadata_release(&adsp->pas_metadata);
+ qcom_pas_metadata_release(adsp->pas_ctx);
if (adsp->dtb_pas_id)
- qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
+ qcom_pas_metadata_release(adsp->dtb_pas_ctx);
disable_px_supply:
if (adsp->px_supply)
regulator_disable(adsp->px_supply);
@@ -788,6 +789,27 @@ static int adsp_probe(struct platform_de
}
qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
+
+ adsp->pas_ctx = devm_kzalloc(adsp->dev, sizeof(*adsp->pas_ctx), GFP_KERNEL);
+ if (!adsp->pas_ctx) {
+ ret = -ENOMEM;
+ goto remove_ssr_sysmon;
+ }
+ adsp->pas_ctx->dev = adsp->dev;
+ adsp->pas_ctx->pas_id = adsp->pas_id;
+ adsp->pas_ctx->mem_phys = adsp->mem_phys;
+ adsp->pas_ctx->mem_size = adsp->mem_size;
+
+ adsp->dtb_pas_ctx = devm_kzalloc(adsp->dev, sizeof(*adsp->dtb_pas_ctx), GFP_KERNEL);
+ if (!adsp->dtb_pas_ctx) {
+ ret = -ENOMEM;
+ goto remove_ssr_sysmon;
+ }
+ adsp->dtb_pas_ctx->dev = adsp->dev;
+ adsp->dtb_pas_ctx->pas_id = adsp->dtb_pas_id;
+ adsp->dtb_pas_ctx->mem_phys = adsp->dtb_mem_phys;
+ adsp->dtb_pas_ctx->mem_size = adsp->dtb_mem_size;
+
ret = rproc_add(rproc);
if (ret)
goto remove_ssr_sysmon;
--- a/drivers/soc/qcom/mdt_loader.c
+++ b/drivers/soc/qcom/mdt_loader.c
@@ -234,13 +234,13 @@ EXPORT_SYMBOL_GPL(qcom_mdt_read_metadata
* @fw_name: name of the firmware, for construction of segment file names
* @pas_id: PAS identifier
* @mem_phys: physical address of allocated memory region
- * @ctx: PAS metadata context, to be released by caller
+ * @ctx: PAS context, metadata to be released by caller
*
* Returns 0 on success, negative errno otherwise.
*/
int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
const char *fw_name, int pas_id, phys_addr_t mem_phys,
- struct qcom_scm_pas_metadata *ctx)
+ struct qcom_scm_pas_context *ctx)
{
const struct elf32_phdr *phdrs;
const struct elf32_phdr *phdr;
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -66,15 +66,19 @@ int qcom_scm_set_warm_boot_addr(void *en
void qcom_scm_cpu_power_down(u32 flags);
int qcom_scm_set_remote_state(u32 state, u32 id);
-struct qcom_scm_pas_metadata {
+struct qcom_scm_pas_context {
+ struct device *dev;
+ u32 pas_id;
+ phys_addr_t mem_phys;
+ size_t mem_size;
void *ptr;
dma_addr_t phys;
ssize_t size;
};
int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
- struct qcom_scm_pas_metadata *ctx);
-void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx);
+ struct qcom_scm_pas_context *ctx);
+void qcom_pas_metadata_release(struct qcom_scm_pas_context *ctx);
int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size);
int qcom_scm_pas_auth_and_reset(u32 pas_id);
int qcom_scm_pas_shutdown(u32 pas_id);
--- a/include/linux/soc/qcom/mdt_loader.h
+++ b/include/linux/soc/qcom/mdt_loader.h
@@ -10,14 +10,14 @@
struct device;
struct firmware;
-struct qcom_scm_pas_metadata;
+struct qcom_scm_pas_context;
#if IS_ENABLED(CONFIG_QCOM_MDT_LOADER)
ssize_t qcom_mdt_get_size(const struct firmware *fw);
int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
const char *fw_name, int pas_id, phys_addr_t mem_phys,
- struct qcom_scm_pas_metadata *pas_metadata_ctx);
+ struct qcom_scm_pas_context *pas_ctx);
int qcom_mdt_load(struct device *dev, const struct firmware *fw,
const char *fw_name, int pas_id, void *mem_region,
phys_addr_t mem_phys, size_t mem_size,
@@ -39,7 +39,7 @@ static inline ssize_t qcom_mdt_get_size(
static inline int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
const char *fw_name, int pas_id, phys_addr_t mem_phys,
- struct qcom_scm_pas_metadata *pas_metadata_ctx)
+ struct qcom_scm_pas_context *pas_ctx)
{
return -ENODEV;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 570/877] remoteproc: qcom: pas: Guard dtb metadata release with dtb_pas_id check
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (568 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 569/877] remoteproc: pas: Replace metadata context with PAS context structure Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 571/877] power: supply: ab8500_fg: Remove redundant dev_err()/dev_err_probe() Greg Kroah-Hartman
` (314 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Konrad Dybcio, Dmitry Baryshkov,
Mukesh Ojha, Bjorn Andersson, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
[ Upstream commit c06c5ab4945392d2c2aded6d832ab6b58cabe351 ]
All other call sites of qcom_scm_pas_metadata_release() for the DTB
context are guarded by a check on pas->dtb_pas_id, but the call inside
qcom_pas_load() was not. Fix this by moving the call to the guarded
block.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Fixes: 29814986b82e ("remoteproc: qcom_q6v5_pas: add support for dtb co-firmware loading")
Cc: stable@vger.kernel.org
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260724182858.1868271-3-mukesh.ojha@oss.qualcomm.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/remoteproc/qcom_q6v5_pas.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -247,17 +247,14 @@ static int adsp_load(struct rproc *rproc
pas->dtb_pas_id, pas->dtb_mem_region,
pas->dtb_mem_phys, pas->dtb_mem_size,
&pas->dtb_mem_reloc);
- if (ret)
- goto release_dtb_metadata;
+ if (ret) {
+ qcom_pas_metadata_release(pas->dtb_pas_ctx);
+ release_firmware(pas->dtb_firmware);
+ return ret;
+ }
}
return 0;
-
-release_dtb_metadata:
- qcom_pas_metadata_release(pas->dtb_pas_ctx);
- release_firmware(pas->dtb_firmware);
-
- return ret;
}
static int adsp_start(struct rproc *rproc)
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 571/877] power: supply: ab8500_fg: Remove redundant dev_err()/dev_err_probe()
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (569 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 570/877] remoteproc: qcom: pas: Guard dtb metadata release with dtb_pas_id check Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 572/877] power: supply: ab8500_fg: fix use-after-free on remove Greg Kroah-Hartman
` (313 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pan Chuang, Linus Walleij,
Sebastian Reichel, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pan Chuang <panchuang@vivo.com>
[ Upstream commit aa5f4decedfb4fc5cd0fe49ab256ad4304d192e4 ]
The devm_request_threaded_irq() and devm_request_irq() now automatically
log detailed error messages on failure. This eliminates the need for
driver-specific dev_err() and dev_err_probe() calls that previously
printed generic messages.
Signed-off-by: Pan Chuang <panchuang@vivo.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260709033428.362970-7-panchuang@vivo.com
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Stable-dep-of: 75b1e88d3425 ("power: supply: ab8500_fg: fix use-after-free on remove")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/power/supply/ab8500_fg.c | 2 --
1 file changed, 2 deletions(-)
--- a/drivers/power/supply/ab8500_fg.c
+++ b/drivers/power/supply/ab8500_fg.c
@@ -3179,8 +3179,6 @@ static int ab8500_fg_probe(struct platfo
ab8500_fg_irq[i].name, di);
if (ret != 0) {
- dev_err(dev, "failed to request %s IRQ %d: %d\n",
- ab8500_fg_irq[i].name, irq, ret);
destroy_workqueue(di->fg_wq);
return ret;
}
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 572/877] power: supply: ab8500_fg: fix use-after-free on remove
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (570 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 571/877] power: supply: ab8500_fg: Remove redundant dev_err()/dev_err_probe() Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 573/877] PCI: starfive: Use regulator APIs to control the 3v3 power supply of PCIe slots Greg Kroah-Hartman
` (312 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Fan Wu, Linus Walleij,
Sebastian Reichel, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
[ Upstream commit 75b1e88d34254f4fb7753345e21bfee47abddd7f ]
ab8500_fg_remove() destroys the driver workqueue while the threaded
interrupt handlers are still armed; they are devm-managed and freed
only after ->remove() returns, so a handler that fires in that
window queues work on the freed workqueue.
Tear the workqueue down through devm instead, registering its cleanup
after the power supply and before the interrupt requests. devm then
frees the interrupts first, so the handlers can no longer queue work,
before disabling the delayed and plain work items and destroying the
workqueue. Disabling the items, rather than cancelling them, keeps
them disabled so no producer (including the power-supply
external_power_changed callback) can requeue them.
Found by an in-house static analysis tool.
Fixes: 13151631b5bd ("ab8500-fg: A8500 fuel gauge driver")
Cc: stable@vger.kernel.org # v6.10+
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260802020316.417757-1-fanwu01@zju.edu.cn
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/power/supply/ab8500_fg.c | 30 +++++++++++++++++++++---------
1 file changed, 21 insertions(+), 9 deletions(-)
--- a/drivers/power/supply/ab8500_fg.c
+++ b/drivers/power/supply/ab8500_fg.c
@@ -3055,6 +3055,20 @@ static void ab8500_fg_unbind(struct devi
flush_workqueue(di->fg_wq);
}
+/* Disable, not cancel: works stay disabled so nothing can re-arm them. */
+static void ab8500_fg_destroy_workqueue(void *data)
+{
+ struct ab8500_fg *di = data;
+
+ disable_work_sync(&di->fg_acc_cur_work);
+ disable_work_sync(&di->fg_work);
+ disable_delayed_work_sync(&di->fg_reinit_work);
+ disable_delayed_work_sync(&di->fg_low_bat_work);
+ disable_delayed_work_sync(&di->fg_check_hw_failure_work);
+ disable_delayed_work_sync(&di->fg_periodic_work);
+ destroy_workqueue(di->fg_wq);
+}
+
static const struct component_ops ab8500_fg_component_ops = {
.bind = ab8500_fg_bind,
.unbind = ab8500_fg_unbind,
@@ -3156,6 +3170,11 @@ static int ab8500_fg_probe(struct platfo
return PTR_ERR(di->fg_psy);
}
+ /* Registered after fg_psy, before the IRQs: devm frees IRQ -> workqueue -> fg_psy. */
+ ret = devm_add_action_or_reset(dev, ab8500_fg_destroy_workqueue, di);
+ if (ret)
+ return ret;
+
di->fg_samples = SEC_TO_SAMPLE(di->bm->fg_params->init_timer);
/*
@@ -3168,20 +3187,16 @@ static int ab8500_fg_probe(struct platfo
/* Register primary interrupt handlers */
for (i = 0; i < ARRAY_SIZE(ab8500_fg_irq); i++) {
irq = platform_get_irq_byname(pdev, ab8500_fg_irq[i].name);
- if (irq < 0) {
- destroy_workqueue(di->fg_wq);
+ if (irq < 0)
return irq;
- }
ret = devm_request_threaded_irq(dev, irq, NULL,
ab8500_fg_irq[i].isr,
IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT,
ab8500_fg_irq[i].name, di);
- if (ret != 0) {
- destroy_workqueue(di->fg_wq);
+ if (ret != 0)
return ret;
- }
dev_dbg(dev, "Requested %s IRQ %d: %d\n",
ab8500_fg_irq[i].name, irq, ret);
}
@@ -3195,7 +3210,6 @@ static int ab8500_fg_probe(struct platfo
ret = ab8500_fg_sysfs_init(di);
if (ret) {
dev_err(dev, "failed to create sysfs entry\n");
- destroy_workqueue(di->fg_wq);
return ret;
}
@@ -3203,7 +3217,6 @@ static int ab8500_fg_probe(struct platfo
if (ret) {
dev_err(dev, "failed to create FG psy\n");
ab8500_fg_sysfs_exit(di);
- destroy_workqueue(di->fg_wq);
return ret;
}
@@ -3223,7 +3236,6 @@ static void ab8500_fg_remove(struct plat
{
struct ab8500_fg *di = platform_get_drvdata(pdev);
- destroy_workqueue(di->fg_wq);
component_del(&pdev->dev, &ab8500_fg_component_ops);
list_del(&di->node);
ab8500_fg_sysfs_exit(di);
^ permalink raw reply [flat|nested] 922+ messages in thread* [PATCH 6.12 573/877] PCI: starfive: Use regulator APIs to control the 3v3 power supply of PCIe slots
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
` (571 preceding siblings ...)
2026-09-30 15:24 ` [PATCH 6.12 572/877] power: supply: ab8500_fg: fix use-after-free on remove Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 574/877] PCI: starfive: Fix resource leaks on error paths in host_init() Greg Kroah-Hartman
` (311 subsequent siblings)
884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hal Feng, Manivannan Sadhasivam,
Kevin Xie, Sasha Levin
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hal Feng <hal.feng@starfivetech.com>
[ Upstream commit 05a75df4182e301a1b0059606f77b65c74deaa9b ]
The driver has been using the "enable-gpios" property to control the 3v3
power supply of PCIe slots. But it is not documented in the dt-bindings and
also using GPIO APIs is not a standard way to control PCIe slot power, so
use the documented "vpcie3v3-supply" property and regulator APIs to control
the slot supply.
This change will break the DTs which used "enable-gpio" or "enable-gpios"
property under the controller node. Since these properties were not defined
in the bindings, it is safe to switch to "vpcie3v3-supply". Any out-of-tree
DTS impacted by this change should migrate to "vpcie3v3-supply" instead.
Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
[mani: reworded description]
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
Acked-by: Kevin Xie <kevin.xie@starfivetech.com>
Link: https://patch.msgid.link/20251218102149.28062-1-hal.feng@starfivetech.com
Stable-dep-of: 22877a061f81 ("PCI: starfive: Fix resource leaks on error paths in host_init()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/pci/controller/plda/pcie-starfive.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
--- a/drivers/pci/controller/plda/pcie-starfive.c
+++ b/drivers/pci/controller/plda/pcie-starfive.c
@@ -55,7 +55,7 @@ struct starfive_jh7110_pcie {
struct reset_control *resets;
struct clk_bulk_data *clks;
struct regmap *reg_syscon;
- struct gpio_desc *power_gpio;
+ struct regulator *vpcie3v3;
struct gpio_desc *reset_gpio;
struct phy *phy;
@@ -153,11 +153,13 @@ static int starfive_pcie_parse_dt(struct
return dev_err_probe(dev, PTR_ERR(pcie->reset_gpio),
"failed to get perst-gpio\n");
- pcie->power_gpio = devm_gpiod_get_optional(dev, "enable",
- GPIOD_OUT_LOW);
- if (IS_ERR(pcie->power_gpio))
- return dev_err_probe(dev, PTR_ERR(pcie->power_gpio),
- "failed to get power-gpio\n");
+ pcie->vpcie3v3 = devm_regulator_get_optional(dev, "vpcie3v3");
+ if (IS_ERR(pcie->vpcie3v3)) {
+ if (PTR_ERR(pcie->vpcie3v3) != -ENODEV)
+ return dev_err_probe(dev, PTR_ERR(pcie->vpcie3v3),
+ "failed to get vpcie3v3 regulator\n");
+ pcie->vpcie3v3 = NULL;
+ }
return 0;
}
@@ -270,8 +272,8 @@ static void starfive_pcie_host_deinit(st
container_of(plda